浏览器的渲染与小优化

学习笔记,原创内容,谢谢支持(git项目验证地址:https://github.com/victory820/validatejs_css)

渲染引擎

主要模块

HTML 解析器

解析 html 文档,主要将 html 解释成 DOM 树

CSS 解析器

为 DOM 的各个元素计算样式信息,为布局提供基础设施

JS 引擎

可以修改网页内容,也能修改 css 信息,通过 dom 接口和 css 接口来修改网页内容和样式

布局模块(layout)

在 DOM 创建后,内核(chrome 为例 webkit)将元素对象和样式结合起来,计算它们的大小位置等布局信息,形成一个能表达所有信息的内部表示模型

绘图模块

将布局计算后的各个网页节点绘制成图像结果

大致的渲染过程

  1. 遇见 HTML 标记调用 HTML 解析器解析为对应 token(一个 token 就是标签文本的序列化,构建的 dom 树就是一块内存保存着 token 信息与标记的关系)

遇见 style/link 标记调用相应解析器处理 css 标记,构建 css 样式树

  1. 遇见 script 标记调用 js 引擎,处理 script 标记、绑定事件、修改 dom 树/css 树等
  2. 将 dom 树和 css 树合并成一个渲染树
  3. 根据渲染树渲染,计算每个节点的几何信息(依赖 GPU)
  4. 最终将各个节点绘制到屏幕上

 

阻塞渲染

css 阻塞

  1. style 形式和 link 形式

style 标签中内容

link 引入内容

由 html 解析器解析

由 css 解析器解析

不阻塞浏览器渲染

阻塞浏览器渲染

不阻塞 DOM 解析

不阻塞 DOM 解析

 

阻塞后面 js 的执行

  1. 优化
    1. 使用 cdn 方式进行加速
    2. 对 css 进行压缩
    3. 减少 http 请求,合并 css(辩证看待)
    4. 优化样式代码

js 阻塞

  1. 阻塞后续 dom 解析。原因:js 是可以操作 dom 的,如果不阻塞可能做无用功
  2. 阻塞页面渲染。原因:js 可以改变样式,如果不阻塞同样可能做无用功
  3. 阻塞后续 js 的执行。原因:维护依赖关系

 

验证

  1. link 进来的 css 阻塞页面渲染
  2. link 进来的 css 不阻塞页面解析
  3. js 阻塞页面渲染
  4. js 阻塞页面解析

 

图层

浏览器在渲染一个页面时,会将页面分为很多个图层,图层有大有小上面有一个或多个节点。

 

图层创建条件

(以 chrome 为例,还有其他暂时只提以下同时也依赖电脑配置和浏览器设置)

1. 拥有具有 3D 变换的 css 属性

2. 使用加速视频解码的 video 节点

3. canvas 节点

4. 拥有 css 加速属性的元素(will-change)

 

在渲染 DOM 的时候,浏览器的实际工作是:

  1. 获取 DOM 后分割为多个图层
  2. 对每个图层的节点计算样式结果(recalculate style 样式重计算)
  3. 为每个节点生成图形和位置(layout 重排/回流)
  4. 将每个节点绘制填充到图层位图中(paint 重绘)
  5. 图层作为纹理上传给 GPU
  6. 组合多个图层到页面上生成最终屏幕图形(composite layers 图层重组)
 

重绘 repaint

是一个元素外观的改变所触发的浏览器行为。重绘不会带来重新布局,所以并不一定伴随重排。

重绘是以图层为单位的,图层中某个元素需要重绘,整个图层都会重绘

为了提高性能应该让变化的东西拥有一个自己的图层

触发重绘的属性

-

-

-

color

background

outline-color

border-style

background-image

outline

border-raius

background-position

outline-style

visibility

background-repeat

outline-width

text-decoration

background-size

box-shadow

 

 

重排 reflow(回流)

渲染对象在创建完成并添加到渲染树时,并不包含位置和大小信息,计算这些值的过程称为重排

重排大多数情况下会导致重绘。比如改变元素的位置,就会触发重绘和重排

触发重排的属性

-

-

-

width

top

text-align

height

bottom

overflow-y

padding

left

font-weight

margin

right

overflow

display

position

font-family

border-width

float

line-height

border

clear

vertival-align

min-height

white-space

 

常见触发重排的操作

reflow 的成本比 repaint 高,一个节点的 reflow 很有可能导致子节点甚至父节点及同级节点的 reflow

下面动作很大可能是成本高的

  1. 增加、删除、修改 DOM 节点时,导致 reflow,repaint
  2. 移动 dom 位置
  3. 修改 css 样式
  4. resize 窗口时
  5. 修改网页的默认字体

 

display:none 会触发 reflow

visibility:hidden 只会触发 repaint

 

优化方案

  1. 元素位置移动变换时尽量使用 css3 的 transform 来替代 top/left 等操作,变换(transform)和透明度(opacity)的改变仅仅影响图层的组合
  2. 将多次改变样式属性的操作合并成一次,即不要一条一条修改 dom 样式,预先定义 class 修改 classname
  3. 将 dom 离线后再修改。先把元素 display:none 后在对隐藏元素进行操作不会引发其他元素重排。
  4. 利用文档碎片-documentFragment.参照 https://developer.mozilla.org/zh-CN/docs/Web/API/DocumentFragment
  5. 不要把获取某些 dom 节点的属性值放到循环内当作循环变量。当向浏览器请求 style 信息时,就会让浏览器 flush 队列.如:offsetTop/Left/Width/Height;scrollTop/Left/Width/Height;clientTop/Left/Widht/Height;width/height
  6. 动画实现过程中,启用 GPU 硬件加速 transform: tranlateZ(0)
  7. 为动画元素新建图层,提高动画元素的 z-index
  8. 编写动画时可以使用以下 api

    requestAnimationFrame https://developer.mozilla.org/zh-CN/docs/Web/API/Window/requestAnimationFrame

 

posted on 2020-11-09 10:51  daV_chen  阅读(117)  评论(0编辑  收藏  举报

导航