一, 概述
在分析浏览器的渲染过程之前, 我们先了解一下什么是进程和线程:
(1) 什么是进程?
进程是 CPU 进行资源分配的基本单位
(2) 什么是线程?
线程是 CPU 调度的最小单位, 是建立在进程的基础上运行的单位, 共享进程的内存空间.
那么我们可以得出结论:
1, 进程是会占用系统资源; 2, 一个进程内可以存在一个或者多个线程, 这就是单线程和多线程; 3, 无论是单线程还是多线程都是在一个进程内.
博客首发地址 (sau 交流学习社区): https://www.mwcxs.top/page/567.html
二, 多进程
从上图中可知:
1, 浏览器是多进程
2, 不同类型的标签页都会开启一个新的进程
3, 相同类型的标签页是会合并到一个进程
上图中浏览器的各个进程的主要作用:
1, 浏览器进程
(1) 负责管理各个标签页的创建和销毁
(2) 负责浏览器的页面显示和功能 (前进, 后退, 收藏等)
(3) 负责资源的管理与下载
2, 第三方插件进程
(1) 负责每个第三方插件的使用, 每个第三方插件使用时候都会创建一个对应的进程
3,GPU 进程
(1) 负责 3D 绘制和硬件加速
4, 浏览器渲染进程 (咱们这回主要分析的)
1, 浏览器内核, 主要负责 HTML,CSS,JS 等文件的解析和执行
三, 浏览器内核
浏览器内核就是浏览器渲染进程, 从接收下载文件后再到呈现整个页面的过程, 由浏览器渲染进程负责, 主要流程如下:
1, 解析 HTML 文件和 CSS 文件, 加载图片等资源文件, 渲染成用户看到的页面
2, 执行解析 JS 文件脚本代码
这里主要讲浏览器页面渲染过程, JS 脚本解析执行过程, 可以看这篇文章: JavaScript 引擎执行的过程的理解 -- 执行阶段 , 所以本文的 JS 解析的内容会省略
在该过程中浏览器渲染进程会开启多个线程协作完成, 主要的线程以及作用如下:
1,GUI 渲染线程
(1) 负责解析 HTML 文件构建 DOM 树, 解析 CSS, 结合 DOM 树渲染成 RenderObject 树, 然后布局和绘制页面
(2) 当 RenderObject 树需要更新样式属性时, 即发生重绘 (Repaint); 当 RenderObject 树中的元素规则尺寸, 布局或显示隐藏等发生变化, 即发生回流 (reflow).
2,JS 引擎线程
3, 时间出发线程
4, 定时器触发线程
5, 异步 Http 请求线程
注: GUI 渲染线程与 JS 引擎线程是相互排斥的, 因为 JS 引擎线程在执行的过程中可能会发生重绘和回流, 所以 GUI 渲染线程执行时候, JS 引擎线程会被挂起, 等待 GUI 渲染线程执行完毕之后, JS 引擎线程执行时候同理.
3.1GUI 渲染线程
首先看一张图, 图如下
接下来我们主要分析 GUI 渲染线程执行的详细过程:
1, 解析 HTML 文件, 构建 DOM 树, 同时浏览器主进程负责下载 CSS 文件
2,CSS 文件下载完成, 解析 CSS 文件成树形的数据结构, 然后结合 DOM 树合并成 RenderObject 树
3, 布局 RenderObject 树, 负责 RenderObject 树中的元素的尺寸, 位置等计算
4, 绘制 RenderObject 树, 绘制页面的像素信息
5, 浏览器主进程将默认的图层和复合图层交给 GPU 进程, GPU 进程再将各个图层合成 (conposite), 最后显示出页面
注意:
1, 默认图层指的是出于普通文档流的元素
2, 复合图层一般指的使用动画执行或者 < video><iframe><canvas><webgl > 等元素, 也可以使用 z-index 将层级高的元素变成复合图层, 使用复合图层可以进行硬件加速, 其原理是避免了默认图层的重绘和回流, 想了解更深入介意自行研究
了解 GUI 渲染线程的执行过程, 我们可以根据原理进行渲染优化:
1, 尽可能早的提前引入 CSS 文件, 例如在头部引入 CSS 文件.
2, 尽可能早的加载 CSS 文件中的引入的资源, 例如自定义字体文件, 可以使用预加载, 在 link 标签中加入 rel="preload" as = "font" 该元素属性, 不会造成渲染阻塞.
3, 在 DOM 和 CSS 渲染之后加载 JS 文件, 例如在尾部加载 JS 文件, 或者使用该元素属性 defer 和 async, 进行 JS 问价异步加载, 但是不同的浏览器会有兼容性问题.
四, 总结
主要是介绍浏览器的渲染过程, 但是没有分析 JS 脚本文件解析过程.
(一) 浏览器渲染进程包含 1, 解析 HTML 文件和 CSS 文件, 加载图片等资源文件, 渲染成用户看到的页面; 2, 执行解析 JS 文件脚本代码.
(二) 整个过程浏览器会开启多个线程协作完成, 包括: GUI 渲染线程, JS 引擎线程, 事件触发线程, 定时器触发线程, 异步 HTTP 请求线程.
(三) 其中 GUI 渲染线程和 JS 引擎线程是相互排斥的, 因为 JS 引擎线程在执行的时候有可能会发生重绘和回流.
来源: https://www.cnblogs.com/chengxs/p/10403622.html