浏览器从页面加载到页面显示,中间发生了什么?
一.现代的浏览器采用的都是多进程架构,本文用到包含以下两种进程:
1.渲染进程
内核进程、负责页面渲染、JS执行,对应的是上述的渲染引擎和JS引擎,一个浏览器可以包含多个渲染进程,每个Tab窗口页对应一个渲染进程
2.GPU进程
负责GPU渲染,整个浏览器应用程序只有一个
多进程浏览器架构的主要优势有如下优势
1.避免单个页面奔溃影响整个浏览器
2.避免第三方插件奔溃影响整个浏览器
3.充分利用多核优势
二.浏览器的渲染进程
浏览器有多个渲染进程、一个Tab页面一个(相同的Tab页面可能会被合并)
一个渲染进程包含多个线程
一个渲染进程主要包括如下线程:
1.GUI线程(主要负责解析HTML、CSS和渲染页面)
2.JS引擎线程(负责解析和执行JS代码)
3.事件线程(控制事件循环)
4.定时器线程(处理定时器相关逻辑)
5.异步请求线程(发起Ajax时会生成该线程)
线程规则:
1.GUI渲染线程与JS引擎线程是互斥的,当JS引擎执行时GUI线程会被挂起,页面的更新操作会等到JS引擎空闲时执行,涉及任务和微任务相关知识
2.一个渲染进程同时只有一个JS解析线程在运行
3.JS引擎线程不停的处理事件线程推送到事件队列中的任务
4.定时器和异步请求最终生成的回调事件也有事件线程来控制和管理
JS引擎涉及的工作是js代码执行后,动态的变更了html和css,之后触发重绘或回流。js引擎的具体工作可自行查找资料,本文将继续了解加载页面的解析过程。
三.浏览器解析html页面的逻辑
在先前了解了上面知识后(现代浏览器采用的都是多进程架构,多进程浏览器架构的优势,浏览器的渲染进程)
我们基本对浏览器的解析有一个宏观的认识,如下
浏览器加载一个[Tab]页面=>生成一个渲染进程=>执行GUI渲染线程=>执行JS引擎线程。
(注意: 前面说过,GUI渲染线程和JS引擎线程是互斥的。)
因此,我们可以具体的说明如下,
在页面加载时候
1.浏览器把HTML文档代码解析成1个HTML DOM树
HTML DOM树上面包含所有节点(包括display:none;隐藏的节点。和JS动态增加的节点)
DOM 定义了访问 HTML 和 XML 文档的标准:
“W3C 文档对象模型 (DOM) 是中立于平台和语言的接口,它允许程序和脚本动态地访问和更新文档的内容、结构和样式。”
HTML DOM 是:
- HTML 的标准对象模型
- HTML 的标准编程接口
- W3C 标准
HTML DOM 定义了所有 HTML 元素的对象和属性,以及访问它们的方法。
换言之,HTML DOM 是关于如何获取、修改、添加或删除 HTML 元素的标准。
2.浏览器把页面所有CSS[样式]代码解析成1个CSS 树(样式结构体)
我理解到的有css选择器定义样式是将选择器的排序从右到左定位到html元素上。从而生成css树。
3.HTML DOM树和样式结构体组合后构建的render树,并设置布局(Layout)。
render树是即将要绘制的树。是要显示到页面的。所以不含含display:none;隐藏的节点和head节点。
实际上html+css制作的页面就包含生成这样子的render树的过程。
4.绘制render树。
通过GUI线程调用操作系统绘制接口,将页面绘制出来。
之后就是回流和重绘了。即接下来涉及到了JS引擎线程。
以上步骤是一个渐进的过程,为了提高用户体验,渲染引擎试图尽可能快的把结果显示给最终用户。它不会等到所有HTML都被解析完才创建并布局渲染树。它会在从网络层获取文档内容的同时把已经接收到的局部内容先展示出来。
页面加载流程图如下:
结语
本文属于个人总结。 如有理解错误,或者遗漏的的重要知识点,希望指出。 如果你觉得这篇文章不错,请别忘记点个赞跟关注哦~😊