这只是一个浏览器渲染流程的索引

我正在参与掘金创作者训练营第4期,点击了解活动详情,一起学习吧!


最近在进行前端知识查漏补缺,遇到了一个经典问题:《从在浏览器中输入网址到页面加载完成这个过程发生了什么?》。说实话,这是一道综合性很强的题目,把网络、加密、浏览器渲染、JavaScript 引擎等多方面问题串联起来,想要回答好也是很困难。今天我就尝试用自己的语言,讲一个浏览器渲染部分的故事,争取做到在不与标准偏离太多的情况下尽量的好理解。

个人理解,有误轻拍,这就是个索引而已。

DOM 和 CSSOM

在这个故事中有两个角色:浏览器和 Web 服务器。其中浏览器作为客户端的角色,给服务端传递一个 URI,向作为服务端的 Web 服务器索要资源。假设请求了一个 html 文档,服务器就会将对应的源代码返回给浏览器。

这个时候浏览器接收到 html 源代码,会在内存空间中开辟一段执行栈内存,并分配一个主线程,用来从上到下逐行解析源代码。

标准的 html5 文档,第一行会是 <!DOCTYPE html>

浏览器发现了这个,就知道需要按照 HTML5 的模式解析。浏览器解析文档有两种模式:标准模式和怪异模式,这两种模式在解析样式上会略有区别。

然后继续解析,当发现有外链资源时,会将请求外链资源这个任务放在单独的一个任务队列里面,同时分配子进程去获取外链资源。一般浏览器限制的同一域名最大并发线程数量为 6,在队列里面的其他任务,将等待其中一个线程完成后依次执行。

当外链资源返回时,会有两种情况:

  • 如果是 CSS、图片、视频、音频等不会修改 DOM 结构的资源,会直接放入主队列

    • 特别的,如果是 CSS,返回后会直接去构建 CSSOM 树

    浏览器解析 CSS 会生成 CSS 规则树,每个文件都会分析为 Stylesheet 对象,包含变量、选择器、媒体查询等多个标记。如果有规则重复,会通过优先级判断决定高优先级生效。有一些合并的写法,也会按照其可拆分的最小部分判断覆盖规则。一般浏览器会自带一套样式,这套样式的优先级是最低的。

  • 如果是 JavaScript,因为可能会去修改 DOM 结构,DOM 解析时为了防止白费劲,就等待 JavaScript 执行完成后才继续解析。但是,如果有 async 和 defer 标志,则事情又有所变化。

    • 有了 async,JavaScript 代码将会异步执行,不会阻塞 DOM 解析队列。
    • 有了 defer,JavaScript 代码会等待 DOM 树整体构建完成之后,才执行

这两个标志,实际上是通过约定的方式让浏览器开个后门减少优化。

你知道这个脚本没有修改 DOM 的功能,可以和 DOM 树构建一起进行,那就给一个 async。我相信你,如果你骗了我,那最终就会有些浪费

浏览器在解析生成 DOM 过程中,经历了词法分析等过程,简单说,可以通过解析字符串知道这是文本、标签还是注释,同时如果标签不全,也会猜测并自动补全。

词法分析部分看这里:www.cnblogs.com/bchjazh/art…

这边 DOM 树解析完成了,那边 CSSOM 树也解析完成了,然后两者一结合,出来个渲染树。当然有时候,一个可能比另一个慢,那就等他们全部解析完成后才结合。

渲染树

从 DOM 树的根节点开始遍历每个可见节点,并在 CSSOM 中找到适配的样式规则并应用,最终展示在屏幕上。在这个过程中,会遇到重绘和回流的过程。

重绘和回流

重绘,就是重新绘制,比如说原来这个正方形没有颜色,CSS 样式把这个正方形变成红色的了,他的样子改变了,就是重绘了。
回流,也叫重排,简单说就是重新排版。由于文档内的元素是以流式排布的,因此如果某个元素的尺寸和位置发生变化,文档流就会发生变化,这就引发了回流的过程。一般回流指的是对当前变化元素下游元素位置的影响。上游元素是没有影响的。

相比较来说,回流对性能的影响可能会更大一些,毕竟做了许多无用功。

对了,回流必然伴随着重绘,重绘不一定回流

总结

随手写了一大堆自己的理解,虽然点了很多,但是都有些没讲透。不过没关系,这篇文章只是一个索引而已。对于浏览器渲染,需要了解的内容远不是那一道流行的面试题答案那么简单,也不可能一步到位。还是得自行整理。

推荐文章

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享