前言

想要成为一名合格的前端工程师,掌握相关浏览器的作业原理是必备的,这姿态才会有一个完整常识体系,要是能参透浏览器的作业原理,你就能解决80%的前端难题

其他文章:

  • [有用]推荐一些十分t M – C棒的前端网站
  • [干货]从详细操作js数组到浅析v8中array.js
  • [诚意满满]Chrome DevTools调试小技巧,功率➡️
  • [建议]再来100道JS输命题酸爽继续(共1.8W字+稳固JS根底)
  • [1.2W字]写给女友的秘籍-浏览器作业原理(上)篇
  • 面试怎么写出一个满意的深复制(适合初级前端)

这篇文章预备整理一下烘托, P R e n # +流程,也便是n V W 浏览器是怎么把HTML,CSS,JSy ? X `,图片等资源终究显现美丽的页面。

仍是那句话,了解浏览器是怎么( * U C O N作业的) E 4 | ^ p n D t,能让你站在更高维度去了解前端w s 9 ;

希望经过这篇文章,能够让你从头认识浏览器,并把JavaScs 4 J vript,网络,页面烘托,浏览器安全等常识串联起来,然后让你对整个前端体系有全新的认识。

这篇首要是整理了烘托流程中几个重要的进程,以及从中有哪些优化的点,怎么样避免和削减重绘、重排,对优化功用上有必定的协助。

读完这一期内容,你将收获

  • 前端功用优化的底层逻辑;
  • 浏览器页m T { j ] Q | R面烘托的中心流程
  • J+ 7 N 6 ! WavaScript 运转机制解析
  • 浏览器网络及安全机制解析

小声说:欢迎在留言区与我共享你的主意,也欢迎你在留言区记录你的考虑进程


假如喜欢的话能够点赞G l D R/关注,支持一下,希望咱们能够看完本文有所收获

回顾上一期

讲浏览器中烘托流程,先把上一篇所整理的内容大约回顾一下

上一篇文章:[1.2W字]写给女友的秘i K K & A V J L籍-浏览器作业原理(上)篇

浏览器架构(Chrome为主)

首要整理以下常识点:

  • 整理单线程与多线程概念,进程与线程差异
  • 以Chrome浏览器为主,整理$ P V了Chromx 9 } y ^ –e浏览器发展史o % a,从单进程浏览器到多进程浏览器
  • 单进程架构到多进程架构趋势,发展趋势的优缺陷
  • 现在大都浏览器多c ~ V r W r / u p进程架构:主进程 烘托进程 插件进程 GPU进程 网络进程

Http恳求

首要整理以下常识点:

  • Http恳求的全体流程,大致分为八个阶段

  • 八个阶段归纳为: 构建恳求 查找缓存 预备 IP 和端口 等候 TCP 行列 树立 TCP 衔接 建议 HTTP 恳求 服务器处理恳求 服务器回来恳求和断开衔接

  • 每个阶段大致的作业原理整理了一下

  • 浏览器缓存顺带提起了一下(面试常考) 功用优化一部分

导航流程:输入url) S ? t } F O 7到页面展现

首要整理常识点:

  • 全体流程,整理这个进程中最为首要的三个进程,浏览器进程 网络进程 烘托进程,它们各自的责任以及三者之间的通讯
  • 尝试去剖析每个阶段,细节h – Z v E e }不提及了。

烘托进程接受到CommitNavigation消M b Q Y { } x息之后,便开端与网络进程树立数据管道说起,此刻烘T M 4 e G E H托进程开端干活了

那么才有了咱们接下来要整理的内容,烘托进程怎么作业的呢

烘托流程

首先要了! 9 G k i解的概念:

  • 烘托引擎:它是浏览器最中心的部分是 “Rendering Engine”,不过咱们一般习惯将之称为 “浏览器内核”

  • 烘托引擎首要包含8 T m ~ u #的线程:

[1.1W字]写给女友的秘籍-浏览器工作原理(渲染流程)篇
  • 各个线程首要责任

    • GUI烘托A E K e + A + P v线程:GUI 烘托线程担任烘托浏览器界面,解析 HTML,CSS,构建 DOM 树和 RenderObject 树,布局和制作等。当界面需求重绘(Repaint)或由于某种操作引发回流(Reflow)时,该线程就会履行$ ~ p r I f w #
    • JavaScript引擎线程: JavaScript 引擎线程首要担任解析 JavaScript 脚本并运转相关代码。 JavaScript 引擎在一个Tab页(Renderer 进程)中不管什么时分都只有一个 JavaScript 线程在运转 JavaScript 程序。需求提起一点便是,GUI线程与JavaScript引擎线程是互斥的,这也是便是为什么JavaScript操作时刻过长,会形成页面烘托不连贯,+ D q N : e : U导致页面呈现堵塞的原理。
    • 作业触发线程:当一个作业被触发时该线程会把作业增加到待处理行列的队尾,等候 JavaScript 引擎的处理。 一般JavaScript引擎是单线程的,所以这些作业都会排队等候JS履行。
    • 定时器触发器: 咱们日常运用的setInterval 和 setTimeout 就在该线程q + g . u V 0中,原因或许便是:由于JS引擎是单线) U + ] ^ – 8 *程的,假如处于堵塞线程状态就会影响记时的精确,所以需求经过独自的线程来记时并触发呼应的作业这姿态更为合理。
    • Http恳求线程: 在 XMLy e O c X pHttpRequest 在衔接后是经过浏览器新开一个线程恳求,这个线程就Http恳求线程,它 将检测到状态改动时,假如设置有回调函数,异步线程就产生状态改动作业放到 JavaScript 引擎的处理行列中等候处理。

以上来自阿宝哥总结:你不知道的 Web Workers (上)[7.8K 字 | 多图预警]

有了上述的概念,对接下咱们讲烘托流水线会有所协助

简略版的烘托机制

好久之前就把浏览器作业原理读完了,看了许多博客,文章,其时简简{ R R 8略单的整理一些内容,如下

简略版烘托机制一般分为以下几个进程

  1. 处理 HTML 并构建 DOM 树。
  2. 处理 CSS 构建 CSSOM 树。
  3. 将 DOM 与 CSSOM 兼并成一f t u d : J o ` _个烘托树。
  4. 依据烘托树来布局,核算每* U t i个节点的方位。
  5. 调用 GH + G b S 5 M uPU 制作,组成图w X M层,显现在屏幕上。
[1.1W字]写给女友的秘籍-浏览器工作原理(渲染流程)篇

接下来大约便是这么说:

w f o 1 7 f t构建 CSSOM 树时,会堵塞烘托,直至 CSSOM 树构建完结。并且构建 CSSOM 树是一个十分耗费功用的进程,所以应该尽量保证层级扁平,削减过度层叠,越是详细的 CSS 挑选器,履行速度越慢。

当 HTML 解析到B @ 3 6 q script 标签时,会暂停构建 DOM,完结后才会从暂停的地方从头开端。也q S h G 2 [ H –便是说,假如你想首屏烘托的f ; R 4 ] Y越快,就越不应该在首屏就加载 JS 文件。并且 CSS 也会影响 JS7 9 K 的履行,只有当解析完款u w 4 t c # 3式表才会履行 JS,所以也能够以为这种状况下,CSS 也会暂停构建 DOM。

[1.1W字]写给女友的秘籍-浏览器工作原理(渲染流程)篇

说完这些,记下来就讲几个面试常常会提起的,会问v L U i你的常识点

Load 和 DOMContentLoaded 差异

Load 作业触发代表页面中的 DOM,CSS,JS,图片现已悉数加载结束。

DOMContentLoaded 作业触X M {发代表初始的 HTML 被彻底加载和解析,不需求等候 CSS,JS,图片加载。

图层

一般来说,能够把一般文档流看成一个图层。特定的属功用够生成一个新的图层。不同的图层烘托互不影响,所以关于~ ` $ [ p m } x某些频频需求烘托的建议独自生成一个新图层,进步功用。但也不能生成过多的图层,会引起反作用。

经过以下几个常用属功用够生成新图层

  • 3D 改换:translate3dM y , 8 n CtranslateZ
  • will-change
  • videoiframe 标签
  • 经过动画完结的 opacity 动画转化
  • position: fixe9 8 V ~ & + w 6d

重绘(Repaint)和回流(Reflow)

重绘和回流是烘托进程中的一末节,可是这两个进程关于功用} C 0 :影响很大。

  • 重绘是当节点需求更改外观而不会影响布局的,比方改动 color 就叫称为重绘
  • 回流是布局或许几许特点需求改动就称为回流。

回流必定会产生重绘,重绘不必定会引t b n发回流。回+ $ K O流所需的本钱比重绘高的多,改动深层次的节点很或许 x A + m _导致父节点的一A 0 ? .系列回流。

所以以下几个动作或许o ? | r D h B会导致功用问题:

  • 改动 window 巨细
  • 改动字体
  • 增加* G l或删去款式
  • 文字改动
  • 定位或许? E # 9 $ } q浮动
  • 盒模型

许多人不知道的A % K w W v [ M :是,重绘和回流其实和 Event loop 有关。

  1. 当 Event loop 履行完 Microtasks 后,会判别 document 是否需求更新。由于浏览器是 60Hz 的刷新率,每 16ms 才会更新一次。
  2. 然后判别是否有 resize 或许 scroll ,有的话会去触发作业,所以 resizesb u ` o 2 lcroll 作业也是至少 16ms 才会触发一次,并且自带节省功用。
  3. 判别是否触发了 media query
  4. 更新动画并且发送作业
  5. 判别是否有全屏操作作业
  6. 履行 requestAnima& 2 - ] etionFrame– , c F
  7. 履行 IntersectionObseu H 5 lrver 回调,该办法用于判别元素是否可见,能够用于懒加载上,可是兼容性不好
  8. 更新界面
  9. 以上便是一帧中或许会做的作业。假如在一帧中有闲暇时刻,就会去履行 requestIdleCallback 回调。

以上内容来自于 HTMX M * L lL 文档

削减重绘和回流

  • 运用 translate 代替 top

    <div class="test"&G  ]gt;</div>
    <style&g[ r { , R 2 D Gt;
    .ts Y N eest {
    posiN p = 2 H [ 1 Qtion: absolute;
    top: 10px;
    width: 100px;
    height: 100px;
    background: red;
    }
    </style>
    <script>
    setTb / s m V ; R 1 6imeout(() => {
    // 引起回流
    document.querySelector('.test').style.top = '100px'
    }, 1000)J E . G
    </script>
    
  • 运用 visibility 替换 display: none ,由于前者只会引起重绘,后者会引发回流(改动了布局)

  • 把 DOM 离线后E U 8 4 z R j修正,比方:先把 DOM 给 display:none (有一次 Reflow),然后; B a你修正100次,然后再把它显现出来

  • 不要把 DOM 结点的特点值放在: . X / G I a 4一个循环里当成循环里的变量

    for(let i = 0; i < 1000; i++) {
    // 获取 offs& ; 6 m V  * y EetTop 会导致回流,由于需求去获取正确的值
    console.log(S B k Q z Mdocuv  k & K e Xment.querySelector('.test').style.on H vffsetTop)
    }
    
  • 不要运用 table 布局,或许很小的一个I , 6 M ^ 2 ` R小改动会形成整个 table 的从头布局

  • 动画完结的速度的挑选,动画速度越快,回流次数越多,也能够挑选运用 requeK w T gstAnimationFrame

  • CSSo ) K E ; o 挑选1 W u 1 k G R符从右往左匹配查找,避免 DOM 深度过深

  • 将频频运转的动画变为图层,图层能够阻挠该节点回流影响其他元素。比方关于 video 标签,浏览器会自动将该节点变为图层。


这不是我想整理的内容

上面的烘托流程是我一年2 F `前就在我笔记中存在的内容,我还记得其时学习的办法是囫囵吞枣式的,上面☝简略版的烘托流} V k程,我印象中是在GK s s 9itHub上面某博看看的,其时直接Copy下来的,其时觉得这个烘托原理这块有了他人整理好的结论,自己多看看,会记住的,事实上,面试的时分,提起这Z ! ] _部分的时分,深度显着不行,自然就被问倒了

下来整理了一份详细的版别,坦白说,作为一个学者,自然是站在伟人的膀子p 4 . [ c $ u i A上,去总结整理常识,我以为这是对我最有效的学习办法

让我带着你重温一般烘托流程吧


详细版的烘托机制

较为; w q专业的术语总结为以下阶段:

  1. 构建DOM树
  2. 款式核算
  3. 布局阶段
  4. 分层
  5. 制作
  6. 分块
  7. 光栅化
  8. 组成

你能够想g S X M 4 R @象一下,从0,1字节省到终究页面展现在你– 9 [ ] | n 6 ?面前u i h l W H,这里边烘托机制必定很杂乱,所以烘托模块把履行进程中] B r j z +化为许多的子阶段e w U U 9 = @ @,烘托引g 9 9擎从网络进程拿到字节省数F n | z I (据后,经过这些子阶段的处理,终究输出像素,这个进程能够称为烘托流水线 ,咱们从一张图上– n . . e ~来看

[1.1W字]写给女友的秘籍-浏览器工作原理(渲染流程)篇

那接下来就从每个阶段来整理一下大致进程。

构建DOM树

这个进程首要作业便是讲HTML内容转化为浏览器DOM树结构J | F @ ]

  • 字节→字符→令牌→节点→目标模型( 6 p G & $DOM)

文档目标模型(DOM)

<html>
<head>
<meta name="viewport" content="| / 6 o 3width=device-width,initial-scale=1">
<link href="style.css2 n n K  d j" rel="stylesheet"&gT E t;
<title>CriticP q 4 a  ^ H hal Path</title>
</head>
<body>
<p>Hello <span>web performance<` t 5 B;/span> students!</p&g/ L % zt;
<div><img src="awesome-photo.jpg"></div>^ J l r `  l  2
</body>
&lb g Y @ : h ? Tt;/hty i Q g ~ ,ml>

咱们X K h j E ~ o Z先看看– 0 J o k a数据是怎么样转4 2 g / 0 s化的

[1.1W字]写给女友的秘籍-浏览器工作原理(渲染流程)篇

大约进程:

  1. **转化:**浏览器从磁盘或网络读取 HTML 的原始字节,并依据文件的指定编码(例如 UTF-8)将它们转化成各个字符。. V ; : k } $
  2. **令牌化:**浏览器将字符串转^ D % – y = / +化成 W3C HTML5 标准规矩的各种令牌,例如,“”、“”,以及其他尖括号内的字符串。每个令牌都具有特殊含义和一组规矩。
  3. *& { C 4 0*词法剖析:**发出的令牌转化成定义其特点和规矩的“目标”。
  4. **DOM构建v ` E:**终究,由于 HTML 符号定义不同符号之间的联系(一些符号包含在其他符号内i V T B V),创立的目标链接在一个树数据结构内,此结构也会捕获原始符号中定义的父项-子项O o M # ^ = i h H联系:HTML 目标是 body 目标的父项,bodyparagraph 目标的父项,依此类推。

咱们把上述这姿态的进程就叫做是构建DOM树A P 2 7 $进程

款式核算

这个子阶段首要有三个进程

  • 格式化款式表
  • ` Z n I U准化款式表
  • 核算每个DOM节点详细款式

格式化款s 4 S B式表

咱们拿到的也便是0,1字节省数据,浏览器无法直接去识其他,所以烘托引擎收到CSS文本数据后,会履行一个操作,转化为浏览器能够了解的结构-styleSheets

假如你很想了解H z A 0 ` q这个格式化的进程,能够好好去研讨下,不同的浏览器或许在CSS格式化进程中0 # n + 9 p I会有所不( w v f同,在这里就不打开篇幅了。

经过浏览器的控制台documee X d Snt.styleSheetsh ? N l B n ,够来检查这个终究成果。经过JavaScript能够完结查询和修正功用,或许说这个阶段为j 7 } 6 R F X %后边的款( H N 3 ~ a &式操作提供基石。

[1.1W字]写给女友的秘籍-浏览器工作原理(渲染流程)篇

标准化款式表

什么是标准化款式表呢?先看一段CSS文本

bz @ 8 } 0 } Fody { font-size: 2em }
p {col N x 8 = :lor:blue;}
span  {display: nr m o r 8 Lone}
div {font-weight: bold}
div  p {colov w F v ? %r:green;}
div {color:red; }

有些时分,咱们写CSS 款式的时分,会写font-size:2em;color:red;font-weight:bold,像这些数值并不容易被烘托引擎所了解,因而需求在核算款式之前将它们标准化,m Q aem->p5 R / V Dx,c [ z a _ l B * Wred->rgba(255,0,0,0),bold->700等等。

上面的代码标准后特点值是什么姿态呢

[1.1W字]写给女友的秘籍-浏览器工作原理(渲染流程)篇

核算每个DOM节点详细款式

经过格式化标准[ c N ],接下来便是核算每个节点详细款式信息了。D x F I ;

核算| H q X @ L规矩:承继层叠

承继:每个子节点会默许去承继父节点的款式,假如父节点中找不到,就会选用浏览器默许的款式,也叫UserAgent款式

层叠:款式层叠,是CSS一个基本特征,它定义怎么兼并来自多个源的特点值的算法。某种意义上,它处于中心地d 4 _位,详细的层叠规矩属于深入 CSS 语言的领域,这里就补打开篇幅说了。

不过值得注意的是,在核算完款式之后,一I ? _ N | D切的款式值会被挂在到window.getComputedStyle当中,也便是能够经过JS来获取核算后的款式,十分方便。

这个阶段,完结了DOM节点中每个元素的详细款式,核算进程中要遵从CSS的承继层叠两条规矩,终究输出的内容是每个节点DOM的款式,被保存在ComputedStyle中。

想了解每个 DOM 元素终究L [ f的核算款式,能够打开 Chrome 的“开发者东西”,挑选第一个“element”标签,比方我下面就挑选了div标签T m p K c ! s f,然后再挑选“Computed”子标签,如下/ ! 7 [ / 2 u 8 图所示:

[1.1W字]写给女友的秘籍-浏览器工作原理(渲染流程)篇

别的一种说法CSSOM

假如不是很了解的话,能够看这里

[1.1W字]写给女友的秘籍-浏览器工作原理(渲染流程)篇

跟处理HTML相同,咱们需求更具CSS两个规矩:承继层叠转化( M 2 h 5 L { v成某种浏览器能了解和处理的东西,处理进程相似处理HTML,如上图☝

CSS 字节转化成字符,接着转化成令牌和节点,终究链接J 0 s 9到一个称为“CSS 目标模型”(CSSOM) 的树结构内

[1.1W字]写给女友的秘籍-浏览器工作原理(渲染流程)篇

许多人必定看这个很熟悉,确实,许多博客都是基于CSS6 . lOM说法来讲的,我要说的是:

和DOM不相同,源码中并没有@ K 2 W / [ t xCS{ c I ) WSOM这个词,所以许多文章说的CSSOM应该便是styleSheets,当然了这个styleSheets咱们能够打印出来的

许多文章说法是烘托树也是t % @ k ( 7 n 716年前的说法,现在代码重构了,咱们能够把LayoutTree看成是烘托树,不过它们之间仍是有些差异的。

生成布局树

上述进程现已完结DOM树(DOM树)构建,以及款式核算y t T 2 s #(DOM款式9 d O n),接下来便是要经过浏览器的布局体系确定元素方位,也便是生成一颗布局树(Layout Tree),之前说法叫 烘托树

创立布局树

  1. 在DOM树上不行见的元素,head元素 5 O y :,meta元素等,以及运用displ6 g y $ay:none特点的元素,终究都不会呈现在布局树上,所k d k a 0浏览器布局体v B = S w K ] a }系需求额定去构建一棵只包含可见元素布局树。

  2. 咱们直接结合图来看看这个布局树构建进程:

    [1.1W字]写给女友的秘籍-浏览器工作原理(渲染流程)篇

    为了构建布局树,浏览器布局体系大体上完结了下面这些作业:

  • 遍历DOM树可见E k t } R S 9 ` f节点,并把这些节点加到布局树中
  • 关于不行见的节点,head,meta标签等都会被忽略。关于body.p.span 这个元素,它的特点包含display:none,所以这个元素没有被包含进布局树。

布局核算

接下来便是要核算布局树g _ Q Q a / Q `节点的坐标方位,布局的核算进程十分杂乱,张开介绍的话,会显得文章过于G P % ) J j @臃肿` X 6 G R , g au r G a 0 ( g大大都状况下,咱们只需求知道它所做的作业是什# I r N * U l d,想知道它是怎么做的话,能够看B ; U a b看以下两篇文章

  • 从Chrome源码看浏览器怎么layout布局
  • 人人FED团队的文章-从Chrome源码看浏览器怎么layout布局

整理前三! ? G t ? m k个阶段

一图归纳上L e .面三个阶段

[1.1W字]写给女友的秘籍-浏览器工作原理(渲染流程)篇

分层

  • 生成图层树(Layer Tree)
  • 具有层叠上下1 6 T j B x文特点的元素会被提高为独自一层
  • 需求裁剪(clip)的地方也会创立图层
  • 图层制作

首先需求知道的便是,浏览器在构建完布局树后,还需求进行一系列操作,这姿态或许考虑到一些杂乱的场景,比方一些些杂乱的 3D 改换、页面翻滚,或许运用 z-indexing 做 z 轴排序等,还有比方是含有层叠上下文怎么控制显现和躲藏等状况。

生成图层树

你终究看到的页面9 ` 4,便是由这些图层一同叠加构成的,它们依照d z ? :必定的次, G o : 4 V序叠加在k + ? 4 ~一同,就形成了终究的页面。

浏览器的页面实践d & d上被分成了许多图层,这些图层叠加后组成了终究的页面。

咱们来看看图层与布局树之间联系,如下图

[1.1W字]写给女友的秘籍-浏览器工作原理(渲染流程)篇

一般状况下,并不是y j t Y布局树的每个节点都包含一个图层,假如一个节点没有对应的层,那么这个节点就从属于父节点的图层。

那什么状况下,烘托引擎会为特定的节点创立新图层呢?

有两种状况需o a ) G 9 ~ 4 – 0求分别评论,一种是显式组成,一种是隐式组成

显式组成

一、 具有层叠上下文的节点。

层叠上下文也基本上是有一些特定的CSS特点创立的,一般有以下状况:

  1. HTML根元素本身就具6 4 1 2 L 有层叠上下文。
  2. 一般元素设k a O Gposition不为static并且设置了z-index特点,会产生层叠上下文。
  3. 元素的 opacity 值不是 1
  4. 元素的 transform 值不是 none
  5. 元素的 filter 值不是 none
  6. 元素的 isolation 值是isolate
  7. will-change指定的特点值为上面恣意一个。(will-change的作用后边会详细介/ 0 ! K 9 v B G绍)

二、需求取舍(clip)的地方。

比方一个标签很小,50*50像素,你在里边放了十! 9 L 0 + _ n h ]分多的文字,那么超出的文字部分就需求被取舍。当然假如呈现了翻滚条,那么翻滚条也会被独自提高为一个图层,a S m . & i l如下图

[1.1W字]写给女友的秘籍-浏览器工作原理(渲染流程)篇

数字1箭头指向的地方,能够看看,+ % o g N Z r或许作用不是很显着,咱们能够自己打开这个Layers探) z v g H j A Q索下。

元素有了层叠v f B ; ` Y *上下文的特点或许需求被取舍,满足其间恣意一点,就会被提高成为独自一层。

隐式组成

这是一种什么样的状况呢,浅显意义上来说,便是z-index比较低的节点会提高为一个独自的途图层,那么p m 0 } w N M f *层叠等级比它高的节点都会成为一个独立的图层。

浏览器烘托流程&ComposiY 1 C S [ =te(烘托层兼并)简略总结

缺陷: 依据上面的文章来说,在一个大型的项目中,一个z-index比较低的节点被提高为独自图层后,层叠在它上面的元素通通都会提高为独自的图层,咱们知道,上千个图层,会增大内存的压力,有时分会让页面e ? &溃散。这便是层爆炸

制作

完结了图层的构建,接下来要做的作业便是图层的制作了。图层的制作跟咱们日常的制作相同,每次都会把一个杂乱的图层拆分为很小的制作指令,然后再依照这些指令的次8 . {序组成一个制作列表,相似于下i * &

[1.1W字]写给女友的秘籍-浏览器工作原理(渲染流程)篇

从图中能够看出,制作列表中的指令其实十分简略,便是让其履行} # 0 R # ! ^一个简略的制作操作,比方制作粉色矩形或许黑色的线等。而制作一个元素一般需求好几条制作指令,由于每个元素的J o Z D布景、前景、边框都需求独自的指令去制作。

咱们能够在 ChH [ J p 1 @ V Wrome 开发者东西中在设置栏中打开 more tools, 然后挑选Layers面板,就能看到下3 y 4 N S面的制作列表:

[1.1W字]写给女友的秘籍-浏览器工作原理(渲染流程)篇

在该图中,*@ V p x*箭头2指向的区域 **便是 docuW ; k rment 的制作列表,**箭头3指向的拖动区域 **中的进度条能够重现列表的制作进程。

当然了,制作图层的操作在烘托进程中有着专门的线程,这个线程叫做组成线程。

e % A {

  • 接下来咱们就要开端制作操作了,实践上在烘托进程中制作操作是由专门的线程来完结的,这个 { ? i a x C线程叫组成线程

  • 制作列表预备好了之后,烘托进程的o O v j ~主线程会给组成线5 X ) u J 9 n F发送commit消息,把制作列表提交给组成线程。接下来便是7 c i Y D * =组成线程一展宏图的时分啦。

你想呀,有时分,你的图层很大,或许说你的页面y g 7 d 2需求运用翻滚条,然后页面的内容太多,多的无法想象,这个时分需求翻滚好久才干翻滚到底部,可是经过视口,用户只能看到页面的很小一部分,所以在这种状况下,要制作出一切图层内容的话,就会产生太大的开支,并且也没有必要g 5 y o )

  • 基于上面的原因,组成线程会讲图层划分为图块(tile)
  • 这些块的巨细一般不会特别大,一般是 256 * 256 或许 512 * 512 这个规格。这样能够大大加快页面的首屏展现。

首屏烘托加快能够这么了解:

由于后边图块(非视口内的图块y P [ r w K S)数据要进入 GPU 内存,考虑到浏览器内存上传到 GPU 内存的操作比较慢,即使是制作一部分图块,也或许会耗费很多时刻。针对这个问题,Chrome 选用了一个策略: 在首次组成图块时只选用一个低分辨率的图片,这样首屏展现的时分只是展现出低分辨率的图片,这个时分继续进行组成操作,当正常的图块内容制作I l a结束后,会将当前低分辨率的图块内容替换。这也是 Chrome 底层优化首屏加载速度的一个手段。

光栅化

接着上面的进程,有l s ~ a o e g ~了图( g p m块之后,组成线程会依照视口邻近的图块来优先生成位图,实践生成位图的操作是由栅格化来履行的。所谓栅格化,是指将图块5 : M I R I c转化为位图。

  • 图块是栅格化履行的最T % i ) % V t J小单位
  • 烘托进程中专门保护了一个栅格化线程池,专门q . . ? g e K c 6担任把图块转化为位图数据
  • 组成线程会挑选视口邻近的图块(tile),把它交给栅格化线程池生成位图y : 6 v
  • 生成位图的进程实践上都会运用 GPU 进行加快,生成的位图终究发送给组成线程

运转办法如下

[1.1W字]写给女友的秘籍-浏览器工作原理(渲染流程)篇

一般,栅格化进程都会运用 GPU 来加快生成,运用 GPU 生成位图的进程叫快速栅格化,或许 GPU 栅格化,生成的位图被保存} _ 3 B N F k F s在 GPU 内存中。

相信你还记得,GPU 操作是运转在 GPU 进程中,假如栅格化操作运用了 GPU,那么终究生成位图的操作是在e ? ! w R + n GPU 中完结的,这就涉及到了跨进程操作。详细形式你能够参阅下图:

从图中能M , & 2 t U够看出,烘托进程把生成图块的指令发送给 GPU,然后在 GPU 中履行生成图块的位图,并保存在 GPU 的内存中。

组成和显现

栅格化操作完结后,组成线程会生成一个制作命令,即”DrawQuad”,并发送给浏览器进程。

浏览器进程中的viz组件接收到这个命令,依据这个& 3 0 s y + w W ju B & G ( 3 |令,把页面内容制作到内存,也便是生成了页面,然后把这部分内存发送给显卡,那你必定对显卡的原理很猎奇。

看了某博主9 z – ; u对显现器显现图画的原了解Z T _ l D @ w T s释:

不管是 PC 显现器仍是手? w d F D k机屏幕,都有一个固定的刷新I , I 1 K x频率,一般是 60 HZ,即 60 帧,也便是一秒更新 60 张图片,一张图片停留的时刻约为 16.7 ms。而每次更f { 3 7 q e B新的图片都来自显卡的前缓冲区。而显卡接收到浏览器进程传来的页面后,会组成相应的图画,并将图画保存到后缓冲区,然后V z y体系自动将前缓冲区后缓冲区对换| ` L @方位,如此循环更新。

这个时分,心中就有点概念了,比方某个动画很多2 ? ; W v Z占用内存时,浏览器生成图_ y * &画的时分会变慢,图画传送给显卡就会不及时,而显现器仍是以不变的频率刷` ~ o |新,因而会u j W O呈现卡顿,也便是显着的掉帧现象。


用一张图来总O @ % ? l K M A

[1.1W字]写给女友的秘籍-浏览器工作原理(渲染流程)篇

回流t l & b *-重绘-组成

咱们把上面整g v 4 t y G个的烘托流水线,用一张图片更直观的表明

[1.1W字]写给女友的秘籍-浏览器工作原理(渲染流程)篇

更新/ h G a ^ ! 视图三种办法

  • 回流
  • 重绘
  • 组成

回流

别的一个叫法是重排,回流触7 ? L q I _ 7 / C发的条件便是:对 DOM 结构的修正引发 DOM 几许尺度改动的时分,会产生回流进程。

详细一点,有以下的操作会触发回流:

  1. 一个 DOM 元素的几许特点改动,常见的几许特点有widthheighV ! $ 3 i X Y }tpaddingmarginlefttopborder 等等, 这个很好了解。
  2. 使 DOM 节点产生增减或许移动
  3. 读写 of3 9 %fset族、scroll族和cliente B r特点的时分,浏览Z I F _ [ s g y L器为了获取这些值,需求进行回流操作。
  4. 调用 window.getCompuU M 6tedStyle 办法。

一些常用且会导致回流的特点和办法:

  • clientWidthclientHeightclientTopclientLeft
  • offsetWidthoffsetHeightoffsetTopoffV h / K HsetLeft
  • scrollWidthscrollHeig0 8 khtscrollTopscrollLer K B X t Xft
  • scrollIntoView()scrollIntoViewIfNeeded()
  • getComputedStyle()
  • getBoundingClientRect()
  • scrollTo()

依照上面的烘托流水线,触发回流的时分,假如 DOM 结构产生改动,则从头烘托 DOM 树,然后将后边的流程(包含主线程之外的任务)悉数走一遍。

[1.1W字]写给女友的秘籍-浏览器工作原理(渲染流程)篇

重绘

T } n K # t S Y页面中元素款式的改动并不影响它在文档流中的方位时(例如:colorbackground-colorvisibility等),浏览器会将新款式赋予给元素并从头D ! 6 & C | w M `制作它,这个进程称为重绘。

依据概念,咱们知道由于没有导致 DOM 几许特点的改动,因而元素的方位信息不需求更新,然后省去布局的进程,流程如下:

[1.1W字]写给女友的秘籍-浏览器工作原理(渲染流程)篇

越过了布局树建图层树,直接去制作列表,然后在去分块,生成位图等一系列操作。

能够看到,重绘不必定导致回流,但回流必定产生了重绘。

组成

还有一种状况:便是更改了一个既不要布局也不要制作的特点,那么烘托引擎会越过布局和制作,直接履行后续的组成操作,这个进程就叫组成

举个例子:比方运用CSS的transform来完结动画作用,避免了回流跟重绘,直接在非主线程中履行组成动画操作。明显这姿态的功率更高,究竟这个是在非主线程上组成的,没有占用主线程资源,别的也避开了布局和制作两个子阶段,所以相关于重绘和重排,组成能大大提高制作功率。

运用这一点好处:

  • 组成层的位图,会交由 GPU 组成,比 CPU 处理要快
  • 当需求 repaint 时s * Q,只需求 repaiI 4 c ; v x 1 q ont 本身,不会影响到其他的层
  • 关于 transform 和 opaci1 ? n A f !ty 作用,不会触发 layout 和 paint

提高组成层的最好办法是运用 CSS 的 will-change 特点

GPU加快原因

比方运用 CSS3 的transformopacityt # : efilter这些特点就能够完结组成的作用,也便是咱们常说的GPU加快

  • 在组成的状况下,直接越过布局和制作流程,进入非主线程处理部分,即直接交给组成线程3 C V x 0 a e r处理。
  • 充分发挥GPU优势,组成线程生成位图的进程中会调用线程池,并+ 9 f在其间运用GPU进行加快生成,而GPU 是拿手处理位图数据的。
  • 没有占用主线程的资源,即使主线程卡住了,作用依然流畅展现。

实践意义

  • 运用create, G z ( ; ) @ k ]DocumentFragment进行批量的 DOM 操作
  • 关于 resize、scroll 等进行防抖/节省处理。
  • 动画运用transform或许opacityN L * k a & D (完结
  • 将元素的will-change 设置为 opacity、transform、top、left、bottom、right 。这姿态烘托引擎会为其独自完结一个图层,当这些改换产生时,仅仅只是运用组成线程去处理这些改换,而不牵扯到主线程C : r p,大大进步烘托功率。
  • 关于不支持will-change 特点的浏览器,运用一个3D transform特点来强制提高为组成 trani x u M fsform: translateZ(0);
  • rAF优化等等

参阅

你不知道的 Web Workers (上)[7.8K 字 | 多图预警]

极客时刻-烘托流程

从浏览器多X z 7 X x : A M进程到JS单线程,JS运转机制最全面的一次整理

How Browsers Work: Behind the scenes of modern webG R l q & | 4 m v browsers

史上最全!图解c $ 1 # . Q 9浏览器的作业原理

W3C HTML5 标准

浏览器烘托流程&Comp! h 2 d ; E Kosite(烘托层兼并)简略总结

浏览器层组成与页面烘托优化

浏览器的回流与重绘 (Reflow & Repaint)

无线功用优化:Composite

CSS GPU Animation: Doing It RigT O E ( &ht

本文运用 mdnice 排版