一:chrome 架构
并行处理 同一时刻处理多个任务
进程 一个进程就是一个程序的运行实例
线程 线程是不能单独存在的,它是由进程来启动和管理
线程是依附于进程的,而进程中使用多线程并行处理能提升运算效率、
进程与线程之间的关系:
- 进程中的任意一线程执行出错,都会导致整个进程崩溃
- 线程之间共享进行中的数据
- 当一个进程关闭后,操作系统会回收进程所占用的内存
- 进程之间的内容相互隔离
二:TCP协议:如何保证页面文件能被完整送达浏览器
FP(“first paint”) : 指从页面加载到首次开始绘制的时长。其中一个重要因素就是网络加载速度
1:ip 把数据包送达目的主机
计算机的地址就称为ip地址,访问任何网站实际上只是你的计算机向另外一台计算机请求信息
ip头是ip数据包开头的信息,包含ip版本,源ip地址,目标ip地址,生存时间等信息。
2.UDP 把数据包送达应用程序
基于ip之上开发能和应用打交道的协议,最常见的是 “用户数据包协议” 简称 UDP
UDP中一个重要的信息是 端口号
流程: ip通过ip地址信息把数据包发送给指定的电脑,而UDP通过端口号把数据包分发给正确的程序。
UDP特点:不能保证数据可靠性、但是传输速度非常快。所以应用场景一般在:在线视频,互动游戏
3.TCP 把数据完整的送达应用程序
使用UDP出现的问题:
- 数据包在传输过程中容易丢失
- 大文件会被拆分成很多小的数据包来传输,这些小的数据包会经过不同的路由,并在不同的时间到达接受端,而UDP协议并不知道如何组装这些数据包,从而无法把这些数据包还原成完整的文件
TCP : (传输控制协议) 是一种面向连接的可靠的基于字节流的传输层通信协议
特点:
1.对于数据包丢失的情况,TCP提供重传机制
2.TCP引入了数据包排序机制,用来保证把乱序的数据包组合成一个完整的文件
- 首先,建立连接阶段。三次握手
- 其次,传输数据阶段。接收端需要对每个数据包进行确认操作
- 最后,断开连接阶段 四次挥手
三:HTTP请求流程:为什么很多站点第二次打开速度会很快
HTTP 是一种允许浏览器向服务器获取资源的协议,是web的基础。
浏览器发起HTTP请求流程
1.构建请求
**
首先构建请求行信息
2.查找缓存
在真正发起网络请求之前,浏览器会现在浏览器缓存中查询是否有要请求的文件。其中,浏览器缓存是一种在本地保存资源的副本,以供下次请求时直接使用的技术
如果存在,会拦截请求,返回该资源的副本并且直接结束请求。
3.准备ip地址和端口
DNS: 域名系统
- 浏览器会请求DNS访问域名对应的ip, 浏览器还提供了DNS数据缓存服务,如果某个域名已经解析过了,那么浏览器会缓存解析的结果,以供下次查询时直接使用,这样也会减少一次网络请求
- 获取端口号,HTTP协议默认是 80端口
4.等待TCP队列
chrome 有个机制,同一个域名同时最多只能建立6个TCP连接,如果在同一个域名下同时有10个请求发生,那么其中4个请求会进入排队等待状态,直至进行中的请求完成。
5.建立TCP连接
在HTTP工作开始之前,浏览器通过TCP与服务器建立连接
6.发送HTTP请求
一旦建立了TCP连接,浏览器就可以和服务器进行通信了
服务器端处理HTTP请求流程
1.返回请求curl -i https://time.geekbang.org
- 首先会返回响应行 包括协议版本和状态码
- 服务器向浏览器发送 响应头
- 服务器向浏览器发送 响应体
2.断开连接
通常情况下,一旦服务器向客户端返回了请求数据,他就要关闭TCP链接,不过浏览器或者服务器在其头信息中加入了
Connection:Keep-Alive
那么TCP连接在发送后仍然保持打开状态,这样浏览器就可以继续通过同一个TCP连接发送请求。
保持TCP连接可以省去下次请求时需要建立连接的时间,提升资源加载速度
3.重定向
注:这种跳转不是必然的,需要自己设置。
问题:
1.为什么很多站点第二次打开速度会很快
因为这些网站把很多资源都缓存在了本地,浏览器缓存直接使用本地副本来回应请求,而不会产生真实的网络请求,从而节省了时间,同时 DNS 数据也被浏览器缓存了,这又省去了DNS查询环节。
当服务器返回 HTTP 响应头给浏览器时,浏览器是通过响应头中的 Cache-Control 字段来设置是否缓存该资源。
通常我们还需要为这个资源设置一个缓存过期时长,通过 Max-age 这个参数设置 、
Cache-Control:Max-age=2000
2.登陆状态是如何保持的 **
如果服务器端发送的响应头内有 Set-Cookie 的字段,那么浏览器就会将该字段的内容保持到本地,当下次客户端再往该服务器发送请求时,客户端会自动在请求头中加入 Cookie 值后在发送出去,服务器端发现客户端发送过来的Cookie之后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到该用户的状态信息 。
总结 :
四:导航流程:从输入URL到页面展示,这中间发生了什么
首先,用户从浏览器进程里输入请求信息
然后,网络进程发起URL请求
服务器响应url请求之后,浏览器进程就又要开始准备渲染进程了
渲染进程准备好之后,需要先向渲染进程提交页面数据,称之为提交文档阶段
渲染进程接收完文档信息之后,便开始解析页面和加载子资源,完成页面的渲染
其中,用户发出URL请求到页面开始解析的这个过程,就叫导航
1.用户输入
当用户在地址栏中输入一个查询关键字时,地址栏会判断输入的关键字是搜索内容,还是请求的 URL
**
如果是搜索内容,地址栏会使用浏览器默认的搜索引擎,来合成新的带搜索关键字的 URL。 如果判断输入内容符合 URL 规则,比如输入的是 time.geekbang.org,那么地址栏会根 据规则,把这段内容加上协议,合成为完整的 URL,如 https://time.geekbang.org。
2.URL请求过程
接下来是页面资源请求过程。浏览器进程会通过进程间通信(IPC)把URL请求发送至网络进程,网络进程接收到URL请求后,会在这里发起真正的URL请求流程。
首先,网络进程会查找本地缓存是否缓存了该资源。
如果有缓存资源,那么直接返回资源给 浏览器进程;
如果在缓存中没有查找到资源,那么直接进入网络请求流程。
这请求前的第一 步是要进行 DNS 解析,以获取请求域名的服务器 IP 地址。如果请求协议是 HTTPS,那么 还需要建立 TLS 连接
接下来就是利用 IP 地址和服务器建立 TCP 连接。
连接建立之后,浏览器端会构建请求行、 请求头等信息,并把和该域名相关的 Cookie 等数据附加到请求头中,然后向服务器发送构 建的请求信息。
服务器接收到请求信息后,会根据请求信息生成响应数据(包括响应行、响应头和响应体等 信息),并发给网络进程。等网络进程接收了响应行和响应头之后,就开始解析响应头的内 容了。(为了方便讲述,下面我将服务器返回的响应头和响应行统称为响应头。)
1)重定向
在接收到服务器返回的响应头后,网络进程开始解析响应头,如果发现返回的状态码是 301 或者 302,那么说明服务器需要浏览器重定向到其他 URL。这时网络进程会从响应头 的 Location 字段里面读取重定向的地址,然后再发起新的 HTTP 或者 HTTPS 请求,一切又重头开始了。
在导航的过程中,如果服务器响应行的状态码包含了 301 302 一类的跳转信息,浏览器会跳转到新的地址继续导航,如果响应行是200,那么表示浏览器可以继续处理该请求。
2)响应数据类型处理
URL请求的数据类型,有时候是一个下载类型,有时候是正常的HTML页面,浏览器如何区分它们
Content-Type, Content-type 是HTTP头中一个非常重要的字段,它告诉浏览器服务器返回的响应体数据是什么类型,然后浏览器会根据Content-Type的值来决定如何显示响应体的内容curl -I https://time.geekbang.org/
- text/html
- application/octet-stream 字节流类型
所以,如果Content-Type字段的值被浏览器判断为下载类型,那么该请求会被提交给浏览器的下载管理器,同时该URL请求的导航流程就此结束。如果是HTML,那么浏览器则会继续进行导航流程。
3.准备渲染进程
通常情况下,打开新的页面都会使用单独的渲染进程。
如果A页面打开B页面,且A和B都属于同一站点的话,那么B页面复用A页面的渲染进程;
如果是其它情况,浏览器进程则会为B创建一个新的渲染进程
渲染进程准备好之后,还不能立即进入文档解析状态,此时的文档数据还在网络进程中,并没有提交给渲染进程,所以下一步就进入了提交文档阶段。
4.提交文档
这里的文档,指的是URL请求的响应体数据
“提交文档”的消息是由浏览器进程发出的,渲染进程接收到“提交文档”的消息后,会 和网络进程建立传输数据的“管道”。
等文档数据传输完成之后,渲染进程会返回“确认提交”的消息给浏览器进程。
浏览器进程在收到“确认提交”的消息后,会更新浏览器界面状态,包括了安全状态、地 址栏的 URL、前进后退的历史状态,并更新 Web 页面
5.渲染阶段
一旦文档被提交,渲染进程便开始页面解析和子资源加载了,关于这个阶段的完整过程,我 会在下一篇文章中来专门介绍。这里你只需要先了解一旦页面生成完成,渲染进程会发送一 个消息给浏览器进程,浏览器接收到消息后,会停止标签图标上的加载动画
五:渲染流程(上):html css javascript 是如何变成页面的
- html : 标记(标签) 和文本组成
- css : 层叠样式表,由选择器和属性组成
- js : 使用它可以让网页内容动起来
按照渲染的时间顺序:构建DOM树 样式计算 布局阶段 分层 绘制 分块 光栅化 合成
构建DOM树
将html转换为浏览器能够理解的结构。其中每个点成为节点,相连的为父子节点。
控制台查看 document
样式计算 (Recalculate Style)
1.将css转换为浏览器能够理解的结构
将css文本转换为浏览器可以理解的结构 styleSheets
控制台 document.styleSheets
2.转换样式表中的属性值,使其标准化
需要将所有值转换为渲染引擎容易理解的,标准化的计算值
3.计算出DOM树中每个节点的具体样式
继承规则
css 继承就是每个dom节点都包含有父节点的样式
控制台 开发者工具 element标签 style子标签
层叠规则
层叠是css的一个基本特征,它是一个定义了如何合并来自多个源的属性值的算法。
dom元素最终的计算样式 ComputedStyle控制台 element Computed子标签
布局阶段
1.创建布局树
在显示之前,需要额外的构建 只包含可见元素 的树
1.遍历dom树中所有可见节点,并把这些节点加到布局中
2.忽略不可见的元素
2.布局计算
计算布局树节点的坐标位置,并保存在布局树中。
分层
渲染引擎需要为特点的节点生成专用的图层,并生成一棵对应的图层树(LayerTree)开发者工具 Layers (more tools 中可以看到)
可以看到 浏览器的页面实际上被分成了很多图层,这些图层叠加后合成了最终的页面
什么情况下,渲染引擎会为特点的节点创建新的层?
满足以下任意一点
1.拥有层叠上下文属性的元素会被提升为单独的一层
明确定义属性的元素,定义透明属性的元素,使用css滤镜的元素
2.需要剪裁(clip)的地方也会被创建为图层
**overflow:hidden
的时候
图层绘制
开发者工具 Layers document层 注:拖动右侧区域的进度条可以重现列表的绘制过程
栅格化(rester)操作
视口(viewport): 用户可以看到的部分
合成线程会将图层划分为图块(tile),大小通常是256256或者512512
栅格化:指将图块转换为位图
图块 :栅格化执行的最小单位
合成线程会按照视口附近的图块来优化生成位图,实际生成位图的操作是由栅格化来执行的。
注:通常栅格化过程都会使用 GPU 来加速生成,使用GPU生成位图的过程叫快速栅格化,或者GPU栅格化,生成的位图被保存在GPU内存中。
合成和显示
当所有图块都被光栅化,合成线程就会生成一个绘制图块的命令 DrawQuad ,然后提交给浏览器进程
浏览器进程中有 viz 组件,用来接收并将其页面内容绘制到内存中,最后将内存显示在屏幕上。
总结
- 渲染进程将HTML内容转换为能够读懂的DOM树结构
- 渲染引擎将css样式表转化为浏览器可以理解的styleSheets,计算出DOM节点的样式
- 创建布局树,并计算元素的布局信息
- 对布局树进行分层,并生成分层树
- 为每个图层生成绘制列表,并将其提交到合成线程
- 合成线程将图层分为图块,并在光栅化线程池中将图块转换为位图
- 合成线程发送绘制图块命令 DrawQuad 给浏览器进程
- 浏览器进程根据 DrawQuad 消息生成页面,并显示在显示器上
相关概念
1.更新了元素的几何属性(重排)
重排: 例如改变元素的宽度高度等,那么浏览器会触发重新布局,这个过程。
重排需要更新完整的渲染流水线,所以开销也是最大的。
2.更新元素的绘制属性(重绘)
重绘省去了布局和分层阶段,所以执行效率会比重排操作要高一些