Step 1 浏览器架构
浏览器架构的演进
单进程 -> 多进程 -> 面向服务架构
浏览器架构对比
| 架构类型 | 扩展性 | 安全性 | 稳定性 | 流畅度 |
|---|---|---|---|---|
| 单进程架构 | 低 | 低 | 低 | 卡顿 |
| 多进程架构 | 中 | 高 | 高 | 流畅 |
| 面向服务架构 | 高 | 高 | 高 | 流畅 |
多进程分工
Step 2 渲染进程
常见浏览器内核
多线程架构
渲染进程主要由页面渲染、脚本执行、事件处理、网络请求等线程组成
js引擎VS渲染引擎
由于JS引擎和渲染引擎是分开的两个进程,所以尽管JS的命令可以很快的被操作系统解析,但是当我们使用JS操作DOM的时候,我们的命令需要通过JS引擎和渲染引擎之间的Bridge,所以会有一定的延迟。
多线程工作流程
JS引擎执行资源以及事件线程返回的函数,JS引擎空闲时渲染线程立即工作。两者形成循环。
Step 3 Chrome运行原理
如何展示网页
- 浏览器地址输入URL之后发生了什么
- 对URL进行输入处理
- 开始导航URL
- 读取服务器端的响应
- 寻找渲染进程
- 渲染进程加载子资源(CSS、HTML等等),在此过程中会执行一些JS脚本
- 加载完成资源后,构建DOM树、CSSOM树、渲染树
- 开始网页的布局
- 构建网页的图层并且绘制图层
- 合成页面之后展示
输入处理
开始导航
- 用户按下回车之后,UI线程通知网络线程发送网络请求,获取站点内容
- 请求过程中tab属于loading状态
读取响应
-
网络线程接受到HTTP响应之后,先检查响应头的媒体类型
-
如果相应主体是一个HTML文件,浏览器会将内容交给渲染进程处理
-
如果拿到哦的是其他类型文件,例如Zip、exe等,则交给下载管理器处理
寻找渲染进程
- 网络进程完成任务后,主进程会为站点寻找一个渲染进程
- 主进程通过IPC消息告知渲染进程去处理本次导航
- 渲染进程接收数据后返回确认消息给主进程,导航结束,进入文档加载阶段
渲染进程-资源加载
- 首先渲染进程开始加载HTML文档
- 除此以外,还要加载子资源,例如图片、CSS样式文件以及JS脚本等
渲染进程-构建渲染树
- 构建DOM树,将HTML文本转换为浏览器能够理解的结构
- 构建CSSOM树,将CSS代码转换为浏览器可理解的CSSOM
- 构建渲染树,渲染树是DOM树和CSSOM树的结合
渲染进程-页面布局
- 根据渲染树计算每个节点的位置和大小
- 在浏览器页面区域绘制元素边框
- 遍历渲染树,将元素以盒模型的形式写入文档流
渲染进程-页面绘制
- 构建图层:为特定的节点生成专用的图层
- 绘制图层:一个图层分为很多绘制指令,然后将这些指令按顺序组成一个绘制列表,交给合成线程
- 合成线程接受指令生成图块
- 栅格线程将图块栅格化
浏览器会调用GPU加速 - 展示
前端性能performance
- Scripting 脚本执行
- Randering 渲染树
- Idle 等待 总结:如果我们的JS脚本执行时间过长,则会影响浏览器加载的延迟,造成浏览器的卡顿
优化
- 压缩、分包、删除无用代码 - 压缩一些代码以及删除无用的代码,缩减JS的加载成本
- 静态资源分离 - 静态资源放在CDN上,减少服务器加载成本
- JS脚本非阻塞加载 - 将JS脚本放在请求头可以在第一时间加载完JS脚本,由于JS引擎和渲染引擎互斥,所以尽快的完成JS脚本的加载,可以进一步优化浏览器的加载
- 缓存策略 - 将图片、预存cookie放在缓存当中可以加快浏览器的加载
- SSR - 预置一些id用于加载框架等JS资源
- 预置loading、骨架屏 - 预置一些loading以及骨架屏,这样可以直接更快的将渲染树里面的资源代入,加快浏览器的加载速度