浏览器工作原理与实践总结一

一、常用Chrome架构

Chrome 打开一个页面需要启动多少进程?你可以点击 Chrome 浏览器右上角的“选项”菜单,选择“更多工具”子菜单,点击“任务管理器”查看

相关概念

并行处理:同一时刻处理多个任务**(多线程,大大提升性能)

线程VS进程:1、线程是不能单独存在的,它是由进程来启动和管理的2、启动一个程序的时候,操作系统会为该程序创建一块内存,用来存放代码、运行中的数据和一个执行任务的主线程,我们把这样的一个运行环境叫进程。

线程是依附于进程的,而进程中使用多线程并行处理能提升运算效率。

  1. 进程中的任意一线程执行出错,都会导致整个进程的崩溃。
  2. 线程之间共享进程中的数据。
  3. 当一个进程关闭之后,操作系统会回收进程所占用的内存。
  4. 进程之间的内容相互隔离。采用进程间通信(IPC)的机制。

单进程浏览器是指浏览器的所有功能模块都是运行在同一个进程里,这些模块包含了网络、插件、JavaScript运行环境、渲染引擎和页面等。使用单进程浏览器会带来以下三个原因:

  • 不稳定
  • 不流畅
  • 不安全

Chrome进程架构(多线程)

《浏览器工作原理与实践总结一》
从图中可以看出,最新的 Chrome 浏览器包括:1 个浏览器(Browser)主进程、1 个 GPU 进程、1 个网络(NetWork)进程、多个渲染进程和多个插件进程。

下面我们来逐个分析下这几个进程的功能。

  • 浏览器进程。主要负责界面显示、用户交互、子进程管理,同时提供存储等功能。
  • 渲染进程。核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页,排版引擎 Blink 和JavaScript 引擎 V8 都是运行在该进程中,默认情况下,Chrome 会为每个 Tab标签创建一个渲染进程。出于安全考虑,渲染进程都是运行在沙箱模式下。
  • GPU 进程。而GPU 的使用初衷是为了实现 3D CSS 的效果,只是随后网页、Chrome 的 UI 界面都选择采用 GPU 来绘。
  • 网络进程。主要负责页面的网络资源加载,之前是作为一个模块运行在浏览器进程里面的,直至最近才独立出来,成为一个单独的进程。
  • 插件进程。主要是负责插件的运行,因插件易崩溃,所以需要通过插件进程来隔离,以保证插件进程崩溃不会对浏览器和页面造成影响。

在多线程模型提升浏览器的稳定性、流畅性、安全性之外也带来了:

  • 更高的资源占用。(消耗内存)
  • 更复杂的体系架构。(浏览器各模块之间耦合性高、扩展性差)

探索未来面向服务的架构

二、TCP协议,保证页面文件能被完整送达浏览器

衡量Web页面性能的时候有一个重要指标叫:“FP”指从页面加载到首次开始绘制的时长。影响FP指标:网络加载速度。

HTTPWebSocket都是基于TCP/IP的,TCP/IP是优化Web页面的加载速度的根基。

如何保证页面文件能被完整地送达到浏览器呢?

站在数据包的视角

《浏览器工作原理与实践总结一》
IP负责把数据包送达目的主机。

2、UDP:把数据包送达应用程序,因为IP是非常底层的协议,只负责把数据包传送到对方电脑,但是对方电脑并不知道把数据包交给哪个程序,因此,需要基于IP之上开发能和应用打交道的协议,常见的“用户数据包协议”称为UDP。

《浏览器工作原理与实践总结一》
IP通过IP地址信息把数据包发送到指定的电脑,而UDP通过端口把数据包分发给正确程序。

使用UDP会产生那些问题:

  • 1、UDP发送数据时因各种因素会有丢包现象,且不提供重发机制,所以不能保证数据可靠性。
  • 2、UDP传输速度非常快,所以UDP会应用在一些关注速度、但不那么严格要求数据完整的领域,如在线视频、互动游戏等。

为了解决UDP数据包传输过程容易丢失,引入TCP。

TCP:把数据完整地送达应用程序,是一种面向连接的、可靠的、基于字节流的传输层通信协议。

TCP两个特点:

  • 1、对于数据包丢失的情况,TCP提供重传机制;
  • 2、TCP引入数据包排序机制,用来保证把乱序的数据包组合成一个完整的文件。

完整的TCP连接的生命周期包括:

  • 1、建立连接
  • 2、传输数据
  • 3、断开连接

《浏览器工作原理与实践总结一》
TCP为了保证数据传输的可靠性(通过TCP头保证了一块大的数据传输),牺牲了数据包的传输速度,因为“三次握手”和“数据包校验机制”等把传输过程的数据包数量提高了一倍。

三、HTTP请求流程,很多站点第二次打开速度会很快?

HTTP协议,是建立在TCP连接的基础上的(HTTP应用层,TCP传输层)。HTTP是一种允许浏览器向服务器获取资源的协议,是Web基础。

为什么很多站点第二次打开速度会很快?这一切都隐藏在HTTP请求中。

浏览器端发起HTTP请求流程:

  • 1、构建请求行信息,构建好后,浏览器准备发起网络请求。
  • 2、查找缓存。

在真正发起网络请求之前,浏览器会先在浏览器缓存中查询是否要请求的文件。其中,浏览器缓存是一种在本地保存资源副本,以供下次请求时直接使用的技术。发起网络请求——浏览器缓存已存副本——拦截请求——返回该资源副本——结束请求(不会重新去服务器下载资源)

这样做的好处:1、缓解服务器端压力,提升性能(获取资源耗时更短)2、对网站来说,缓存是实现快速资源加载的重要组成部分。

  • 3、准备IP地址和端口

HTTP网络请求的第一步是和服务器建立TCP连接,建立TCP连接第一步准备IP地址和端口号(HTTP默认80,HTTPS默认443)。DNS数据缓存服务,对域名解析以供下次直接使用,这样会减少一次网络请求。

  • 4、等待TCP队列

Chrome有个机制,同一个域名同时最多只能建立6个TCP连接,如果在同一个域名下同时有10个请求发生,那么4个请求会进入排队等待状态,直至进行中请求完成。

  • 5、建立TCP连接
  • 6、发送HTTP请求(请求行、请求头、请求体(数据))Get跟post方法

服务器端处理浏览器端发送过来的HTTP请求

  • 1、返回请求(成功状态码200,没找到页面404,响应行、响应头、响应体)
  • 2、断开连接(服务器向客户端返回请求数据,关闭TCP连接)
  • 3、重定向

页面二次打开会很快?

  • 1、DNS缓存
  • 2、页面资源缓存

DNS缓存:浏览器本地IP和域名关联起来
页面资源缓存:响应头Cache-Control字段来设置是否缓存该资源。时长是Max-age参数设置。

Cache-Control:Max-age=2000

若缓存资源过期则会继续发起请求。

很多网站第二次访问能够秒开,是因为这些网站把很多资源都缓存在了本地,浏览器缓存直接使用本地副本来回应请求,而不会产生真实的网络请求,从而节省了时间。同时,DNS 数据也被浏览器缓存了,这又省去了 DNS 查询环节。

如何保持登录状态?

《浏览器工作原理与实践总结一》

四、从输入URL到页面展示经历什么?

整个过程需要各个进程之间的配合:

  • 浏览器进程:主要负责用户交互、子进程管理和文件储存等功能。
  • 网络进程:是面向渲染进程和浏览器进程等提供网络下载功能。
  • 渲染进程:主要职责是把从网络下载的HTML、JavaScript、CSS、图片等资源解析为可以显示和交互的页面。因为渲染进程所有的内容都是通过网络获取的,会存在一些恶意代码利用浏览器漏洞对系统进行攻击,所以运行在渲染进程里面的代码是不被信任的。这也是为什么 Chrome 会让渲染进程运行在安全沙箱里,就是为了保证系统的安全。

不考虑用户输入搜索关键字的情况:

1、用户输入url并回车
2、浏览器进程检查url,组装协议,构成完整的url
3、浏览器进程通过进程间通信(IPC)把url请求发送给网络进程
4、网络进程接收到url请求后检查本地缓存是否缓存了该请求资源,如果有则将该资源返回给浏览器进程

5、如果没有,网络进程向web服务器发起http请求(网络请求),请求流程如下:
    5.1 进行DNS解析,获取服务器ip地址,端口(http端口默认80,https默认443)
    5.2 利用ip地址和服务器建立tcp连接
    5.3 构建请求头信息
    5.4 发送请求头信息
    5.5 服务器响应后,网络进程接收响应头和响应信息,并解析响应内容
6、网络进程解析响应流程;
    6.1 检查状态码,如果是301/302,则需要重定向,从Location自动中读取地址,重新进行第4步。 301资源被永久移除 ,302资源还在。          
    6.2 200响应处理:
        检查响应类型Content-Type,如果是字节流类型,则将该请求提交给下载管理器,该导航流程结束,不再进行
        后续的渲染,如果是html则通知浏览器进程准备渲染进程准备进行渲染。
7、准备渲染进程
    7.1 浏览器进程检查当前url是否和之前打开的渲染进程根域名是否相同,如果相同,则复用原来的进程,如果不同,则开启新的渲染进程
8、传输数据、更新状态
    8.1 渲染进程准备好后,浏览器向渲染进程发起“提交文档”的消息,渲染进程接收到消息和网络进程建立传输数据的“管道”
    8.2 渲染进程接收完数据后,向浏览器发送“确认提交”
    8.3 浏览器进程接收到确认消息后更新浏览器界面状态:安全、地址栏url、前进后退的历史状态、更新web页面。    
9、渲染进程对文档进行页面解析和子资源加载,HTML 通过HTM 解析器转成DOM Tree
 (二叉树类似结构的东西),CSS按照CSS规则和CSS解释器转成CSSOM TREE,两个tree结合,
  形成rendertree(不包含HTML的具体元素和元素要画的具体位置),
  通过Layout可以计算出每个元素具体的宽高颜色位置,结合起来,开始绘制,最后显示在屏幕中新页面显示出来

五、渲染流程:HTML、CSS、JavaScript是如何变成页面?

渲染机制过于复杂,所以渲染模块在执行过程中会被划分为很多子阶段,输入的 HTML 经过这些子阶段,最后输出像素。我们把这样的一个处理流程叫做渲染流水线。
从 HTML 到 DOM、样式计算、布局、图层、绘制、光栅化、合成和显示

  • DOM树:渲染进程将 HTML 内容转换为能够读懂的DOM 树结构。
  • 样式计算:渲染引擎将 CSS 样式表转化为浏览器可以理解的styleSheets,计算出 DOM 节点的样式。
  • 布局树:创建布局树,并计算元素的布局信息。
  • 分层:对布局树进行分层,并生成分层树。
  • 绘制:为每个图层生成绘制列表,并将其提交到合成线程。
  • 光栅化:合成线程将图层分成图块,并在光栅化线程池中将图块转换成位图。
  • 合成:合成线程发送绘制图块命令DrawQuad给浏览器进程。
  • 显示:浏览器进程根据 DrawQuad 消息生成页面,并显示到显示器上。

重排:如果你通过 JavaScript 或者 CSS 修改元素的几何位置属性,例如改变元素的宽度、高度等,那么浏览器会触发重新布局,解析之后的一系列子阶段,这个过程就叫重排。无疑,重排需要更新完整的渲染流水线,所以开销也是最大的。

重绘:如果修改了元素的背景颜色,那么布局阶段将不会被执行,因为并没有引起几何位置的变换,所以就直接进入了绘制阶段,然后执行之后的一系列子阶段,这个过程就叫重绘。相较于重排操作,重绘省去了布局和分层阶段,所以执行效率会比重排操作要高一些。

合成:如果你更改一个既不要布局也不要绘制的属性,会发生什么变化呢?渲染引擎将跳过布局和绘制,只执行后续的合成操作,我们把这个过程叫做合成。

减少重排重绘, 方法很多:

  1. 使用 class 操作样式,而不是频繁操作 style
  2. 避免使用 table 布局
  3. 批量dom 操作,例如 createDocumentFragment,或者使用框架,例如 React
  4. Debounce window resize 事件
  5. 对 dom 属性的读写要分离
  6. will-change: transform 做优化。

课程地址

    原文作者:阳光总在风雨后
    原文地址: https://segmentfault.com/a/1190000020372713
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞