浏览器渲染原理-解释回流重绘以及为什么transform效率高

  1. 浏览器是如何渲染页面

    当浏览器的网络线程收到 HTML 文档后,会产生一个渲染任务,并将其传递给渲染主线程的消息队列。在事件循环机制的作用下,渲染主线程取出消息队列中的渲染任务,开启染流程。

    整个渲染流程分为多个阶段,分别是: HTML 解析、样式计算、布局、分层、绘制、分块、光栅化、画每个阶段都有明确的输入输出,上一个阶段的输出会成为下一个阶段的输入。这样,整个渲染流程就形成了一套组织严密的生产流水线。
    第一步完成后,会得到 DOM 树和 CSSOM 树,浏览器的默认样式、内部样式、外部样式、行内样式均会包含在 CSSOM 树中。
    1.渲染的第一步是HTML解析。
    主线程会遍历得到的 DOM 树,依次为树中的每个节点计算出它最终的样式,称之为Computed Style。在这一过程中,很多预设值会变成绝对值,比如red会变成rgb(255,0,0);相对单位会变成绝对单位,比如 em 会变成 pX
    这一步完成后,会得到一棵带有样式的 DOM 树。
    接下来是布局,布局完成后会得到布局树。
    布局阶段会依次遍历 DOM 树的每一个节点,计算每个节点的几何信息。例如节点的宽高、相对包含块的位
    解析过程中遇到 CSS 解析 CSS,遇到JS 执行 JS。为了提高解析效率,浏览器在开始解析前,会启动一个预解析的线程,率先下载 HTML中的外部CSS 文件和 外部的 JS 文件
    如果主线程解析到 link 位置,此时外部的 CSS 文件还没有下载解析好,主线程不会等待,继续解析后续的HTML。这是因为下载和解析 CSS 的工作是在预解析线程中进行的。这就是CSS不会阻塞 HTML 解析的根本原因。
    如果主线程解析到 script 位置,会停止解析 HTML,转而等待 JS 文件下载好,并将全局代码解析执行完成后,才能继续解析 HTML。这是因为JS代码的执行过程可能会修改当前的DOM 树,所以 DOM 树的生成必须暂停。这就是 JS 会阻塞 HTML 解析的根本原因。

    第一步完成后,会得到 DOM 树和 CSSOM 树,浏览器的默认样式、内部样式、外部样式、行内样式均会包含在 CSSOM 树中。
    2.渲染的下一步是样式计算。
    主线程会遍历得到的 DOM 树,依次为树中的每个节点计算出它最终的样式,称之为Computed Style。在这一过程中,很多预设值会变成绝对值,比如red会变成rgb(255,0,0);相对单位会变成绝对单位,比如 em 会变成 pX
    这一步完成后,会得到一棵带有样式的 DOM 树。
    3.接下来是布局,布局完成后会得到布局树。
    布局阶段会依次遍历 DOM 树的每一个节点,计算每个节点的几何信息。例如节点的宽高、相对包含块的位置。大部分时候,DOM 树和布局树并非一一对应。
    比如 display:none 的节点没有几何信息,因此不会生成到布局树;又比如使用了伪元素选择器,虽然DOM树中不存在这些伪元素节点,但它们拥有几何信息,所以会生成到布局树中。还有匿名行盒、匿名块盒等等都会导致 DOM 树和布局树无法一一对应。
    4.下一步是分层
    主线程会使用一套复杂的策略对整个布局树中进行分层,分层的好处在于,将来某一个层改变后,仅会对该层进行后续处理,从而提升效率滚动条、堆叠上下文、transform、opacity 等样式都会或多或少的影响分层结果,也可以通过 will-change 属性更大程度的影响分层结果。

    5.再下一步是绘制
    主线程会为每个层单独产生绘制指令集,用于描述这一层的内容该如何画出来。完成绘制后,主线程将每个图层的绘制信息提交给合成线程,剩余工作将由合成线程完成,合成线程首先对每个图层进行分块,将其划分为更多的小区域。它会从线程池中拿取多个线程来完成分块工作。
    6.分块完成后,进入光栅化阶段
    合成线程会将块信息交给 GPU 进程,以极高的速度完成光栅化,GPU 进程会开启多个线程来完成光栅化,并且优先处理靠近视口区域的块。光栅化的结果,就是一块一块的位图。

    7.最后一个阶段是画
    合成线程拿到每个层、每个块的位图后,生成一个个「指引(quad)」信息。指引会标识出每个位图应该画到屏幕的哪个位置,以及会考虑到旋转、缩放等变形。变形发生在合成线程,与渲染主线程无关,这就是 transform 效率高的本质原因。合成线程会把quad 提交给 GPU 进程,由 GPU 进程产生系统调用,提交给 GPU 硬件,完成最终的屏幕成像。

    8.总结

    解析HTML生成dom树和cssom树,计算样式让每个dom得到最终的样式,布局计算出每个dom节点的几何信息,布局树和dom树不一样不能对应。分层提高后续的渲染效率,将页面通过算法分成几个图层,每个层可以单独的绘制,产生绘制指令,先画啥再画啥,把指令交个给合成线程的分块,分块完成后对每一个层的每一个小块分别进行光栅化,变成一个个像素点即位图,优先光栅化靠近屏幕的小块,最后把小块发送给gpu画出来

  2. 什么是回流

    reflow 的本质就是重新计算 layout 树(修改了几何信息)。需要重新计算布局树,会引发 layout。当进行了会影响布局树的操作后,为了避免连续的多次操作导致布局树反复计算,浏览器会合并这些操作,当 JS 代码全部完成后再进行统一计算。所以,改动属性造成的 reflow 是异步完成的。也同样因为如此,当 JS 获取布局属性时,就可能造成无法获取到最新的布局信息,浏览器在反复权衡下,最终决定获取属性立即 reflow

  3. 什么是重绘

    repaint 的本质就是重新根据分层信息计算了绘制指令(未修改几何信息),当改动了可见样式后,就需要重新计算,会引发repaint。由于元素的布局信息也属于可见样式,所以reflow 一定会引起 repaint。

  4. 为什么transform的效率高

    因为 transform 既不会影响布局也不会影响绘制指令,它影响的只是染流程的最后一个「draw」阶段由于 draw 阶段在合成线程中,所以 transform 的变化几乎不会影响渲染主线程。反之,渲染主线程无论如何忙碌,也不会影响 transform 的变化

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/545776.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HW面试经验分享 | 某服蓝队初级

前言 依稀记得是22年 7、8月份参加的HW,当时是比较炎热的时候,但又夹杂一丝秋意。也是头一次去离家乡比较远的地方,多少有点忐忑……(怕被噶腰子、水土不服、吃穿用住没着落等等),但最终也是平安无事且顺利…

笔记84:关于递归法的一些感悟

题目1:二叉树的前序遍历 链接:. - 力扣(LeetCode) /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(…

独立服务器如何安装Webmin面板

本周有一个客户,购买Hostease的独立服务器,询问我们的在线客服,独立服务器支持安装Webmin及如何安装的问题。我们为用户提供教程,用户很快完成了设置。在此,我们分享这个操作教程,希望可以对您有帮助。 Web…

SkyWalking 为所有的API接口增加 tag

背景胡扯 线上接口报错,接着被 SkyWalking 抓到,然后 SkyWalking 触发告警,最后老板你,让你辛苦一下,在明早上班前把这个bug 改了,并告诉你你是全公司的希望。谁说不是呢?为公司业务保驾护航&a…

成都欣丰洪泰文化传媒有限公司领航电商新纪元

在当今数字化飞速发展的时代,电商行业异军突起,成为推动经济增长的重要力量。在这股浪潮中,成都欣丰洪泰文化传媒有限公司以其专业的电商服务脱颖而出,成为业界的佼佼者。本文将带您一探这家公司的独特魅力和专业服务,…

D365开发-在视图按钮的js里,引用别的js里的公共方法

公共方法写法: "use strict"; var JJMC window.JJMC || {}; JJMC.SamMCommon JJMC.SamMCommon || {}; (function () { this.cloneRecord function (excludeAttrbuteNames){ / } }).call(JJMC.SamMCommon); 然后在需要调方法的command里面,之…

手机适配,在真机上适配正常,在pc端适配出现横向滚动条

问题背景 最近,在做一个项目适配的时候,出现一个很奇怪的问题,在真机上,适配一切正常,但是在pc端,适配,偶现横向滚动条。 而且发现一个离奇的事情,就是适配出现横向滚动条&#xff…

UE5 GAS开发P32,33 初始化状态并绑定在HUD上,拾取物品增加血量和减少蓝量

这节课主要是修改WidgetController和OverlayController,在EffectActor内新增了一个减少蓝量的代码,同时修复了一个bug,并且展示了为什么要写成单独的控制器,因为要考虑多人游戏的情况,每一个控制器都是一个单独的角色 首先修改AuraAttirbuteSet.cpp UAuraAttributeSet::UAura…

泰山众筹:低门槛高回报的电商营销新模式

大家好,我是吴军,来自一家专注于软件开发的公司,担任产品经理一职。今天,我想与大家分享一种备受瞩目的商业模式——泰山众筹。 泰山众筹之所以能够在市场上迅速走红,其背后的原因值得我们深入探讨: 首先&…

ATFX港股:长周期看,恒生指数报价已经回到2008年以来的底部区域

消息面: 1、 4月12日,官方发布《推动资本市场高质量发展的若干意见》文件,其中提到九条意见,被称为“国九条”,重要内容有:将上市前突击“清仓式”分红等情形纳入发行上市负面清单;推动一年多次…

Vue3学习05 一些API

Vue3-API 其它 API【shallowRef 与 shallowReactive 】shallowRefshallowReactive总结 【readonly 与 shallowReadonly】readonlyshallowReadonly 【toRaw 与 markRaw】toRawmarkRaw 【customRef】 Vue3新组件【Teleport】【Suspense】【全局API转移到应用对象】【其他】 其它 …

罗芬COHERENT pmb激光电源维修HPC830

Rofin激光电源 PMB高压电源维修:HPC625,HPC520,HPC210,HPC840,HPC830,HPC810,HPC818,HPC818 HPC814 HPC910等型号。 大型设备往往都配有功能较为故障诊断程序,我们可以充分利用软件的提示,缩小故障排查范围,但有时诊断软件提示的受损元件是否…

导入数据库文件到宝塔提示导入成功但是没有任何表信息

本地数据库上传到宝塔,提示导入成功但是没有数据库的任何数据表信息,这个很可能是与你本地mysql服务器和你宝塔上的mysql版本不一致导致的,我的本地的数据库是8.0的,但是宝塔上面是5.7的,所以肯定就导入不进去。 解决…

c语言-预处理详解【求个关注!】

预处理详解 一 预处理阶段1 知识背景:2 预定义符号3 #define 定义常量当定义的标识符的值过长时:注意,如果#define定义的标识符,其值的末尾有; 则说明; 是该标识符值的一部分 4 #define 定义宏宏的声明方式:当传入的参…

【系统分析师】数据库部分

文章目录 1、数据库模式2、数据库设计过程2.1ER模型 3、关系代数 ☆5、规范化理论☆5.1 非规范存在的问题5.2 相关概念5.3范式5.3.1 第一范式-1NF5.3.2 第二范式-2NF5.2.3 第三范式5.2.4 BC范式 5.4 函数依赖分解5.4.1保持函数依赖分解5.4.2 无损分解 5.5 Armstong公理系统 6、…

FANUC机器人单轴零点标定的具体方法(全轴零点标定不方便时可采用)

FANUC机器人单轴零点标定的具体方法(全轴零点标定不方便时可采用) 前面和大家分享了FANUC机器人进行零点标定的原因和方法,具体可参考以下链接中的内容:: FANUC机器人进行零点标定的目的和具体方法步骤详解

从零开始学习Linux(1)---基本命令(1)

1.学习准备 我学习Linux是使用xshell远程登录自己的云服务器来进行。 xshell是一个远程终端管理软件,下载官网: https://www.netsarang.com/products/xsh_overview.htm 下载安装的时候选择 "home/school"…

如何在OceanBase v4.2 中快速生成随机数据

在使用传统数据库如 MySQL 和 Oracle 时,由于缺乏多样化的随机数据生成方案,或者实现成本过高,构造随机数据的开发成本受到了影响。OceanBase在老版本中虽然有相应的解决方案,但语法复杂和性能较差等问题仍然存在。 现在&#xf…

主播美颜SDK:实现精细化美颜功能的关键技术分析

主播美颜SDK作为实现精细化美颜功能的关键技术,其背后蕴含着丰富的算法和工程技术。本文将对主播美颜SDK的关键技术进行深入分析,探讨其实现精细化美颜功能的原理与方法。 图像识别与面部分析 通过图像识别技术,SDK能够准确地识别出人脸位置…

策略模式类图与代码

某大型购物中心欲开发一套收银软件,要求其能够支持购物中心在不同时期推出的各种促销活动,如打折、返利(例如,满300返100),等等。现采用策略(Strategy)模式实现该要求,得到如图7.13 所示的类图。 【Java 代码】 import java.util…