常见面试题
1. 什么是 reflow?
reflow 的本质就是重新计算 layout 树。
当进行了会影响布局树的操作后,需要重新计算布局树,会引发 layout。
为了避免连续的多次操作导致布局树反复计算,浏览器会合并这些操作,当 JS 代码全部完成后再进行统一计算。所以,改动属性造成的 reflow 是异步完成的。
也同样因为如此,当 JS 获取布局属性时,就可能造成无法获取到最新的布局信息。
浏览器在反复权衡下,最终决定获取属性立即 reflow。
2. 什么是 repaint?
repaint 的本质就是重新根据分层信息计算了绘制指令。
当改动了可见样式后,就需要重新计算,会引发 repaint。
由于元素的布局信息也属于可见样式,所以 reflow 一定会引起 repaint。
3. 为什么 transform 的效率高?
因为 transform 既不会影响布局也不会影响绘制指令,它影响的只是渲染流程的最后一个「draw」阶段
由于 draw 阶段在合成线程中,所以 transform 的变化几乎不会影响渲染主线程。反之,渲染主线程无论如何忙碌,也不会影响 transform 的变化。
4. 说一下浏览器渲染流程?
浏览器渲染网页的过程是一个复杂且多步骤的过程,它涉及从接收 HTML、CSS 和 JavaScript 代码到最终在屏幕上显示内容的多个阶段。
1. 构建 DOM 树(Document Object Model Tree)
- 解析 HTML:当浏览器接收到服务器返回的 HTML 文档后,开始自上而下解析 HTML 标记,转换成 DOM 节点,并构建 DOM 树。如果遇到外部资源如图片、样式表或脚本,则会发起额外请求。
- 处理阻塞:默认情况下,浏览器会在遇到
<script>标签时暂停 HTML 解析,优先加载并执行 JavaScript 代码,因为脚本可能需要操作尚未完全加载的 DOM。
2. 构建 CSSOM(CSS Object Model)
- 解析 CSS:同时,浏览器也会解析所有可用的 CSS 规则,包括内联样式、内部样式表以及外部样式表,生成 CSS 对象模型(CSSOM)。与 DOM 类似,CSSOM 也是一个树状结构。
- CSS 优先级计算:在这个过程中,浏览器还会根据选择器的特异性来决定哪些样式应该应用于哪个元素。
3. 创建渲染树(Render Tree)
- 合并 DOM 与 CSSOM:浏览器将 DOM 树和 CSSOM 树结合起来创建渲染树。注意,只有那些可见的元素才会被包含进渲染树中(例如,
display: none;的元素不会出现在渲染树里)。 - 应用样式:此时,每个节点都已经知道了其对应的样式信息。
4. 布局(Layout)
- 确定位置大小:基于渲染树,浏览器计算每个节点在屏幕上的确切位置和大小。这个过程被称为“布局”或者“重排”(reflow),涉及到页面上所有元素的位置调整以适应不同的视口尺寸或内容变化。
5. 绘制(Painting)
- 绘制像素:一旦布局完成,浏览器就知道了每个节点的确切外观和位置,接下来就是将这些信息转化为实际的像素点显示在屏幕上。这一步骤叫做“绘制”或“重绘”(repaint)。
6. 合成(Compositing)
- 优化显示:现代浏览器通常会进一步优化显示过程,通过分层技术将页面的不同部分分别绘制到不同的图层上,然后利用 GPU 加速合成这些图层以提高性能。
注意事项
- 避免不必要的重排和重绘:频繁的 DOM 操作可能导致大量的重排和重绘,影响性能。可以通过批量修改 DOM、使用
requestAnimationFrame()等方法减少这种影响。 - 异步加载资源:对于非关键资源(如字体、图片等),可以采用懒加载或异步加载策略,以加快首屏加载速度。
- JavaScript 的影响:JavaScript 能够直接操作 DOM 和 CSSOM,因此不当的脚本可能会显著拖慢页面加载速度。合理安排脚本的位置和执行时机至关重要。


