面试系列-浏览器渲染

131 阅读3分钟

「这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战

如果你参加过前端面试的话,这道题你一定听过:浏览器是如何渲染页面的?

很多人一定会说渲染过程和我写页面有什么关系,这种想法就大错特错了,前端再开发过程中,如果能知道渲染过程,就会在一定程度加快请求,提升体验感,那接下来就一起看看他是如何实现渲染的吧

image.png

1. 渲染过程

  • 打开网页开始解析HTML,生成DOM树。解析CSS创建CSSOM树
  • 当DOM树和CSSOM树生成之后,就会将这两棵树组合成渲染树。
  • 根据渲染树继续布局,计算每个节点的位置
  • 之后调用GPU绘制,合成图层,显示在屏幕上。

在构建CSSOM树的时,会阻塞渲染,直至CSSOM树渲染完毕。并且构建CSSOM树十分消耗性能的过程,所以应该尽可能的保证层级扁平,减少过度层叠,越是具体的CSS选择器,执行速度越慢。

2. 为什么操作DOM慢?

答:因为DOM是属于渲染引擎中的东西,JS是JS引擎中的东西,当我们使用JS操作DOM,这个操作涉及两个进程之间的通信,所以在性能上一定会有损耗。操作DOM的次数越多,也就等同于一直在进行进程之间的通信,并且操作DOM还会带来回流。

3. JS会阻塞DOM树吗

答:会,当渲染进程开始解析HTML文档时,会先开启一个预解析线程,遇到JS和CSS文件,预解析会提前下载这些数据。如果代码里引用了外部的CSS文件,那么在执行JS之前,要先将CSS文件下载完成,并解析成CSSOM对象之后,才能执行JS脚本。在JS引擎解析JS之前,是不知道JS是否操纵了CSSOM的,所以渲染引擎在遇见JS的时候,不管有没有操纵CSSOM,都会先执行下载CSS,解析操作,在执行JS。最后在继续构建DOM树,构建布局树,绘制页面。

4. JS为什么阻塞页面渲染

答:由于JS是可以操控DOM的,如果在修改元素的同时渲染页面,会造成前后数据不一致,为了解决这个问题,浏览器设置渲染线程和JS引擎为互斥关系。也就是说JS引擎在执行时,渲染线程被保存到一个队列里面等待被执行,等到JS引擎执行完毕,才会开始渲染页面。如果JS执行的时间过长,那么就会造成页面渲染的不连续,导致页面渲染加载有阻塞的感觉

5. css加载会造成阻塞吗

答:DOM树和CSSOM树是并行构建的,所以css加载并不会阻塞DOM的解析

然而,渲染树是依赖于DOM树和CSSOM树的,也就是说只有CSS资源加载完成才会开始渲染。因此,CSS加载会阻塞DOM的渲染。

由于JS可以操控DOM和CSS样式,如果在修改这些样式的时候同时渲染页面,就会发生数据不一致的情况,为了避免这种结果,浏览器设置渲染线程和JS引擎是互斥关系,因此样式表会在后面的JS执行前先加载执行完毕,所以,CSS会阻塞后面的JS执行。