号外号外!!!----浏览器渲染原理

1.1、进程和线程
进程
CPU 资源分配的最小单位(是用于资源和独立运行的最下单位)。

线程
CPU 调度的最小的单位(是建立在进程基础上的一次程序运行单位)。

也就是说,对于操作系统而言,一个任务就是一个进程,比如打开一个浏览器就是启动了一个浏览器进程。例如如下:
在这里插入图片描述
与此同时,一个进程可能同时不止做一件事。比如我们打开百度网盘,我们可以在下载文件的同时上传文件,这些事情就是由一个个的线程操作着。稍微形象点说,进程就好像是个工厂,工厂里面的工人好比线程,工厂里面里面可以拥有 1~n 个工人,每个工人负责某件相应的事情运作。

1.2、浏览器的多进程架构
一个nice的程序,一般是由多个独立且相互配合的模块组成的。同时,浏览器也是由多个进程所构成的。比如主线程、第三方插件进程、GPU 进程、渲染进程等

优点
1、多进程充分的利用了现代 CPU 多核的优势
2、由于各个进程的独立存在,提高了浏览器的稳定性。(比如:浏览器的某个插件崩溃,但是并不影响浏览器的其他进程运行)

缺点
1、由于多进程构造,那就需要系统分配更加多的资源

1.3、浏览器的主要进程和职责
在这里插入图片描述
主进程
负责浏览器界面的显示和交互,各个页面管理,创建和销毁其他进程。网络资源的下载管理等。

第三方插件进程
每个浏览器插件都有其对应的进程,不过只有当使用插件时才会创建其对应的第三方进程插件进程。

GPU 进程
用于 3D 绘制,注意只允许创建一个进程。

渲染进程
称为浏览器渲染进程,同时也被叫做浏览器内核,内部为多线程结构。主要负责页面的渲染,脚本的执行,事件的处理等。

1.4、渲染进程的多线程及作用
浏览器的渲染进程是由多个线程组成的,我们看看它有哪些主要的线程。
在这里插入图片描述
GUI 渲染线程
1、负责渲染浏览器界面。解析 HTML、CSS,构建 DOM、CSSOM,布局和绘制等。
2、当页面需要重绘或者回流(重排)时,此线程将会被执行。
3、GUI 线程与 JS 引擎线程是互斥。当 JS 引擎执行时,GUI 线程就会被挂起,只有 JS 引擎空闲时,GUI 线程才能被执行。

JS 引擎线程
1、JavaScript 引擎,也称为 JS 内核,负责处理 JavaScript 脚本程序。
2、JS 引擎线程负责解析 JavaScript 脚本,运行代码。
3、JS 引擎与 GUI 线程是互斥。

事件触发线程
1、归属于浏览器而不是 JS 引擎,用来控制事件循环

定时触发线程
1、setInterval 和 setTimeout 所在线程。
2、对于计数异步函数,不会由 JS 引擎计数(因为 JS 引擎是单线程,如果 JS 执行脚本过长导致阻塞便会计数不准,因此使用一单独线程用于 setInterval 和 setTimeout 等计数异步函数)。
3、注意:setTimeout 最低时间间隔为 4ms,也就是说当时间间隔低于 4ms,便以 4ms 间隔计数。

异步 http 请求线程
用于 http 请求处理。

1.5、浏览器渲染流程
了解了浏览器的进程和渲染进程的相关线程,我们就来谈谈浏览器渲染流程。不多说,先喝口水!
在这里插入图片描述
浏览器渲染流程图
在这里插入图片描述
1、解析 HTML 文件,构建 DOM 树,遇到 <script> 标签时(内联和外链 JS 文件),GUI 线程会被挂起,阻塞 DOM 的解析,直到 js 加载并执行完毕。

2、在解析 HTML 同时解析拥有 属性 rel 值为 stylesheet<link> 标签 <link rel="stylesheet" href="./css/test.css">style 标签,浏览器主进程下载 CSS 文件,构建 CSSOM 树。之后便和已解析完毕的 DOM 树结合成为渲染树。

3、布局渲染树,负责渲染树种元素的尺寸,位置等计算。

4、绘制渲染树,负责页面的像素,颜色等的信息绘制。

5、浏览器将默认的图层交给 GPU 进程,GPU 进程再将各个图层合成,最后显示页面。

1.6、提问
最后了,看了这么多,来来来,先喝阔水水!!!
在这里插入图片描述
JavaScript 为什么是单线程的呢?
这是为了便于处理页面复杂的交互,倘若是多线程,则 JS 随时可以改变 UI 元素。虽然可以用“锁”来控制,但是这便使得 JS 操作更加的复杂以及资源的加剧消耗。

JS 加载与解析会阻塞 DOM 解析吗?为什么呢?
首先, JS(内联或外链) 的加载和运行都会阻塞 DOM 的解析。这是因为当 JS 加载运行时,JS 引擎线程被调用,从而 GUI 线程被挂起,因此会停止解析 DOM。

defer 和 async 的区别?
1、当浏览器碰到 <script> 标签时,且标签中无任何标志 <script src="script.js">,浏览器这会立马挂起 GUI 线程,并加载执行 JS 资源。执行完毕后继续解析 DOM。

2、当浏览器碰到 <script> 标签时,且标签中存在 async 标志 <script async src="script.js">,浏览器这不会挂起 GUI 线程,而是异步加载执行 JS 资源。JS 资源的加载执行不影响解析 DOM。

3、当浏览器碰到 <script> 标签时,且标签中无 defer 标志 <script defer src="myscript.js">,浏览器这不会挂起 GUI 线程,而是异步加载 JS 资源,并等待 DOM 解析完毕后执行。JS 资源的加载不影响解析 DOM。

CSS 加载与解析会造成什么阻塞呢?
1、因为 CSS 资源加载与解析和 DOM 的解析是同步构建的(可以理解为 GUI 可以同时处理 CSS 和 DOM)。因此 CSS 资源的加载和解析是不会阻塞 DOM 的解析的。但是由于 渲染树依赖 DOM 和 CSSOM ,因此 CSS 资源加载与解析会阻塞 渲染树的生成。

2、又因为浏览器防止 CSS 资源成为一个临界资源。因此,当浏览器主进程加载 CSS 文件时,会阻塞 JS 资源的加载。

什么是 CRP,关键渲染路径?
关键渲染路径是浏览器将 HTML、CSS、JavaScript 转换为屏幕上呈现的像素内容所经历的一系列步骤。也就是我们上面说的浏览器渲染流程。

1.7、怎么优化关键渲染路径
真真的是最最后啦!!!!!加油,奥利给!!!!

网络层次方面
1、要求服务器使用 GZIP 等压缩响应报文方式发送请求
2、使用 HTTP 缓存,减少在服务器上资源未改变时,资源请求的浪费
3、使用长连接(keep-alive)方式,减少由于 TCP 频繁建立连接所带来的的资源及时间消耗

资源体积层次方面
1、对相关图片在不失真的前提下进行压缩
2、使用 icon 替换小图标
3、webpack 项目整体的代码压缩

HTML 文件结构层次方面
1、样式标签 <style>、<link> 放在 HTML 文件结构尾部,<script> 标签前部
2、减少不必要的部分,包括 dom、style、script

script 标签层次方面
1、关于全局公共功能模块,提取出来公共模块化
2、当 js 内容不改变 dom 及 css 时,使用 async 标志
3、当 js 内容改变 dom 及 css 时,使用 defer 标志

css 内容层次方面
1、关于公共样式,提取出来公共模块化
2、减少样式的重复叠加

参考:
从 8 道面试题看浏览器渲染过程与性能优化
梳理浏览器内核中线程之间的关系

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值