We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
首先,在开始讲解整个过程前,我们需要认识一下 Chrome 多进程架构。因为,从浏览器输入 URL 到页面渲染的整个过程都是由 Chrome 架构中的各个进程之间的配合完成。
Chrome
URL
Chrome 的多进程架构:
HTML
JavaScript
HTTP
WebSocket
GPU
UI
发生这个过程的前提,用户在地址栏中输入了 URL,而地址栏会根据用户输入,做出如下判断:
IPC
在网络进程接收到 URL 后,并不是马上对指定 URL 进行请求。首先,我们需要进行 DNS 解析域名得到对应的 IP,然后通过 ARP 解析 IP 得到对应的 MAC(Media Access Control Address)地址。
DNS
IP
ARP
MAC
Media Access Control Address
域名是我们取代记忆复杂的 IP 的一种解决方案,而 IP 地址才是目标在网络中所被分配的节点。MAC 地址是对应目标网卡所在的固定地址。
1. DNS 解析
而 DNS 解析域名的过程分为以下几个步骤:
host
ISP
Internet Service Provider
2. 通信过程
首先,建立 TCP 连接,即三次握手过程:
TCP
SYN
SYN/ACK
ACK
然后,利用 TCP 通道进行数据传输:
最后,断开 TCP 连接,即四次握手过程:
而这整个过程的客户端则是网络进程。并且,在数据传输的过程还可能会发生的重定向的情况,即当网络进程接收到状态码为 3xx 的响应报文,则会根据响应报文首部字段中的 Location 字段的值进行重新向,即会重新发起请求
3. 数据处理
当网络进程接收到的响应报文状态码,进行相应的操作。例如状态码为 200 OK 时,会解析响应报文中的 Content-Type 首部字段,例如我们这个过程 Content-Type 会出现 application/javascript、text/css、text/html,即对应 Javascript 文件、CSS 文件、HTML 文件。
200 OK
Content-Type
application/javascript
text/css
text/html
Javascript
CSS
详细的 MIME 类型讲解可以看 MDN
MIME
当前需要渲染 HTML 时,则需要创建渲染进程,用于后期渲染 HTML。而对于渲染进程,如果是同一站点是可以共享一个渲染进程,例如 a.abc.com 和 c.abc.com 可以共享一个渲染渲染进程。否则,需要重新创建渲染进程
a.abc.com
c.abc.com
需要注意的是,同站指的是顶级域名和二级域名相等
在创建完渲染进程后,网络进程会将接收到的 HTML、JavaScript 等数据传递给渲染进程。而在渲染进程接收完数据后,此时用户界面上会发生这几件事:
enable
大家都知道页面渲染的过程也是面试中单独会考的点,并且时常会由这个点延申出另一个问题,即如何避免回流和重绘。
渲染过程,是整个从理器输入 URL 到页面渲染过程的最后一步。而页面渲染的过程可以分为 9 个步骤:
DOM
CSSOM
Render Tree
由于网络进程传输给渲染进程的是 HTML 字符串,所以,渲染进程需要将 HTML 字符串转化成 DOM 树。例如:
需要注意的是这个 DOM 树不同于 Chrome-devtool 中 Element 选项卡的 DOM 树,它是存在内存中的,用于提供 JavaScript 对 DOM 的操作。
Chrome-devtool
Element
构建 CSSOM 的过程,即通过解析 CSS 文件、style 标签、行内 style 等,生成 CSSOM。而这个过程会做这几件事:
style
color: blue
color: rgb()
ES6
ES5
font-size
color
CSS Object Model 是一组允许用 JavaScript 操纵 CSS 的 API。详细 API 讲解可以看 MDN
CSS Object Model
API
通常情况下,在构建 DOM 树或 CSSOM 的同时,如果也要加载 JavaScript,则会造成前者的构建的暂停。当然,我们可以通过 defer 或 sync 来实现异步加载 JavaScript。虽然 defer 和 sync 都可以实现异步加载 JavaScript,但是前者是在加载后,等待 CSSOM 和 DOM 树构建完后才执行 JavaScript,而后者是在异步加载完马上执行,即使用 sync 的方式仍然会造成阻塞。
defer
sync
而 JavaScript 执行的过程,即编译和运行 JavaScript 的过程。由于 JavaScript 是解释型的语言。所以这个过程会是这样的:
Token
AST
Abstract Sytanx Tree
在有了 DOM 树和 CSSOM 之后,需要将两者结合生成渲染树 Render Tree,并且这个过程会去除掉那些 display: node 的节点。此时,渲染树就具备元素和元素的样式信息。
display: node
根据 Render Tree 渲染树,对树中每个节点进行计算,确定每个节点在页面中的宽度、高度和位置。
需要注意的是,第一次确定节点的大小和位置的过程称为布局,而第二次才被称为回流
由于层叠上下文的存在,渲染引擎会为具备层叠上下文的元素创建对应的图层,而诸多图层的叠加就形成了我们看到的一些页面效果。例如,一些 3D 的效果、动画就是基于图层而形成的。
3D
值得一提的是,对于内容溢出存在滚轮的情况也会进行分层
对于存在图层的页面部分,需要进行有序的绘制,而对于这个过程,渲染引擎会将一个个图层的绘制拆分成绘制指令,并按照图层绘制顺序形成一个绘制列表。
有了绘制列表后,渲染引擎中的合成线程会根据当前视口的大小将图层进行分块处理,然后合成线程会对视口附近的图块生成位图,即光栅化。而渲染进程也维护了一个栅格化的线程池,专门用于将图块转为位图。
栅格化的过程通常会使用 GPU 加速,例如使用 wil-change、opacity,就会通过 GPU 加速显示
wil-change
opacity
当所有的图块都经过栅格化处理后,渲染引擎中的合成线程会生成绘制图块的指令,提交给浏览器进程。然后浏览器进程将页面绘制到内存中。最后将内存绘制结果显示在用户界面上。
而这个整个从生成绘制列表、光栅化、显示的过程,就是我们常说的重绘的过程
The text was updated successfully, but these errors were encountered:
No branches or pull requests
从浏览器输入 URL 到页面展示过程发生了什么?
一、Chrome 多进程架构
首先,在开始讲解整个过程前,我们需要认识一下
Chrome
多进程架构。因为,从浏览器输入URL
到页面渲染的整个过程都是由Chrome
架构中的各个进程之间的配合完成。Chrome
的多进程架构:HTML
文档和JavaScript
等转化为用户界面HTTP
请求、WebSocket
模块GPU
(图形处理器)进程,它负责对UI
界面的展示二、过程详解
2.1 解析输入
发生这个过程的前提,用户在地址栏中输入了
URL
,而地址栏会根据用户输入,做出如下判断:URL
结构的字符串,则会用浏览器默认的搜索引擎搜索该字符串URL
结构字符串,则会构建完整的URL
结构,浏览器进程会将完整的URL
通过进程间通信,即IPC
,发送给网络进程2.2 请求过程
在网络进程接收到
URL
后,并不是马上对指定URL
进行请求。首先,我们需要进行DNS
解析域名得到对应的IP
,然后通过ARP
解析IP
得到对应的MAC
(Media Access Control Address
)地址。1. DNS 解析
而
DNS
解析域名的过程分为以下几个步骤:DNS
缓存DNS
缓存(即查找本地host
文件)ISP
(Internet Service Provider
)互联网服务提供商(例如电信、移动)的DNS
服务器2. 通信过程
首先,建立
TCP
连接,即三次握手过程:SYN
的数据包,表示我将要发送请求。SYN/ACK
的数据包,表示我已经收到通知,告知客户端发送请求。ACK
的数据包,表示我要开始发送请求,准备被接受。然后,利用
TCP
通道进行数据传输:TCP
的重发机制TCP
头中的需要进行排序,形成完整的数据最后,断开
TCP
连接,即四次握手过程:3. 数据处理
当网络进程接收到的响应报文状态码,进行相应的操作。例如状态码为
200 OK
时,会解析响应报文中的Content-Type
首部字段,例如我们这个过程Content-Type
会出现application/javascript
、text/css
、text/html
,即对应Javascript
文件、CSS
文件、HTML
文件。2.3 创建渲染进程
当前需要渲染
HTML
时,则需要创建渲染进程,用于后期渲染HTML
。而对于渲染进程,如果是同一站点是可以共享一个渲染进程,例如a.abc.com
和c.abc.com
可以共享一个渲染渲染进程。否则,需要重新创建渲染进程2.4 开始渲染
在创建完渲染进程后,网络进程会将接收到的 HTML、JavaScript 等数据传递给渲染进程。而在渲染进程接收完数据后,此时用户界面上会发生这几件事:
URL
enable
,显示正在加载状态2.5 渲染过程
渲染过程,是整个从理器输入 URL 到页面渲染过程的最后一步。而页面渲染的过程可以分为 9 个步骤:
HTML
生成DOM
树CSS
生成CSSOM
JavaScript
Render Tree
)2.5.1 构建 DOM 树
由于网络进程传输给渲染进程的是
HTML
字符串,所以,渲染进程需要将HTML
字符串转化成DOM
树。例如:2.5.2 构建 CSSOM
构建
CSSOM
的过程,即通过解析CSS
文件、style
标签、行内style
等,生成CSSOM
。而这个过程会做这几件事:CSS
,即将color: blue
转化成color: rgb()
形式,可以理解成类似ES6
转ES5
的过程CSS
样式会继承父级的样式,如font-size
、color
之类的。2.5.3 加载 JavaScript
通常情况下,在构建
DOM
树或CSSOM
的同时,如果也要加载JavaScript
,则会造成前者的构建的暂停。当然,我们可以通过defer
或sync
来实现异步加载JavaScript
。虽然defer
和sync
都可以实现异步加载JavaScript
,但是前者是在加载后,等待CSSOM
和DOM
树构建完后才执行JavaScript
,而后者是在异步加载完马上执行,即使用sync
的方式仍然会造成阻塞。而
JavaScript
执行的过程,即编译和运行JavaScript
的过程。由于JavaScript
是解释型的语言。所以这个过程会是这样的:Token
化Token
,生成AST
(Abstract Sytanx Tree
) 抽象语法树和创建上下文AST
,生成字节码。2.5.4 生成渲染树(Render Tree)
在有了
DOM
树和CSSOM
之后,需要将两者结合生成渲染树Render Tree
,并且这个过程会去除掉那些display: node
的节点。此时,渲染树就具备元素和元素的样式信息。2.5.5 布局
根据
Render Tree
渲染树,对树中每个节点进行计算,确定每个节点在页面中的宽度、高度和位置。2.5.6 分层
由于层叠上下文的存在,渲染引擎会为具备层叠上下文的元素创建对应的图层,而诸多图层的叠加就形成了我们看到的一些页面效果。例如,一些
3D
的效果、动画就是基于图层而形成的。2.5.7 生成绘制列表
对于存在图层的页面部分,需要进行有序的绘制,而对于这个过程,渲染引擎会将一个个图层的绘制拆分成绘制指令,并按照图层绘制顺序形成一个绘制列表。
2.5.8 光栅化
有了绘制列表后,渲染引擎中的合成线程会根据当前视口的大小将图层进行分块处理,然后合成线程会对视口附近的图块生成位图,即光栅化。而渲染进程也维护了一个栅格化的线程池,专门用于将图块转为位图。
2.5.9 显示
当所有的图块都经过栅格化处理后,渲染引擎中的合成线程会生成绘制图块的指令,提交给浏览器进程。然后浏览器进程将页面绘制到内存中。最后将内存绘制结果显示在用户界面上。
The text was updated successfully, but these errors were encountered: