• 浏览器的渲染与小优化


    学习笔记,原创内容,谢谢支持(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

  • 相关阅读:
    Java读取文件方法和给文件追加内容
    Java中String类的format方法使用总结
    Java时间戳与日期格式字符串的互转
    Eclipse遇到Initializing Java Tooling解决办法
    CSS的总结(选择器,伪类等...)
    Redis中的关系查询(范围查询,模糊查询等...)
    Redis中文显示为Unicode编码的解决办法
    用bash命令得到Windows一个目录下的所有文件并且把结果输入到一个文件
    MapReduce按照两个字段对数据进行排序
    Scala中的抽象类
  • 原文地址:https://www.cnblogs.com/victory820/p/13947411.html
Copyright © 2020-2023  润新知