有线性能优化,前端品质优化之

时间:2019-11-21 23:56来源:关于计算机
有线品质优化:Composite 2016/04/26 · 基础技艺 ·无线 原稿出处: Taobao前端团队(FED卡塔 尔(阿拉伯语:قطر‎-冬萌    一个 Web 页面包车型大巴来得,轻松的话能够认为经验了以下下多

有线品质优化:Composite

2016/04/26 · 基础技艺 · 无线

原稿出处: Taobao前端团队(FED卡塔 尔(阿拉伯语:قطر‎- 冬萌   

图片 1

一个 Web 页面包车型大巴来得,轻松的话能够认为经验了以下下多少个步骤。

图片 2

  • JavaScript:经常的话,我们会利用 JavaScript 来兑现部分视觉变化的功用。比方做三个动漫也许往页面里增加一些 DOM 成分等。
  • Style:计算样式,这几个历程是基于 CSS 接纳器,对各样 DOM 成分匹配对应的 CSS 样式。这一步停止之后,就分明了各个 DOM 成分上该应用什么 CSS 样式法规。
  • Layout:布局,上一步鲜明了各类 DOM 成分的体裁法则,这一步正是呼之欲出估测计算每一个 DOM 成分最终在荧屏上海展览中心示的大大小小和职务。web 页面桐月素的布局是绝没有错,由此一个因素的布局发生变化,会联合浮动地抓住其它因素的布局发生变化。比方,`` 成分的肥瘦的变动会影响其子元素的大幅,其子成分宽度的更改也会一而再对其外孙子成分产生影响。由此对于浏览器来讲,布局进程是常事发出的。
  • Paint:绘制,本质上就是填充像素的经过。包涵绘制文字、颜色、图像、边框和阴影等,也正是三个DOM 成分全数的可视效果。经常的话,这么些绘制进度是在多少个层上成功的。
  • Composite:渲染层归总,由上一步可以看到,对页面中 DOM 成分的绘图是在多少个层上扩充的。在各种层上做到绘制进度之后,浏览器会将全部层根据合理的种种合并成三个图层,然后展现在显示器上。对于有职分重叠的元素的页面,这一个历程特别首要,因为假设图层的会师顺序出错,将会促成成分呈现至极。

本来,本文大家只来关爱 Composite 部分。

摘要: 多少个 Web 页面包车型大巴体现,轻松的话能够以为经历了 JavaScript/Style/Layout/Paint/Composite 多少个步骤。本文首要深刻Composite 部分,从渲染原理、Composite 原因以至如何针对其张开质量优化等张开荒展。

浏览器渲染原理

在谈论 Composite 在此以前,有必不可少先轻便精晓下一些浏览器(本文只是指向性 Chrome 来讲卡塔 尔(英语:State of Qatar)的渲染原理,方便对之后有的定义的知晓。越多详细的开始和结果能够参阅 GPU Accelerated Compositing in Chrome

注:由于 Chrome 对 Blank 引擎某个落成的修改,某个大家早先熟稔的类名有了变动,例如 RenderObject 产生了 LayoutObject,RenderLayer 形成了 PaintLayer。感兴趣的看以参阅 Slimming Paint。

在浏览器中,页面内容是储存为由 Node 对象组成的树状结构,也正是 DOM 树。每二个 HTML element 成分都有二个 Node 对象与之对应,DOM 树的根节点永恒都以 Document Node。那一点相信大家都很熟悉了,但实质上,从 DOM 树到最后的渲染,供给进行部分转变映射。

图片 3

多个 Web 页面的来得,轻巧的话能够感觉经验了以下下多少个步骤。

从 Nodes 到 LayoutObjects

DOM 树中得每个 Node 节点皆有叁个一倡百和的 LayoutObject 。LayoutObject 知道怎么样在荧屏上 paint Node 的剧情。

图片 4

从 LayoutObjects 到 PaintLayers

雷同的话,拥有相近的坐标空间的 LayoutObjects,归属同叁个渲染层(PaintLayer卡塔 尔(英语:State of Qatar)。PaintLayer 最先是用来达成 stacking contest(层叠上下文卡塔 尔(英语:State of Qatar),以此来确认保证页面成分以准确的各种合成(composite卡塔尔,那样技能科学的体现成分的交汇以至半透明成分等等。由此满意产生层叠上下文条件的 LayoutObject 一定会为其创造新的渲染层,当然还应该有此外的有的例外意况,为一些破例的 LayoutObjects 创设三个新的渲染层,比方 overflow != visible 的要素。根据成立 PaintLayer 的缘故见仁见智,能够将其分为管见所及的 3 类:

  • NormalPaintLayer
    • 根元素(HTML)
    • 有断定的一定属性(relative、fixed、sticky、absolute卡塔 尔(阿拉伯语:قطر‎
    • 透明的(opacity 小于 1)
    • 有 CSS 滤镜(fliter)
    • 有 CSS mask 属性
    • 有 CSS mix-blend-mode 属性(不为 normal)
    • 有 CSS transform 属性(不为 none)
    • backface-visibility 属性为 hidden
    • 有 CSS reflection 属性
    • 有 CSS column-count 属性(不为 auto)或者 有 CSS column-width 属性(不为 auto)
    • 脚下有对于 opacity、transform、fliter、backdrop-filter 应用动漫
  • OverflowClipPaintLayer
    • overflow 不为 visible
  • NoPaintLayer
    • 无需 paint 的 PaintLayer,比方二个未有视觉属性(背景、颜色、阴影等卡塔 尔(阿拉伯语:قطر‎的空 div。

满意以上规范的 LayoutObject 会具备独立的渲染层,而别的的 LayoutObject 则和其首先个具有渲染层的父元素共用一个。

▪ JavaScript:常常的话,我们会使用 JavaScript 来兑现部分视觉变化的机能。比如做一个卡通恐怕往页面里增多一些 DOM 成分等。

从 PaintLayers 到 GraphicsLayers

一些特殊的渲染层会被认为是合成层(Compositing Layers卡塔尔,合成层具有独立的 GraphicsLayer,而其余不是合成层的渲染层,则和其首先个颇负 GraphicsLayer 父层公用多个。

种种 GraphicsLayer 都有二个 GraphicsContext,GraphicsContext 会担负输出该层的位图,位图是积存在分享内部存款和储蓄器中,作为纹理上传到 GPU 中,最后由 GPU 将多少个位图举办合成,然后 draw 到荧屏上,那个时候,大家的页面也就呈现到了显示屏上。

渲染层提高为合成层的原故有刹那间二种:

注:渲染层提高为合成层有四个先决条件,该渲染层必须是 SelfPaintingLayer(基本可以为是上文介绍的 NormalPaintLayer卡塔 尔(阿拉伯语:قطر‎。以下所商量的渲染层提高为合成层的场合都以在该渲染层为 SelfPaintingLayer 前提下的。

  • 直接原因(direct reason卡塔 尔(阿拉伯语:قطر‎
    • 硬件加快的 iframe 成分(比如 iframe 嵌入的页面中有合成层卡塔 尔(英语:State of Qatar)demo
    • video 元素
    • 覆盖在 video 成分上的摄像调控栏
    • 3D 可能 硬件加速的 2D Canvas 成分
      • demo:普通 2D Canvas 不会晋级为合成层
      • demo:3D Canvas 进步为合成层
    • 硬件加速的插件,譬如 flash 等等
    • 在 DPI 较高的显示器上,fix 定位的要素会活动地被升高到合成层中。但在 DPI 相当的低的设施上却并非那样,因为那么些渲染层的晋升会使得字体渲染格局由子像素变为灰阶(详细内容请参见:Text Rendering)
    • 有 3D transform
    • backface-visibility 为 hidden
    • 对 opacity、transform、fliter、backdropfilter 应用了 animation 只怕 transition(要求是 active 的 animation 或然 transition,当 animation 可能 transition 效果未早先或收尾后,提高合成层也会失灵卡塔尔国
      • demo:animation
      • demo:transition图片 5
    • will-change 设置为 opacity、transform、top、left、bottom、right(此中 top、left 等需求安装醒目标定势属性,如 relative 等卡塔 尔(英语:State of Qatar)demo
  • 后人成分原因
    • 有合成层后代同有时常候自己有 transform、opactiy(小于 1卡塔 尔(阿拉伯语:قطر‎、mask、fliter、reflection 属性 demo
    • 有合成层后代同一时候自个儿 overflow 不为 visible(借使自个儿是因为肯定的固定因素发生的 SelfPaintingLayer,则必要 z-index 不为 auto卡塔 尔(阿拉伯语:قطر‎ demo
    • 有合成层后代同有时候小编 fixed 定位 demo
    • 有 3D transfrom 的合成层后代同期小编有 preserves-3d 属性 demo
    • 有 3D transfrom 的合成层后代同一时间小编有 perspective 属性 demo
  • overlap 重叠原因怎会因为重叠原因此发出合成层呢?举个轻易的栗子。图片 6青色的矩形重叠在青色矩形之上,同不平时候它们的父成分是一个GraphicsLayer。那个时候纵然深黄矩形为叁个 GraphicsLayer,假如 overlap 不大概升高合成层的话,那么中蓝矩形不会提高为合成层,也就能够和父元素公用一个GraphicsLayer。图片 7那个时候,渲染顺序就能够生出错误,由此为确认保证渲染顺序,overlap 也化为了合成层产生的原因,也正是之类的平常化境况。图片 8理之当然overlap 的原由也会细分为几类,接下去我们会详细看下。
    • 丰腴或许说部分重叠在三个合成层之上。那什么毕竟重叠呢,最广大和易于领悟的正是因素的 border box(content + padding + border卡塔 尔(阿拉伯语:قطر‎和合成层的有重叠,例如:demo,当然 margin area 的重叠是不行的(demo卡塔尔。别的的还会有风流倜傥部分不广泛的动静,也算是同合成层重叠的规格,如下:
      • filter 效果同合成层重叠 demo
      • transform 转换后同合成层重叠 demo
      • overflow scroll 情形下同合成层重叠。即假诺二个 overflow scroll(不管 overflow:auto 还是 overflow:scrill,只借使能 scroll 就能够卡塔 尔(阿拉伯语:قطر‎的因素同一个合成层重叠,则其可视子成分也同该合成层重叠 demo
    • 若是重叠在一个合成层之上(assumedOverlap卡塔 尔(英语:State of Qatar)。那几个原因听上去有一点虚,什么叫假使重叠?其实也相比较好精晓,譬如二个因素的 CSS 动画功用,动漫运转时期,成分是有相当的大希望和其余因素有重合的。针对于这种地方,于是就有了 assumedOverlap 的合成层发生原因,示例可知:demo。在本 demo 中,动漫成分视觉上并从未和其兄弟成分重叠,但因为 assumedOverlap 的来由,其兄弟成分依旧提高为了合成层。须要专心的是该原因下,有八个相当特别的景况:若是合成层有内联的 transform 属性,会导致其兄弟渲染层 assume overlap,从而升高为合成层。比如:demo。

▪ Style:总结样式,那一个进程是依附 CSS 采纳器,对各种 DOM 成分配成对应的 CSS 样式。这一步截止之后,就规定了各样 DOM 成分上该利用什么 CSS 样式准则。

层压缩

基本上附近的有的合成层的进级换代原因如上所说,你会发觉,由于重叠的来由,恐怕轻松就能够发出出大方合成层来,而种种合成层都要消耗 CPU 和内部存储器财富,岂不是严重影响页面质量。这点浏览器也思谋到了,由此就有了层压缩(Layer Squashing卡塔尔的拍卖。假设三个渲染层同八个合成层重叠时,这一个渲染层会被裁减到叁个GraphicsLayer 中,避防范由于重叠原因促成可能出现的“层爆炸”。具体能够看如下 demo。生龙活虎开端,黄绿方块由于
translateZ 提高为了合成层,其余的方框成分因为重叠的缘故,被裁减了伙同,大小便是带有这3 个方块的矩形大小。

图片 9

当我们 hover 清水蓝方块时,会给其安装 translateZ 属性,招致石磨蓝方块也被进级为合成层,则剩下的三个被减去到了三头,大小就收缩为含有这2 个方块的矩形大小。

图片 10

当然,浏览器的自行的层压缩亦不是才疏意广的,有超多特定情景下,浏览器是无可奈何打开层压缩的,如下所示,而这几个情况也是我们相应尽量防止的。(注:以下处境都以基于重叠原因此言卡塔 尔(阿拉伯语:قطر‎

  • 不能进展览会打破渲染顺序的滑坡(squashingWouldBreakPaintOrder卡塔 尔(英语:State of Qatar)示比方下:demo
CSS

#ancestor { -webkit-mask-image:
-webkit-linear-gradient(rgba(0,0,0,1), rgba(0,0,0,0)); }
#composited { width: 100%; height: 100%; transform: translateZ(0);
} #container { position: relative; width: 400px; height: 60px;
border: 1px solid black; } #overlap-child { position: absolute;
left: 0; top: 0 ; bottom: 0px; width: 100%; height: 60px;
background-color: orange; }

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6d201886f149137440-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d201886f149137440-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f6d201886f149137440-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d201886f149137440-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f6d201886f149137440-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d201886f149137440-6">
6
</div>
<div class="crayon-num" data-line="crayon-5b8f6d201886f149137440-7">
7
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d201886f149137440-8">
8
</div>
<div class="crayon-num" data-line="crayon-5b8f6d201886f149137440-9">
9
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d201886f149137440-10">
10
</div>
<div class="crayon-num" data-line="crayon-5b8f6d201886f149137440-11">
11
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d201886f149137440-12">
12
</div>
<div class="crayon-num" data-line="crayon-5b8f6d201886f149137440-13">
13
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d201886f149137440-14">
14
</div>
<div class="crayon-num" data-line="crayon-5b8f6d201886f149137440-15">
15
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d201886f149137440-16">
16
</div>
<div class="crayon-num" data-line="crayon-5b8f6d201886f149137440-17">
17
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d201886f149137440-18">
18
</div>
<div class="crayon-num" data-line="crayon-5b8f6d201886f149137440-19">
19
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d201886f149137440-20">
20
</div>
<div class="crayon-num" data-line="crayon-5b8f6d201886f149137440-21">
21
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d201886f149137440-22">
22
</div>
<div class="crayon-num" data-line="crayon-5b8f6d201886f149137440-23">
23
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d201886f149137440-24">
24
</div>
<div class="crayon-num" data-line="crayon-5b8f6d201886f149137440-25">
25
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d201886f149137440-26">
26
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6d201886f149137440-1" class="crayon-line">
  #ancestor {
</div>
<div id="crayon-5b8f6d201886f149137440-2" class="crayon-line crayon-striped-line">
    -webkit-mask-image: -webkit-linear-gradient(rgba(0,0,0,1), rgba(0,0,0,0));
</div>
<div id="crayon-5b8f6d201886f149137440-3" class="crayon-line">
  }
</div>
<div id="crayon-5b8f6d201886f149137440-4" class="crayon-line crayon-striped-line">
  
</div>
<div id="crayon-5b8f6d201886f149137440-5" class="crayon-line">
  #composited {
</div>
<div id="crayon-5b8f6d201886f149137440-6" class="crayon-line crayon-striped-line">
    width: 100%;
</div>
<div id="crayon-5b8f6d201886f149137440-7" class="crayon-line">
    height: 100%;
</div>
<div id="crayon-5b8f6d201886f149137440-8" class="crayon-line crayon-striped-line">
    transform: translateZ(0);
</div>
<div id="crayon-5b8f6d201886f149137440-9" class="crayon-line">
  }
</div>
<div id="crayon-5b8f6d201886f149137440-10" class="crayon-line crayon-striped-line">
 
</div>
<div id="crayon-5b8f6d201886f149137440-11" class="crayon-line">
  #container {
</div>
<div id="crayon-5b8f6d201886f149137440-12" class="crayon-line crayon-striped-line">
    position: relative;
</div>
<div id="crayon-5b8f6d201886f149137440-13" class="crayon-line">
    width: 400px;
</div>
<div id="crayon-5b8f6d201886f149137440-14" class="crayon-line crayon-striped-line">
    height: 60px;
</div>
<div id="crayon-5b8f6d201886f149137440-15" class="crayon-line">
    border: 1px solid black;
</div>
<div id="crayon-5b8f6d201886f149137440-16" class="crayon-line crayon-striped-line">
  }
</div>
<div id="crayon-5b8f6d201886f149137440-17" class="crayon-line">
 
</div>
<div id="crayon-5b8f6d201886f149137440-18" class="crayon-line crayon-striped-line">
  #overlap-child {
</div>
<div id="crayon-5b8f6d201886f149137440-19" class="crayon-line">
    position: absolute;
</div>
<div id="crayon-5b8f6d201886f149137440-20" class="crayon-line crayon-striped-line">
    left: 0;
</div>
<div id="crayon-5b8f6d201886f149137440-21" class="crayon-line">
    top: 0 ;
</div>
<div id="crayon-5b8f6d201886f149137440-22" class="crayon-line crayon-striped-line">
    bottom: 0px;
</div>
<div id="crayon-5b8f6d201886f149137440-23" class="crayon-line">
    width: 100%;
</div>
<div id="crayon-5b8f6d201886f149137440-24" class="crayon-line crayon-striped-line">
    height: 60px;
</div>
<div id="crayon-5b8f6d201886f149137440-25" class="crayon-line">
    background-color: orange;
</div>
<div id="crayon-5b8f6d201886f149137440-26" class="crayon-line crayon-striped-line">
  }
</div>
</div></td>
</tr>
</tbody>
</table>




XHTML

&lt;div id="container"&gt; &lt;div id="composited"&gt;Text behind
the orange box.&lt;/div&gt; &lt;div id="ancestor"&gt; &lt;div
id="overlap-child"&gt;&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6d201887b075031864-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d201887b075031864-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f6d201887b075031864-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d201887b075031864-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f6d201887b075031864-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d201887b075031864-6">
6
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6d201887b075031864-1" class="crayon-line">
&lt;div id=&quot;container&quot;&gt;
</div>
<div id="crayon-5b8f6d201887b075031864-2" class="crayon-line crayon-striped-line">
  &lt;div id=&quot;composited&quot;&gt;Text behind the orange box.&lt;/div&gt;
</div>
<div id="crayon-5b8f6d201887b075031864-3" class="crayon-line">
  &lt;div id=&quot;ancestor&quot;&gt;
</div>
<div id="crayon-5b8f6d201887b075031864-4" class="crayon-line crayon-striped-line">
    &lt;div id=&quot;overlap-child&quot;&gt;&lt;/div&gt;
</div>
<div id="crayon-5b8f6d201887b075031864-5" class="crayon-line">
  &lt;/div&gt;
</div>
<div id="crayon-5b8f6d201887b075031864-6" class="crayon-line crayon-striped-line">
&lt;/div&gt;
</div>
</div></td>
</tr>
</tbody>
</table>
  • video 元素的渲染层十分的小概被裁减同一时候也无从将其他渲染层压缩到 video 所在的合成层上(squashingVideoIsDisallowed卡塔 尔(英语:State of Qatar)demo
  • iframe、plugin 的渲染层无法被减少同临时候也无从将其他渲染层压缩到其所在的合成层上(squashingLayoutPartIsDisallowed卡塔 尔(英语:State of Qatar)demo
  • 无能为力回降有 reflection 属性的渲染层(squashingReflectionDisallowed卡塔尔国demo
  • 没辙回退有 blend mode 属性的渲染层(squashingBlendingDisallowed卡塔 尔(阿拉伯语:قطر‎demo
  • 当渲染层同合成层有差异的剪裁容器(clipping container卡塔尔时,该渲染层不能回降(squashingClippingContainerMismatch卡塔尔国。示例如下:demo
CSS

.clipping-container { overflow: hidden; height: 10px;
background-color: blue; } .composited { transform: translateZ(0);
height: 10px; background-color: red; } .target { position:absolute;
top: 0px; height:100px; width:100px; background-color: green; color:
#fff; }

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6d2018880297868155-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d2018880297868155-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f6d2018880297868155-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d2018880297868155-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f6d2018880297868155-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d2018880297868155-6">
6
</div>
<div class="crayon-num" data-line="crayon-5b8f6d2018880297868155-7">
7
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d2018880297868155-8">
8
</div>
<div class="crayon-num" data-line="crayon-5b8f6d2018880297868155-9">
9
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d2018880297868155-10">
10
</div>
<div class="crayon-num" data-line="crayon-5b8f6d2018880297868155-11">
11
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d2018880297868155-12">
12
</div>
<div class="crayon-num" data-line="crayon-5b8f6d2018880297868155-13">
13
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d2018880297868155-14">
14
</div>
<div class="crayon-num" data-line="crayon-5b8f6d2018880297868155-15">
15
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d2018880297868155-16">
16
</div>
<div class="crayon-num" data-line="crayon-5b8f6d2018880297868155-17">
17
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d2018880297868155-18">
18
</div>
<div class="crayon-num" data-line="crayon-5b8f6d2018880297868155-19">
19
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d2018880297868155-20">
20
</div>
<div class="crayon-num" data-line="crayon-5b8f6d2018880297868155-21">
21
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d2018880297868155-22">
22
</div>
<div class="crayon-num" data-line="crayon-5b8f6d2018880297868155-23">
23
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6d2018880297868155-1" class="crayon-line">
.clipping-container {
</div>
<div id="crayon-5b8f6d2018880297868155-2" class="crayon-line crayon-striped-line">
 
</div>
<div id="crayon-5b8f6d2018880297868155-3" class="crayon-line">
    overflow: hidden;
</div>
<div id="crayon-5b8f6d2018880297868155-4" class="crayon-line crayon-striped-line">
    height: 10px; 
</div>
<div id="crayon-5b8f6d2018880297868155-5" class="crayon-line">
    background-color: blue;
</div>
<div id="crayon-5b8f6d2018880297868155-6" class="crayon-line crayon-striped-line">
  }
</div>
<div id="crayon-5b8f6d2018880297868155-7" class="crayon-line">
 
</div>
<div id="crayon-5b8f6d2018880297868155-8" class="crayon-line crayon-striped-line">
  .composited {
</div>
<div id="crayon-5b8f6d2018880297868155-9" class="crayon-line">
 
</div>
<div id="crayon-5b8f6d2018880297868155-10" class="crayon-line crayon-striped-line">
    transform: translateZ(0); 
</div>
<div id="crayon-5b8f6d2018880297868155-11" class="crayon-line">
    height: 10px; 
</div>
<div id="crayon-5b8f6d2018880297868155-12" class="crayon-line crayon-striped-line">
    background-color: red;
</div>
<div id="crayon-5b8f6d2018880297868155-13" class="crayon-line">
  }
</div>
<div id="crayon-5b8f6d2018880297868155-14" class="crayon-line crayon-striped-line">
 
</div>
<div id="crayon-5b8f6d2018880297868155-15" class="crayon-line">
  .target {
</div>
<div id="crayon-5b8f6d2018880297868155-16" class="crayon-line crayon-striped-line">
 
</div>
<div id="crayon-5b8f6d2018880297868155-17" class="crayon-line">
    position:absolute; 
</div>
<div id="crayon-5b8f6d2018880297868155-18" class="crayon-line crayon-striped-line">
    top: 0px; 
</div>
<div id="crayon-5b8f6d2018880297868155-19" class="crayon-line">
    height:100px; 
</div>
<div id="crayon-5b8f6d2018880297868155-20" class="crayon-line crayon-striped-line">
    width:100px; 
</div>
<div id="crayon-5b8f6d2018880297868155-21" class="crayon-line">
    background-color: green;
</div>
<div id="crayon-5b8f6d2018880297868155-22" class="crayon-line crayon-striped-line">
    color: #fff;
</div>
<div id="crayon-5b8f6d2018880297868155-23" class="crayon-line">
  }
</div>
</div></td>
</tr>
</tbody>
</table>




XHTML

&lt;div class="clipping-container"&gt; &lt;div
class="composited"&gt;&lt;/div&gt; &lt;/div&gt; &lt;div
class="target"&gt;不会被压缩到 composited div 上&lt;/div&gt;

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6d2018884301689224-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d2018884301689224-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f6d2018884301689224-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d2018884301689224-4">
4
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6d2018884301689224-1" class="crayon-line">
&lt;div class=&quot;clipping-container&quot;&gt;
</div>
<div id="crayon-5b8f6d2018884301689224-2" class="crayon-line crayon-striped-line">
  &lt;div class=&quot;composited&quot;&gt;&lt;/div&gt;
</div>
<div id="crayon-5b8f6d2018884301689224-3" class="crayon-line">
&lt;/div&gt;
</div>
<div id="crayon-5b8f6d2018884301689224-4" class="crayon-line crayon-striped-line">
&lt;div class=&quot;target&quot;&gt;不会被压缩到 composited div 上&lt;/div&gt;
</div>
</div></td>
</tr>
</tbody>
</table>


本例中 .target 同 合成层 `.composited` 重叠,但是由于
.composited`在一个 overflow: hidden 的容器中,导致 .target 和合成层有不同的裁剪容器,从而 `.target` 无法被压缩。`
  • 相对于合成层滚动的渲染层无法被核减(scrollsWithRespectToSquashingLayer卡塔尔国示举个例子下:demo

CSS

body { height: 1500px; overflow-x: hidden; } .composited { width: 50px; height: 50px; background-color: red; position: absolute; left: 50px; top: 400px; transform: translateZ(0); } .overlap { width: 200px; height: 200px; background-color: green; position: fixed; left: 0px; top: 0px; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
body {
    height: 1500px;
    overflow-x: hidden;
  }
 
  .composited {
 
    width: 50px;
    height: 50px;
    background-color: red;
    position: absolute;
    left: 50px;
    top: 400px;
    transform: translateZ(0);
  }
 
  .overlap {
    width: 200px;
    height: 200px;
    background-color: green;
    position: fixed;
    left: 0px;
    top: 0px;
  }

XHTML

<div class="composited"></div> <div class="overlap"></div>

1
2
<div class="composited"></div>
<div class="overlap"></div>

本例中,红色的 .composited提升为了合成层,绿色的.overlapfix 在页面顶部,一开始只有.composited合成层。

![]()

当滑动页面,.overlap重叠到.composited上时,.overlap` 会因重叠原因升高为合成层,同期,因为相对于合成层滚动,因而不可能被减去。

![]()

  • 当渲染层同合成层有两样的装有 opacity 的祖先层(一个装置了 opacity 且小于 1,三个不曾设置 opacity,也终于分裂卡塔 尔(阿拉伯语:قطر‎时,该渲染层不可能回退(squashingOpacityAncestorMismatch,同 squashingClippingContainerMismatch卡塔 尔(阿拉伯语:قطر‎demo
  • 当渲染层同合成层有例外的富有 transform 的上代层时,该渲染层相当小概回退(squashingTransformAncestorMismatch,同上卡塔尔国 demo
  • 当渲染层同合成层有两样的装有 filter 的上代层时,该渲染层不大概回退(squashingFilterAncestorMismatch,同上卡塔 尔(阿拉伯语:قطر‎demo
  • 当覆盖的合成层正在周转动漫时,该渲染层无法回退(squashingLayerIsAnimating卡塔 尔(阿拉伯语:قطر‎,当动漫未起先依旧运维达成之后,该渲染层才足以被压缩 demo图片 11

▪ Layout:布局,上一步鲜明了每种 DOM 成分的样式法规,这一步便是切实地度量算各个 DOM 成分最终在显示屏上出示的大大小小和职务。web 页面瓜时素的布局是绝没有错,由此三个成分的布局发生变化,会联合浮动地抓住别的因素的布局发生变化。比方, 成分的肥瘦的改换会潜移暗化其子成分的肥瘦,其子元素宽度的变迁也会继续对其儿子成分爆发影响。由此对此浏览器来说,布局进度是常事产生的。

怎么着查看合成层

运用 Chrome DevTools 工具来查看页面中合成层的情事。

比较轻巧的不二等秘书技是展开 DevTools,勾选上 Show layer borders

图片 12

中间,页面上的合成层会用淡绿边框框出来。

图片 13

自然,特别详细的音信能够透过 Timeline 来查阅。

每三个独自的帧,见到各种帧的渲染细节:

图片 14

点击之后,你就能够在视图中看出一个新的选项卡:Layers。

图片 15

点击这几个 Layers 选项卡,你会看见三个新的视图。在这里个视图中,你能够对这一帧中的全数合成层进行围观、缩放等操作,同期还是可以看见种种渲染层被创建的来头。

图片 16

有了这一个视图,你就会精通页面中终究有稍许个合成层。若是您在对页面滚动或渐变效果的习性分析中窥见 Composite 进程花销了太多时间,那么您能够从那个视图里观察页面中有稍许个渲染层,它们为啥被创设,进而对合成层的多寡实行优化。

▪ Paint:绘制,本质上正是填充像素的进度。包罗绘制文字、颜色、图像、边框和阴影等,约等于二个DOM 成分全数的可视效果。平日的话,这一个绘制进程是在多少个层上到位的。

天性优化

提拔为合成层简单说来有以下几点好处:

  • 合成层的位图,会交由 GPU 合成,比 CPU 管理要快
  • 当须要 repaint 时,只供给 repaint 自个儿,不会影响到其余的层
  • 对此 transform 和 opacity 效果,不会触发 layout 和 paint

动用合成层对于晋级页面质量方面有极大的机能,因而大家也总括了生龙活虎晃几点优化提议。

▪ Composite:渲染层合併,由上一步可见,对页面中 DOM 成分的绘图是在三个层上海展览中心开的。在各样层上到位绘制进程之后,浏览器会将全体层依据合理的顺序归并成三个图层,然后彰显在荧屏上。对于有职位重叠的因素的页面,那些进度更是着重,因为要是图层的统黄金时代顺序出错,将会促成元素展现至极。

晋级动画效果的要素

合成层的好处是不会影响到任何因素的绘图,因而,为了减小动漫成分对任何因素的影响,进而降低paint,大家要求把动漫效果中的成分进步为合成层。

进级合成层的最佳法子是采取 CSS 的 will-change 属性。从上生龙活虎节合成层发生原因中,能够清楚 will-change 设置为 opacity、transform、top、left、bottom、right 能够将成分进步为合成层。

CSS

#target { will-change: transform; }

1
2
3
#target {
  will-change: transform;
}

其合营如下所示:
图片 17

对于那几个近些日子还不帮助 will-change 属性的浏览器,近些日子常用的是使用三个 3D transform 属性来强制升高为合成层:

CSS

#target { transform: translateZ(0); }

1
2
3
#target {
  transform: translateZ(0);
}

但须要潜心的是,不要成立太多的渲染层。因为每创造二个新的渲染层,就表示新的内部存储器分配和更目迷五色的层的保管。之后咱们会详细钻探。

如若您早已把一个要素放到二个新的合成层里,那么能够使用 提姆eline 来确认这么做是还是不是确实改革了渲染质量。别盲目提高合成层,必定要剖判其实际质量表现。

自然,本文我们只来关怀 Composite 部分。

使用 transform 恐怕 opacity 来达成动画效果

文章最开始,大家讲到了页面展现出来所经历的渲染流水生产线,其实从品质方面思谋,最优越的渲染流水生产线是未有布局和制图环节的,只要求做合成层的统生龙活虎就能够:

图片 18

为了落到实处上述功效,就供给只使用这几个仅触发 Composite 的品质。近期,唯有三个天性是满意那个规范的:transforms 和 opacity。更详细的音讯方可查看 CSS Triggers。

瞩目:成分进步为合成层后,transform 和 opacity 才不会触发 paint,如果不是合成层,则其依旧会触发 paint。具体见如下四个 demo。

  • demo 1:transform图片 19
  • demo 2:opacity图片 20

能够观察未晋级 target element 为合成层,transform 和 opacity 依旧会触发 paint。

在评论 Composite 早先,有不可缺乏先简单了然下一些浏览器(本文只是针对性 Chrome 来讲卡塔 尔(英语:State of Qatar)的渲染原理,方便对现在有的概念的知道。越来越多详细的剧情能够参照 GPU Accelerated Compositing in Chrome

减掉绘制区域

对此无需再行绘制的区域应尽量制止绘制,以降低绘制区域,比方多个 fix 在页面最上部的定势不改变的导航 header,在页面内容某个区域 repaint 时,整个显示器包蕴 fix 的 header 也会被重绘,见 demo,结果如下:

图片 21

而对此一直不改变的区域,我们愿意其并不会被重绘,因而能够因那一件事先的章程,将其晋级为单身的合成层。

裁减绘制区域,要求精心分析页面,区分绘制区域,收缩重绘区域以至制止重绘。

注:由于 Chrome 对 Blank 引擎有个别达成的退换,有些大家从前了解的类名有了改换,举例 RenderObject 形成了 LayoutObject,RenderLayer 变成了 PaintLayer。感兴趣的看以参阅 Slimming Paint。

创造管理合成层

看完下面的文章,你会开采进步合成层会落得更加好的天性。那看起来十三分迷人,不过难点是,创立贰个新的合成层并非免费的,它得消耗额外的内部存款和储蓄器和管理财富。实际上,在内部存款和储蓄器财富有限的装置上,合成层带给的性格改过,大概远远赶不上过多合成层花费给页面质量带来的不好的一面影响。同有时候,由于种种渲染层的纹理都亟需上盛传 GPU 处理,因而大家还要求考虑 CPU 和 GPU 之间的带宽难点、以至有多大内部存款和储蓄器供 GPU 管理这个纹理的难题。

对此合成层占用内存的难点,大家简要做了多少个 demo 实行了求证。

demo 1 和 demo 2 中,会创建 贰零零零 个雷同的 div 成分,分化的是 demo 2 中的成分通过 will-change 都升高为了合成层,而多个 demo 页面的内部存款和储蓄器消耗却有很显著的反差。

图片 22

在浏览器中,页面内容是储存为由 Node 对象组成的树状结构,也正是 DOM 树。每一个 HTML element 成分都有多个 Node 对象与之对应,DOM 树的根节点长久都以 Document Node。这点亲信我们都很熟练了,但实则,从 DOM 树到最终的渲染,需求开展局地转变映射。

严防层爆炸

由那件事先的介绍,大家驾驭同合成层重叠也会使成分进步为合成层,纵然有浏览器的层压压编制,不过也可能有大多不能打开裁减的场所。也正是说除了大家显式的宣示的合成层,还大概由于重叠原因不经意间爆发局地不在预期的合成层,极端一点大概会时有产生大批量的额外合成层,现身层爆炸的景观。大家大约写了一个极端点但实际上在我们的页面中相比较宽泛的 demo。

CSS

@-webkit-keyframes slide { from { transform: none; } to { transform: translateX(100px); } } .animating { width: 300px; height: 30px; background-color: orange; color: #fff; -webkit-animation: slide 5s alternate linear infinite; } ul { padding: 5px; border: 1px solid #000; } .box { width: 600px; height: 30px; margin-bottom: 5px; background-color: blue; color: #fff; position: relative; /* 会导致不能回退:squashingClippingContainerMismatch */ overflow: hidden; } .inner { position: absolute; top: 2px; left: 2px; font-size: 16px; line-height: 16px; padding: 2px; margin: 0; background-color: green; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
@-webkit-keyframes slide {
    from { transform: none; }
    to { transform: translateX(100px); }
    }
    .animating {
    
    width: 300px;
    height: 30px;
    background-color: orange;
    color: #fff;
      -webkit-animation: slide 5s alternate linear infinite;
    }
 
  ul {
 
    padding: 5px;
    border: 1px solid #000;
  }
 
    .box {
 
    width: 600px;
    height: 30px;
    margin-bottom: 5px;
    background-color: blue;
    color: #fff;
    position: relative;
    /* 会导致无法压缩:squashingClippingContainerMismatch */
    overflow: hidden;
    }
 
    .inner {
      position: absolute;
      top: 2px;
      left: 2px;
      font-size: 16px;
      line-height: 16px;
      padding: 2px;
      margin: 0;
      background-color: green;
    }

XHTML

<!-- 动漫合成层 --> <div class="animating">composited animating</div> <ul> <!-- assume overlap --> <li class="box"> <!-- assume overlap --> <p class="inner">asume overlap, 因为 squashingClippingContainerMismatch 不可能回降</p> </li> ... </ul>

1
2
3
4
5
6
7
8
9
10
11
<!-- 动画合成层 -->
<div class="animating">composited animating</div>
<ul>
  <!-- assume overlap -->
  <li class="box">
    <!-- assume overlap -->
    <p class="inner">asume overlap, 因为 squashingClippingContainerMismatch 无法压缩</p>
  </li>
  
  ...
</ul>

demo 中,.animating 的合成层在运作动漫,会产生 .inner 成分因为上文介绍过的 assumedOverlap 的因由,而被进级为合成层,同期,.inner 的父成分 .box 设置了 overflow: hidden,导致 .inner 的合成层因为 squashingClippingContainerMismatch 的缘故,不能够回降,就现身了层爆炸的主题素材。

图片 23

这种场馆平日在大家的事体中依旧很广泛的,比方 slider + list 的组织,大器晚成旦满意了不可能张开层压缩的景况,就相当的轻便现身层爆炸的标题。

解决层爆炸的主题素材,最棒方案是打破 overlap 的尺码,相当于说让此外因素不要和合成层元素重叠。对于上述的演示,我们得以将 .animation 的 z-index 提高。修改后 demo

CSS

.animating { ... /* 让此外因素不和合成层重叠 */ position: relative; z-index: 1; }

1
2
3
4
5
6
7
.animating {
  
  ...
  /* 让其他元素不和合成层重叠 */
  position: relative;
  z-index: 1;
}

此时,就只有 .animating 进步为合成层,如下:

图片 24

还要,内部存款和储蓄器占用相比前面也大跌了重重。

图片 25

比方受限于视觉需求等因素,其余因素应当要覆盖在合成层之上,那应该尽量制止不恐怕层压缩意况的面世。针对上述示范中,不大概层压缩的情事(squashingClippingContainerMismatch卡塔尔国,我们可以将 .boxoverflow: hidden 去掉,那样就能够运用浏览器的层压缩了。修改后 demo

这会儿,由于第一个 .box 因为 squashingLayerIsAnimating 的案由不能回退,其余的都被裁减到了风流洒脱道。

图片 26

再正是,内部存款和储蓄器占用比较早前也下落了广大。

图片 27

图片 28

最后

从前有线支付时,大多数人都相当的慢乐使用 translateZ(0) 来开展所谓的硬件加快,以晋级质量,不过品质优化并从未所谓的“银弹”,translateZ(0) 不是,本文列出的优化建议亦非。抛开了对页面包车型地铁具体深入分析,任何的性质优化都以站不住脚的,盲目标行使部分优化措施,结果或者会节外生枝。因而具体的去分析页面包车型地铁其实质量表现,不断的修改测量试验,才是不易的优化渠道。

DOM 树中得每一种 Node 节点皆有二个对应的 LayoutObject 。LayoutObject 知道怎么在显示屏上 paint Node 的剧情。

参考

  • PaintLayer.h
  • PaintLayer.cpp
  • CompositingReasons.cpp
  • CompositingReasons.h
  • CompositingRequirementsUpdater.cpp
  • chrome layout test
  • Slimming Paint
  • The stacking contest
  • Blink Compositing Update: Recap and Squashing
  • GPU Accelerated Compositing in Chrome
  • CSS Triggers
  • google render performance

    1 赞 6 收藏 评论

图片 29

诚如的话,具备同等的坐标空间的 LayoutObjects,归属同五个渲染层(PaintLayer卡塔 尔(英语:State of Qatar)。PaintLayer 最早是用来达成stacking contest,以此来保障页面成分以精确的顺序合成(composite卡塔尔,那样本领科学的体现成分的重合以致半透明元素等等。由此满意形成层叠上下文条件的 LayoutObject 一定会为其成立新的渲染层,当然还也有别的的生机勃勃对非凡情形,为一些非常的 LayoutObjects 创制一个新的渲染层,举例 overflow != visible 的成分。依据创设 PaintLayer 的来由莫衷一是,能够将其分成不可胜计的 3 类:

▪ NormalPaintLayer

根元素

有水落石出的一定属性(relative、fixed、sticky、absolute卡塔 尔(阿拉伯语:قطر‎

透明的(opacity 小于 1)

有 CSS 滤镜

有 CSS mask 属性

有 CSS mix-blend-mode 属性(不为 normal)

有 CSS transform 属性

backface-visibility 属性为 hidden

有 CSS reflection 属性

有 CSS column-count 属性也许 有 CSS column-width 属性

时下有对于 opacity、transform、fliter、backdrop-filter 应用动漫

▪ OverflowClipPaintLayer

overflow 不为 visible

▪ NoPaintLayer

没有必要 paint 的 PaintLayer,比方一个未曾视觉属性(背景、颜色、阴影等卡塔 尔(阿拉伯语:قطر‎的空 div。

满足上述典型的 LayoutObject 会具有独立的渲染层,而其余的 LayoutObject 则和其首先个具有渲染层的父成分共用几个。

有些特殊的渲染层会被以为是合成层(Compositing Layers卡塔尔,合成层具有独立的 GraphicsLayer,而任何不是合成层的渲染层,则和其首先个具备 GraphicsLayer 父层公用一个。

每种 GraphicsLayer 皆有叁个 GraphicsContext,GraphicsContext 会担负输出该层的位图,位图是积攒在分享内部存储器中,作为纹理上传到 GPU 中,最终由 GPU 将七个位图举行合成,然后 draw 到显示器上,当时,大家的页面也就展现到了显示器上。

渲染层进步为合成层的开始和结果有刹那间二种:

注:渲染层提高为合成层有三个先决条件,该渲染层必得是 SelfPaintingLayer(基本可以为是上文介绍的 NormalPaintLayer卡塔 尔(英语:State of Qatar)。以下所斟酌的渲染层升高为合成层的景况都是在该渲染层为 SelfPaintingLayer 前提下的。

▪ 直接原因(direct reason卡塔尔

硬件加快的 iframe 成分(比方 iframe 嵌入的页面中有合成层卡塔尔国demo

video 元素

蒙面在 video 成分上的录像调控栏

3D 或然 硬件加快的 2D Canvas 成分

demo:普通 2D Canvas 不会晋级为合成层

demo:3D Canvas 进步为合成层

硬件加快的插件,比如 flash 等等

在 DPI 较高的显示屏上,fix 定位的要素会自行地被进步到合成层中。但在 DPI 非常的低的设备上却并不是那样,因为那几个渲染层的升官会使得字体渲染方式由子像素变为灰阶(详细内容请参见:Text Rendering卡塔尔国

有 3D transform

backface-visibility 为 hidden

对 opacity、transform、fliter、backdropfilter 应用了 animation 也许transition(需若是 active 的 animation 或然 transition,当 animation 只怕 transition 效果未初步或结束后,升高合成层也会失灵卡塔 尔(阿拉伯语:قطر‎

demo:animation

demo:transition

图片 30

will-change 设置为 opacity、transform、top、left、bottom、right(其中top、left 等供给安装醒指标原则性属性,如 relative 等卡塔 尔(阿拉伯语:قطر‎demo

▪ 后代成分原因

有合成层后代同一时间小编有 transform、opactiy、mask、fliter、reflection 属性 demo

有合成层后代同时本人 overflow 不为 visible(假如笔者是因为分明的固化因素产生的 SelfPaintingLayer,则必要z-index 不为 auto卡塔尔国 demo

有合成层后代同期笔者 fixed 定位 demo

有 3D transfrom 的合成层后代同一时候小编有 preserves-3d 属性 demo

有 3D transfrom 的合成层后代同一时间作者有 perspective 属性 demo

▪ overlap 重叠原因

怎会因为重叠原因此暴发合成层呢?举个大约的尖栗。

图片 31

黄铜色的矩形重叠在黑灰矩形之上,同期它们的父成分是一个GraphicsLayer。那时候只要影青矩形为一个 GraphicsLayer,假若 overlap 不可能进级合成层的话,那么中蓝矩形不会晋级为合成层,也就能够和父成分公用一个GraphicsLayer。

图片 32

那会儿,渲染顺序就能够时有产生错误,由此为保险渲染顺序,overlap 也造成了合成层产生的自始至终的经过,也正是之类的正规意况。

图片 33

自然 overlap 的来由也会细分为几类,接下去大家会详细看下。

痴肥或许说部分重叠在多少个合成层之上。

那怎么着毕竟重叠呢,最常见和轻巧理解的就是因素的 border box(content + padding + border卡塔尔 和合成层的有肥壮,举个例子:demo,当然 margin area 的交汇是没用的。其余的还应该有风姿浪漫部分不广泛的意况,也终于同合成层重叠的标准,如下:

filter 效果同合成层重叠 demo

transform 转换后同合成层重叠 demo

overflow scroll 景况下同合成层重叠。即假使三个 overflow scroll(不管 overflow:auto 还是 overflow:scrill,只若是能 scroll 就能够卡塔尔国的因素同五个合成层重叠,则其可视子成分也同该合成层重叠 demo

只要重叠在叁个合成层之上(assumedOverlap卡塔 尔(英语:State of Qatar)。

那个原因听起来有一些虚,什么叫假如重叠?其实也比较好了然,举个例子一个因素的 CSS 动漫成效,动漫运维时期,成分是有极大概率和别的因素有重合的。针对于这种意况,于是就有了 assumedOverlap 的合成层发生原因,示例可知:demo。在本 demo 中,动漫成分视觉上并从未和其兄弟成分重叠,但因为 assumedOverlap 的缘由,其兄弟成分依旧提高为了合成层。

急需留意的是该原因下,有四个很独特的情景:

假设合成层有内联的 transform 属性,会促成其兄弟渲染层 assume overlap,进而晋级为合成层。比如:demo。

层压缩

基本下相近的一些合成层的晋升原因如上所说,你会意识,由于重叠的开始和结果,恐怕Infiniti定就能生出出大批量合成层来,而各类合成层都要花销CPU 和内存能源,岂不是严重影响页面品质。那或多或少浏览器也思虑到了,因而就有了层压缩(Layer Squashing卡塔尔的拍卖。假使四个渲染层同二个合成层重叠时,那几个渲染层会被压缩到一个GraphicsLayer 中,以免御出于重叠原因招致也许现身的“层爆炸”。具体能够看如下 demo。一同首,玉海蓝方块由于

translateZ 升高为了合成层,其余的方框成分因为重叠的由来,被减去了协同,大小便是带有这3 个方块的矩形大小。

图片 34

当大家 hover 土灰方块时,会给其设置 translateZ 属性,招致铅白方块也被提高为合成层,则剩下的多少个被削减到了伙同,大小就减少为含有这2 个方块的矩形大小。

图片 35

理所必然,浏览器的自动的层压缩亦非才高行洁的,有众多一定情景下,浏览器是心余力绌开展层压缩的,如下所示,而那些情况也是大家理应尽量防止的。(注:以下情况都以基于重叠原由此言卡塔尔

▪ 不可能实行会打破渲染顺序的削减(squashingWouldBreakPaintOrder卡塔 尔(英语:State of Qatar)

图片 36图片 37图片 38

▪ video 成分的渲染层不能够被核减同不常候也无可奈何将别的渲染层压缩到 video 所在的合成层上(squashingVideoIsDisallowed卡塔 尔(英语:State of Qatar)demo

▪ iframe、plugin 的渲染层不可能被缩小同有时候也力不可能及将其余渲染层压缩到其所在的合成层上(squashingLayoutPartIsDisallowed卡塔尔国demo

▪ 不能回退有 reflection 属性的渲染层(squashingReflectionDisallowed卡塔尔demo

▪ 不能够回降有 blend mode 属性的渲染层(squashingBlendingDisallowed卡塔尔国demo

▪ 当渲染层同合成层有差别的剪裁容器(clipping container卡塔 尔(阿拉伯语:قطر‎时,该渲染层不能回降(squashingClippingContainerMismatch卡塔 尔(英语:State of Qatar)。

图片 39图片 40图片 41

▪ 相对于合成层滚动的渲染层无法被压缩(scrollsWithRespectToSquashingLayer卡塔 尔(阿拉伯语:قطر‎

图片 42图片 43图片 44

▪ 当渲染层同合成层有分裂的持有 opacity 的祖先层(三个装置了 opacity 且低于 1,三个不曾安装 opacity,也究竟分裂卡塔 尔(英语:State of Qatar)时,该渲染层无法回降(squashingOpacityAncestorMismatch,同 squashingClippingContainerMismatch卡塔 尔(阿拉伯语:قطر‎demo

▪ 当渲染层同合成层有例外的全部 transform 的古人层时,该渲染层不能够回退(squashingTransformAncestorMismatch,同上卡塔尔demo

▪ 当渲染层同合成层有两样的持有 filter 的祖先层时,该渲染层不能够回退(squashingFilterAncestorMismatch,同上卡塔尔demo

▪ 当覆盖的合成层正在运行动漫时,该渲染层不可能回退(squashingLayerIsAnimating卡塔 尔(阿拉伯语:قطر‎,当动画未初叶依然运营实现之后,该渲染层才方可被削减demo

图片 45

行使 Chrome DevTools 工具来查阅页面中合成层的事态。

比较轻松的法子是开垦 DevTools,勾选上 Show layer borders

图片 46

里头,页面上的合成层会用浅橙边框框出来。

图片 47

理所必然,越发详实的音讯方可由此 Timeline 来查阅。

每一个单身的帧,看见各样帧的渲染细节:

图片 48

点击之后,你就能在视图中见到多少个新的选项卡:Layers。

图片 49

点击这些 Layers 选项卡,你拜访到叁个新的视图。在这里个视图中,你能够对那生龙活虎帧中的全数合成层举办扫描、缩放等操作,同有的时候候还是能够观察各类渲染层被成立的原因。

图片 50

有了那一个视图,你就能够精晓页面中到底有微微个合成层。如若你在对页面滚动或渐变效果的质量剖析中发觉 Composite 进程耗费了太多日子,那么你能够从那一个视图里见到页面中有微微个渲染层,它们为什么被创设,从而对合成层的多寡举办优化。

进级为合成层轻易说来有以下几点好处:

▪ 合成层的位图,会交由 GPU 合成,比 CPU 管理要快

▪ 当必要 repaint 时,只须要 repaint 自己,不会影响到此外的层

▪ 对于 transform 和 opacity 效果,不会触发 layout 和 paint

运用合成层对于升级页面品质方面有比非常大的效率,因而大家也总括了弹指间几点优化指出。

合成层的利润是不会潜移暗化到任何因素的绘图,因而,为了减小动漫元素对此外因素的影响,进而降低paint,大家供给把动漫效果中的元素进步为合成层。

升级合成层的最佳点子是接受 CSS 的 will-change 属性。从上大器晚成节合成层产生原因中,能够精晓 will-change 设置为 opacity、transform、top、left、bottom、right 能够将成分进步为合成层。

图片 51

其相称如下所示:

图片 52

对于那个近期还不扶助 will-change 属性的浏览器,如今常用的是采用二个 3D transform 属性来强制升高为合成层:

图片 53

但需求小心的是,不要成立太多的渲染层。因为每制造三个新的渲染层,就表示新的内部存款和储蓄器分配和更复杂的层的保管。之后我们会详细切磋。

若果你早就把一个成分放到一个新的合成层里,那么能够选拔 Timeline 来认同这么做是否真正改进了渲染质量。别盲目进步合成层,应当要解析其实际品质表现。

小说最开始,大家讲到了页面呈现出来所经历的渲染流水生产线,其实从性质方面考虑,最美好的渲染流水生产线是还没有布局和制图环节的,只须求做合成层的会集就能够:

图片 54

为了落成上述意义,就须要只行使那么些仅触发 Composite 的习性。如今,唯有多个属性是满足那几个条件的:transforms 和 opacity。更详尽的消息能够查看 CSS Triggers。

小心:成分提高为合成层后,transform 和 opacity 才不会触发 paint,如果不是合成层,则其依旧会触发 paint。具体见如下八个 demo。

▪ demo 1:transform

图片 55

▪ demo 2:opacity

图片 56

能够观望未进级 target element 为合成层,transform 和 opacity 依旧会触发 paint。

对此不须要再行绘制的区域应尽量幸免绘制,以减掉绘制区域,比方一个 fix 在页面顶上部分的固化不改变的领航 header,在页面内容有些区域 repaint 时,整个荧屏包罗 fix 的 header 也会被重绘,见 demo,结果如下:

图片 57

而对于一贯不改变的区域,大家意在其并不会被重绘,因而能够通过事先的秘诀,将其进级为独立的合成层。

收缩绘制区域,须求细致剖析页面,区分绘制区域,减弱重绘区域以至防止重绘。

看完上面包车型客车稿子,你会意识升高合成层会高达越来越好的质量。那看起来特别摄人心魄,但是难题是,创设二个新的合成层却非免费的,它得消耗额外的内部存款和储蓄器和拘系能源。实际上,在内部存款和储蓄器能源有限的器材上,合成层带给的质量改进,恐怕远远赶不上过多合成层花销给页面质量带给的消极面影响。同时,由于各样渲染层的纹路都急需上传来 GPU 管理,因而大家还亟需构思 CPU 和 GPU 之间的带宽难点、以致有多大内部存款和储蓄器供 GPU 管理那几个纹理的标题。

对此合成层占用内部存款和储蓄器的标题,大家简要做了多少个 demo 进行了认证。

demo 1 和 demo 2 中,会创设 二零零三 个相仿的 div 成分,差别的是 demo 第22中学的成分通过 will-change 都进步为了合成层,而多个 demo 页面的内部存款和储蓄器消耗却有很扎眼的异样。

图片 58

因而事先的牵线,我们领会同合成层重叠也会使成分升高为合成层,即便有浏览器的层压压编写制定,不过也许有那多少个无法开展压缩的动静。也正是说除了咱们显式的宣示的合成层,还或者是因为重叠原因不经意间发生局地不在预期的合成层,极端一点或然会发出大批量的额外合成层,现身层爆炸的景象。大家简要写了一个极端点但事实上在大家的页面中比较分布的 demo。

图片 59

demo 中,.animating 的合成层在运营动漫,会形成 .inner 元素因为上文介绍过的 assumedOverlap 的原故,而被进步为合成层,同一时间,.inner 的父成分 .box 设置了 overflow: hidden,招致 .inner 的合成层因为 squashingClippingContainerMismatch 的原由,不可能回退,就涌出了层爆炸的标题。

图片 60

这种情形日常在我们的事体中仍然很宽泛的,比如 slider + list 的协会,大器晚成旦满意了不能开展层压缩的景况,就超级轻松并发层爆炸的标题。

消弭层爆炸的主题材料,最好方案是打破 overlap 的尺度,也正是说让此外因素不要和合成层成分重叠。对于上述的演示,大家得以将 .animation 的 z-index 升高。纠正后 demo

图片 61

此刻,就只有 .animating 升高为合成层,如下:

图片 62

同时,内部存款和储蓄器占用相比较前边也裁减了超级多。

图片 63

如若受限于视觉必要等要素,别的因素必供给覆盖在合成层之上,那应该尽量制止不只怕层压缩情状的现身。针对上述示范中,无法层压缩的事态(squashingClippingContainerMismatch卡塔 尔(英语:State of Qatar),我们得以将 .box 的 overflow: hidden 去掉,这样就足以动用浏览器的层压缩了。更正后 demo

那会儿,由于第1个 .box 因为 squashingLayerIsAnimating 的原故无法回降,其余的都被减去到了协作。

图片 64

还要,内部存款和储蓄器占用比较在此之前也下落了众多。

图片 65

前边有线支付时,大好多人都很喜欢使用 translateZ 来拓宽所谓的硬件加快,以晋级质量,不过质量优化并从未所谓的“银弹”,translateZ 不是,本文列出的优化提议亦非。抛开了对页面包车型地铁具体深入分析,任何的属性优化都是站不住脚的,盲目标运用一些优化措施,结果只怕会适得其反。由此实际的去深入分析页面包车型大巴实在质量表现,不断的修改测量检验,才是科学的优化路子。

正文小编:wibud

翻阅原著

正文为云栖社区原创内容,未经同意不得转发。

编辑:关于计算机 本文来源:有线性能优化,前端品质优化之

关键词: