Chrome浏览器渲染原理

116 阅读5分钟

Chrome浏览器渲染原理

1. 浏览器渲染过程详解

1.1 DNS解析

用户输入网址域名,HTML页面被定位到对应IP的服务器,如果以前没有访问过这个网站,就需要进行DNS查询。 Dns有优化策略,取到域名对应的IP会缓存一段时间,这样就可以从缓存中拿到IP。

1.2 建立连接 三次握手

TCP握手: SYN(同步) 、 SYN-ACK(同步---确认) 、ACK(确认)

  • 浏览器向服务器发送SYN包
  • 服务器接收到SYN包之后,发送一个SYN-ACK(同步--确认)
  • 浏览器收到服务器的SYN-ACK后,发送一个ACK(确认),服务器收到ACK之后,TCP套接字连接建立。

1.3 TLS协商(HTTPS协议,建立在TCP连接的基础上的):

  • 客户端向服务端发送ClinentHello请求 (客户端 ->服务端 发送支持加密套件和第一个随机数

  • 服务端向客户端发送ServiceHello请求&Certificate(加密)证书 (服务端->客户端 发送数字证书和第二个随机数,使用CA证书获取服务端公钥)

  • 客户端向服务端发送ClientKey (客户端 ->服务端 生成第三个随机数,用服务端公钥加密)

  • 服务端向客户端发送Finished确认

  • 客户端返回Server Finished确认协商完成

    补充:随机数:3个随机数,密码学范畴,在三个阶段使用,密钥协商

1.4 响应

当我们成功与服务端建立连接之后,浏览器会发送一个GET请求给服务端,一旦服务器收到请求,对网站来说通常服务器会使用相关的响应头和HTML内容进行回复。第一字节时间是衡量响应速度的重要指标

第一字节时间(TTFB)是指从浏览器请求页面到接收来自服务器发送的信息的第一个字节的时间。这包括 DNS 查询和使用 TCP 握手建立连接的时间。如果请求是通过 HTTPS 发出的,则还包括 TLS 握手建立连接的时间。

1.5 解析构建DOM树

Dom树描述了文档的内容,DOM节点数量越多,构建DOM树所需的时间就越长。当解析器发现非阻塞资源,浏览器会请求这些资源并继续解析,当遇到CSS文件也可以继续进行,但是对于script标签(特别是没有asyncdefer属性的)会阻塞渲染并停止HTML解析,尽管浏览器的预加载扫描器加速了这个过程,但过多的脚本依然是个重要的瓶颈。预加载扫描器:当js解析和执行顺序不重要时,可以添加async属性或defer属性处理脚本

1.6 构建CSSOM树

CSS对象模型和DOM是相似的。构建CSSOM非常快,可以使用styleSheet拿到样式表,在web性能优化方面,它是可以轻易实现的,因为创建CSSOM的总时间通常小于一次DNS查询所需时间

1.7 渲染

渲染步骤包括样式、布局、绘制,某些情况还包含合成。将创建的DOM树和CSSOM树组合成一个渲染树,然后用于计算每个可见元素的布局,将其绘制到屏幕上。某些情况可以将内容提升到它们自己的层进行合成,通过在GPU而不是CPU上绘制屏幕的一部分来提升性能,从而释放主线程。

样式、布局(第一次确定每个节点的大小和位置)&重排(布局后对节点大小和位置的重新计算)、绘制、合成(文档各部分以不同层绘制,相互重叠,必须合成)&回流(会触发重绘和重新 合成

1.8 交互

主线程绘制页面完成,如果加载包括正确延迟加载的js,并且仅在onload时间触发后执行,那么主线程坑你会忙于执行脚本,无法用于其他交互操作

可交互时间(TTI)是测量第一个请求导致DNS查询和SSL连接到页面可交互时所用的时间

首次内容绘制时间(FCP)

2. 浏览器的多进程

如果是单进程的话,十分限制,只能同时做一件事。(不稳定、不流畅、不安全)

浏览器的进程类型,请参照:developer.chrome.com

GPU进程:处理所有GPU加速任务,如CSS动画、Canvas和WebGL渲染,利于提高性能效率

nacl:本地化处理进程,可以用来实现网页端剪辑之类功能

renderer:渲染进程 -------处理特定标签页内的网页内容

Worker:webWorker进程:允许在后台执行代码,不干扰用户界面,适合处理大文件上传

browser进程:浏览器一些相关操作(标签栏操作、窗口操作、输入网址等等)

进程协作/通信(ipc):主进程通过网络进程发送请求,请求回来之后将HMTL交由渲染进程,涉及GPU加速操作,通过ipc将任务告诉给主进程(当作一个领导,指挥其他进程做事情)给GPU进程进行加速

GPU和CPU模型:

  • CPU模型(管子):速度很快,适合处理复杂数据
  • GPU模型(筛子):适合处理简单数据(加减计算、矩阵转换)

3. 渲染层性能优化思路

渲染优化思路围绕任务执行时长(一般是HTML|CSS|JS执行时长,音视频还包括webAssembly)来评估.

  • 减轻主进程压力(50ms衡量一个任务是否“耗时”,表现卡顿)---解决方案:拆分长任务

  • 手动推迟代码执行(另推荐postmessage()推迟)

  • React Scheduler

      
      function saveSettings () { //This is a long task.
      2  validateForm()
      3  showSpinner()
      4  saveToDatabase()
      5  updateUI()
      6  sendAnalytics()
      }
    
      
      fuction saveSetting(){  //将相关函数传递给setTimeout()来推迟某些任务的执行
          validateForm()
          showSpinner()
          updateUI()
          
          setTimeout(() => {
              saveToDatabase()
              sendAnalytics()
          },0)
      }