浏览器的16ms渲染侦
Chromimum的Blink引擎的结论:
- 一个渲染帧内commit的多次DOM改动会被合并渲染
- 耗时JS会造成丢帧
- 渲染帧间隔为16ms左右
- 避免耗时脚本、交错读写样式以保证流畅的渲染
渲染帧:浏览器一次完整绘制过程。帧之间的时间间隔是DOM视图更新的最小间隔
主流的屏幕刷新频率都在60Hz,则渲染一帧的时间必须控制在16ms才能保证不掉帧(每一次渲染都要在16ms页面才能流程不卡顿)
渲染帧的任务
- 脚本执行(JS):脚本造成需要重绘的改动 eg: 增删DOM、请求动画等
- 样式计算(CSS Object Model): 级联地生成每个节点的生效样式
- 布局(Layout): 计算布局,执行渲染算法
- 重绘(Paint): 各层分别进行绘制
- 合成(Composite): 合成各层的渲染结果
耗时JS会造成丢帧
JS在并发编程的一个特点:“Run Tom Completion" 在事件循环的一次Tick中,若要执行的逻辑太多会一直阻塞下一个Tick,所有异步过程会阻塞
一个JS引擎的执行队列:
执行JS -> 空闲 -> 绘制(16ms) -> 执行JS -> 空闲 -> 绘制(32ms) -> ...
若某个时刻太多的JS要执行则一次丢帧的绘制:
执行较多的JS...(20ms) -> 空闲 -> 绘制(32ms) -> ...
eg: 案例:脚本在保持JS忙的状态(持续5s)下每隔1s新增一行DOM内容
<body>
<div id="message"></div>
</body>
<script>
var then = Date.now()
var i = 0
var el = document.getElementById('message')
while(true) {
var now = Date.now()
if(now - then > 1000) {
if(i++ >= 5) {
break;
}
el.innerText += 'hello! \n'
console.log(i)
then = now
}
}
</script>
学而不思则罔,思而不学则殆!

浙公网安备 33010602011771号