前面的话
浏览器应用程序是专门用于访问和浏览万维网页面的客户端软件。它也是现代计算机系统中应用最广泛的软件之一,其重要性不言而喻。前端工程师作为负责显示程序页面的工程师,需要直接与浏览器打交道。本文将详细介绍浏览器的工作原理
形成
浏览器的组成如下图所示
主要组件包括:
1.用户界面-包括地址栏、后退/前进按钮、书签目录等。,即用于显示所请求页面的主窗口之外的其他部分。
2.浏览器引擎-用于查询和操作渲染引擎的界面
3.渲染引擎-用于显示请求的内容。例如,如果请求的内容是html,它负责解析html和css,并显示解析结果。
4.网络-用于完成网络调用,如http请求。它有独立于平台的接口,可以在不同的平台上工作。
5.UI后端——用于绘制组合选择框、对话框等基本组件,具有非特定平台的通用界面,底层使用操作系统的用户界面。
6.JS解释器——用于解释和执行JS代码。
7.数据存储——属于持久层,浏览器需要把cookie之类的各种数据保存在硬盘上。HTML5定义了web数据库技术,这是一种轻量级的、完整的客户端存储技术
核心部分
浏览器内核分为两部分:渲染引擎和js引擎。由于js引擎越来越独立,内核倾向于只引用渲染引擎,渲染引擎负责请求网络页面资源进行解析、排版并呈现给用户
默认情况下,渲染引擎可以显示html、xml文档和图片,也可以在插件的帮助下显示其他类型的数据,例如使用可以显示PDF格式的PDF阅读器插件
[渲染引擎]
火狐使用壁虎引擎
IE用的是三叉戟发动机。2015年,微软推出了自己的新浏览器,最初名为斯巴达,后来更名为边缘,使用边缘引擎
Opera最早使用的是Presto引擎,后来放弃了
Chromesafariopera使用webkit引擎,chrome和opera年开始使用Blink引擎
UC使用U3引擎
QQ浏览器和微信内核都用X5引擎,Blink引擎用了16年
[js引擎]
旧版IE使用J引擎,IE9使用Chakra引擎后,边缘浏览器仍然使用Chakra引擎
Firefox使用monkey系列引擎
狩猎使用的松鼠鱼系列引擎
Opera使用卡拉坎发动机
Chrome采用V8发动机。NodeJs实际上封装了V8引擎
渲染过程
从资源下载到最终页面展示,渲染过程可以简单理解为线性系列转换过程的组合。原始输入是网址,最终输出是页面位图,依次经过加载器、解析器、布局和绘制模块
渲染引擎的核心流程如下
【装载机】
Loader模块负责处理所有HTTP请求和缓存网络资源,相当于从URL输入到Page Resource输出的转换过程。HTML页面通常有外部JS/CSS/Image资源。为了不阻塞后续的解析过程,一般同时有两个IO管道,一个用于下载主页,另一个用于下载各种外部资源
注意:虽然在大多数情况下可以异步下载和解析不同的资源(例如,图片资源可以在主页面解析和显示后显示),但是JS脚本可能需要更改页面,所以有时不可避免地会保持执行顺序,阻塞下载管道的后续处理。
【解析器】
1.解析超文本标记语言
解析器模块主要负责解析HTML页面,完成从HTML文本到HTML语法树再到文档对象模型树(DOM Tree)的映射过程
HTML语法树生成是一个典型的解析过程,可以分为两个子过程:词法解析和语法解析
词法解析根据词法规则(如正则表达式)将HTML文本划分为大量的标记,去除空等无关字符。语法解析根据语法规则(如上下文无关语法)匹配Token序列生成语法树,通常有自顶向下和自底向上两种匹配方式
浏览器内核中HTML页面真正的内部表示不是语法树,而是W3C标准化的文档对象模型(DOM)。DOM也是以Document对象为根的树形结构。DOM节点基本上与HTML语法树节点一一对应,所以最终的DOM树通常是在解析的过程中直接生成的。
2.解析CSS
页面中所有的CSS都是由样式表CSS style集合组成的,是一系列的CSSRules。每个CSS规则由选择器CSSStyleSelector和声明CSSStyleDeclaration组成,后者是CSS属性和值的键值集合
CSS解析后会进行CSSRule的匹配过程,即找到满足每个CSS规则的Selector部分的HTML元素,然后将其声明部分应用到元素上。实际的规则匹配过程会考虑默认和继承的CSS属性,匹配的效率和规则的优先级
3.解析Java
Java一般由单独的脚本引擎解析执行,其功能通常是动态改变DOM树(比如为DOM节点添加事件响应处理程序),即根据定时器或事件将一个DOM树映射到另一个DOM树。
简而言之,在被解析器模块处理后,内核将页面文本转换成带有CSS样式的样式化的DOM树,并响应定制事件
【布局】
排版过程是排版,它包括两个主要过程
1.创建渲染树
布局树(或render tree,Render Tree)和DOM树可以大致一一对应,同时存在于内核中但功能不同。DOM树是HTML文档的对象表示,也是Java操纵HTML的对象接口。渲染树是DOM树的排版表示,用于计算可视化DOM节点的布局信息(如宽度、高度、坐标)以及后续阶段的绘制和显示
注意:不是所有的DOM节点都是可见的,也就是说,不是所有的DOM树节点都会相应地生成一个Render树节点。例如,head标记(HTMLHeadElement节点)不代表任何布局区域,因此没有对应的Render节点。同时,DOM树视觉节点的CSS样式是其对应的渲染树节点的样式
2.计算布局
布局是排列和计算页面上每个元素的大小和位置等几何信息的过程。HTML采用流式布局模型,基本原理是页面元素从左到右、从上到下排列,在顺序遍历的过程中确定各自的位置区域
一个HTML元素对应一个CSS盒子模型描述的盒子区域。HTML元素分为两种基本类型,内嵌和块。内联元素不换行,而是从左到右排列。块元素的外观意味着您需要从上到下更改到下一行进行布局。除了根据元素的行内和块的流布局的基本顺序之外,还有一些特别指定的布局方法,例如绝对/固定/相对定位布局和浮动布局
在简单的情况下,布局可以通过依次遍历渲染树一次来完成,但是也有需要迭代的情况。当祖先元素的大小和位置依赖于后代元素或相互依赖时,布局不能通过一次遍历来完成,例如没有明确指定表格元素的宽度和高度,并且其子元素Tr的高度被指定为父表格高度的30%的情况
在布局阶段之后,带有样式的DOM树被转换成包含布局信息和绘图信息的渲染树,并且下一个显示工作被移交给绘制模块
【油漆】
绘制模块负责将渲染树映射到可见图形。它将遍历渲染树,并调用每个渲染节点的绘制方法,以在画布或位图上显示其内容,最后在浏览器应用程序窗口中显示为用户看到的实际页面。每个节点的大小和位置等信息已经由布局阶段计算出来,节点的内容取决于相应的HTML元素、文本、图片或UI控件
通常,布局和绘图是耗时的操作。如果DOM树每次稍有改动都需要重新铺设和绘制,效率会相当低。所以一般的浏览内核会实现一种增量布局和增量绘制的方式。当一个DOM树节点(或其子节点)的内容或样式发生变化时,内核会决定其影响范围。在布局阶段,它将标记受节点布局影响的其他节点(如子节点),在绘制阶段,它将标记一个脏区域,并通知系统重新绘制
根据HTML相关规范,页面元素的CSS属性也规定了它们的绘制顺序。例如,根据不同的图层,必须按顺序绘制,否则叠加效果会有误差。例如,还指定了元素的边框轮廓和内容背景的绘制顺序
资源加载
当使用浏览器上网时,您将首先在地址栏中输入一个网址。浏览器会根据网址向服务器发送一个资源请求,服务器会解析该请求,并将相关的数据资源发送回浏览器。这些数据资源包括描述文档、图片、Java脚本、CSS等。第页。之后浏览器引擎会对数据进行解码、解析、排版、绘制,最后呈现出完整的页面。Loader是浏览器的先锋,负责加载资源
Loader是浏览器中连接前一个和后一个的链接。一方面作为网络模块的客户,通过网络模块加载资源;另一方面,它为Parser模块加载页面内容,并控制浏览器的后续解析和绘制过程
加载器有两个资源加载路径:主资源加载路径和派生资源加载路径。这两种资源的加载过程是截然不同的。比如在处理加载资源失败时,下载主资源失败会给出错误提示,而下载派生资源如图片失败往往只显示一个占位符
在地址栏中输入一个新地址,或者在打开的页面上点击一个链接,都会触发主资源的加载过程。当主资源在HTTP协议的传输下分段到达时,浏览器的Parser模块解析主资源的内容,生成派生资源对应的DOM结构,然后根据需要触发派生资源的加载过程。主资源的加载立即开始,而派生资源可以在队列中等待,以便优化网络
主资源和派生资源的加载还有一个区别。Android版本中,主资源没有缓存,而派生资源有缓存机制。这里的缓存是指Memory Cache,用来保存原始数据(比如CSS、JS等)。)和解码数据。内存缓存可以节省网络请求和图片解码的时间
浏览器在加载主资源后,主资源会被解码,然后进行解析,生成DOM(文档对象模型)树。在解析过程中,如果遇到<img的起始标签,会创建相应的image元素HTMLImageElement,接着依据img标签的内容设置HTMLImageElement的属性。在设置src属性时,会触发图片资源加载,发起加载资源请求浏览器加载主资源后,主资源将被解码,然后被解析以生成DOM(文档对象模型)树。在解析过程中,如果
高速缓存
缓存在浏览器中的应用也很广泛,对改善用户体验起到了重要作用。浏览器中的缓存主要有三种:页面缓存、内存缓存和磁盘缓存。这三种缓存的容量可以配置,如将最大内存缓存限制为30MB,页面缓存缓存的页数不超过5页等。
页面缓存:将浏览页面的状态临时保存在缓存中,以加快页面返回。内存缓存:浏览器的内部缓存机制。具有相同url的资源直接从缓存中获取,无需再次下载磁盘缓存。资源加载缓存并与服务器交互,服务器可以通过HTTP头信息设置是否缓存页面。
[内存缓存]
内存缓存,顾名思义,主要用于缓存使用各种派生资源的页面。用浏览器浏览网页时,尤其是浏览大型网站的不同页面时,经常会遇到网页包含相同资源的情况。应用内存缓存可以显著改善浏览器的用户体验,减少不必要的内存、时间和网络带宽开销
[页面缓存]
页面缓存,即页面缓存。用于缓存用户访问的网页的DOM树、渲染树等数据。设计页面缓存的目的是为了提供页面前向和后向的流畅浏览体验。几乎所有现代浏览器都支持页面缓存
如果浏览器没有页面缓存,当用户点击链接访问新页面时,各种派生资源、Java对象、DOM树节点等占用的内存。所有的原始页面都被回收了。之后,当用户点击后退按钮浏览原始页面时,浏览器必须先从网络上重新下载相关资源,然后进行解码、解析、布局、渲染等一系列操作,最后才能将页面呈现给用户,这无疑增加了用户的等待时间,影响了用户体验。
加载时,所有派生资源都将与内存缓存相关联。如果内存缓存中有资源备份,并且条件合适,可以直接从内存缓存中加载。只有当用户单击向前或向后按钮时,才会查询页面缓存。如果页面满足缓存条件并被缓存,则直接从页面缓存加载。即使需要加载的页面在Page Cache中有备份,如果触发加载的原因是用户在地址栏中输入了url或点击了链接,那么页面仍然是通过网络加载的。也就是说,页面缓存不是主资源的通用缓存
[磁盘缓存]
磁盘缓存,即磁盘缓存。现代浏览器基本上都有磁盘缓存机制。为了改善用户体验,浏览器将下载的资源保存到本地磁盘。当浏览器下次请求相同的资源时,可以节省从网络下载资源的时间,直接从本地磁盘取出资源。
磁盘缓存,我们通常称之为Web缓存,分为强缓存和协商缓存。它们之间的区别在于,强缓存不向服务器发送请求,而协商缓存向服务器发送请求
网页解析
整个浏览器可以看作一个网页处理模块,这个模块的输入是网络上接收到的字节流形式的网页内容。输出是一个三树逻辑结构:DOM树,渲染树和渲染层树
浏览器的解析过程是将网页内容以字节流的形式构建成DOM树、渲染树和渲染层树的过程
浏览器的分析对象是网页内容,包括以下三个部分:
1.超文本标记语言,制作网页的标准语言
2.CSS样式表:层叠样式表,用于控制网页的样式,允许样式信息与网页内容分离。
3.Java脚本:Java是一种无类型的解释性脚本语言。通常用于向网页添加动态功能
HTML文档决定了DOM树和Render树的结构。CSS样式表决定了渲染树上节点的布局。Java代码可以操作DOM树,改变DOM树的结构,也可以用来给页面添加更多的动态函数
对HTML文档进行解析,生成DOM树。当DOM节点创建渲染树节点时,会触发CSS匹配过程。CSS匹配的结果是RenderStyle实例,由Render节点持有,保存Render节点的布局信息。CSS的解析过程是CSS语法在浏览器中的内部表示过程,解析的结果是一系列CSS规则。CSS的匹配过程主要取决于CSS选择器的优先级不同,高优先级的选择器优先。根据网页上定义的Java脚本的属性不同,下载和执行Java脚本的机会也不同。Java脚本的执行从渲染引擎切换到JS引擎执行。让我们分别看一下HTML、CSS和Java的具体解析和执行
[DOM树构造]
文档对象模型是一个平台和语言无关的接口。它允许程序和脚本动态访问和更新文档的内容结构和样式。DOM是页面上数据和结构的树形表示,DOM树形结构可以使用DOM接口进行操作。DOM规范只定义了编程接口,对文档的呈现没有任何限制。用树形结构表示DOM文档是一种常见的方式。这种树形结构称为DOM树。DOM树是DOM文档中节点的分层组织。以HTML文档为例,每个标签对应着DOM树上的一个节点。因为是用树形结构表示的,所以这些节点之间的关系也是由父子或者兄弟来维护的
渲染引擎解析HTML文档的过程就是将字节流中的网页内容解析成三棵树的过程:DOM树、渲染树、渲染层树。这个过程可以分为四个步骤:解码、分词、解析和树构建
1.解码:将网络上接收的编码字节流解码成Unicode字符
2.分词:根据一定的分词规则将Unicode字符流切割成标记
3.分析:根据单词的语义,创建相应的节点
4.建立一个树:将节点关联在一起,创建DOM树,渲染树和渲染层树
[渲染树构造]
渲染树用于表示文档的视觉信息,记录文档中每个视觉元素的布局和渲染方式。渲染树和DOM树是同时创建的
HTML页面通过CSS控制页面布局,所以RenderObject需要知道自己的CSS属性,CSSStyleSelector负责为元素提供RenderStyle。渲染对象包含对其自身渲染样式的引用。CSS样式选择器是在CSS解析过程中生成的。创建渲染节点后,它将被附加到渲染树
当前渲染节点的父节点负责将当前渲染节点插入到适当的位置。当父渲染节点设置当前渲染节点的前后兄弟节点时,当前渲染节点将附加到渲染树
渲染对象是渲染树中所有节点的基类,其行为类似于DOM树的节点类。此类存储绘制页面的视觉元素所需的样式和布局信息。RenderObject及其子类都知道如何绘制自己。其实绘制Render树的过程就是按照一定顺序绘制RenderObject本身的过程。DOM树上的节点和Render树上的节点没有一一对应关系。只有DOM树的根节点和可视节点才会创建相应的RenderObject节点
[渲染层树构造]
渲染层树以层为节点组织文档的视觉信息,网页上的每个层对应一个渲染层对象。渲染层树可以看作是渲染树的稀疏表示。渲染层树的每个节点对应渲染树的一个子树,该子树中的所有渲染节点都显示在网页的同一层
渲染层树是基于渲染对象树构建的,只有当渲染对象满足一定条件时,才会建立相应的渲染层节点。以下是创建渲染层节点的条件:
1.网页的根节点
2.有一个显式的CSS位置属性(相对、绝对、固定)
3.为元素设置了转换
4.元素是透明的,即不透明度不等于1
5.该节点有溢出、alpha蒙版或反射效果。
6.元素具有CSS过滤器属性
7、2D帆布或WebGL
8.视频元素
当满足这些条件之一时,将创建一个渲染层实例。渲染对象节点和渲染层节点具有多对一的关系,即一个或多个渲染对象节点对应一个渲染层节点。可以理解,网页的一层可以包含一个或多个可视节点。渲染层树的根节点是渲染视图实例
RenderLayers的一个重要用途是在绘制时加速合成,即每个renderlayer对应一个系统的后端存储,这样当网页内容更新时,只有改变后的renderlayers才能更新,从而提高渲染效率
[CSS解析]
CSS解析是将原始CSS文件中包含的一系列CSS规则表示为渲染引擎中相应规则类的实例的过程
解析选择器的过程和解析属性值的过程都可以被执行多次。呈现引擎为解析的选择器创建一个CSSSelector实例。因为可能有多个选择器,所以呈现引擎使用CSSSelectorList类来保存所有选择器,并为每个解析的属性值对创建一个CSSProperty实例
解析完CSS文件后,CSS规则被保存在CSSRuleList实例中,这些规则将在创建Render节点的过程中使用。节点节点通过调用CSSStyleSelector实例的StyleForElement()函数为渲染节点创建一个渲染样式实例。创建渲染对象实例需要渲染样式实例。RenderStyle描述RenderObject的布局信息,即匹配后的样式信息
CSS规则的匹配过程发生在CSSStyleSelector创建RenderStyle实例的过程中。CSSStyleSelector负责从CSSRuleList中查找与相应元素的样式属性相匹配的所有属性值对
CSS规则匹配是根据选择器类型的优先级进行的,不同类型的选择器优先级不同。常见选择器类型的优先级如下:
标识选择器>:类型选择器>:标签选择器>:相邻选择器>:子选择器>:后代选择器
所有与上的元素匹配的CSSStyleRule将被放入结果数组中。渲染引擎将根据选择器的优先级对结果数组中存储的所有规则进行排序,首先使用高优先级的规则,最后使用的规则将用于创建RenderStyle实例。RenderStyle实例由RenderObject对象持有,它根据RenderStyle中包含的信息进行自己的排版和绘制
[JS执行]
Java是一种解释性的动态脚本语言,需要由专门的Java引擎来执行。Android WebKit版使用V8作为Java执行引擎,是Google支持的开源项目。它的设计目的是追求更高的性能,最大化Java的执行效率。与JavaCore等传统引擎不同,V8将Java代码直接编译成机器码运行,与传统的“中间代码+解释器”引擎相比,具有明显的性能优势。JS代码通常存储在单独的JS文件中,通过标签引用HTML文档
在创建DOM树的过程中遇到标签时,就会创建HTMLElement实例。元素,HTML-Element的父类,包含JS脚本的所有处理,包括下载、缓存、执行等等。根据标签的属性不同,JS脚本加载后的执行机会也不同。如果在标记中使用了异步属性,那么JS脚本加载过程不会阻塞文档解析,脚本会在加载后立即执行。如果在sript标记中使用了defer属性,那么JS脚本加载过程不会阻止文档解析,脚本执行将一直等到文档解析完成。对于外部引用的脚本文件,从脚本下载到脚本执行,文档解析过程始终被阻止
硬件加速
WebKit渲染引擎的渲染方法分为软件渲染和硬件渲染。这两种渲染方法可以分为两大过程:一是获取网页的渲染信息;第二种是将网页绘图信息转换成像素并显示在屏幕上
在获取网页绘制信息的过程中,需要遍历RenderLayer树,并在渲染前记录RenderLayer树中包含的网页绘制信息。记录网页绘制信息的步骤是渲染引擎的绘制过程,渲染引擎本身并不知道是否实际执行了绘制命令。
[软件渲染]
软件渲染的过程可以概括为以下三个步骤:
1.从SurfaceFlinger获取图形缓冲区
2.在SkCanvas上执行封装该图形缓冲区的网页绘制命令
3.将绘制的图形缓冲区返回到曲面抛转器
软件渲染简单,网页内容直接绘制到一个图形缓冲区,占用内存少。缺点是网页内容绘制在同一个图形缓冲区上,更新网页内容时需要完全更新,不能本地更新
[硬件渲染]
相比软件渲染,硬件渲染更加复杂。网页内容需要先在一个SkBitmap上绘制,然后通过图形缓冲区上传到GPU,需要更多内存
硬件渲染是指网页各层的合成由GPU完成,采用分块渲染的策略。块渲染是指网页内容被一组切片覆盖,每个切片对应一个独立的后端存储。当网页内容更新时,仅更新内容已更改的切片。分块策略可以实现局部更新和更高的渲染效率
硬件渲染过程分为以下五个步骤:
1.在封装有SkBitmap的SkCanvas上执行平铺覆盖的网页信息的绘制命令;
2.将每个图块对应的SKBitmap复制到从SurfaceFlinger获得的图形缓冲区中;
3.将Tile对应的所有图形缓冲区上传到GPU进行合成;
4.将合成的网页内容传送到纹理;与对应于平铺的屏幕帧缓冲区相关联;
5.图形处理器绘制图块对应纹理的硬件实现
打开硬件渲染,即合成加速,将为每个需要单独绘制的层创建一个图形层
在加速合成的情况下,每一层网页内容对应一个后端商店,由平台实现,Android 4.2平台提供的后端商店是GraphicsLayerAndroid。在记录网页绘制命令的开始,RenderLayerCompositor负责控制RenderLayer的遍历,RenderLayer中包含的绘制信息最终记录在其后端存储中,即GraphicsLayerAndroid中包含的PicturePile实例。
如果渲染层对象需要后端存储,它将创建一个渲染层堆栈对象,负责渲染层对象所需的各种存储。理想情况下,每个渲染层都可以创建自己的后端存储。事实上,并不是所有的渲染层都有自己的渲染层堆叠对象。如果渲染层对象是为后端存储正确创建的,那么渲染层称为合成层
哪个渲染层可以是复合层?如果渲染层对象具有以下特征之一,则它是一个复合层:
1.渲染层有CSS 3D属性或者CSS透视效果。
2.渲染层中包含的渲染对象节点使用硬件加速视频解码技术来表示HTML5“视频”元素。
3.包含在渲染层中的渲染对象节点代表Canvas2D元素或硬件加速的WebGL技术。
4.渲染层使用CSS透明度动画或CSS变换动画。
5.渲染层使用硬件加速的CSSfilters技术。
6.渲染层使用剪辑或反射属性,其后代包括一个复合层。
7.渲染层有一个兄弟节点,它的Z坐标小于它本身,这是一个复合层
因此,硬件加速的渲染过程如下
重新喷漆回流
重绘和回流是页面渲染过程中两个非常重要的概念。页面生成后,脚本操作、样式表更改和用户操作可能会触发重绘和重排
[回流]
Reflow是firefox中的一个术语,在chrome中称为重排
回流焊是指当窗口大小被修改、发生滚动操作或元素的位置相关属性被更新时,布局过程将被触发,布局过程中应计算所有元素的位置信息。因为HTML使用的是流布局,如果页面中某个元素的大小发生变化,其后续的元素位置也会发生变化,也就是重新流布局的过程,所以称之为回流
前面介绍了渲染引擎生成的三棵树:DOM树、渲染树和渲染层树。回流发生在渲染树中。人们常说,离开文档流意味着离开渲染树渲染树
触发回流包括以下操作:
1.正射影像元素的几何属性会改变
2.DOM树的结构变化
3.获取以下属性
offsetopofsetleftoffsetidthoffsetheightscrolltopscrollefscrollwidthscrolheighclienttopclientleftclientwidthclientheighgetcomputed style()currentStyle()
4.更改元素的一些样式
5.调整浏览器窗口大小
触发回流焊肯定会触发后续的重绘操作,元素的回流焊可能会影响父元素。例如,子元素浮动后,父元素将高度折叠。因此,性能优化的重点是尽量只触发小规模重绘,尽量不触发回流
[重画]
重画是指当视觉相关的样式属性值更新时,会触发绘制过程。在绘制过程中,应重新计算元素的视觉信息,以使元素呈现新的外观
元素的重画仅发生在渲染层渲染层。因此,如果您想要更改元素的视觉属性,最好将元素作为独立的渲染层
以下描述将以元素显示为例。有许多方法可以实现元素显示和隐藏
显示:无/块,会造成回流,从而导致重绘,性能差
可见性:visible/hidden,只造成重绘,但因为没有成为独立的渲染层,会造成整个页面(或者当前渲染层)的重绘,性能不错
不透明度:0/1,当不透明度小于1时,会生成渲染层。所以不透明在0和1的变化中造成了渲染层的产生和破坏,所以也造成了回流焊,造成重绘,性能差。如果不透明度:0/0.9,只会导致重绘
如果一个元素是用硬件加速渲染的,比如CSS 3D属性,就不会重绘和回流。但是如果硬件渲染的元素太多,会造成GPU的传输压力
[性能优化]
以下是一些减少回流时间的方法
1.不要一个接一个地修改DOM样式,而是修改类名或样式
2.在内存中操作该节点几次,完成后将其添加到文档中
3.对元素执行复杂操作时,可以先隐藏它,然后在操作完成后显示它
4.当您需要获取导致浏览器频繁返回的属性值时,请将它们缓存到变量中
5.不要使用表格布局,因为一个小的变化可能会导致整个表格重新布局。表格渲染通常需要三倍于等效元素的时间
另外,需要多次回流的元素独立渲染为渲染层,比如设置绝对,可以更少的重绘范围;对于一些动画元素,可以执行硬件渲染以避免重绘和回流。
1.《ie系列浏览器 深入理解浏览器工作原理》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。
2.《ie系列浏览器 深入理解浏览器工作原理》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。
3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/shehui/1007915.html