Appearance
记录一次前端输入框引发的抖动 Bug 修复
背景
最近接到一个 AI 公文助手输入优化的需求,需要对 UI 进行改版。发现这个表单处的输入框体验非常不好,于是改为了项目中已引用的 Element-UI 组件库中的 EL-Inpt,改完后发现了问题,只要连续的输入就会出现页面抖动的现象。于是我知道了之前为什么不用组件库中的 EL-Inpt 而是自己写了一个不好用的输入框组件了(🤪)。
如图: 右侧表单填写内容,会导致左侧红色框整体都在抖动
当然自己重新写一个好用的组件是一个好办法,但是重新造轮子 。。。 也是个好办法。
那还是需要去看下具体是什么原因导致的这个抖动。
问题分析定位
从 HTML5 层进行排查
第一步:
F12进行CSSdebug ,查看右侧表单输入时,CSS变化,发现右侧表单宽度未发生异常,但是左侧区域出现了10px的抖动第二步:怀疑是我们的布局有问题,于是固定右侧的布局宽度以及将左侧布局直接替换为一个
Div,发现还是会抖动。其实前面提到替换为EL-Inpt后出现了抖动、那么大概率也就是这个组件引起的原因。第三步:大概率确定就是
EL-Inpt组件出了问题,于是将EL-Inpt的布局中最外层的Div移除掉 (EL-Inpt组件的布局是Div -> textarea),发现抖动也消失了。基本确定就是EL-Inpt导致的。第四步:去
Github上Element-UI仓库看了下issue好像没发现类似的问题,看来还是比较不好复现的 🤪,接着大致看了下EL-Inpt组件的实现,发现calcTextareaHeight.js中在计算动态输入框高度时会在内容变动时新建了一个隐藏的Textarea元素用于计算高度,然后又移除掉,感觉这里很可疑,于是准备先从这里下手。第五步:继续回到项目中找到
calcTextareaHeight.js文件
从项目中调式排查
第六步:项目是基于 Vite 的,为了好验证直接在项目中调试。
Element-UI下node_modules/element-ui/lib/input.js文件是打包后的EL-Inpt实现,整体阅读性还好,可以参考着node_modules/element-ui/packages/input源码进行阅读,将calcTextareaHeight.js中的创建的隐藏域的Textarea直接移除掉;将
node_modules/.vite/deps文件夹下的文件全部删掉(这个是调式的缓存的chunk文件,Vite之所以高效,多半也是因为如此),然后重新刷新项目,Vite 会继续打包缓存node_modules/element-ui/lib/input.js文件到node_modules/.vite/deps中; 发下此时不在抖动,也发现问题了, 隐藏域的Textarea创建时直接挂载到document上,然后在进行样式属性的赋值,这导致在挂载到document时,Textarea占据了一些位置导致左侧视图被挤,导致抖动。继续上面的步骤,这次只是将 隐藏域的
Textarea进行了隐藏,问题解决; 当然这里也可以设置让它浮动等等其他方式,在创建时不占空间。
解决问题
Hook ?,似乎不是那么方便Fork 一份Element-UI到私有Git仓库,然后进行源码修改,再npm publish到npm私有仓库 ? 但是这样每次更新组件很麻烦,而且还受网络环境影响- 这里直接仿照
EL-Inpt实现重新写了一份组件,满足各种各样的需求
