BrowserStack-浏览器引擎及渲染机理(含重排和重绘)

Created
Feb 27, 2021 04:04 AM
Tags
browser
 

渲染引擎和 JS 引擎?

网页在客户端的呈现, 重度依赖于浏览器。因此,了解浏览器在网页渲染方面的过程和机理,必利于网页开发。
如何解释两个引擎?
现代浏览器都有两个基本工作, 把页面呈现出来[渲染引擎(HTML、CSS)]和对 JS 的处理[JS 引擎], 两个过程可以通过 DOM 数据结构联系起来。
那什么是浏览器内核?
内核其实就是引擎的别名,起初包含 JS 引擎,(随着 JS 的扩展,不仅仅只有浏览器使用 JS 引擎),现在一般只表示渲染引擎

主流浏览器和引擎

1.看市场, 了解趋势
2020 年浏览器的市场份额占比
notion image
2.主流的浏览器都用什么引擎
  • firefox: Gecko
  • chrome & opera: Blink[Google 联手 Facebook、IBM、Opera 等大厂开发]
  • safari: Webkit
  • IE: Trident
  • Edge: Edgehtml => Blink[2020 年发布]
  • firefox: SpiderMonkey
  • chrome: V8[目前最通用,用于 Nodejs 和 Deno 项目]
  • safari: javascriptcore
  • IE: chakra
  • Edge: chakra => V8[2020 年更新]
notion image

渲染引擎机理(简)

1.渲染引擎的主要工作
为了呈现页面,渲染引擎需要:
  • 1.解析成对象模型:
    • 找到页面结构(内容):首先, 读取 HTML 文件, 根据其编码把它转换成字符;利用 html 的标签以及标签之间的层级关系创建 DOM tree
      • notion image
    • 看看页面长啥样: 同理 DOM tree, 分析 CSS 生成CSSOM Tree
      • notion image
        为什么要解析成对象模型: 比如 DOM 和 CSSOM 两者都是对象模型( OM 后缀), 从上面的图例也可以看出它们都是树形数据结构,而树形结构的最基本单元 ——— node 节点, 其中每个 node 节点都含一个对象(比如 document.documentElement 是根 node,通过这个 node 的信息我们知道它对应的对象是整个 HTML), 对象里的属性和方法就可以描述或和操作这个节点(这就可以很好地解释我们通过 JS 获取的元素集合为什么是 NodeList),所以可以理解为有了对象模型, 页面文档具有编程接口, 就可以利用 js 操作页面中的内容。
  • 2.根据 js 更改 DOM Tree CSSOM Tree[js 没有更改则跳过]
  • 3.合并DOM TreeCSSOM Tree , 生成 Render Tree:
    • Render Tree 是最终用于布局, 所以一些不参与布局的内容不会被加入到Render Tree中(比如<meta> <link> display:none等)
    • DOM Tree 和 CSSOM Tree 不会被删除 , 方便 js 的交互
  • 4.计算布局(computing layout) 根据Render Tree来排版布局, 以计算每个节点的几何信息(位置 尺寸)注意:(只要几何布局不改变)第二次渲染并不一定需要此步骤,比如改变了元素颜色,不需要进行二次排版布局
  • 5.绘制页面(paint)
    • 布局完成后, 浏览器根据布局确定每个像素点的显示,利用 GPU, 完成网页的绘制;至此, 一个 UI 制作完毕,我们就可以看见页面啦!
      我画了一个简单的流程图简要概括以上的五个步骤:
      notion image

重排和重绘 [reflows/layouting & Repaints]

注:reflows 又可称作 layouting(回流)
简单点说, 初次浏览器渲染后, 由于 CSS、JS 有动画存在,JS 也可以进行许多动态操作, 会导致网页会进行二次渲染,再次执行以上的步骤
注意:渲染的第四步(computing layout)可以在二次渲染的时候跳过,前提是不改变页面的几何布局
因为第四步的可跳过性,我们把二次渲染分为重排和重绘(分别对应第 4、5 步)
前三步也会执行,但是处理速度很快,所以忽略
如何区分两者?
  • 重排:对于影响布局的更改,浏览器会进行重排
    • 实列:设定宽高、浮动、定位、input内容更改、DOM 操作等等
  • 重绘:相对直观——只要页面可视内容发生改变,一定会重绘。比如透明度、 颜色等
为什么要关注重排和重绘?
它们成为前端性能优化的切入点,需要减少重回和重排的次数来尽量优化性能,绘制更流畅的 UI,获得更佳的用户体验
浏览器有帮我们优化吗?
  • 浏览器也很懒,不会傻到每一次小的变动都去重新渲染,多个连续的页面变化会暂时集中储存到一个队列,每一个 frame 批次执行更改并且清空队列,再去执行渲染步骤。不过有几个列外(当我们需要实时获取页面的状态时,队列会被强制清空用于获取最新最精确的状态):
    • 请求 JS 盒子模型的属性,如clientTop scroolTop等等
    • 请求获得元素样式、宽高:ele.width ele.getComputedStyle()等等
  • 第一步不一定需要全部重新执行(可以只有部分重新更改)
  • 第二步本身是不存在于初次渲染中的,但如果页面载入时 JS 便对页面 DOM 或 CSSOM 进行了更改,为避免连续渲染两次,会先执行更改,再执行第三步
  • 只要重新渲染,第三步一定重新执行,重新生成 Render Tree
自己如何优化?
网络上有比较好的例子,在这里备注提供几个地址

JS 引擎

参考及补充:

欢迎讨论、指正