浏览器渲染机制

文章详细介绍了浏览器渲染机制,包括HTML解析生成DOM树和CSSOM树的过程,渲染阻塞现象及其影响,以及如何通过CSS优先和合理放置JS来优化性能。重点讲解了回流、重绘的区别,以及async和defer属性在JavaScript优化中的作用。
摘要由CSDN通过智能技术生成

学习渡一课程、参考 必须明白的浏览器渲染机制 - 掘金

渲染机制的流程

HTML解析

布局

分层

绘制

分块

光栅化

HTML解析 - Parse HTML

解析html会生成一个 dom树和cssom树

 

document.styleSheets  可以看到cssom树 

 

渲染阻塞

在渲染的过程中,遇到一个script标记时,就会停止渲染,去请求脚本文件并执行脚本文件,因为浏览器渲染和 JS 执行共用一个线程,而且这里必须是单线程操作,多线程会产生渲染 DOM 冲突。JavaScript的加载、解析与执行会严重阻塞DOM的构建。只有等到脚本文件执行完毕,才会去继续构建DOM。

js不单会阻塞DOM构建,还会导致CSSOM也阻塞DOM的构建,如果JavaScript脚本还操作了CSSOM,而正好这个CSSOM还没有下载和构建,浏览器甚至会延迟脚本执行和构建DOM,直至完成其CSSOM的下载和构建,然后再执行JavaScript,最后在继续构建DOM

因此script的位置很重要,在实际使用过程中遵循以下两个原则:

  • CSS 优先:引入顺序上,CSS 资源先于 JavaScript 资源。
  • JS置后:我们通常把JS代码放到页面底部,且JavaScript 应尽量少影响 DOM 的构建

渲染

当我们生成DOM树和CSSOM树后,我们需要将这两颗树合并成渲染树,渲染步骤包括样式、布局、绘制

样式计算

主线程会遍历得到DOM树,依次为树中每个节点计算出它最终的样式,称之为Computed Style

这一过程中,很多预设值会变成绝对值,比如 red会变成rgb(255,0,0)相对单位会变成觉得单位 em 变成px。

布局

浏览器拿到渲染树后,就会从渲染树的根节点开始遍历,然后确定每个节点对象在页面上的确切大小与位置,通常这一行为也被称为“自动重排”。布局阶段的输出是一个盒子模型,它会精确地捕获每个元素在屏幕内的确切位置与大小,所有相对测量值都将转换为屏幕上的绝对像素。这一过程也可称为回流。

 分层

分层是占用内存空间的,主线程会使用一套复杂的策略对整个布局树进行分层,分层的好处在于,将来某一个层改变后,仅会对该层进行后续处理,重而提升效率。

 绘制和光栅化

在绘制或光栅化阶段,浏览器将在布局阶段计算的每个框转换为屏幕上的实际像素。绘画包括将元素的每个可视部分绘制到屏幕上,包括文本、颜色、边框、阴影和替换的元素(如按钮和图像)。浏览器需要非常快地完成这项工作。

性能优化策略

在我们了解浏览器的渲染机制后,DOM 和 CSSOM 结构构建顺序,我们可以针对性能优化问题给出一些方案,提升页面性能。

回流(reflow)与重绘(repaint)

当元素的样式发生变化时,浏览器需要触发更新,重新绘制元素。这个过程中,有两种类型的操作,即重绘与回流。

  • 重绘(repaint): 当元素样式的改变不影响布局时,浏览器将使用重绘对元素进行更新,此时由于只需要UI层面的重新像素绘制,因此损耗较少
  • 回流(reflow): 当元素的尺寸、结构或触发某些属性时,浏览器会重新渲染页面,称为回流。此时,浏览器需要重新经过计算,计算后还需要重新页面布局,因此是较重的操作。会触发回流的操作:
  • 添加或删除可见的DOM元素
  • 元素的位置发生变化
  • 元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)
  • 内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代。
  • 页面一开始渲染的时候(这肯定避免不了)
  • 浏览器的窗口尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的

注意:回流一定会触发重绘,而重绘不一定会回流,重绘的开销较小,回流的代价较高

因此为了减少性能优化,我们可以尽量避免回流或者重绘操作 css

  • 避免使用table布局
  • 将动画效果应用到position属性为absolute或fixed的元素上

javascript

  • 避免频繁操作样式,可汇总后统一 一次修改
  • 尽量使用class进行样式修改
  • 减少dom的增删次数,可使用 字符串 或者 documentFragment 一次性插入
  • 极限优化时,修改样式可将其display: none后修改
  • 避免多次触发上面提到的那些会触发回流的方法,可以的话尽量用 变量存住
async和defer的作用是什么?有什么区别?

defer 和 async 属性的区别:

image

其中蓝色线代表JavaScript加载;红色线代表JavaScript执行;绿色线代表 HTML 解析 1)情况1 <scriptsrc="script.js"> 没有 defer 或 async,浏览器会立即加载并执行指定的脚本,也就是说不等待后续载入的文档元素,读到就加载并执行。

2)情况2 (异步下载) async 属性表示异步执行引入的 JavaScript,与 defer 的区别在于,如果已经加载好,就会开始执行——无论此刻是 HTML 解析阶段还是 DOMContentLoaded 触发之后。需要注意的是,这种方式加载的 JavaScript 依然会阻塞 load 事件。换句话说,async-script 可能在 DOMContentLoaded 触发之前或之后执行,但一定在 load 触发之前执行。

3)情况3 <scriptdefersrc="script.js">(延迟执行) defer 属性表示延迟执行引入的 JavaScript,即这段 JavaScript 加载时 HTML 并未停止解析,这两个过程是并行的。整个 document 解析完毕且 defer-script 也加载完成之后(这两件事情的顺序无关),会执行所有由 defer-script 加载的 JavaScript 代码,然后触发 DOMContentLoaded 事件。

defer 与相比普通 script,有两点区别:

  • 载入 JavaScript 文件时不阻塞 HTML 的解析,执行阶段被放到 HTML 标签解析完成之后;
  • 在加载多个JS脚本的时候,async是无顺序的加载,而defer是有顺序的加载

js优化可以在script标签加上 defer属性 和 async属性用于在不阻塞页面文档解析的前提下,控制脚本的下载和执行

其他: CSS 标签的 rel属性 中的属性值设置为 preload 能够让你在你的HTML页面中可以指明哪些资源是在页面加载完成后即刻需要的,最优的配置加载顺序,提高渲染性能

首屏优化加载
  • 减少首屏CGI的计算量:比如在微信8.8无现金日H5开发中,前端希望拿到用户的个人信息、消费记录、排名三类数据,如果只通过一个CGI来处理,那么后台响应时间肯定会变长;由于在H5的首屏中,只包含了用户信息,消费记录、排名都在第2屏和第3屏,此时其实可以利用异步的方式来拿消费记录、排名的数据。
  • 页面瘦身:压缩HTML、CSS、JavaScript。
  • 减少请求:CSS、JavaScript文件数尽量少,甚至当CSS、JS的代码不多时,可以考虑直接将代码内嵌到页面中。
  • 多用缓存:缓存能大幅度降低页面非首次加载的时间。
  • 少用table布局,浏览器在渲染table时会消耗较多资源,而且只有table里有一点变化,整个table都会重新渲染。
  • 做预加载:部分H5页面首屏可能要下载较多的静态资源,比如图片,这时为了避免加载时出现“难看”的页面,用预加载(loading的方式)做一个过渡
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
浏览器渲染机制可以分为以下几个步骤: 1. 构建 DOM 树:根据 HTML 文本构建 DOM 树,即将 HTML 文本解析成一个个的节点,然后将这些节点按照其在文档中的层级关系组成一棵树。 2. 构建 CSSOM 树:根据 CSS 文本构建 CSSOM 树,即将 CSS 文本解析成一个个的样式规则,然后将这些样式规则按照其在文档中的层级关系组成一棵树。 3. 合并生成渲染树:将 DOM 树和 CSSOM 树组合成渲染树(也称为呈现树或布局树)。渲染树只包含需要显示的节点和这些节点的样式信息。渲染树的构建过程中,浏览器会忽略掉那些不需要显示的节点,例如 head 标签、display:none 的节点等。 4. 计算布局信息:根据渲染树计算每个节点在屏幕上的位置和大小,这个过程被称为布局或排版(layout 或 reflow)。布局是一个相当昂贵的操作,因为浏览器需要遍历渲染树的每个节点,并根据节点的样式、大小、位置等信息计算其在屏幕上的位置和大小。 5. 绘制页面:根据渲染树和布局信息,将页面绘制到屏幕上,这个过程被称为绘制(painting 或 rasterization)。绘制的过程中,浏览器会将渲染树中每个节点的内容转换成位图,然后将这些位图组合成一张完整的页面。 6. 提交更新:将绘制好的页面提交到 GPU,由 GPU 将其显示到屏幕上。 以上是浏览器渲染机制的主要流程,其中布局(layout 或 reflow)是整个渲染过程中最耗时的步骤,因此在开发中需要尽可能减少布局的次数,以提高页面的性能表现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值