有个流传已久的面试题:从浏览器输入url到页面出现会发生什么?
这里面有很多可以说的东西,基本属于自由发挥,本篇就一起来聊聊最“看得见”的一环。
浏览器线程
浏览器线程了解过的基本会知道有5个线程
- js引擎线程
- 异步请求线程
- 定时器线程
- 事件触发线程
- html页面渲染线程
这里主要了解下html页面渲染线程,一般请求从服务端带回一串html,浏览器开始解析,主要分两步。 第一步把html解析成树型DOM的同时,把css解析成树型css规则。 第二步把这两个树型数据合为一个渲染用的render树。
这个时候拿到render树浏览器就可以实际渲染了,计算dom树挂载的盒子位置和占位大小,将内容及样式展现在网页上。
重排&重绘
基于上面的渲染线程,样式相关主要有两个计算,一个是计算盒子位置和占位,一个是渲染里面内容和样式。
- 重排:当一个盒子位置或占位大小改变,重新计算相关盒子(同一个文档流或者BFC)的位置和占位大小。
- 重绘:当一个盒子的位置、占位大小不变,重新计算当前盒子的渲染样式。比如:颜色、背景图。
重绘的计算量相比于重排的要小得多,甚至基本可以忽略不计。
所以前端功能为了良好的体验可以尽量避免重排计算,从渲染线程来看会引起重排的无非就以下几点:
- dom树移除或新增节点。
- css树有关布局、大小样式更改。
代码Tips
display
display: none;的节点是不会挂在render树的,所以display: none;是一定会触发重排的,如果需要优化可以尝试用display: hidden;代替。
定位偏移和z-index
绝对定位position: absolute;是参照最近非static定位的父级进行偏移定位。
例如下面id=c盒子就是参照id=a盒子偏移
<div id="a" style="position: absolute;width: 200px;height: 400px;background-color: #323232;top: 50px;">
<div id="b" style="margin-top: -50px;margin-left: 50px;height: 100px;width: 200px;background-color: red;">
<div id="c" style="position: absolute;height: 100px;width: 200px;background-color: blue;top: 50px;left: 50px;"></div>
</div>
</div>
需要值得注意的是z-index在上面的dom结构中不会生效。 z-index生效的条件是
- 比较层级的小盒子是在同一个大盒子中,
- 且在同一个文档流中。 所以absolute和fixed定位要比较z-index时需要注意,比较的盒子是否也是脱离正常文档流。