AI 打字跟随优化
作者:互联网
2026-04-18
前文提到通过API去滚动容器或容器尺寸去触发打字跟随,用户的滚动去读取造成重排的属性来实现用户是否跟随打字实际会造成浏览器多次重排。
重排
浏览器重排(回流)是浏览器对DOM元素计算位置、尺寸、布局的过程。 浏览器解析HTML合成DOM树,解析CSS合成CSSOM树,它们会一步步合成渲染树,进行布局。页面、结构、尺寸发生变化就会再走一遍布局的计算流程,称为重排。
为什么重排会造成性能开销?
- 当一个元素变化后,可能影响父元素、子元素、兄弟元素等,浏览器需要进行递归遍历。
- 重排需要在浏览器主线程发生,阻塞JS、渲染。
- 频繁重排会造成浏览器卡顿,浏览器的刷新率是60fps,每帧近16ms,一次重排就会占据一部分时间;多次重排会导致掉帧。
哪些操作会导致重排?
- 元素几何属性发生变化。
- 增删、移动DOM。
- 窗口变化(resize、scroll页面等)
- 获取布局相关属性:
-
offsetTop/offsetLeft/offsetWidth/offsetHeight -
scrollTop/scrollHeight -
clientTop/clientWidth等 -
getComputedStyle() -
getBoundingClientRect()
-
IntersectionObserver 哨兵模式
这里直接取消滚动事件的,在容器的最底部放一个哨兵容器,通过 IntersectionObserver 去哨兵在的父元素在可视区域的交叉值来判断用户是否滚动。让哨兵通过 scrollIntoView 直接暴露在可视区域,实现打字跟随。
<div class="ch@t-scroll-container" ref="scrollContainerRef">
<div class="ch@t-container" id="messagesRef">div>
<div class="scroll-sentinel" ref="sentinelRef">div> // 哨兵
div>
threshold: 1 // 1 :表示全部进入,0 :露头就秒
onMounted(() => {
const ro = new ResizeObserver(() => {
if (enableAutoScroll.value) {
scrollToBottom();
}
});
ro.observe(ch@tMessagesRef.value);
observer = new IntersectionObserver(
(entries) => {
const isIntersecting = entries[0].isIntersecting;
enableAutoScroll.value = isIntersecting;
},
{
root: scrollContainerRef.value, // 父元素,默认为 root
threshold: 1, // 1表示全部进入,0 :露头就秒
rootMargin: '10px', // 提前10px开始生效
}
);
if (sentinelRef.value) observer.observe(sentinelRef.value);
});
const scrollToBottom = () => {
nextTick(() => {
const el = sentinelRef.value;
if (!el) return;
if (enableAutoScroll.value) {
sentinelRef.value.scrollIntoView({ behavior: 'instant' });
}
});
};
在实践过程中,如果使用 behavior: 'smooth' ,浏览器在触发 scrollToBottom 时发生的动画会频繁抖动,将哨兵挤到父容器的可视区域外,导致 IntersectionObserver 频繁触发,可能产生 bug,使用 instant 取消浏览器动画抖动,直接抵达底部,避免该情况产生。
相关推荐
专题
+ 收藏
+ 收藏
+ 收藏
+ 收藏
+ 收藏
+ 收藏
最新数据
相关文章
vue3 数据响应式遇到的问题
vxe-table 自定义数字行主键,解决默认字符串主键与后端类型不匹配问题
AI 打字跟随优化
你的 Vue 3 defineEmits(),VuReact 会编译成什么样的 React?
Vue3 + TS 企业级工程化项目全套实战(Vue3 + Vite + Pinia + VueRouter + Element Plus)
Vue 3 defineOptions 宏,用 VuReact 编译成 React 长什么样?
Vue3 KeepAlive 深度揭秘:组件缓存的魔法是如何实现的?
你的 Vue 3 useAttrs(),VuReact 会编译成什么样的 React?
虚拟 DOM 的 Diff 算法:Vue/React 如何实现高效更新
前端必看!console 调试不只有 log,这 8 个技巧省一半调试时间
AI精选
