动画质量提高商量,有线质量优化

有线品质优化:Composite

2016/04/26 · 基本功技术 ·
无线

初稿出处: 天猫前端团队(FED)-
冬萌   

亚洲必赢官网 1

一个 Web 页面的显示,简单的话可以认为经历了以下下多少个步骤。

亚洲必赢官网 2

  • JavaScript:一般的话,大家会选择 JavaScript
    来促成部分视觉变化的功能。比如做一个动画或者往页面里添加一些 DOM
    元素等。
  • Style:总括样式,那个进程是根据 CSS 选取器,对每个 DOM
    元素匹配对应的 CSS 样式。这一步甘休将来,就确定了每个 DOM
    元素上该行使什么 CSS 样式规则。
  • Layout:布局,上一步确定了每个 DOM
    元素的样式规则,这一步就是现实测算每个 DOM
    元素最终在显示屏上显得的深浅和岗位。web
    页面中元素的布局是相持的,由此一个要素的布局爆发变化,会联动地吸引任何因素的布局爆发变化。比如,“
    元素的小幅的变动会潜移默化其子元素的宽度,其子元素宽度的更动也会延续对其孙子元素爆发影响。由此对此浏览器来说,布局进度是常事爆发的。
  • Paint:绘制,本质上就是填充像素的经过。包罗绘制文字、颜色、图像、边框和影子等,也就是一个
    DOM 元素所有的可视效果。一般的话,那些绘制进程是在三个层上达成的。
  • Composite:渲染层合并,由上一步可见,对页面中 DOM
    元素的绘图是在五个层上展开的。在各种层上到位绘制进度之后,浏览器会将所有层根据合理的种种合并成一个图层,然后展现在显示器上。对于有职位重叠的因素的页面,这几个进度更是重点,因为如果图层的统一顺序出错,将会促成元素突显万分。

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

1.浏览器渲染原理分析

CSS3 3D 行星运转动画 + 浏览器渲染原理

2016/04/29 · CSS ·
动画

本文小编: 伯乐在线 –
chokcoco
。未经小编许可,禁止转载!
欢迎出席伯乐在线 专栏撰稿人。

承接上一篇:《CSS3进阶:酷炫的3D旋转透视》 。

近日入坑 Web 动画,所以把自己的上学进程记录一下分享给大家。

CSS3 3D 行星运转 demo
页面请戳:Demo。(提议选拔Chrome打开)

本文完整的代码,以及越多的 CSS3
效果,在本人 Github 上可以见见,也指望我们可以点个
star。

啊,可能有点人打不开 demo
或者页面乱了,贴几张效果图:(图片有点大,耐心等待一会)

CSS3 3D 行星运转效果图

亚洲必赢官网 3

随意再截屏了一张:

亚洲必赢官网 4

强烈提议你点进
Demo页感受一下
CSS3 3D 的魅力,图片能表现的事物到底有限。

下一场,那些 CSS3 3D 行星运转动画的制作进度不再详细赘述,本篇的最首要放在
Web 动画介绍及质量优化方面。详细的 CSS3 3D
可以重放上一篇博客:《CSS3进阶:酷炫的3D旋转透视》。容易的笔触:

  1. 使用上一篇所制作的 3D 照片墙为原型,改造而来;

2.
每一个圆球的造作,想了众多格局,最后选择了那种折中的格局,每一个圆球本身也是一个
CSS3 3D 图形。然后在制作进程中利用 Sass 编写 CSS 可以减去过多麻烦的编写
CSS 动画的经过;

  1. Demo 当中有选用 Javascript
    写了一个鼠标跟随的监听事件,去掉那几个事件,整个行星运动动画本身是纯 CSS
    已毕的。

上边将跻身本文的重点,从性质优化的角度讲讲浏览器渲染体现原理,浏览器的重绘与重排,动画的性质检测优化等:

 

差异于传统的 PC
Web 或者是活动
WEB,在腾讯摄像客厅盒子端,接大屏屏幕(电视机)下,许多能流利运行于 PC
端、移动端的 Web
动画,受限于硬件水平,在盒子端的表现的高频不如愿。

浏览器渲染原理

在研究 Composite 此前,有必不可少先简单通晓下一些浏览器(本文只是指向 Chrome
来说)的渲染原理,方便对之后有的定义的接头。更多详细的始末可以参阅 GPU
Accelerated Compositing in
Chrome

注:由于 Chrome 对 Blank
引擎某些已毕的改动,某些大家事先熟识的类名有了变更,比如 RenderObject
变成了 LayoutObject,RenderLayer 变成了 PaintLayer。感兴趣的看以参阅
Slimming Paint。

在浏览器中,页面内容是储存为由 Node 对象组成的树状结构,也就是 DOM
树。每一个 HTML element 元素都有一个 Node 对象与之相应,DOM
树的根节点永远都是 Document Node。这点亲信大家都很熟习了,但实际,从
DOM 树到终极的渲染,须求开展局地更换映射。

亚洲必赢官网 5

想要提升网页的质量,紧要的便是要领悟浏览器渲染原理,上边关于浏览器的法则分析,大家以chrome内核webkit为例,其余基本的浏览器原理也基本安顺小异,可触类旁通。

浏览器渲染显示原理 及 对web动画的熏陶

小标题起得有点大,大家知道,分裂浏览器的水源(渲染引擎,Rendering
Engine)是不均等的,例如现在最主流的 chrome 浏览器的根本是 Blink
内核(在Chrome(28及未来版本)、Opera(15及以后版本)和Yandex浏览器中利用),火狐是
Gecko,IE 是 Trident
,浏览器内核负责对网页语法的分解并渲染(突显)网页,不相同浏览器内核的劳作规律并不完全一致。

由此其实下边将重点研讨的是 chrome 浏览器下的渲染原理。因为 chrome
内核渲染可查证的素材较多,对于此外基本的浏览器不敢妄下定论,所以上边展开的研究默许是针对性
chrome 浏览器的。

首先,我要抛出某些定论:

利用 transform3d api 代替 transform api,强制早先 GPU 加快

那边谈到了 GPU 加快,为啥 GPU 可以加快 3D
变换?这一体又必须要从浏览器底层的渲染讲起,浏览器渲染体现网页的长河,老生常谈,面试必问,大约分成:

    1. 解析HTML(HTML Parser)
    1. 构建DOM树(DOM Tree)
    1. 渲染树创设(Render Tree)
    1. 制图渲染树(Painting)

找到了一张很经典的图:

亚洲必赢官网 6

以此渲染进度作为一个基础知识,继续往下深刻。

当页面加载并分析完成后,它在浏览器内表示了一个我们丰裕熟识的构造:DOM(Document
Object
Model,文档对象模型)。在浏览器渲染一个页面时,它应用了成百上千从未有过揭破给开发者的中档表现方式,其中最重点的结构便是层(layer)。

本条层就是本文重点要探究的内容:

而在 Chrome 中,存在有分化类型的层: RenderLayer(负责 DOM
子树),GraphicsLayer(负责 RenderLayer
的子树)。接下来大家所谈论的将是 GraphicsLayer 层。

GraphicsLayer 层是用作纹理(texture)上传给 GPU 的。

此地那么些纹理很重点,那么,

怎么样是纹理(texture)

那里的纹理指的是 GPU 的一个术语:可以把它想象成一个从主存储器(例如
RAM)移动到图像存储器(例如 GPU 中的 VRAM)的位图图像(bitmap
image)。一旦它被挪动到 GPU 中,你可以将它卓殊成一个网格几何体(mesh
geometry),在 Chrome 中使用纹理来从 GPU
上取得大块的页面内容。通过将纹理应用到一个卓殊简单的矩形网格就能很简单匹配差距的岗位(position)和变形(transformation),那也就是
3D CSS 的办事规律。

说起来很难懂,直接看例子,在 chrome 中,大家是足以看看上文所述的
GraphicsLayer — 层的定义。在开发者工具中,我们开展如下选取调出 show
layer borders 选项:

亚洲必赢官网 7

在一个极不难的页面,大家可以看看如下所示,那个页面唯有一个层。红色网格表示瓦片(tile),你可以把它们作为是层的单元(并不是层),Chrome
可以将它们当做一个大层的片段上传给 GPU:

亚洲必赢官网 8

要素自身层的创始

因为上边的页面极度简易,所以并没有生出层,然而在很复杂的页面中,譬如我们给元素设置一个
3D CSS 属性来转换它,我们就能观看当元素拥有和谐的层时是怎么着体统。

留意橘藏红色的边框,它画出了该视图中层的大概:

亚洲必赢官网 9

 

几时触发创建层 ?

地点示意图中藏灰色边框框住的层,就是 GraphicsLayer ,它对于我们的 Web
动画而言更加重大,日常,Chrome 会将一个层的内容在作为纹理上传到 GPU
前先绘制(paint)进一个位图中。若是情节不会转移,那么就从未需要重绘(repaint)层。

如此那般做的意义在于:花在重绘上的年华可以用来做其余事情,例如运行
JavaScript,假若绘制的大运很长,还会促成动画的故障与延迟。

这就是说一个因素何时会接触创设一个层?从此时此刻以来,满意以下任意情形便会创设层:

  • 3D 或透视变换(perspective、transform) CSS 属性
  • 使用加快录像解码的 <video> 元素
  • 负有 3D (WebGL) 上下文或加紧的 2D 上下文的 <canvas> 元素
  • 混合插件(如 Flash)
  • 对协调的 opacity 做 CSS 动画或使用一个卡通变换的要素
  • 不无加速 CSS 过滤器的因素
  • 要素有一个含有复合层的后生节点(换句话说,就是一个因素拥有一个子元素,该子元素在团结的层里)
  • 要素有一个 z-index
    较低且含有一个复合层的哥们儿元素(换句话说就是该因素在复合层上面渲染)

层的重绘

对于静态 Web 页面而言,层在首回被绘制出来以后将不会被改动,但对于 Web
动画,页面的 DOM
元素是在不停变换的,若是层的始末在转移进程中暴发了改动,那么层将会被重绘(repaint)。

强硬的 chrome
开发者工具提供了工具让我们可以查阅到动画页面运行中,哪些内容被再一次绘制了:

亚洲必赢官网 10

在旧版的 chrome 中,是有 show paint rects
那几个选项的,可以查阅页面有如何层被重绘了,并以黄色边框标识出来。

而是新版的 chrome 貌似把那一个选项移除了,现在的选项是 enable paint
flashing ,其效果也是标识出网站动态转换的地点,并且以灰色边框标识出来。

看上边的示意图,可以见见页面中有几处黑色的框,表示爆发了重绘。注意
Chrome 并不会始终重绘整个层,它会尝试智能的去重绘 DOM 中失效的一对。

按照道理,页面爆发那样多动画,重绘应该很频仍才对,不过上图我的行星动画中我只见到了顾影自怜褐色重绘框,我的私家领会是,一是
GPU 优化,二是一旦整个动画页面只有一个层,那么运用了 transform
举办转移,页面必然须要重绘,不过使用分段(GraphicsLayer )技术,也就是地点说符合情形的元素分别创立层,那么一个因素所成立的层运用
transform 变换,譬如 rotate
旋转,这几个时候该层的旋转变换并不曾影响到其他层,那么该层不肯定必要被重绘。(个人之见,还请提出指正)。

驾驭层的重绘对 Web 动画的质量优化至关首要。

是什么样原因造成失效(invalidation)进而强制重绘的啊?那个标题很难详尽回答,因为存在大批量造成边界失效的情况。最广大的状态即便通过操作
CSS 样式来修改 DOM 或促成重排。

寻找引发重绘和重排根源的最好格局就是运用开发者工具的时间轴和 enable
paint flashing 工具,然后试着找出恰好在重绘/重排前改动了 DOM 的地点。

总结

那就是说浏览器是何等从 DOM 元素到结尾动画的突显呢?

  • 浏览器解析 HTML 获取 DOM 后分开为多个图层(GraphicsLayer)
  • 对每个图层的节点统计样式结果(Recalculate style–样式重统计)
  • 为各类节点生成图形和职位(Layout–回流和重布局)
  • 将每个节点绘制填充到图层位图中(Paint Setup和Paint–重绘)
  • 图层作为纹理(texture)上传至 GPU
  • 符合八个图层到页面上转移最后屏幕图像(Composite Layers–图层重组)

Web
动画很大一些付出在于层的重绘,以层为底蕴的复合模型对渲染品质兼备深入的熏陶。当不要求绘制时,复合操作的支付可以忽略不计,因而在试着调节渲染质量难题时,主要目的就是要避免层的重绘。那么那就给动画的性质优化提供了大方向,收缩元素的重绘与回流。

 

基于此,对于 Web
动画的习性难点,仅仅逗留在感到已经优化的OK之上,是不够的,想要在盒子端跑出高质量接近
60 FPS 的流利动画,就亟要求刨根问底,深挖每一处能够荣升的方式。

从 Nodes 到 LayoutObjects

DOM 树中得每个 Node 节点都有一个遥相呼应的 LayoutObject 。LayoutObject
知道什么在显示器上 paint Node 的内容。

 亚洲必赢官网 11

回流(reflow)与重绘(repaint)

此地首先要分清四个概念,重绘与回流。

回流(reflow)

当渲染树(render
Tree)中的一有的(或任何)因为元素的范畴尺寸,布局,隐藏等转移而须求再行创设。那就称为回流(reflow),也就是再一次布局(relayout)。

各样页面至少要求几遍回流,就是在页面第五回加载的时候。在回流的时候,浏览器会使渲染树中屡遭震慑的一部分失效,比量齐观新组织那有的渲染树,落成回流后,浏览器会重新绘制受影响的部分到屏幕中,该进程变为重绘。

重绘(repaint)

当render
tree中的一些要素须要立异属性,而这一个属性只是影响因素的外观,风格,而不会潜移默化布局的,比如
background-color 。则就叫称为重绘。

值得注意的是,回流必将唤起重绘,而重绘不自然会唤起回流。

强烈,回流的代价更大,简单而言,当操作元素会使元素修改它的分寸或岗位,那么就会发出回流。

回流哪天触发:

  • 调整窗口大小(Resizing the window)
  • 转移字体(Changing the font)
  • 充实依然移除样式表(Adding or removing a stylesheet)
  • 情节变更,比如用户在input框中输入文字(Content changes, such as a
    user typing text in
  • an input box)
  • 激活 CSS 伪类,比如 :hover (IE 中为小兄弟结点伪类的激活)(Activation
    of CSS pseudo classes such as :hover (in IE the activation of the
    pseudo class of a sibling))
  • 操作 class 属性(Manipulating the class attribute)
  • 剧本操作 DOM(A script manipulating the DOM)
  • 计算 offsetWidth 和 offsetHeight 属性(Calculating offsetWidth and
    offsetHeight)
  • 安装 style 属性的值 (Setting a property of the style attribute)

之所以对于页面而言,大家的要旨就是尽量裁减页面的回流重绘,不难的一个板栗:

CSS

will-change: auto will-change: scroll-position will-change: contents
will-change: transform // Example of <custom-ident> will-change:
opacity // Example of <custom-ident> will-change: left, top //
Example of two <animateable-feature> will-change: unset
will-change: initial will-change: inherit // 示例 .example{ will-change:
transform; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
will-change: auto
will-change: scroll-position
will-change: contents
will-change: transform        // Example of <custom-ident>
will-change: opacity          // Example of <custom-ident>
will-change: left, top        // Example of two <animateable-feature>
will-change: unset
will-change: initial
will-change: inherit
// 示例
.example{
    will-change: transform;
}

下边四句,因为关乎了 offsetHeight
操作,浏览器强制 reflow 了四遍,而下边四句合并了 offset
操作,所以收缩了四回页面的回流。 

减掉回流、重绘其实就是索要裁减对渲染树的操作(合并很多次多DOM和体裁的改动),并缩减对一部分style音信的伸手,尽量采取好浏览器的优化策略。

flush队列

实质上浏览器自身是有优化策略的,倘诺每句 Javascript 都去操作 DOM
使之进行回流重绘的话,浏览器可能就会受持续。所以广大浏览器都会优化那几个操作,浏览器会维护
1
个系列,把装有会唤起回流、重绘的操作放入那些队列,等行列中的操作到了一定的数目依然到了迟早的时光间隔,浏览器就会
flush 队列,举行一个批处理。那样就会让数次的回流、重绘变成一回回流重绘。

只是也有例外,因为一些时候我们须求规范获取某些样式音信,上面那几个:

  • offsetTop, offsetLeft, offsetWidth, offsetHeight

  • scrollTop/Left/Width/Height

  • clientTop/Left/Width/Height

  • width,height

  • 请求了getComputedStyle(), 或者 IE的 currentStyle

这么些时候,浏览器为了反映最精确的新闻,须要及时回流重绘一回,确保给到大家的音信是精确的,所以可能引致
flush 队列提前实施了。

display:none 与 visibility:hidden

两岸都得以在页面上隐藏节点。分歧之处在于,

  • display:none 隐藏后的要素不占用任何空间。它的宽度、中度等种种属性值都将“丢失”
  • visibility:hidden 隐藏的因素空间照旧存在。它仍保有莫大、宽度等属性值

从品质的角度而言,即是回流与重绘的上面,

  • display:none  会触发 reflow(回流)
  • visibility:hidden  只会触发 repaint(重绘),因为尚未发觉地点变动

她俩彼此在优化中 visibility:hidden
会显得更好,因为我们不会因为它而去改变了文档中曾经定义好的来得层次结构了。

对子元素的震慑:

  • display:none 一旦父节点元素应用了
    display:none,父节点及其子孙节点元素全体不可知,而且无论其子孙元素如何设置
    display 值都心有余而力不足体现;
  • visibility:hidden
    一旦父节点元素应用了 visibility:hidden,则其后代也都会全部不可知。但是存在隐匿“失效”的情事。当其子孙元素应用了
    visibility:visible,那么这么些子孙元素又会显现出来。

 

 

从 LayoutObjects 到 PaintLayers

诚如的话,拥有相同的坐标空间的
LayoutObjects,属于同一个渲染层(PaintLayer)。PaintLayer 最初是用来兑现
stacking
contest(层叠上下文),以此来保管页面元素以科学的一一合成(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
则和其首先个有着渲染层的父元素共用一个。

如上图所示,浏览器解析页面步骤可分为:

动画片的属性检测及优化

耗品质样式

不等样式在费用品质方面是例外的,譬如 box-shadow
从渲染角度来讲卓殊耗品质,原因就是与其余样式相比,它们的绘图代码执行时间过长。那就是说,假设一个耗品质严重的体制平日要求重绘,那么您就会碰到品质难点。其次你要精通,没有不变的事情,在后天质量很差的体制,可能前些天就被优化,并且浏览器之间也设有差异。

之所以关键在于,你要借助开发工具来甄别出质量瓶颈所在,然后设法减少浏览器的工作量。

好在 chrome
浏览器提供了成百上千精锐的作用,让我们得以检测大家的动画质量,除了上边提到的,大家还足以由此勾选上面那几个show FPS meter 突显页面的 FPS 新闻,以及 GPU 的使用率:

亚洲必赢官网 12

 

选取 will-change 进步页面滚动、动画等渲染品质

法定文档说,那是一个仍居于试验阶段的作用,所以在以后版本的浏览器中该作用的语法和行事或者随着更改。

亚洲必赢官网 13

行使方法言传身教:(具体每个取值的意思,去翻翻文档)

CSS

will-change: auto will-change: scroll-position will-change: contents
will-change: transform // Example of <custom-ident> will-change:
opacity // Example of <custom-ident> will-change: left, top //
Example of two <animateable-feature> will-change: unset
will-change: initial will-change: inherit // 示例 .example{ will-change:
transform; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
will-change: auto
will-change: scroll-position
will-change: contents
will-change: transform        // Example of <custom-ident>
will-change: opacity          // Example of <custom-ident>
will-change: left, top        // Example of two <animateable-feature>
will-change: unset
will-change: initial
will-change: inherit
// 示例
.example{
    will-change: transform;
}

will-change 为 web
开发者提供了一种告知浏览器该因素会有啥变化的法门,那样浏览器能够在要素属性真正暴发变化此前提前做好相应的优化准备干活。 那种优化可以将部分繁杂的推测工作提前准备好,使页面的感应越来越高效灵敏。

值得注意的是,用好那一个特性并不是很简单:

  • 永不将 will-change
    应用到太多元素上:浏览器已经尽力尝试去优化整个可以优化的东西了。有部分更强力的优化,假如与 will-change 结合在协同来说,有可能会损耗很多机器资源,即便过度使用以来,可能引致页面响应缓慢或者消耗卓殊多的资源。

  • 有总统地利用:平日,当元素复苏到起来状态时,浏览器会舍弃掉此前做的优化办事。不过假若平昔在体制表中显式评释了 will-change 属性,则表示目的元素可能会时时转移,浏览器会将优化办事保存得比从前更久。所以最佳实践是当元素变化在此之前和事后经过脚本来切换 will-change 的值。

  • 不用过早应用 will-change
    优化:若是您的页面在质量方面没什么难题,则不用添加 will-change 属性来榨取一丁点的速度。 will-change 的统筹初衷是当做最终的优化手段,用来品尝解决现有的习性难题。它不该被用来防护质量难题。过度施用 will-change 会导致大气的内存占用,并会导致更复杂的渲染进度,因为浏览器会盘算准备可能存在的成形进度。那会促成更要紧的特性难点。

  • 给它丰盛的干活时间:那一个特性是用来让页面开发者告知浏览器哪些属性可能会变动的。然后浏览器可以选择在变更暴发前提前去做一些优化办事。所以给浏览器一点日子去真正做那么些优化工作是不行关键的。使用时索要尝试去找到一些方法提前一定时间获知元素可能暴发的转变,然后为它助长 will-change
    属性。

 

运用 transform3d api 代替 transform api,强制开首 GPU 加快

GPU 可以加快 Web 动画,那些上文已经数十次提到了。

3D transform
会启用GPU加快,例如 translate3D, scaleZ 之类,当然大家的页面可能并从未
3D 变换,可是不意味着我们不可能启用 GPU 加快,在非 3D 变换的页面也运用 3D
transform
来操作,算是一种 hack 加快法。我们实际不须要z轴的变通,不过依旧假模假样地宣称了,去欺上瞒下浏览器。

参考文献:

  • Rendering: repaint, reflow/relayout,
    restyle
  • Scrolling
    Performance
  • MDN–will-change
  • How (not) to trigger a layout in
    WebKit
  • High Performance
    Animations
  • Accelerated Rendering in
    Chrome
  • CSS3
    制作3D旋转球体

到此本文停止,若是还有啥样难题依旧建议,可以多多调换,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。

打赏辅助自己写出更加多好小说,谢谢!

打赏小编

顺理成章动画的业内

辩论上说,FPS
越高,动画会越流畅,近期多数设备的显示器刷新率为 60 次/秒,所以经常来讲FPS 为 60frame/s 时动画效果最好,也就是每帧的消耗时间为 16.67ms。

从 PaintLayers 到 GraphicsLayers

动画质量提高商量,有线质量优化。某些特殊的渲染层会被认为是合成层(Compositing Layers),合成层拥有独立的
GraphicsLayer,而其余不是合成层的渲染层,则和其首先个具有 GraphicsLayer
父层公用一个。

种种 GraphicsLayer 都有一个 GraphicsContext,GraphicsContext
会负责输出该层的位图,位图是储存在共享内存中,作为纹理上传到 GPU
中,最终由 GPU 将三个位图进行合成,然后 draw
到显示器上,此时,大家的页面也就显示到了显示器上。

渲染层升高为合成层的原委有须臾间两种:

注:渲染层进步为合成层有一个先决条件,该渲染层必须是
SelfPaintingLayer(基本可认为是上文介绍的
诺玛lPaintLayer)。以下所商量的渲染层进步为合成层的场所都是在该渲染层为
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亚洲必赢官网 14
    • will-change 设置为
      opacity、transform、top、left、bottom、right(其中 top、left
      等急需设置显著的一向属性,如 relative
      等)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
    重叠原因为啥会因为重叠原由此发出合成层呢?举个简单的栗子。亚洲必赢官网 15红色的矩形重叠在灰色矩形之上,同时它们的父元素是一个
    GraphicsLayer。此时即使黑色矩形为一个 GraphicsLayer,假诺 overlap
    不能晋级合成层的话,那么青色矩形不会升级为合成层,也就会和父元素公用一个
    GraphicsLayer。亚洲必赢官网 16此刻,渲染顺序就会爆发错误,由此为力保渲染顺序,overlap
    也改为了合成层暴发的由来,也就是之类的健康境况。亚洲必赢官网 17当然
    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)。那些原因听上去有点虚,什么叫假如重叠?其实也正如好通晓,比如一个因素的
      CSS
      动画成效,动画运行时期,元素是有可能和其余因素有重合的。针对于那种气象,于是就有了
      assumedOverlap
      的合成层爆发原因,示例可知:demo。在本
      demo 中,动画元素视觉上并没有和其兄弟元素重叠,但因为
      assumedOverlap
      的案由,其兄弟元素仍旧升高为了合成层。须求注意的是该原因下,有一个很特其余情况:若是合成层有内联的
      transform 属性,会促成其兄弟渲染层 assume
      overlap,从而升级为合成层。比如:demo。

* 解析HTML(HTML Parser)

打赏协理自己写出越来越多好小说,谢谢!

任选一种支付格局

亚洲必赢官网 18
亚洲必赢官网 19

3 赞 14 收藏
评论

直观感受,不相同帧率的感受

  • 帧率可以达标
    50 ~ 60 FPS 的动画将会一定流利,让人感到舒服;
  • 帧率在
    30 ~ 50 FPS 之间的卡通片,因各人敏感程度不一,舒适度人己一视;
  • 帧率在
    30 FPS 以下的卡通片,令人感觉到明确的卡顿和不适感;
  • 帧率波动很大的卡通片,亦会使人倍感到卡顿。

 

层压缩

大抵周边的有的合成层的升官原因如上所说,你会意识,由于重叠的原委,可能随便就会生出出大量合成层来,而各样合成层都要消耗
CPU
和内存资源,岂不是严重影响页面性能。那点浏览器也考虑到了,因而就有了层压缩(Layer
Squashing)的拍卖。借使两个渲染层同一个合成层重叠时,那个渲染层会被核减到一个
GraphicsLayer
中,以避免由于重叠原因促成可能出现的“层爆炸”。具体可以看如下
demo。一先河,灰色方块由于
translateZ
升高为了合成层,其他的正方元素因为重叠的来头,被减少了一块儿,大小就是带有那3 个方块的矩形大小。

亚洲必赢官网 20

当大家 hover 紫色方块时,会给其设置 translateZ
属性,导致粉红色方块也被升高为合成层,则剩下的八个被缩减到了协同,大小就缩短为涵盖那2 个方块的矩形大小。

亚洲必赢官网 21

本来,浏览器的机关的层压缩也不是文韬武韬的,有许多特定情景下,浏览器是力不从心进展层压缩的,如下所示,而这一个意况也是我们理应尽量防止的。(注:以下境况都是基于重叠原由此言)

  • 惊惶失措开展会打破渲染顺序的削减(squashingWouldBreakPaintOrder)示例如下: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)demo
  • iframe、plugin
    的渲染层无法被核减同时也惊惶失措将其他渲染层压缩到其所在的合成层上(squashingLayoutPartIsDisallowed)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亚洲必赢官网 22

* 构建DOM树(DOM Tree)

关于小编:chokcoco

亚洲必赢官网 23

经不住流年似水,逃不过此间少年。

个人主页 ·
我的稿子 ·
63 ·
   

亚洲必赢官网 24

盒子端动画优化

在腾讯摄像客厅盒子端,Web
动画未开展优化以前,一些错综复杂动画的帧率仅有 10 ~ 30
FPS,卡顿感非凡分明,带来很不好的用户体验。

而开展优化未来,能将
10 ~ 30 FPS的动画片优化至 30 ~ 60
FPS,即便不算优化到最周到,可是近来盒子硬件的规则下,已经算是这么些大的提升。

什么样查看合成层

应用 Chrome DevTools 工具来查阅页面中合成层的状态。

比较简单的点子是开辟 DevTools,勾选上 Show layer borders

亚洲必赢官网 25

里头,页面上的合成层会用藏黄色边框框出来。

亚洲必赢官网 26

自然,越发详实的音信方可经过 提姆eline 来查阅。

每一个单独的帧,看到种种帧的渲染细节:

亚洲必赢官网 27

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

亚洲必赢官网 28

点击那一个 Layers
选项卡,你会晤到一个新的视图。在那几个视图中,你能够对这一帧中的所有合成层进行扫描、缩放等操作,同时仍可以观望各样渲染层被创设的原因。

亚洲必赢官网 29

有了这几个视图,你就能精通页面中究竟有微微个合成层。如若您在对页面滚动或渐变效果的品质分析中窥见
Composite
进度用度了太多时间,那么您能够从这么些视图里观望页面中有微微个渲染层,它们为啥被创建,从而对合成层的数额举行优化。

* 构建CSSOM树(Style)

盒子端 Web 动画质量相比

首先先提交在盒子端差距类型的Web
动画的习性比较。经过相比,在盒子端 CSS 动画的特性要打折 Javascript
动画,而在 CSS 动画里,使用 GPU
硬件加快的动画片质量要优化不选用硬件加快的质量。

由此在盒子端,完结一个
Web 动画,优先级是:

GPU
硬件加快 CSS 动画 > 非硬件加快 CSS 动画 > Javascript 动画

 

特性优化

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

  • 合成层的位图,会交由 GPU 合成,比 CPU 处理要快
  • 当需求 repaint 时,只须求 repaint 本身,不会影响到其余的层
  • 对此 transform 和 opacity 效果,不会触发 layout 和 paint

利用合成层对于进步页面质量方面有很大的效应,由此大家也计算了一晃几点优化提出。

* 创设渲染树(Render Tree)

动画质量上报分析

要有优化,就亟须得有数据做为支撑。比较优化前后是还是不是有进步。而对于动画而言,衡量一个卡通的业内也就是
FPS 值。

因而现在的首要性是什么样计算出每个动画运行时的帧率,那里自己使用的是 requestAnimationFrame这些函数近似的获取动画运行时的帧率。

style=”font-family: verdana, geneva; font-size: 14px;”>考虑到盒子都是安卓系统,且大多版本较低且硬件品质堪忧,导致一是累累高等
API 无法使用,二是此处只是好像得到动画帧率

原理是,正常而言 requestAnimationFrame 那几个点子在一秒内会实施
60 次,也就是不掉帧的状态下。如果动画在时刻 A 初叶举行,在时刻 B
为止,耗时 x ms。而当中 requestAnimationFrame 一共执行了 n
次,则此段动画的帧率大致为:n / (B – A)。

主题代码如下,能近似总计每秒页面帧率,以及大家至极记录一个 allFrameCount,用于记录
rAF 的施行次数,用于统计每一回动画的帧率 :

var rAF = function () {
    return (
        window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        function (callback) {
            window.setTimeout(callback, 1000 / 60);
        }
    );
}();

var frame = 0;
var allFrameCount = 0;
var lastTime = Date.now();
var lastFameTime = Date.now();

var loop = function () {
    var now = Date.now();
    var fs = (now - lastFameTime);
    var fps = Math.round(1000 / fs);

    lastFameTime = now;
    // 不置 0,在动画的开头及结尾记录此值的差值算出 FPS
    allFrameCount++;
    frame++;

    if (now > 1000 + lastTime) {
        var fps = Math.round((frame * 1000) / (now - lastTime));
        // console.log('fps', fps); 每秒 FPS
        frame = 0;
        lastTime = now;
    };

    rAF(loop);
}

  

晋级动画效果的因素

合成层的裨益是不会影响到别的因素的绘图,因而,为了削减动画元素对任何因素的震慑,从而减少paint,大家要求把动画效果中的元素提升为合成层。

提高合成层的最好办法是运用 CSS 的 will-change
属性。从上一节合成层发生原因中,可以知晓 will-change 设置为
opacity、transform、top、left、bottom、right 可以将元素提高为合成层。

CSS

#target { will-change: transform; }

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

其匹配如下所示:
亚洲必赢官网 30

对于那多少个近日还不辅助 will-change 属性的浏览器,方今常用的是使用一个 3D
transform 属性来强制提高为合成层:

CSS

#target { transform: translateZ(0); }

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

但须求小心的是,不要创制太多的渲染层。因为每创设一个新的渲染层,就意味着新的内存分配和更复杂的层的管理。之后我们会详细切磋。

倘若您曾经把一个元素放到一个新的合成层里,那么可以选用 提姆eline
来确认这么做是还是不是真正立异了渲染品质。别盲目提高合成层,一定要分析其实际质量表现。

* 页面布局(Layout)

探讨结论

就此,大家的目的就是在利用
GPU 硬件加快的底子之上,更长远的去优化 CSS
动画,先交付最终的一个优化步骤方案:

  1. 简短
    DOM ,合理布局
  2. 使用
    transform 代替 left、top,收缩使用耗品质样式
  3. 控制频仍动画的层级关系
  4. 设想使用
    will-change
  5. 动用
    dev-tool 时间线 timeline 观察,找出导致高耗时、掉帧的首要操作

下文仲有每一步骤的具体分析解释。

 

行使 transform 或者 opacity 来落到实处动画效果

小说最初阶,大家讲到了页面突显出来所经历的渲染流水线,其实从性质方面考虑,最理想的渲染流水线是从未有过布局和制图环节的,只须求做合成层的联结即可:

亚洲必赢官网 31

为了完结上述功用,就必要只利用那多少个仅触发 Composite
的习性。方今,只有五个属性是满意这么些原则的:transforms 和
opacity。更详尽的音信方可查看 CSS Triggers。

留意:元素提高为合成层后,transform 和 opacity 才不会触发
paint,借使不是合成层,则其如故会触发 paint。具体见如下多少个 demo。

  • demo
    1:transform亚洲必赢官网 32
  • demo
    2:opacity亚洲必赢官网 33

可以见见未提高 target element 为合成层,transform 和 opacity 如故会触发
paint。

* 绘制渲染树(Painting)

Web 每一帧的渲染

要想达到 60
FPS,每帧的预算时间仅比 16 微秒多一点 (1 秒/ 60 = 16.67
飞秒)。但实则,浏览器有整理工作要做,由此你的兼具工作亟待尽可能在 10
微秒内到位。

而每一帧,即便有必不可少,咱们能说了算的部分,也是像素至屏幕管道中的关键步骤如下:

亚洲必赢官网 34

一体化的像素管道 JS
/ CSS > 样式 > 布局 > 绘制 > 合成:

  1. JavaScript。一般的话,大家会使用
    JavaScript 来完成部分视觉变化的功效。比如用 jQuery 的 animate
    函数做一个动画片、对一个数额集进行排序或者往页面里添加一些 DOM
    元素等。当然,除了
    JavaScript,还有别的一些常用方法也可以完成视觉变化作用,比如:CSS
    Animations、Transitions 和 Web Animation API。

  2. 体制总计。此进程是基于匹配拔取器(例如
    .headline 或 .nav > .nav__item)总结出哪些要素运用哪些 CSS 3.
    规则的长河。从中领略规则之后,将选择规则并盘算每个元素的末梢样式。

  3. 布局。在通晓对一个元素运用哪些规则之后,浏览器即可初始总括它要占有的长空大小及其在显示屏的地方。网页的布局格局表示一个元素可能影响其余因素,例如
    <body>
    元素的宽窄相似会影响其子元素的幅度以及树中各处的节点,因而对此浏览器来说,布局进程是日常暴发的。

  4. 绘图。绘制是填充像素的长河。它事关绘出文本、颜色、图像、边框和影子,基本上包罗元素的每个可视部分。绘制一般是在五个外表(平日称为层)上成功的。

  5. 合成。由于页面的各部分或者被绘制到多层,由此它们须求按正确顺序绘制到显示器上,以便正确渲染页面。对于与另一元素交汇的元一直说,那一点越发主要,因为一个不当可能使一个要素错误地冒出在另一个元素的上层。

本来,不必然每帧都一连会由此管道每个部分的拍卖。大家的靶子就是,每一帧的卡通,对于上述的管道流程,能防止则防止,不可能避免则最大限度优化。

 

减去绘制区域

对于不必要重新绘制的区域应尽量幸免绘制,以调减绘制区域,比如一个 fix
在页面顶部的固定不变的领航 header,在页面内容某个区域 repaint
时,整个屏幕包涵 fix 的 header 也会被重绘,见
demo,结果如下:

亚洲必赢官网 35

而对此固定不变的区域,大家期望其并不会被重绘,因而得以因此事先的点子,将其升级为独立的合成层。

调减绘制区域,要求精心分析页面,区分绘制区域,收缩重绘区域如故防止重绘。

这一历程可在chrome开发者工具的小时线中寓目:

优化动画步骤

先交给一个步骤,调优一个卡通,有一定的点拨原则得以依据,一步一步深刻动画:

合理管理合成层

看完上边的文章,你会发觉提高合成层会达到更好的品质。那看起来更加诱人,不过难点是,创设一个新的合成层并不是免费的,它得消耗额外的内存和治本资源。实际上,在内存资源有限的装备上,合成层带来的质量改革,可能远远赶不上过多合成层费用给页面质量带来的负面影响。同时,由于各样渲染层的纹理都亟待上盛传
GPU 处理,因而我们还必要考虑 CPU 和 GPU 之间的带宽难题、以及有多大内存供
GPU 处理这一个纹理的难点。

对于合成层占用内存的题材,大家大约做了多少个 demo 进行了注明。

demo
1
和 demo
2
中,会成立 2000 个一样的 div 元素,分歧的是 demo
2
中的元素通过 will-change 都升高为了合成层,而八个 demo
页面的内存消耗却有很醒目标差别。

亚洲必赢官网 36

 亚洲必赢官网 37

1.简短 DOM ,合理布局

其一没什么好说的,如若能够,精简
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
的原委,不可能回落,就应运而生了层爆炸的难点。

亚洲必赢官网 38

那种情景常常在大家的业务中仍然很广泛的,比如 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 提高为合成层,如下:

亚洲必赢官网 39

与此同时,内存占用相比之前也下滑了广大。

亚洲必赢官网 40

倘使受限于视觉需求等因素,其余因素必必要遮盖在合成层之上,那应该尽量防止不可能层压缩意况的面世。针对上述示范中,无法层压缩的图景(squashingClippingContainerMismatch),我们可以将
.boxoverflow: hidden
去掉,那样就可以利用浏览器的层压缩了。修改后
demo

那儿,由于第二个 .box 因为 squashingLayerIsAnimating
的原因无法回落,其余的都被缩减到了一同。

亚洲必赢官网 41

与此同时,内存占用比较前边也下滑了许多。

亚洲必赢官网 42

此地大家简要说一下以下多少个概念:

2.应用 transform 代替 left、top,减少使用耗质量样式

当代浏览器在做到以下多样特性的动画时,消耗资金较低:

  • position(位置): transform: translate(npx, npx)
  • scale(比例缩放):transform: scale(n)
  • rotation(旋转)
    transform: rotate(ndeg)
  • opacity(透明度):opacity: 0...1

假设得以,尽量只利用上述多样特性去决定动画。

不等体制在用度品质方面是例外的,改变部分性质的支付比改变其余品质要多,由此更可能使动画卡顿。

比如说,与转移元素的文件颜色比较,改变元素的 box-shadow 将索要支出大过多的绘图操作。
改变元素的 width 可能比改变其 transform 要多一些支付。如 box-shadow 属性,从渲染角度来讲至极耗质量,原因就是与任何样式比较,它们的绘图代码执行时间过长。

那么,即使一个耗品质严重的体裁平常索要重绘,那么你就会碰着品质难点。其次你要通晓,没有不变的作业,在昨日质量很差的体裁,可能前天就被优化,并且浏览器之间也设有差别。

最后

事先无线支付时,大部分人都很喜爱使用 translateZ(0)
来进展所谓的硬件加速,以提高质量,不过质量优化并没有所谓的“银弹”,translateZ(0)
不是,本文列出的优化指出也不是。抛开了对页面的具体分析,任何的品质优化都是站不住脚的,盲目标应用一些优化措施,结果也许会差强人意。因此具体的去分析页面的实在质量表现,不断的革新测试,才是毋庸置疑的优化途径。

* 布局(layout)

拉开 GPU 硬件加快

总归,上述多样特性的动画片消耗较低的案由是会张开了
GPU 硬件加快。动画元素生成了祥和的图形层(GraphicsLayer)。

常备而言,开启
GPU 加快的主意我们可以利用

  • will-change: transform

那会使注解了该样式属性的元素生成一个图形层,告诉浏览器接下去该因素将会展开
transform 变换,让浏览器提前做好准备。

style=”font-family: verdana, geneva; font-size: 14px;”>使用 will-change 并不一定会有质量的升级换代,因为即便浏览器预料到会有这个改动,仍然会为这么些属性运行布局和制图流程,所以提前告知浏览器,也并不会有太多属性上的晋级。那样做的补益是,创设新的图层代价很高,而等到要求时心切地创立,不如一发端一贯创制好。

对此 Safari
及部分旧版本浏览器,它们不可以识别 will-change,则需求使用某种 translate
3D 进行 hack,常常会接纳

  • transform: translateZ(0)

因而,正常而言,在生产环境下,大家恐怕须要采纳如下代码,开启硬件加快:

{
    will-change: transform;
    transform: translateZ(0);
}

参考

  • 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 收藏
    评论

亚洲必赢官网 43

布局也叫做重排或回流,布局流程输出的是一个“盒模型”,它会准确地捕获每个元素在视口内的纯粹地方和尺寸,HTML就是使用基于流的布局模型,页面元素的转移频繁可能造成回流的暴发,而回流的频发暴发亦是潜移默化页面质量的根本元素,其余,处于流后置位平日不会影响前置位的几何特点,故对前置位的改动往往比对后置位的修改对页面全部的熏陶要低。

3.操纵频仍动画的层级关系

动画层级的主宰的意思是硬着头皮让急需举行CSS
动画的因素的 z-index 保持在页面最顶端,防止浏览器创造不需要的图形层(GraphicsLayer),可以很好的升级换代渲染品质。

OK,那里又涉及了图形层(GraphicsLayer),那是一个浏览器渲染原理相关的学问(WebKit/blink内核下)。它能对动画片进行加速,但同时也存在对应的加速坑!

 亚洲必赢官网 44

大致来说,浏览器为了升高动画的习性,为了在动画的每一帧的经过中不要每一趟都重复绘制整个页面。在特定措施下得以触爆发成一个合成层,合成层拥有独立的
GraphicsLayer。

亟待展开动画的元素包括在这些合成层之下,那样动画的每一帧只须求去重新绘制那一个Graphics Layer 即可,从而完结提高动画质量的目标。

那么一个因素什么时候会触发创立一个
Graphics Layer 层?从脚下来说,知足以下任意情形便会创建层:

  • 硬件加快的
    iframe 元素(比如 iframe 嵌入的页面中有合成层)
  • 硬件加快的插件,比如
    flash 等等
  • 运用加快摄像解码的 <video> 元素
  • 3D 或者
    硬件加快的 2D Canvas 元素
  • 3D
    或透视变换 (perspective、transform) 的 CSS 属性
  • 对自己的
    opacity 做 CSS 动画或利用一个动画变换的元素
  • 享有加快 CSS
    过滤器的要素
  • 要素有一个饱含复合层的子孙节点(换句话说,就是一个元素拥有一个子元素,该子元素在团结的层里)
  • 要素有一个
    z-index 较低且带有一个复合层的哥们儿元素

本小点中说到的卡通层级的主宰,原因就在于地点生成层的尾声一条:

style=”font-family: verdana, geneva; font-size: 14px;”>元素有一个
z-index 较低且带有一个复合层的小兄弟元素。

那里是存在坑的地点,首先我们要明显两点:

  1. 大家愿意大家的动画得到GPU
    硬件加速,所以我们会使用类似 transform: translateZ()这么的不二法门生成一个
    Graphics Layer 层。
  2. Graphics
    Layer 虽好,但不是越来越多越好,每一帧的渲染内核都会去遍历计算当前享有的
    Graphics Layer ,并盘算他们下一帧的重绘区域,所以过量的 Graphics
    Layer 统计也会给渲染造成品质影响。

记住那两点之后,回到地方大家说的坑。

万一大家有一个轮播图,有一个
ul 列表,结构如下:

<div class="container">
<div class="swiper">轮播图</div>
<ul class="list">
<li>列表li</li>
<li>列表li</li>
<li>列表li</li>
<li>列表li</li>
</ul>
</div>

若果给他们定义如下
CSS:

.swiper {
    position: static;
    animation: 10s move infinite;
}

.list {
    position: relative;
}

@keyframes move {
    100% {
        transform: translate3d(10px, 0, 0);
    }
}

由于给 .swiper 添加了 translate3d(10px, 0, 0) 动画,所以它会转移一个
Graphics
Layer,如下图所示,用开发者工具得以打开层的呈现,图形外的风骚边框即表示生成了一个独自的复合层,拥有独立的
Graphics Layer 。

亚洲必赢官网 45

只是!在上头的图中,大家并不曾给上边的 list 也添加任何能触暴发成
Graphics Layer
的属性,但是它也如出一辙也有风骚的边框,生成了一个独自的复合层。

原因在于地点那条元素有一个
z-index 较低且富含一个复合层的哥们儿元素。大家并不希望 list 元素也生成
Graphics Layer ,不过由于 CSS 层级定义原因,下边的 list 的层级高于地点的
swiper,所以它被动的也生成了一个 Graphics Layer 。

动用
Chrome,我们也足以洞察到那种层级关系,可以见到 .list 的层级高于 .swiper

 亚洲必赢官网 46

故此,上边大家修改一下
CSS ,改成:

.swiper {
    position: relative;
    z-index: 100;
}

.list {
    position: relative;
}

此处,大家显著使得 .swiper 的层级高于 .list ,再打开开发者工具观望一下:

 亚洲必赢官网 47

可以看看,那三回,.list 元素已经远非了色情外边框,表明此风尚无生成
Graphics Layer 。再看看层级图:

亚洲必赢官网 48

那会儿,层级关系才是我们希望观察的,.list 元素没有触发生成
Graphics Layer
。而我们期望须求硬件加快的 .swiper 保持在最上方,每一遍动画进度中只会独自重绘那部分的区域。

* 绘制(paint)

总结

以此坑最早见于张云龙(英文名:Leon)发布的那篇小说CSS3硬件加快也有坑,这里还要总括补充的是:

  • GPU
    硬件加快也会有坑,当大家愿意利用使用类似 transform: translate3d() 那样的主意打开
    GPU 硬件加快,一定要小心元素层级的涉嫌,尽量有限辅助让急需举办 CSS
    动画的要素的 z-index 保持在页面最顶端。

  • Graphics
    Layer 不是越来越多越好,每一帧的渲染内核都会去遍历统计当前具有的
    Graphics Layer ,并盘算他们下一帧的重绘区域,所以过量的 Graphics
    Layer 总括也会给渲染造成质量影响。

  • 可以选取Chrome ,用地方介绍的多个工具对协调的页面生成的 Graphics Layer
    和要素层级举办察看然后进行相应修改。

  • 上边观看页面层级的
    chrome
    工具极度吃内存?好像依然一个高居实验室的效益,分析稍微大一点的页面简单直接卡死,所以要多学会使用第一种着眼紫色边框的艺术查看页面生成的
    Graphics Layer 那种艺术。

制图即是对DOM所分割的层(layer)进行相应的绘图,页面的回流一般都会伴随重视绘,但重绘行为的面世不必然伴随回流。

4. 行使 will-change 能够在要素属性真正发生变化以前提前做好相应准备

// 示例
.example {
    will-change: transform;
}

地点已经涉及过
will-change 了。

will-change
为 web
开发者提供了一种告知浏览器该因素会有何样变化的艺术,那样浏览器可以在要素属性真正暴发变化以前提前做好对应的优化准备干活。
这种优化可以将部分错综复杂的测算工作提前准备好,使页面的反应更加飞速灵敏。

值得注意的是,用好那个特性并不是很不难:

  • 在有些低端盒子上,will-change 会导致众多不成难题,譬如会使图片模糊,有的时候很不难画蛇添足,所以选用的时候还亟需多加测试。

  • 毫无将
    will-change
    应用到太多元素上:浏览器已经开足马力尝试去优化整个可以优化的东西了。有一对更强力的优化,要是与
    will-change
    结合在联名来说,有可能会损耗很多机器资源,若是过于施用以来,可能引致页面响应缓慢或者消耗非凡多的资源。

  • 有总统地运用:平日,当元素苏醒到起来状态时,浏览器会甩掉掉此前做的优化工作。但是借使平素在体制表中显式注解了
    will-change
    属性,则象征目标元素可能会平常变化,浏览器会将优化办事保存得比以前更久。所以最佳实践是当元素变化以前和将来通过脚本来切换
    will-change 的值。

  • 不要过早应用
    will-change 优化:假若您的页面在性质方面没什么难点,则不用添加
    will-change 属性来榨取一丁点的进程。 will-change
    的设计初衷是当做最后的优化手段,用来尝试解决现有的品质难题。它不应有被用来防患质量难点。过度施用
    will-change
    会导致变化大量图层,进而导致大气的内存占用,并会招致更复杂的渲染进程,因为浏览器会臆想准备可能存在的变迁历程,那会导致更严重的习性难题。

  • 给它丰富的办事时间:这么些特性是用来让页面开发者告知浏览器哪些属性可能会生成的。然后浏览器能够选拔在变化暴发前提前去做一些优化办事。所以给浏览器一点光阴去真正做那一个优化工作是不行主要的。使用时索要尝试去找到一些艺术提前一定时间获知元素可能爆发的生成,然后为它助长
    will-change 属性。

* 渲染层

5. 选用 dev-tool 时间线 timeline 观望,找出导致高耗时、掉帧的最首要操作

层(layer)的定义对于有宏图基础的人来说应该不生疏,我们平面直观所观看标图像是依照空间图层的重合获得的,一般的话,拥有一致坐标空间的节点属于同一个渲染层。渲染层最初是用来贯彻层叠上下文,以此来保管页面元素以科学的次第合成(composite),达成半透明重叠等效用。

1)比较显示屏快照,观看每一帧包涵的情节及具体的操作

创制渲染层的规格:

2)找到掉帧的那一帧,分析该帧内不一致步骤的耗时占比,举行有指向的优化

  * 根元素(HTML)

3)观看是还是不是留存内存泄漏

 对于 timeline
的应用用法,那里有个尤其好的课程,通俗易懂,可以看看:

浏览器渲染优化
Udacity
课程

 

  * 有为之侧目标position属性(relative,fixed,sticky,absolute)

小结一下

对于盒子端
CSS
动画的习性,很多方面仍处于探索中,本文大量内容在前头小说已经冒出过,那里越来越多的是汇总计算提炼成可参看执行的流程。

本文的优化方案琢磨同样适用于
PC Web 及活动 Web,著作难免有错误及疏漏,欢迎不吝赐教。

  * 透明的(opacity小于1)

  * 有css滤镜(filter)

  * 有css mask 属性

  * 当前有对于 opacity,transform,fliter,backdrop-filter 应用动画

  * overflow属性不为visible

  * 等等……

* 合成层

合成层是杰出的渲染层,每个合成层有独立的绘图层,绘图层中的绘图上下文负责输出该层的位图,位图储存在共享内存中,作为纹理上传到GPU,最终由GPU将三个位图举行合成,最终绘制到显示屏上,而相对于合成层,一般的渲染层是和其首先个颇具绘图层的父层共用一个的绘图层的,升高为合成层后当需求repaint或reflow本身,不影响其余层,别的,合成层的位图会直接交由GPU合成处理,功效比CPU高。

渲染层升高为合成层的触及原因:

  * 直接原因

    * iframe video canvas flash 元素 有 3D transform

    * backface-visibility 为 hidden

    * 对 opacity、transform、fliter、backdropfilter 应用了
animation 或 transition

    * will-change(设置为
opacity、transform、top、left、bottom、right(其中 top、left
等急需设置显著的固定属性,如 relative 等))

   * 后代原因

    *亚洲必赢官网, 有合成层后代同时我有 transform、opactiy(小于
1)、mask、fliter、reflection 属性

    * 有合成层后代同时我 overflow 不为 visible

    * 有合成层后代同时自身 fixed 定位

    * 有 3D transform 的合成层后代同时自身有 preserves-3d 属性

    * 有 3D transform 的合成层后代同时自己有 perspective 属性

  * 重叠原因

    * 元素的 border box(content + padding + border)
和合成层的有臃肿,margin 的重合无效

    * 动画运行时期,元素可能和别的因素有臃肿

 

2.震慑页面品质的操作及优化分析

* 频仍操作DOM元素

运用js脚本频仍地操作DOM元素是熏陶页面品质的一大因素,频仍地对DOM进行操作可能造成页面重绘和回流的多次暴发,从而导致页面卡顿和属性消耗难点,从细节上可按如下方法开展优化:

1)使用文档片段

var fragment = document.createDocumentFragment();

//一些基于fragment的大量DOM操作
......

document.getElementById('myElement').appendChild(fragment);

2)设置DOM元素的display样式为none再操作该因素

var myElement = document.getElementById('myElement');
myElement.style.display = 'none';

//一些基于myElement的大量DOM操作
......

myElement.style.display = 'block';

3)复制DOM元素到内存中再对其进展操作

var old = document.getElementById('myElement');
var clone = old.cloneNode(true);

//一些基于clone的大量操作
......

old.parentNode.replaceChild(clone, old);

4)用一些变量缓存样式音信之所以幸免频仍获取DOM数据

//bad operation

for (var i = 0; i < paragraphs.length; i++){
    paragraphs[i].style.width = box.offsetWidth + 'px';
}

//better operation

var width = box.offsetWidth;
for (var i = 0; i < paragraphs.length; i++){
    paragraphs[i].style.width = width + 'px';
}

5)合并往往DOM操作

//bad operation

var left = 10, top = 10;
el.style.top = top;
el.style.left = left;

//better operation

el.style.cssText += "; left: " + left + "px; top: " + top + "px;";

//better operation(将样式内容设置于某一类名,再进行元素类名绑定)

el.className += " theclassName";

*css动画造成页面不流畅难点分析优化

运用css3动画造成页面的不流利和卡顿难题,其潜在原因反复仍旧页面的回流和重绘,收缩页面动画元素对其他因素的震慑是拉长品质的一直方向,而落成可正如:

1)设置动画元素position样式为absolute或fixed,可防止动画的进展对页面其它元素造成影响,导致其重排和重绘的爆发;

2)幸免使用margin,top,left,width,height等属性执行动画,用transform进行替代;

//bad operation

div {   
    height: 100px;   
    transition: height 1s linear;   
}   

div:hover {   
    height: 200px;   
}

//better operation

div {   
    transform: scale(0.5);   
    transition: transform 1s linear;   
}   

div:hover {   
    transform: scale(1.0);   
} 

可想而知,尽量用transform和opacity完结动画的来得,因为那七个属质量够防止重排和重绘的暴发。

页面渲染的流水线其实可概括表示为以下步骤,从性质方面考虑,应该尽量避开layout和paint八个步骤,只触发composite步骤,但眼下能不负众望这一效应的唯有transform和opacity多少个属性,其它索要专注的是:唯有元素升高为合成层的时候transform和opacity才不会触发paint,否则依然触发。

亚洲必赢官网 49

3)合理的晋级合成层,以减小页面不要求的绘图和重排

合成层的好处是不会影响到其它因素的绘图和不被其它层所影响,由此,为了互相从前的熏陶导致的特性损失,大家需合理的将动画片效果中的元素或一定元素升高为合成层。

晋级合成层的最好形式是选取 CSS 的 will-change 属性。将will-change 设置为
opacity、transform、top、left、bottom、right 可以将元素进步为合成层。

#target {
  will-change: transform;
}

will-target的兼容性如下:

亚洲必赢官网 50

对于还不合作该属性的浏览器,我们应用3D transform予以代替

#target {
  transform: translateZ(0);
}

对此像页面顶部栏,侧栏等稳定不变的岗位元素,我们也可将其进步为合成层以幸免其被其余因素影响而发生重绘,但要注意,合成层的擢升也表示品质的损耗增添,大家不能够不通过调节以测出合理的临界值,无法盲目升高合成层,其它,盲目进步合成层也说不定造成重叠发生的额外合成层,不难造成层爆炸的产出,即页面连锁出现多量合成层默许升高,提出用google的timeline进行监督调试,防止出现不须求的奇怪消耗。

 

网站地图xml地图