searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

浏览器渲染

2023-07-07 09:24:23
12
0

网络线程收到HTML文档,会产生一个渲染任务,传递给渲染主线程,渲染主线程会从事件循环的消息队列中拿到这个任务

 

渲染流程:

    1. 解析html
    • 构建文档对象模型(DOM):浏览器将接收到的 HTML 文件解析成 DOM 树的结构,表示网页的结构和内容。

    image.png

    • 构建CSS对象模型(CSSOM):浏览器解析 CSS 文件,生成 CSSOM,表示网页的样式规则。

    image.pngdocument.styleSheets 是代表整个文档中所有样式表的集合,CSSOM 则是表示样式规则的对象模型,可以从 document.styleSheets 中获取 CSSOM 对象进行操作。

    解析html过程中,遇到css会解析css,遇到js执行js。解析开始前会有线程率先下载外部的css和js文件

    主线程解析到link位置时候,如果css文件没有下载解析好,主线程不会等待,会继续解析后面的html。因为下载和解析css工作在其他线程进行,所以css不会阻塞html解析

    主线程解析到script位置,会停止解析html,等待js文件下载好并且解析执行完成。因为js代码可能会改变当前的dom。需要注意,如果 <script> 标签设置了 async 属性,脚本将在下载完成后立即执行,与 HTML 解析过程异步进行;如果<script> 标签设置了 defer 属性,脚本将在 HTML 解析完成后执行,但在 DOMContentLoaded 事件被触发前执行。

    1. 合并DOM和CSSOM,生成渲染树(Render Tree):将 DOM 树和 CSSOM 结合起来,生成渲染树。渲染树只包含需要显示的元素,例如可见的标签和文本,而不包含隐藏的元素或不显示的元素。
    1. 布局(Layout):渲染树中的每个元素都会被计算其在页面中的位置和大小,这个过程被称为布局或重排。浏览器计算并确定每个元素在屏幕上的准确位置。
    1. 绘制(Paint):根据布局阶段的计算结果,浏览器使用绘图工具将渲染树中的每个元素转换成屏幕上的像素。
    1. 合成与显示:浏览器将绘制好的像素提交给显卡进行合成,并在用户的屏幕上显示。

分层

布局计算之后会有一个分层的过程,这称为图层分割(Layer Segmentation)或合成帧(Compositing)。

图层分割是为了优化页面的渲染性能和效果而进行的一个步骤。在布局计算完成后,浏览器会将渲染树中的元素分成不同的图层,每个图层都是一个独立的绘制表面。图层内的元素在页面上可以独立地进行绘制、布局和合成,并且可以通过硬件加速来加快渲染速度。

图层通常会根据以下因素进行分割:

  1. 元素的层叠上下文(Stacking Context):具有不同的层叠上下文的元素会被放置在不同的图层中。层叠上下文是指通过 CSS 属性(例如 position: absolutez-index 等)创建的元素层级关系。
  2. CSS 3D 变换和透视:应用了 3D 变换和透视(transform 和 perspective)的元素会被放置在单独的图层中。
  3. 视频和 Canvas 元素:包含视频或 Canvas 的元素可以被放置在单独的图层中,以便更好地处理它们的绘制。

通过分割图层,浏览器可以更加高效地处理页面中的变化和动画效果,只需对影响的图层进行重新绘制和合成,而不必重绘整个页面。这可以提高渲染性能和动画的流畅度。

 

分块

还有一个重要的步骤是分块(Chunking),也称为渲染过程中的异步绘制或增量渲染。

分块是为了提高页面的渲染性能而进行的优化策略。在浏览器渲染流程的绘制阶段,分块会将绘制任务划分为多个小块(chunks),然后在适当的时机进行异步绘制。这样可以让浏览器更早地将部分内容显示给用户,提高页面的响应速度和流畅度。

分块通常发生在布局计算和绘制之间的阶段。当浏览器在布局计算阶段完成了一个块的计算后,它会将该块发送给渲染引擎,然后继续计算下一个块。渲染引擎可以将这些块按照优先级排序,并在适当的时间执行绘制。

分块的好处包括:

  1. 提高渲染性能:通过将绘制任务拆分为小块并异步处理,可以减少单个绘制操作的时间,提高整体渲染速度。
  2. 增强用户体验:分块渲染可以更早地将部分内容显示给用户,让用户感知到页面的加载速度更快。
  3. 平滑动画效果:在动画的情况下,分块绘制可以使动画更加平滑,减少动画卡顿的情况。

需要注意的是,浏览器的分块策略可以因浏览器的不同而有所差异,并且可能会受到设备性能和页面复杂度的影响。不同的浏览器可能有不同的优化策略和算法来进行分块。

 

连续dom操作时候的reflow

1. 概要

在 JavaScript 中进行 DOM 操作(例如修改元素的样式或属性、插入或移除元素等)会触发重排。然而,浏览器通常会对连续的 DOM 操作进行优化,以尽量减少重排的次数。它会将多个 DOM 操作合并成一个批量操作,然后在适当的时机进行一次重排。这种机制被称为"批处理"。

但是,会造成一个问题,js获取布局属性时候,可能无法获取到最新的布局信息。所以,某些属性或方法的读取操作可能会导致重排,因为浏览器需要在读取之前更新元素的布局信息。而修改属性或进行写操作后,并不会立即触发重排,而是等待队列中的批处理操作一起发生。

2. 导致重排的操作

当访问以下属性或方法时,会触发重排操作:

  1. 获取布局或几何属性:包括 offsetTopoffsetLeftoffsetWidthoffsetHeightscrollTopscrollLeftscrollWidthscrollHeightclientTopclientLeftclientWidthclientHeight 等属性。
  2. 获取样式信息:例如使用 getComputedStyle(element) 或 element.style.* 访问元素的计算后的样式属性。
  3. 获取尺寸和位置等属性:例如使用 element.getBoundingClientRect() 获取元素相对于视口的位置和尺寸信息。

这些属性或方法需要浏览器实时计算元素的布局或样式信息,因此会导致重排操作。在需要多次读取这些属性时,建议将其保存在变量中,以避免重复触发重排。

然而,以下操作通常不会触发重排:

  1. 修改元素的样式或属性:例如设置元素的 classNamestyle.*setAttribute() 等,只有在修改实际属性后,浏览器才会在需要的时候触发重排。
  2. 插入或移除元素:添加或删除 DOM 元素不会立即触发重排,而是在需要绘制的时候进行批处理操作。

总的来说,读取布局或几何属性、获取样式信息以及获取元素的尺寸和位置等操作通常会导致重排,而修改元素的样式或属性、插入或移除元素则不一定会立即触发重排,而是延迟到浏览器执行渲染的时候进行处理。

重排和重绘区别

重排(reflow)和重绘(repaint)是两个关键概念,它们在处理和优化网页性能时非常重要。

重排指的是当DOM结构发生变化或样式属性改变时,浏览器需要重新计算网页元素的几何属性(尺寸、位置等),以确定它们在页面中的布局。重排通常是由于以下操作引起的:

  1. 添加、删除、修改DOM元素。
  2. 修改元素的位置、尺寸、边距等样式属性。
  3. 用户交互事件或响应式布局导致布局变化。

重绘指的是当元素的样式属性改变时,浏览器需要重新绘制这个元素的外观(颜色、背景、边框等),但不影响其几何属性。重绘通常是由于以下操作引起的:

  1. 修改元素的颜色、背景、边框等样式属性。
  2. 添加、删除、修改元素的类名。

重排和重绘的区别在于影响范围和开销。重排需要重新计算整个文档的布局,可能涉及其他元素的重新排列,因此开销较大。而重绘只需要重新绘制受影响的元素,开销相对较小。

为了提高网页性能,开发者应该尽量减少重排和重绘的次数。可以采取以下措施:

  1. 使用CSS3的transform和opacity等属性,它们通常不会引起重排或重绘。
  2. 批量修改样式属性,避免多次单独修改。
  3. 使用文档片段(Document Fragment)来批量添加或更新DOM元素。
  4. 避免频繁访问布局属性(例如offsetTop、offsetLeft等),可以将它们缓存起来。
  5. 使用CSS中的will-change属性来提前告知浏览器某个元素将发生变化,以优化重排的性能。

通过理解重排和重绘的区别,并采取相应的优化方法,可以提升网页性能,提供更好的用户体验。

0条评论
0 / 1000