Draft.js mac 吞字问题
曾经解决的问题,遗忘在了角落
缘起
Q、H 反馈那两天写部门规划材料,输入文字饱受吞字问题困扰,我临危受命,需要优先解决这个问题。
过程
我目前在 windows 上未遇到过吞字问题,之前产生的吞字问题是由于处理合成输入会出现问题,不过现在已经好了。领导都是 mac,那我自然需要找一台 mac 测试。从 T 那里借了一台 mac,访问本机 playground ,发现在我狂暴输入下并没有什么问题。转头在 Q 那里尝试,逐渐是摸索出了稳定触发方式。按下空格,输入 hufu(忽复乘舟梦日边),h 会消失,只显示 ufu。
后面用了周围的六七台 mac 试了一圈,都能稳定复现,但我手上的 T 机器就是复现不了。起初以为是 T 机器版本最低,跟版本有关,第二天又拿了 Z 的高版本机器测试,发现也没问题。
然后回想了测试机器的情况,发现是出了问题的机器都是在一个高负载的工作状态,而 T 和 Z 的机器都是只单开了一个 chrome,难不成更负载有关?
于是打开终端 for i in {1..8}; do yes > /dev/null & done,把机子的 CPU 负载压力拉上去。果然就容易复现了。于是思路就从输入法和 draft 的兼容问题转到了 draft 本身问题。在尝试了不同的文本下的输入后确定了以下条件
- 要在两个富文本中间,先输入空格问题才会触发。快速按下空格加一个字符 这是怎么回事,搜搜 draft.js issue 都没有相关的反馈。于是再次确认输入情况,打 log 观察整体代码的运行情况。 最终发现是 draft rerender 引起的选区重定位,造成了一切。所以思路就变成了
why children will be rerendered;
- leaf start,end, selection,
- 为什么只有光标两边的节点会 rerendered,
- 在同一个节点上面的进行输入时,节点不会 rerendered
但我现在对代码不熟怎么办,还是加 log ,输入加 log,render 加 log,感觉代码会跑到的地方都加上 log。最终真的发现了问题在哪里。 draft 是为了修复一个 bug 而对类似情况加了强制重渲染,把这个代码去掉之后,发现并没有什么问题,于是就去掉了,能正常输入了,最后也顺利上线了。感谢 draft 写的详细注释,让我敢去掉这段代码。
if (!mustPreventNative) {
// Browsers tend to insert text in weird places in the DOM when typing at
// the start of a leaf, so we'll handle it ourselves.
// mustPreventNative = isSelectionAtLeafStart(editor._latestCommittedEditorState)
}
track
这是一些解决问题时想到的思路
- 只在 mac 上复现,跟 mac 什么内容有关? https://github.com/facebookarchive/draft-js/issues/2422 https://github.com/facebookarchive/draft-js/issues/1102
- 需要看看其他库对 mac 上做了什么处理
- 后面测试发现 windows 也会出现,只不过出现几率小于 mac
- 为什么相同样式文本里输入时没问题,不同样式文本输入就会有问题
- composition https://github.com/facebookarchive/draft-js/pull/1084 https://blog.csdn.net/weixin_41697143/article/details/108179432