字节面试题:多次改变DOM元素会渲染几次

253 阅读2分钟

前言

在面试字节的时候被问到了这样一道题

let app = document.getElementById('app')
app.style.width = (app.offsetWidth+1)+'px'
app.style.width = 10+'px'
app.style.width = (app.offsetWidth+1)+'px'
app.style.width = 10+'px'
app.style.width = (app.offsetWidth+1)+'px'

问我这样一段代码会触发几次浏览器的渲染,当时第一时间就感觉到这道题目有坑,但是还是回答了三次,认为是修改一次就会触发一次,面试官微微一笑,我就知道,我寄了。

浏览器的优化策略

这道题其实主要考的就是浏览器的一个优化策略。我们都知道浏览器整个渲染过程是

  1. 构建DOM树
  2. 构建CSS树
  3. 将DOM树和CSS树合并构建Render树
  4. 回流
  5. 重绘

而修改DOM元素的几何属性就会触发回流然后触发重绘,如果单独修改DOM元素非几何属性如背景颜色字体颜色就只会触发重绘。起初我以为是要考我关于回流和重绘的问题,但是又总隐隐感觉不对劲。面试官告诉我这个答案是3次


其实简单的说就是浏览的的优化策略对于回流和重绘这部分的优化。浏览器内部会有一个渲染队列,当有回流和重绘的行为时会将其放入渲染队列,直至渲染队列满或是使用 `offset` 属性进行相关的操作,就会将渲染队列清空,然后进行一次浏览器的渲染也就是回流重绘操作。 至此,上面整个代码流程就是
let app = document.getElementById('app')
app.style.width = (app.offsetWidth+1)+'px'//使用offset属性读取清空渲染队列
// 但是此时渲染队列为空,就没有渲染操作,然后是修改app宽度操作被压入渲染队列
app.style.width = 10+'px'// 被压入渲染队列
app.style.width = (app.offsetWidth+1)+'px'// 清空渲染队列一次渲染,同时新的回流操作被压入渲染队列
app.style.width = 10+'px'// 被压入渲染队列
app.style.width = (app.offsetWidth+1)+'px'// 清空渲染队列,同时压入一个回流操作
// 最后代码结束,渲染队列还有值,清空渲染队列,总共是三次渲染

尾声

其实最近面试下来,我感觉很多大厂其实不会太考八股,他们很多考的内容都是基础的部分然后基于工作需要知道的东西进行拓展,我觉得想要面大厂其实应该多练练手写,并不是去单纯的背,而是去理解它,这个过程你的基础就会越来越牢固。当然一些基本的八股还是需要知道的。