浏览器页面渲染机制

他们夫妻,丈夫是高个子,妻子要矮上近四十公分。女儿的个子当然不高,成年以后常怨毒地责问“你凭什么娶个侏儒来连累后代”。当年,他在兵团的广播站里第一次听到她的声音,就开始疯狂地想念她,不知羞耻地逢人便诉说。当得知她的个子只到自己胸前时,不是失望,而是鼓起了追求的勇气。

1.基本概念

浏览器内核两个核心程序:渲染引擎,JS引擎。当然,DOM是属于渲染引擎里面的东西,所以使用JS去操作DOM的时候,本质上是JS引擎和DOM引擎进行了跨界交流,而这个跨界交流的开销并不小,所以需要尽量减少操作DOM。需要注意的地方,这里所说的DOM操作不仅包括了修改,而且也包括了读取。

页面经过下面这些步骤呈现在用户眼中:1).输入域名,浏览器进行DNS解析获取服务器IP地址;2).浏览器向这个IP地址的机器发送请求;3).服务器处理请求,发送响应;4).浏览收到响应数据,接着根据关键渲染路径进行渲染页面。

2.关键渲染路径

浏览器在收到了文件的字节码之后,会根据charset解码出对应的字符串。在没有JS干扰的情况下,关键渲染路径分为了下面几个步骤:构建DOM(document object model);构建CSSOM(css object model);利用构建出来的DOM和CSSOM创建出渲染树。接下来浏览器会分析渲染树中的每一个节点在网页中所对应的位置,这步也叫做布局。布局完接下来便开始在屏幕上绘制像素。正常情况下,DOM构建和CSSOM构建是并行构建的。

那么在有JS干扰的情况下呢?JS会阻塞DOM构建,同时JS也会阻塞CSSOM的构建,如果某个时刻下,浏览器还没有完成CSSOM的下载和构建的话,但是此时同时还在运行脚本,那么浏览器将会延迟脚本执行和DOM构建,直至完成CSSOM的下载和构建。划重点,不仅会阻塞js执行而且还会阻塞DOM构建。遇到脚本时,优先级为先构建CSSOM,接着执行JS,然后构建DOM。

CSSOM会阻塞渲染,只有当CSSOM构建完毕后才会进入下一个阶段构建渲染树。

关于关键渲染路径的详细解释博文链接

构建出来的DOM树和渲染树还是存在区别的,对于那些因为样式导致元素不存在(比如display:none;)的节点在DOM树中会存在;但是在渲染树中就不会存在了。

3.布局和绘制

当浏览器生成渲染树后,就会根据渲染树来进行布局。布局也叫做回流,浏览器在回流过程中做的主要工作就是计算渲染树中各个节点在屏幕上确切位置和大小。

4.回流reflow和重绘repaint

重绘repaint:当我们对DOM节点样式的修改并没有影响到位置属性的时候(比如说设置背景色),此时只需要进行重绘repaint步骤。

回流reflow:对DOM节点样式的修改影响了位置属性(比如设置box的宽高,隐藏显示元素等),此时将会引起回流reflow过程。

回流必定重绘,重绘并不引起回流。回流的成本会比重绘要高。需要注意的是下面这些行为也会引发回流reflow:内容变化,比如input输入文字;计算offseWidth和offsetHeight;浏览器窗口尺寸发生变化。

5.script的async属性,defer属性区别。

默认行为下的script行为是会阻塞页面,这里的阻塞页面既包括了执行js期间的阻塞;也包括从其它存储空间里面加载js文件期间的阻塞(如从网络中获取);

async行为:从其它存储空间加载js文件这个过程是不会阻塞页面文档解析的,此时文档解析和网络加载js在浏览器中是并行执行;但是一旦加载完js文件,执行js期间将会阻塞页面解析;js运行完毕后,在从中断位置处继续进行页面解析步骤;

defer行为:加载js和不阻塞页面文档解析,加载js和页面解析在浏览器中是并行执行;但是js的运行并不是js一加载完成便开始运行的,而是等到页面文档解析完成的时候,js才开始执行。也就是说,defer下script被延迟了运行,但是加载过程是和页面解析过程并行的。

6.如何进行性能优化?

1.可以给某些引用的js文件加上async或者defer标签,避免阻塞页面解析;

2.css的link可以加上preload标签,因为CSSOM + DOM 才能构建出渲染树,而且CSSOM还会阻塞JS。

7.参考文章:

berwin’s blog

优化关键路径渲染

性能优化相关