现代浏览器的渲染过程与优化思路

前言

概括渲染的流程

  • prase HTML 解析富文本
  • recalculate style (DOM + CSS = render tree) 将DOM和CSS合成实际显示的树状节点
  • multi surfaces, layouts and composite 合成图层
  • raster, draw bitmap 矢量转位图,光栅器生成像素点

详细流程

prase HTML

请求页面

brower-render-prase-html

  • 浏览器向服务端发出获取请求,如 GET / HTTP/1.1
  • 服务端返回HTML,浏览器会采取非常机智的措施并提前解析,生成DOM(document object model)
  • 下一步就是将HTML与CSS结合起来

recalculate style,

brower-render-dom-css-recalculate-style

  • HTML结合CSS重新计算样式

brower-render-dom-css-to-renderTree

  • HTML与CSS结合起来,生成渲染树render tree,与DOM tree类似,但是有所不同
  • 渲染数比起DOM树缺少某些内容,如<HEAD>,<style>,<script>等,头部与脚本等元素不见了

brower-render-renderTree-only-display

  • 值得一提的时,如果有元素的CSS属性有display:none,该节点的段落也不会出现在渲染树

brower-render-tree

  • 同样,如果CSS中添加了伪元素,如after,befor,就会添加到渲染树中

  • 总而言之,只有实际上会显示在网页上的元素,才会出进入渲染树,课程的原话如下

so this is essentially a simplified view of where the critical rendering path 所以这本质上是关键渲染路径的简化视图

layout

布局

brower-render-layout

  • 这一步在chrome的devTool中显示为Layout, 也有称为reflow
  • 布局,简单来说就是排版成一个个嵌套的方框 —— 网络布局模型
  • 这意味着某个元素可以影响到其他元素, 例如body的宽度通常会影响到子项的宽度等,一直往树的下方蔓延
  • 值得注意的是,如果网页中执行javascript脚本修改了页面中任意可显示元素宽高,不管这个元素是body还是某个毫不起眼的divscope作用域都是document,都会导致整个document重新layout

raster 光栅化

brower-render-raster

  • 这一步是光栅,可以理解为将矢量图转化为位图

    raster for page 页面

brower-render-raster-paint

  • 图中,左边是光栅器需要执行的的绘制调用,以便填充像素

brower-render-raster-paint-complete

  • 上图是填充完成的状态
  • 填充顺序正如图左边的绘制调用如下
    • 绘制文本
    • 接着是阴影边框线条图片
    • 等等。。
  • 这些步骤在devTool中显示为Paint

raster for image 图片

brower-render-raster-image-draw-bitmap

  • 在前面的光栅调用中,可以看到drawBitmap
  • 网页中出现图片时,浏览器需要请求图片文件,拿到之后,需要将图片文件的数据解码到内存,如下

brower-render-raster-image-decode-resize

  • 解码后,可能还需要调整尺寸

layouts and composite

  • 之前的layout布局与raster光栅步骤是处理单个layer图层,接下来是合成多个图层
  • devTool中称作composite layers

brower-render-layout-composite

  • 合成图层,影响的因素有:透明度,动画

GPU put the pictures up on screen

brower-render-layout-upload-gpu

  • 最后GPU根据指示将图片显示到屏幕上

In brief, it is how we get from a single request all the way through to pixels on screen 最后,这就是从单个请求一直到将像素填充到屏幕上的简单流程

render pipline

渲染的管道, 这是渲染性能优化的重要知识点

  • 当网页执行javascript脚本使页面发生变化时,可能执行以下步骤

    • javascript 通常,我们会使用javascript来处理内容并导致外观变化
    • style 如果通过CSS或js做出外观更改,浏览器必须重新计算受到影响的元素的样式
    • layout 如果改变了布局属性,即更改元素的几何结构,例如宽度高度,相对位置或者间距,那么浏览器需要检查所有其他元素并re-flow the page回流网页
    • paint 受到影响的区域需要重新绘制
    • composite 最后绘制的元素将需要合成在一起
  • 不同的变化可能会执行不同的步骤,推荐网站csstriggers.com,它罗列出了不同的css样式修改影响到的不同的渲染步骤

附录

Browser Rendering Optimization 课程

csstriggers.com