浏览器的16ms渲染侦

Chromimum的Blink引擎的结论:

  1. 一个渲染帧内commit的多次DOM改动会被合并渲染
  2. 耗时JS会造成丢帧
  3. 渲染帧间隔为16ms左右
  4. 避免耗时脚本、交错读写样式以保证流畅的渲染
    渲染帧:浏览器一次完整绘制过程。帧之间的时间间隔是DOM视图更新的最小间隔
    主流的屏幕刷新频率都在60Hz,则渲染一帧的时间必须控制在16ms才能保证不掉帧(每一次渲染都要在16ms页面才能流程不卡顿)

渲染帧的任务

  1. 脚本执行(JS):脚本造成需要重绘的改动 eg: 增删DOM、请求动画等
  2. 样式计算(CSS Object Model): 级联地生成每个节点的生效样式
  3. 布局(Layout): 计算布局,执行渲染算法
  4. 重绘(Paint): 各层分别进行绘制
  5. 合成(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>
posted @ 2025-02-15 14:15  Felix_Openmind  阅读(48)  评论(0)    收藏  举报
*{cursor: url(https://files-cdn.cnblogs.com/files/morango/fish-cursor.ico),auto;}