网络营销的网站分类有哪些,设计师网站 pins,网站咋建立,微信微信宏观视角下的浏览器 Chrome架构线程 VS 进程进程架构 TCP协议IP#xff1a;把数据包送达目的主机UDP#xff1a;把数据包送达应用程序TCP#xff1a;把数据完整地送达应用程序 HTTP请求流程构建请求查找缓存准备IP地址和端口等待TCP队列建立TCP连接发送HTTP请求 服务器端处理… 宏观视角下的浏览器 Chrome架构线程 VS 进程进程架构 TCP协议IP把数据包送达目的主机UDP把数据包送达应用程序TCP把数据完整地送达应用程序 HTTP请求流程构建请求查找缓存准备IP地址和端口等待TCP队列建立TCP连接发送HTTP请求 服务器端处理HTTP请求流程返回请求断开连接重定向 HTTP请求示意图从输入URL到页面展示完整用户输入URL请求过程准备渲染进程提交文档渲染阶段 HTML、CSS和JavaScript是如何变成页面的渲染流程构建DOM树样式计算Recalculate Style布局阶段渲染流程分层图层绘制栅格化raster操作合成和显示 相关介绍 Chrome架构
线程 VS 进程
多线程可以并行处理任务但是线程是不能单独存在的它是由进程来启动和管理的。那什么又是进程呢 一个进程就是一个程序的运行实例。详细解释就是启动一个程序的时候操作系统会为该程序创建一块内存用来存放代码、运行中的数据和一个执行任务的主线程我们把这样的一个运行环境叫进程。 从图中可以看到线程是依附于进程的而进程中使用多线程并行处理能提升运算效率。 总结来说进程和线程之间的关系有以下4个特点。 1. 进程中的任意一线程执行出错都会导致整个进程的崩溃。 2. 线程之间共享进程中的数据。 3. 当一个进程关闭之后操作系统会回收进程所占用的内存。 4. 进程之间的内容相互隔离。
进程架构
单进程浏览器是指浏览器的所有功能模块都是运行在同一个进程里
存在不稳定插件来实现诸如Web视频、Web游戏等各种强大的功能不流畅脚本或者插件会让单进程浏览器变卡顿外页面的内存泄漏也是单进程变慢的一个重要原因不安全 通过浏览器的漏洞来获取系统权限
你可以先看看下面这张图这是2008年Chrome发布时的进程架构。 我们先看看最新的Chrome进程架构你可以参考下图
浏览器进程。主要负责界面显示、用户交互、子进程管理同时提供存储等功能。渲染进程。核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页排版引擎Blink和JavaScript引擎V8都是运行在该进程中默认情况下Chrome会为每个Tab标签创建一个渲染进程。出于安全考虑渲染进程都是运行在沙箱模式下。GPU进程。其实Chrome刚开始发布的时候是没有GPU进程的。而GPU的使用初衷是为了实现3D CSS的效果只是随后网页、Chrome的UI界面都选择采用GPU来绘制这使得GPU成为浏览器普遍的需求。最后Chrome在其多进程架构上也引入了GPU进程。网络进程。主要负责页面的网络资源加载之前是作为一个模块运行在浏览器进程里面的直至最近才独立出来成为一个单独的进程。插件进程。主要是负责插件的运行因插件易崩溃所以需要通过插件进程来隔离以保证插件进程崩溃不会对浏览器和页面造成影响。
未来面向服务的架构 为了解决这些问题在2016年Chrome官方团队使用“面向服务的架构”Services Oriented Architecture简称SOA的思想设计了新的Chrome架构。也就是说 Chrome 整体架构会朝向现代操作系统所采用的“面向服务的架构” 方向发展原来的各种模块会被重构成独立的服务Service每个服务Service都可以在独立的进程中运行访问服务Service必须使用定义好的接口通过IPC来通信从而构建一个更内聚、松耦合、易于维护和扩展的系统更好实现 Chrome 简单、稳定、高速、安全的目标。
TCP协议
在衡量Web页面性能的时候有一个重要的指标叫“FPFirst Paint”是指从页面加载到首次开始绘制的时长。这个指标直接影响了用户的跳出率更快的页面响应意味着更多的PV、更高的参与度以及更高的转化率。那什么影响FP指标呢其中一个重要的因素是网络加载速度。 互联网实际上是一套理念和协议组成的体系架构。 那么如何保证页面文件能被完整地送达浏览器呢
IP把数据包送达目的主机
数据包要在互联网上进行传输就要符合网际协议Internet Protocol简称IP标准。互联网上不同的在线设备都有唯一的地址地址只是一个数字这和大部分家庭收件地址类似你只需要知道一个家庭的具体地址就可以往这个地址发送包裹这样物流系统就能把物品送到目的地。 计算机的地址就称为IP地址访问任何网站实际上只是你的计算机向另外一台计算机请求信息。
UDP把数据包送达应用程序
IP是非常底层的协议只负责把数据包传送到对方电脑但是对方电脑并不知道把数据包交给哪个程序是交给浏览器还是交给王者荣耀因此需要基于IP之上开发能和应用打交道的协议最常见的是“用户数据包协议User Datagram Protocol”简称UDP。 UDP中一个最重要的信息是端口号端口号其实就是一个数字每个想访问网络的程序都需要绑定一个端口号。通过端口号UDP就能把指定的数据包发送给指定的程序了所以IP通过IP地址信息把数据包发送给指定的电脑而UDP通过端口号把数据包分发给正确的程序。和IP头一样端口号会被装进UDP头里面UDP头再和原始数据包合并组成新的UDP数据包。UDP头中除了目的端口还有源端口号等信息。
TCP把数据完整地送达应用程序
对于浏览器请求或者邮件这类要求数据传输可靠性reliability的应用如果使用UDP来传输会存在两个问题
数据包在传输过程中容易丢失大文件会被拆分成很多小的数据包来传输这些小的数据包会经过不同的路由并在不同的时间到达接收端而UDP协议并不知道如何组装这些数据包从而把这些数据包还原成完整的文件。
基于这两个问题我们引入TCP了。TCPTransmission Control Protocol传输控制协议是一种面向连接的、可靠的、基于字节流的传输层通信协议。相对于UDPTCP有下面两个特点:
对于数据包丢失的情况TCP提供重传机制TCP引入了数据包排序机制用来保证把乱序的数据包组合成一个完整的文件。
和UDP头一样TCP头除了包含了目标端口和本机端口号外还提供了用于排序的序列号以便接收端通过序号来重排数据包。
从下图可以看出一个完整的TCP连接的生命周期包括了“建立连接”“传输数据”和“断开连接”三个阶段。
首先建立连接阶段。这个阶段是通过“三次握手”来建立客户端和服务器之间的连接。TCP 提供面向连接的通信传输。面向连接是指在数据通信开始之前先做好两端之间的准备工作。所谓三次握手是指在建立一个TCP连接时客户端和服务器总共要发送三个数据包以确认连接的建立。其次传输数据阶段。在该阶段接收端需要对每个数据包进行确认操作也就是接收端在接收到数据包之后需要发送确认数据包给发送端。所以当发送端发送了一个数据包之后在规定时间内没有接收到接收端反馈的确认消息则判断为数据包丢失并触发发送端的重发机制。同样一个大的文件在传输过程中会被拆分成很多小的数据包这些数据包到达接收端后接收端会按照TCP头中的序号为其排序从而保证组成完整的数据。最后断开连接阶段。数据传输完毕之后就要终止连接了涉及到最后一个阶段“四次挥手”来保证双方都能断开连接。
到这里你应该就明白了TCP为了保证数据传输的可靠性牺牲了数据包的传输速度因为“三次握手”和“数据包校验机制”等把传输过程中的数据包的数量提高了一倍。
HTTP请求流程
HTTP是一种允许浏览器向服务器获取资源的协议是Web的基础通常由浏览器发起请求用来获取不同类型的文件例如HTML文件、CSS文件、JavaScript文件、图片、视频等。此外HTTP也是浏览器使用最广的协议所以要想学好浏览器就要先深入了解HTTP。
构建请求
首先浏览器构建请求行信息如下所示构建好后浏览器准备发起网络请求。
查找缓存
在真正发起网络请求之前浏览器会先在浏览器缓存中查询是否有要请求的文件。其中浏览器缓存是一种在本地保存资源副本以供下次请求时直接使用的技术。
准备IP地址和端口
不过先不急在了解网络请求之前我们需要先看看HTTP和TCP的关系。因为浏览器使用HTTP协议作为应用层协议用来封装请求的文本信息并使用TCP/IP作传输层协议将它发到网络上所以在HTTP工作开始之前浏览器需要通过TCP与服务器建立连接。也就是说HTTP的内容是通过TCP的传输数据阶段来实现的你可以结合下图更好地理解这二者的关系。 这套域名映射为IP的系统就叫做“域名系统”简称DNSDomain Name System。 所以这样一路推导下来你会发现在第一步浏览器会请求DNS返回域名对应的IP。当然浏览器还提供了DNS数据缓存服务如果某个域名已经解析过了那么浏览器会缓存解析的结果以供下次查询时直接使用这样也会减少一次网络请求。 拿到IP之后接下来就需要获取端口号了。通常情况下如果URL没有特别指明端口号那么HTTP协议默认是80端口。
等待TCP队列
现在已经把端口和IP地址都准备好了那么下一步是不是可以建立TCP连接了呢 答案依然是“不行”。Chrome有个机制同一个域名同时最多只能建立6个TCP连接如果在同一个域名下同时有10个请求发生那么其中4个请求会进入排队等待状态直至进行中的请求完成。 当然如果当前请求数量少于6会直接进入下一步建立TCP连接。
建立TCP连接
发送HTTP请求
首先浏览器会向服务器发送请求行它包括了请求方法、请求URIUniform Resource Identifier和HTTP版本协议。 发送请求行就是告诉服务器浏览器需要什么资源最常用的请求方法是Get。比如直接在浏览器地址栏键入极客时间的域名time.geekbang.org这就是告诉服务器要Get它的首页资源。 另外一个常用的请求方法是POST它用于发送一些数据给服务器比如登录一个网站就需要通过POST方法把用户信息发送给服务器。如果使用POST方法那么浏览器还要准备数据给服务器这里准备的数据是通过请求体来发送。
服务器端处理HTTP请求流程
返回请求
断开连接 Connection:Keep-Alive 那么TCP连接在发送后将仍然保持打开状态这样浏览器就可以继续通过同一个TCP连接发送请求。保持TCP连接可以省去下次请求时需要建立连接的时间提升资源加载速度。
重定向
到这里似乎请求流程快结束了不过还有一种情况你需要了解下比如当你在浏览器中打开geekbang.org后你会发现最终打开的页面地址是 https://www.geekbang.org。
HTTP请求示意图
为了便于你理解我画了下面这张详细的“HTTP请求示意图”用来展现浏览器中的HTTP请求所经历的各个阶段。 从图中可以看到浏览器中的HTTP请求从发起到结束一共经历了如下八个阶段构建请求、查找缓存、准备IP和端口、等待TCP队列、建立TCP连接、发起HTTP请求、服务器处理请求、服务器返回请求和断开连接。
从输入URL到页面展示完整
这其中用户发出URL请求到页面开始解析的这个过程就叫做导航。
用户输入
URL请求过程
从返回的响应头信息来看其Content-Type的值是application/octet-stream显示数据是字节流类型的通常情况下浏览器会按照下载类型来处理该请求。 需要注意的是如果服务器配置Content-Type不正确比如将text/html类型配置成application/octet-stream类型那么浏览器可能会曲解文件内容比如会将一个本来是用来展示的页面变成了一个下载文件。 所以不同Content-Type的后续处理流程也截然不同。如果Content-Type字段的值被浏览器判断为下载类型那么该请求会被提交给浏览器的下载管理器同时该URL请求的导航流程就此结束。但如果是HTML那么浏览器则会继续进行导航流程。由于Chrome的页面渲染是运行在渲染进程中的所以接下来就需要准备渲染进程了。
准备渲染进程
默认情况下Chrome会为每个页面分配一个渲染进程也就是说每打开一个新页面就会配套创建一个新的渲染进程。但是也有一些例外在某些情况下浏览器会让多个页面直接运行在同一个渲染进程中。 那什么情况下多个页面会同时运行在一个渲染进程中呢 要解决这个问题我们就需要先了解下什么是同一站点same-site。具体地讲我们将“同一站点”定义为根域名例如geekbang.org加上协议例如https:// 或者http://还包含了该根域名下的所有子域名和不同的端口比如下面这三个
https://time.geekbang.org
https://www.geekbang.org
https://www.geekbang.org:8080它们都是属于同一站点因为它们的协议都是HTTPS而且根域名也都是geekbang.org。 Chrome的默认策略是每个标签对应一个渲染进程。但如果从一个页面打开了另一个新页面而新页面和当前页面属于同一站点的话那么新页面会复用父页面的渲染进程。官方把这个默认策略叫process-per-site-instance。
提交文档
所谓提交文档就是指浏览器进程将网络进程接收到的HTML数据提交给渲染进程具体流程是这样的
首先当浏览器进程接收到网络进程的响应头数据之后便向渲染进程发起“提交文档”的消息渲染进程接收到“提交文档”的消息后会和网络进程建立传输数据的“管道”等文档数据传输完成之后渲染进程会返回“确认提交”的消息给浏览器进程浏览器进程在收到“确认提交”的消息后会更新浏览器界面状态包括了安全状态、地址栏的URL、前进后退的历史状态并更新Web页面。
渲染阶段
HTML、CSS和JavaScript是如何变成页面的
HTML的内容是由标记和文本组成。标记也称为标签每个标签都有它自己的语义浏览器会根据标签的语义来正确展示HTML内容。比如上面的
标签是告诉浏览器在这里的内容需要创建一个新段落中间的文本就是段落中需要显示的内容。 如果需要改变HTML的字体颜色、大小等信息就需要用到CSS。CSS又称为层叠样式表是由选择器和属性组成比如图中的p选择器它会把HTML里面
标签的内容选择出来然后再把选择器的属性值应用到
标签内容上。选择器里面有个color属性它的值是red这是告诉渲染引擎把
标签的内容显示为红色。 至于JavaScript简称为JS使用它可以使网页的内容“动”起来比如上图中可以通过JavaScript来修改CSS样式值从而达到修改文本颜色的目的。
渲染流程
一个完整的渲染流程大致可总结为如下
渲染进程将HTML内容转换为能够读懂的DOM树结构。渲染引擎将CSS样式表转化为浏览器可以理解的styleSheets计算出DOM节点的样式。创建布局树并计算元素的布局信息。对布局树进行分层并生成分层树。为每个图层生成绘制列表并将其提交到合成线程。合成线程将图层分成图块并在光栅化线程池中将图块转换成位图。合成线程发送绘制图块命令DrawQuad给浏览器进程。浏览器进程根据DrawQuad消息生成页面并显示到显示器上 构建DOM树
为什么要构建DOM树呢这是因为浏览器无法直接理解和使用HTML所以需要将HTML转换为浏览器能够理解的结构——DOM树。
样式计算Recalculate Style
样式计算的目的是为了计算出DOM节点中每个元素的具体样式这个阶段大体可分为三步来完成。
把CSS转换为浏览器能够理解的结构。当渲染引擎接收到CSS文本时会执行一个转换操作将CSS文本转换为浏览器可以理解的结构——styleSheets。转换样式表中的属性值使其标准化需要将所有值转换为渲染引擎容易理解的、标准化的计算值计算出DOM树中每个节点的具体样式这就涉及到CSS的继承规则和层叠规则了。 首先是CSS继承。CSS继承就是每个DOM节点都包含有父节点的样式。层叠是CSS的一个基本特征它是一个定义了如何合并来自多个源的属性值的算法。它在CSS处于核心地位CSS的全称“层叠样式表”正是强调了这一点。
布局阶段
现在我们有DOM树和DOM树中元素的样式但这还不足以显示页面因为我们还不知道DOM元素的几何位置信息。那么接下来就需要计算出DOM树中可见元素的几何位置我们把这个计算过程叫做布局。
创建布局树 。在显示之前我们还要额外地构建一棵只包含可见元素布局树。布局计算。现在我们有了一棵完整的布局树。那么接下来就要计算布局树节点的坐标位置了 从图中可以看出本节内容我们介绍了渲染流程的前三个阶段DOM生成、样式计算和布局。要点可大致总结为如下
浏览器不能直接理解HTML数据所以第一步需要将其转换为浏览器能够理解的DOM树结构生成DOM树后还需要根据CSS样式表来计算出DOM树所有节点的样式最后计算DOM元素的布局信息使其都保存在布局树中。
渲染流程
分层
渲染引擎还需要为特定的节点生成专用的图层并生成一棵对应的图层树LayerTree。 通常情况下并不是布局树的每个节点都包含一个图层如果一个节点没有对应的层那么这个节点就从属于父节点的图层。 通常满足下面两点中任意一点的元素就可以被提升为单独的一个图层。
拥有层叠上下文属性的元素会被提升为单独的一层。第二点需要剪裁clip的地方也会被创建为图层。
图层绘制
渲染引擎实现图层的绘制与之类似会把一个图层的绘制拆分成很多小的绘制指令然后再把这些指令按照顺序组成一个待绘制列表
栅格化raster操作
绘制列表只是用来记录绘制顺序和绘制指令的列表而实际上绘制操作是由渲染引擎中的合成线程来完成的。你可以结合下图来看下渲染主线程和合成线程之间的关系 通常一个页面可能很大但是用户只能看到其中的一部分我们把用户可以看到的这个部分叫做视口viewport合成线程会将图层划分为图块tile然后合成线程会按照视口附近的图块来优先生成位图实际生成位图的操作是由栅格化来执行的。所谓栅格化是指将图块转换为位图。
合成和显示
一旦所有图块都被光栅化合成线程就会生成一个绘制图块的命令——“DrawQuad”然后将该命令提交给浏览器进程。
浏览器进程里面有一个叫viz的组件用来接收合成线程发过来的DrawQuad命令然后根据DrawQuad命令将其页面内容绘制到内存中最后再将内存显示在屏幕上。
相关介绍
如果你通过JavaScript或者CSS修改元素的几何位置属性例如改变元素的宽度、高度等那么浏览器会触发重新布局解析之后的一系列子阶段这个过程就叫重排。无疑重排需要更新完整的渲染流水线所以开销也是最大的。
如果修改了元素的背景颜色那么布局阶段将不会被执行因为并没有引起几何位置的变换所以就直接进入了绘制阶段然后执行之后的一系列子阶段这个过程就叫重绘。相较于重排操作重绘省去了布局和分层阶段所以执行效率会比重排操作要高一些。 那如果你更改一个既不要布局也不要绘制的属性会发生什么变化呢渲染引擎将跳过布局和绘制只执行后续的合成操作我们把这个过程叫做合成。
我们使用了CSS的transform来实现动画效果这可以避开重排和重绘阶段直接在非主线程上执行合成动画操作。这样的效率是最高的因为是在非主线程上合成并没有占用主线程的资源另外也避开了布局和绘制两个子阶段所以相对于重绘和重排合成能大大提升绘制效率。