金沙棋牌官方平台

当前位置:金沙棋牌 > 金沙棋牌官方平台 > 金沙棋牌官方平台用CSS开启硬件加速来提高网站

金沙棋牌官方平台用CSS开启硬件加速来提高网站

来源:http://www.logblo.com 作者:金沙棋牌 时间:2019-11-06 08:14

记一次淘宝首页奇葩的渲染问题

2015/11/23 · CSS · 渲染

原文出处: 淘宝前端团队(FED)- 阎王   

金沙棋牌官方平台 1

或许你曾经在 Chrome 浏览器上碰到过这样让人瞠目结舌的问题:

  • hover 触发一个层展示,hover 离开后,这个层还遗留残影
  • 浏览器没有清理一个元素渲染的上一个状态,导致页面多出一个错位的跟该元素一模一样的影子
  • 交互时突然出现一个方形色块,覆盖在元素上
  • 或者还有更奇葩的……

以上列举到的三个问题,我在维护淘宝首页的时候都遇到过。这些都是浏览器渲染页面时,因为渲染引擎的 bug 导致的问题,不常见,更加难以写 demo 演示,它们只在特定的复杂场景下,程序计算存在误差或者漏洞的时候出现,尤其是涉及到边界判断的时候。

1. 何为硬件加速

CSS镂空图片transition过渡初加载背景色块问题解决

2016/02/25 · CSS · transition

原文出处: 张鑫旭(@张鑫旭)   

一、从哪里说起呢…

数年前写过一篇很实用的文章,介绍了一个很有创意的技术:“CSS背景色镂空技术实际应用及进阶”,讲的图标图形为了更容易控制其颜色,对图片采用了镂空的处理。例如,下面这张图片(点击会有随机的背景色):
金沙棋牌官方平台 2

于是,我们只要一套图片就可以实现各种颜色效果了!
金沙棋牌官方平台 3

而不要类似下面这样,为了各种状态凑齐完整的葫芦七兄弟:
金沙棋牌官方平台 4

除了节约图片资源大小,CSS镂空图片技术还有一个好处,就是由于我们的图标颜色是CSS属性控制的,因此,我们可以渐进使用transition实现过渡效果,让交互更细腻。

说到CSS控制图标颜色,我们自然而然会想到icon fonts, 或者使用SVG sprites技术,或者使用混合模式来实现。

然而,都是有不足的,比方说:
金沙棋牌官方平台 5

SVG的兼容性以及混合模式的理解成本和环境限制等。

因此,转了一圈,会发现,有时候,还是图片来得最实在,且看下面demo实现的效果,虽然使用的是background-image实现的,但是hover态,selected态都和文字hover transition过渡,这是传统背景图片所没法实现的。

您可以狠狠地点击这里:镂空背景图片下的transition过渡效果

一行:

transition: background-color .25s;

1
transition: background-color .25s;

就可以让交互变得细腻!

金沙棋牌官方平台 6

default, hover, selected三种颜色态仅仅一个系列图片就搞定(见下图),看上去很赞,赞到飞起来。

金沙棋牌官方平台 7

然而,这种实现有一个致命的不足,就是CSS的加载和背景图片的加载不是同步的,尤其首次加载的时候,图片是异步的,具有明显的延迟,于是,我们会看到非常丑陋的色块在一瞬间出现了(大家可以强刷demo体验到)! 金沙棋牌官方平台 8

金沙棋牌官方平台 9

正所谓“开发可忍设计不可忍”,这种问题显然是非常严重的,直接导致此看上去很酷的方法濒临夭折的边缘,看上去只适用于默认隐藏的元素。

大家莫慌莫慌,有我在呢!

引言          对于大多数Web开发者而言,Web页面的基本模型就是DOM模型。页面的渲染过程常常并不为人所知,大家只是知道它是一个将页面的DOM表示方式转化为在屏幕上显示的一个图片的过程。近几年,现代浏览器利用图形卡对页面渲染方式进行了改进:这种改进一般都笼统地称为“硬件加速”。当谈及普通Web页面(也即:非Canvas2D或者WebGL页面)时,硬件加速这个词到底意味着什么?本文将对作为Chrome中硬件加速下Web页面渲染基础的基本模型进行说明。
  冗长的注意事项          我们在这里讨论的是WebKit,更具体地讲,我们讨论的是Chromium下的WebKit。 本文所涉及的是Chrome的实现细节,而不是Web平台的特性。Web平台及其标准并没有对这个层次的实现细节做出详细的规定,所以我们并不能保证本文中的内容可以适用于其它的浏览器,但是对浏览器内部工作机理的了解定会有益于对应用进行高水平的错误调试和性能调优。          另外还要主意,整个这篇文章讨论的都是Chrome渲染架构中的一个核心部分,但这个结构仍在迅速变化之中。本文试图仅仅涉及那些不太可能发生变化的部分,但要是在6个月后再看这篇文章,那可就不一定是什么情况了。
       很重要的是要明白Chrome当下有段时间还会有两个不同的渲染途径:硬件加速式的渲染和早期软件式的渲染。直到写这篇文章之时为止,在Windows、ChromeOS和Android下的Chrome中,所有的页面都走的是硬件加速途径。在Mac和Linux下, 只有那些部分内容需要组合的页面才会走硬件加速途径(更多关于什么才需要组合的说明请参见下文),但用不了多久,所有页面将都会走硬件加速途径。
         最后要说的是,我们在这里的内容只是对Chrome的渲染引擎的管窥之见,所看到的只是其对性能影响比较大的一些特性。当你想要提高你的网站的性能时,对层模型有所了解会非常有帮助作用,但这也容易造成搬起石头砸自己脚的情况:层这种结构非常有用,但是创建过多的层会造成整个图形栈开销的增加。到时候可别说我没有提前警告过你哦!     从DOM到屏幕   层的引入          页面一旦在装入并解析完成后,就会表示为许多Web开发者所熟悉的结构:DOM。然而,在页面的渲染过程中,浏览器还具有一系列并不直接暴露给开发者的页面中间表示方式。这些表示方式中最重要的结构就是层。
       在Chrome中实际上有几种不同类型的层:掌管DOM子树的渲染层(RenderLayer)以及掌管渲染层子树的图形层(GraphicsLayer)。 我们这里最关心的是后者,因为作为纹理上传到GPU之中的就是图形层。本文自此就只用“层”来指代图形层了。          稍稍离题说一下同GPU有关的几个术语:什么是纹理?纹理可以看作是位图图像,从主存储器(也就是RAM)传递到视频存储器(也就是GPU之上的VRAM)之中的就是这个图像。一旦传递到GPU之中后,你就能够将纹理映射到一个网格几何结构之上 —— 在视频游戏或者CAD程序中,这种技术用来给框架式的3D模型添加“皮肤”。Chrome采用纹理把页面中的内容分块发送给GPU。纹理能够以很低的代价映射到不同的位置,而且还能够以很低的代价通过把它们应用到一个非常简单的矩形网格中进行变形。这就是3D CSS的实现原理,而且这么做对页面在屏幕的快速滚动也非常好 —— 现在先说这些,这两方面更详细的探讨情况下文。
下面让我们用几个例子来说明层的概念。          在Chome中研究层时有一个非常有用的工具就是Chrome的开发者工具里设置(也就是那个小齿轮图标)中“渲染(rendering)”小标题下的“显示层的组合边界(show composited layer borders)”开关。让我们把这个开关打开。本文中所有的截屏和例子都来自最新版的Chrome Canary,在写这篇文章的时候是Chrome 27。
图1: 只有一层的页面 (将在新窗口中打开) 1  <html> 2    <body> 3      <div>I am a strange root.</div> 4    </body> 5 </html> (译者注:这里缺了一个图,原文中的图就看不到,可能是需要翻墙?) 

问题复现

很难得有机会让我碰到一个可以复现的,我把它记录下来了。如下图所示,hover 到学习模块的边界位置时:

金沙棋牌官方平台 10

手动 hover 和模拟 hover 都有一样的问题,没有多想,立马加上了一句话修复了这个问题:

CSS

.channel2 .channel-item { transform: translateZ(0); }

1
2
3
.channel2 .channel-item {
    transform: translateZ(0);
}

这个不是直觉,多次遇到这种奇葩问题,我第一想到的便是使用 3D 加速将这个渲染层隔离渲染,80% 以上的概率能够解决问题,而解决问题的关键在于找准加这句代码的 DOM 元素。

就是将浏览器的渲染过程交给GPU处理,而不是使用自带的比较慢的渲染器。这样就可以使得animation与transition更加顺畅。

二、base64 url图片与异步色块问题解决

这个很好理解,就是把背景图片转换成base64 url图片,因为是集成在CSS文件中的,因此,基本上是同时呈现,不会出现色块。然而,此方法局限性很明显,就是只适用于一些尺寸很小的小图。类似上面demo的背景图片,有5K多大小,直接内嵌在CSS文件中,就像是身体里长了个瘤子,太笨重了,而且base64渲染是比较烧性能的,图片越大越慢,且IE7浏览器很难支持base64图片。

因此,此方法在这里不适用,难道要天亡我也?非也!

在页面的基本层中组合层的渲染边界屏幕截图
       这个页面只有一层。蓝色的栅格表示的是分块,这些分块可以看作是比层更低一级的单位,Chrome以这些分块为单位,一次向GPU上传一个分块的内容。这里它们并不怎么重要。   图2:有自己的层的元素 (open stand-alone) 1  <html> 2    <body> 3      <div style="-webkit-transform: rotateY(30deg) rotateX(-30deg); width: 200px;"> 4        I am a strange root. 5      </div> 6    </body> 7  </html>   (译者注:这里缺了一个图,原文中的图就看不到,可能是需要翻墙?) 
旋转后层的渲染边界的截屏        在<div>上加上让它旋转一个角度的3D CSS属性后,我们就能够看到一个元素有自己的层是个什么样子:请注意其中的橘色边界,这个边界给出了这个视图中层的轮廓。   层的创建准则   还要其它什么元素会得到自己的层?Chrome在这方面采用的规则仍在随着时间推移逐渐发展变化,但在目前下面这些因素都会引起Chrome创建层:

探索 bug

这个层在我的代码中肯定是不存在的,我们只能用 bug 来形容这个问题。因为元素刚好贴在 .channel2 的边界,猜测应该跟层渲染有关,于是打开了控制台 ESC -> Rendering -> Show layer borders,看到了这个:

金沙棋牌官方平台 11

仔细观察,可以看到,这个粉色块在瓦片边界和父元素边界之中,可以断定,这几个瓦片在渲染的时候存在问题。


这里需要补充下关于瓦片的知识。瓦片,英文里头称之为 tile,它是 webkit/blink 渲染页面时的中间过程,将整个页面分成多个大小一样的瓦片,并发渲染每个瓦片的内容。一个元素开启 3D 硬件加速之后,会变成一个独立的层,这个层的渲染也会被分割成瓦片,可以想象成一个子页面。

瓦片和瓦片之间的边界计算是处理的难点,因为渲染的内容不能错位。


其实让我找到问题根本原因的是,rendering 块的颜色,平时在网页上开启 show layer borders 看到的是半透明的绿色块,而这里显示的是粉色块,搜索了下不同色块代表的含义,没找到具体的文档说明,但是找到了 金沙棋牌官方平台,代码:

JavaScript

// Missing resize invalidations are in salmon pink. SkColor DebugColors::MissingResizeInvalidations() { return SkColorSetARGB(255, 255, 155, 170); }

1
2
3
4
// Missing resize invalidations are in salmon pink.
SkColor DebugColors::MissingResizeInvalidations() {
  return SkColorSetARGB(255, 255, 155, 170);
}

对应的就是这个颜色,“缺失调整验证”,在 chromium 的源码仓库中搜了上面的代码,找到了 具体说明:

JavaScript

if (!deflated_content_rect.Contains(canvas_playback_rect)) { if (clear_canvas_with_debug_color) { // Any non-painted areas outside of the content bounds are left in // this color. If this is seen then it means that cc neglected to // rerasterize a tile that used to intersect with the content rect // after the content bounds grew. canvas->save(); canvas->translate(-canvas_bitmap_rect.x(), -canvas_bitmap_rect.y()); canvas->clipRect(gfx::RectToSkRect(content_rect), SkRegion::kDifference_Op); canvas->drawColor(DebugColors::MissingResizeInvalidations(), SkXfermode::kSrc_Mode); canvas->restore(); } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if (!deflated_content_rect.Contains(canvas_playback_rect)) {
  if (clear_canvas_with_debug_color) {
    // Any non-painted areas outside of the content bounds are left in
    // this color.  If this is seen then it means that cc neglected to
    // rerasterize a tile that used to intersect with the content rect
    // after the content bounds grew.
    canvas->save();
    canvas->translate(-canvas_bitmap_rect.x(), -canvas_bitmap_rect.y());
    canvas->clipRect(gfx::RectToSkRect(content_rect),
                     SkRegion::kDifference_Op);
    canvas->drawColor(DebugColors::MissingResizeInvalidations(),
                      SkXfermode::kSrc_Mode);
    canvas->restore();
  }
}

这里能看的肯定就是注释啦,没有太多上下文,看的挺头痛!大致翻译了下上下几段注释:

  1. 即使完全覆盖,对于触碰到渲染层边界的栅格化处理,我们依然需要,在上次记录没有覆盖到的纹理下方和纹理化线性过滤的上方,栅格化处理背景颜色。
  2. 内容的最后的纹理可能只有部分被栅格覆盖
  3. 在内容边界外没有被渲染到的部分将使用 MissingResizeInvalidations 颜色,如果这个块能够被看见,那就意味着程序忽视处理了内边边界增长之后栅格化与内容相交的瓦片。

从第三句大致可以了解到,因为元素的边界增长导致了这个渲染 bug,回头看了下元素的边界状态,果然…

我们可以在浏览器中用css开启硬件加速,使GPU (Graphics Processing Unit) 发挥功能,从而提升性能

三、content url图片与异步色块问题解决

6年前,也就是10年的时候,我在“CSS content内容生成技术以及应用”一文中首次介绍了CSS content url图片内容生成技术,就是before, after伪元素可以直接插入图片,注意,是直接图片,不是元素的背景图,语法如下:

.demo:after { content: url(xxx.png); }

1
.demo:after { content: url(xxx.png); }

OK, 大家如果观察过页面图片的加载,应该注意到这么个现象,就是如果图片没有通过HTML属性或者CSS值限定width/height宽高的时候,在浏览器get到图片的原始尺寸之前,图片占据的空间大小是0. 我们如果刷新浪微博,会发现页面高度蹭蹭蹭地往上涨,就是这么个原因,这种不对图片限定尺寸的做法在网页布局中是不推荐的,因为,会造成页面布局重绘,影响加载性能。

但是,存在必有道理,在这里,我们就可以好好地利用图片为加载时候占据空间为0的特性避免出现色块的问题,怎么解决呢?就是把元素的background-image url值变成伪元素的content url值;同时background-position定位改成其他定位,如relative定位,如下代码示意:

.icon { width: 140px; height: 140px; background: #c8c8c8 url(icon.png) no-repeat 0 -140px; } ↓ .icon { /* 注意,只设高度不设宽度 */ height: 140px; background-color: #c8c8c8; overflow: hidden; } .icon:after { content: url(icon.png); position: relative; top: -140px; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.icon {
    width: 140px; height: 140px;
    background: #c8c8c8 url(icon.png) no-repeat 0 -140px;
}
.icon {
    /* 注意,只设高度不设宽度 */
    height: 140px;
    background-color: #c8c8c8;
    overflow: hidden;
}
.icon:after {
    content: url(icon.png);
    position: relative;
    top: -140px;
}

上面绿色注释“只设高度不设宽度”点出了实现的关键:

页面渲染流程如下,1. CSS加载;2. 对应DOM渲染,背景色出现;3.拉取DOM样式对应背景图片。

传统实现就是从2到3的时候出现了问题,图片从服务器重新请求,导致了时间差,出现了色块。而我们这里的实现就不一样,当我们背景色出现,但是图片未加载的时候,由于我们的CSS没有设置元素的宽度,加上图片未加载占据宽度为0的特性,于是,在2完成3即将进行的时候,我们整个元素的高度140px, 宽度0,宽度是0啊!这意味着什么,意味着元素看不见啊,也即是虽然有背景色,无奈尺寸为0,我们是看不出有一丝丝背景色的;然后等图片请求到,自然就填满了元素,背景色也被遮掉了。没有了时间差,于是,完美解决了色块出现的问题!

金沙棋牌官方平台 12

您可以狠狠地点击这里:content url生成的解决色块问题demo

IE7浏览器
什么年代了,还IE7浏览器,要是喜欢,可以使用expression表达式,或者直接JS打个补丁,小弟我现在对这些浏览器不奉陪了!

  • 进行3D或者透视变换的CSS属性
  • 使用硬件加速视频解码的<video>元素
  • 具有3D(WebGL)上下文或者硬件加速的2D上下文的<canvas>元素
  • 组合型插件(即Flash)
  • 具有有CSS透明度动画或者使用动画式Webkit变换的元素
  • 具有硬件加速的CSS滤镜的元素
  • 子元素中存在具有组合层的元素的元素(换句话说,就是存在具有自己的层的子元素的元素)
  • 同级元素中有Z索引比其小的元素,而且该Z索引比较小的元素具有组合层(换句话说就是在组合层之上进行渲染的元素)

直接原因

我们看看 hover 上去之后,层边界的变化:

金沙棋牌官方平台 13

很明显,这里的高度溢出了,但是没有处理,看了下这个元素的 css,确实高度上没有做处理,在元素上添加

CSS

.channel-item { overflow: hidden; }

1
2
3
.channel-item {
  overflow: hidden;
}

同样可以解决问题。

最后的解决手段:

金沙棋牌官方平台 14

层渲染的问题我还是比较喜欢使用 3d 硬件加速来处理,而 overflow:hidden 这样的 css 布局处理上,我是不太推荐的,搞不好就把哪个重要的内容隐藏掉了。

现在大多数电脑的显卡都支持硬件加速。鉴于此,我们可以发挥GPU的力量,从而使我们的网站或应用表现的更为流畅。

四、结束语

我测试发现,时间差似乎就Chrome浏览器比较明显,另外后面的content url有一定几率会出现最后一个有色块的情况,按照道理应该不会的,现在太晚了,都2点了,我有时间在研究研究。

金沙棋牌官方平台 15

相关文章

  • CSS背景色镂空技术实际应用及进阶 (0.695)
  • 未来必热:SVG Sprite技术介绍 (0.244)
  • IE6下png背景不透明问题的综合拓展 (0.225)
  • CSS3图标图形生成技术个人攻略 (0.225)
  • javascript HEX十六进制与RGB, HSL颜色的相互转换 (0.169)
  • SVG图标颜色文字般继承与填充 (0.169)
  • SVG-Morpheus实现SVG图标图形间的补形动画 (0.169)
  • CSS1-CSS3 颜色知识知多少? (0.169)
  • 伪类+js实现CSS3 media queries跨界准确判断 (0.136)
  • CSS content内容生成技术以及应用 (0.097)
  • 小tip: 某简单的字符重叠与图形生成 (RANDOM – 0.075)

    1 赞 2 收藏 评论

金沙棋牌官方平台 16

实际意义:动画   我们还可以将层在页面中到处移动,正好可用于动画。 图3: 动画层(将在新窗口中打开) 01  <html> 02  <head> 03      <style type="text/css"> 04      div { 05          -webkit-animation-duration: 5s; 06          -webkit-animation-name: slide; 07          -webkit-animation-iteration-count: infinite; 08          -webkit-animation-direction: alternate; 09          width: 200px; 10          height: 200px; 11          margin: 100px; 12          background-color: gray; 13      } 14      @-webkit-keyframes slide { 15          from { 16              -webkit-transform: rotate(0deg); 17          } 18          to { 19              -webkit-transform: rotate(120deg); 20          } 21      } 22      </style> 23  </head> 24  <body> 25      <div>I am a strange root.</div> 26  </body> 27  </html>          正如前文所述,层在将Web页面中的静态内容随处移动方面真的很有用。在最基本的情况下,Chrome将层中的内容绘制到软件位图中,然后再将该位图作为纹理上载到GPU之中。如果层中的内容将来不会发生变化,那就不需要对其进行重绘了。这是个好事:重绘将会占用本可以用于干其它事情,比如运行JavaScript的时间,而且如果绘制过程太长,动画还会出现卡顿现象。
       例如,可以在Chrome的开发工具中看一下这个页面的时间线:但该层在来回旋转的时候,并没有出现绘制操作。 动画过程中的开发者工具时间线屏幕截图   无效!重绘   但是如果层中的内容发生了改变,它就需要重绘了。
  图4:层的重绘 (将在新窗口打开) 01  <html> 02  <head> 03    <style type="text/css"> 04    div { 05        -webkit-animation-duration: 5s; 06        -webkit-animation-name: slide; 07        -webkit-animation-iteration-count: infinite; 08        -webkit-animation-direction: alternate; 09        width: 200px; 10        height: 200px; 11        margin: 100px; 12        background-color: gray; 13    } 14    @-webkit-keyframes slide { 15        from { 16            -webkit-transform: rotate(0deg); 17        } 18        to { 19            -webkit-transform: rotate(120deg); 20        } 21    } 22    </style> 23  </head> 24  <body> 25    <div id="foo">I am a strange root.</div> 26    <input id="paint" type="button" onclick="" value=”repaint”> 27    <script> 28      var w = 200; 29      document.getElementById('paint').onclick = function() { 30      document.getElementById('foo').style.width = (w++)

类似问题处理方案

如果以后大家遇到类似的问题,可以打开 chrome 的层和瓦片分析工具,看看渲染出来的块有没有异常色块,尤其是粉色块。也可以观察交互过程中,元素的边界有没有变化。

CSS 在浏览器中的渲染是我们触及比较少的知识,如果想迅速找到问题,必须对浏览器的渲染原理有所了解,并且能够熟练的使用 chrome 提供的调试工具,这是基础。

1 赞 1 收藏 评论

金沙棋牌官方平台 17

2硬件加速原理

  • 'px'; 31      } 32    </script> 33  </body> 34  </html>
             每次点击按钮后,旋转中的元素的宽度就会增加1px。这将导致页面重新布局,整个元素都需要重绘,在这个例子中需要重绘的是整个层。 查看Chrome重绘了哪些元素的一个很好的办法是使用开发者工具中的“显示绘制矩形”开关,这个开关同样也在开发者工具设置中的“渲染”标题下。打开该开关后,在点击按钮的时候请注意动画中的元素和按钮周围都会有一个红色的矩形闪现。
      金沙棋牌官方平台 18
      显示绘制矩形检查框的屏幕截图          同时绘制时间也出现在开发者工具里的时间线中了。明眼的读者可能还注意到这里有两个绘制事件:一个是层的,另外一个是按钮的。按钮会在它的状态变成按下状态和从按下状态变为非按下状态时需要进行重绘。   金沙棋牌官方平台 19

浏览器接收到页面文档后,会将文档中的标记语言解析为DOM树。DOM树和CSS结合后形成浏览器构建页面的渲染树。渲染树中包含了大量的渲染元素,每一个渲染元素会被分到一个图层中,每个图层又会被加载到GPU形成渲染纹理,而图层在GPU中transform 是不会触发 repaint 的,最终这些使用 transform 的图层都会由独立的合成器进程进行处理。

开发者工具时间线中层的重绘的屏幕截图
       请注意Chrome并不总是需要重绘整个层,它会尽量地以聪明的方式只绘制DOM中发生变化的那部分内容。在我们的这个例子中,我们所改变的DOM元素是整个层的尺寸。但是在很多情况下,在一层中会有大量的DOM元素。          很显然接下来的问题是页面内容失效和强制进行重绘是由什么引起的。要全面回答这个问题并不容易,因为引起强制进行重绘的有大量不太容易区分的情况。其中最常见的原因是通过操纵CSS样式或者引起重新进行页面布局来改变DOM的特性。Tony Gentilcore写了一篇很不错的讨论引起页面重新布局的原因的博文,Stoyan Stefanov有一篇更近详尽地讨论浏览器绘制过程的文章(但这篇文章仅仅止于绘制过程,并没有涉及奇特的组合部分的内容)。找出重绘是否影响到了某些你正在关注中的元素的最好方式是使用开发者工具中的时间线以及“显示绘制矩形”工具,用这两个工具能够看出浏览器是否在重绘一些你并不认为需要重绘的内容,然后找出就在重新布局/重绘前的那个时刻之前到底是在哪里改变了DOM结构。如果绘制过程无法避免但绘制过程却长的不太合理,请参考一下Eberhard Gräther的文章,这是一篇关于在开发者工具中如果对持续性绘制模式进行性能优化的文章。   Chrome是如何将DOM转换为屏幕上的图像的呢?从概念上讲,它:

CSS transform 会创建了一个新的复合图层,可以被GPU直接用来执行 transform 操作。

  • 取得DOM并将其分成若干个层
  • 分布将这些层绘制到各自的软件位图中
  • 将绘制好的位图作为纹理上载至GPU之中
  • 将这些不同的层组合起来形成屏幕上最后显示出的图像

浏览器什么时候会创建一个独立的复合图层呢?事实上一般是在以下几种情况下:

这些步骤在Chrome第一次产生Web页面的帧时都需要执行。但是在产生随后的帧时,就可能会走一些捷径:

  • 3D 或者 CSS transform
  • <video> 和 <canvas> 标签
  • CSS filters
  • 元素覆盖时,比如使用了 z-index 属性
  • 如果有某些CSS属性发生了改变,就并不一定要重绘所有的内容了。Chrome能够将已经作为纹理保存在GPU之中的层重新组合起来,但只是在重新组合时,使用不同的组合属性(比如,在不同的位置、以不同的透明度来组合等等)。
  • 如果某一层中的某个部分的内容变成无效的了,那么该层就需要重绘并在重绘完成后重新上载至GPU中。如果其内容仍然不变,只是其组合属性发生了变化(比如它的位置或者透明度改变了),Chrome就不会对GPU中该层的位图做任何处理,只是通过重新进行组合来生成新的帧。

 

         现在大家应该弄清楚了,基于层的组合模型对渲染性能有着非常大的意义。在没有需要重新绘制的内容时,组合的代价相对来说代价更低一些,所以在调试渲染性能时,避免层的重绘是一个非常好的总体目标。经验老道的开发者会去看上文提到的组合触发的列表,并意识到很可能会非常容易的导致浏览器创建很多层。但是,一定要小心无意识地去创建层,因为使用层是有代价的:它们会占用系统RAM以及GPU中的存储空间(移动设备上的存储空间特别有限),层太多的话还会在跟踪哪些从可见哪些层不可见的算法中引入额外的开销。如果层都很大而且原先不重叠的层突然重叠了起来,那么太多的层就会增加浏览器花在栅格化方面的时间,这会导致有时称之为“过度绘制”的情况。所以,一定要明智地运用你所学到的知识! 暂时先写到这里了。请你以后再到这里来查看另外几篇关于层模型实际意义的文章。

3 为什么硬件加速会使页面流畅

其它参考资料

因为 transform 属性不会触发浏览器的 repaint(重绘),而绝对定位absolute中的 left 和 top 则会一直触发 repaint(重绘)。

  • Scrolling Performance
  • Profiling Long Paint Times with DevTools' Continuous Painting Mode

为什么 transform 没有触发 repaint 呢?简而言之,transform 动画由GPU控制,支持硬件加速,并不需要软件方面的渲染。

英文原文:Accelerated Rendering in Chrome - The Layer Model

 

对于大多数Web开发者而言,Web页面的基本模型就是DOM模型。页面的渲染过程常常并不为人所知,大家只是知道它是一个将页面的DOM表示...

浏览器什么时候会创建一个独立的复合图层呢?事实上一般是在以下几种情况下:

3D 或者 CSS transform

<video> 和 <canvas> 标签

CSS filters

元素覆盖时,比如使用了 z-index 属性

 

4并不是所有的CSS属性都能触发GPU的硬件加速,实际上只有少数属性可以,比如下面的这些:

transform

opacity

filter

 

 

5.如何在桌面端和移动端用CSS开启硬件加速

CSS animations, transforms 以及 transitions 不会自动开启GPU加速,而是由浏览器的缓慢的软件渲染引擎来执行。那我们怎样才可以切换到GPU模式呢,很多浏览器提供了某些触发的CSS规则。

现在,像Chrome, FireFox, Safari, IE9+和最新版本的Opera都支持硬件加速,当它们检测到页面中某个DOM元素应用了某些CSS规则时就会开启,最显著的特征的元素的3D变换。

例如:

.cube {

   -webkit-transform: translate3d(250px,250px,250px)

   rotate3d(250px,250px,250px,-120deg)

   scale3d(0.5, 0.5, 0.5);

}

可是在一些情况下,我们并不需要对元素应用3D变换的效果,那怎么办呢?这时候我们可以使用个小技巧“欺骗”浏览器来开启硬件加速。

虽然我们可能不想对元素应用3D变换,可我们一样可以开启3D引擎。例如我们可以用transform: translateZ(0); 来开启硬件加速 。

.cube {

   -webkit-transform: translateZ(0);

   -moz-transform: translateZ(0);

   -ms-transform: translateZ(0);

   -o-transform: translateZ(0);

   transform: translateZ(0);

   /* Other transform properties here */

}

在 Chrome and Safari中,当我们使用CSS transforms 或者 animations时可能会有页面闪烁的效果,下面的代码可以修复此情况:

.cube {

   -webkit-backface-visibility: hidden;

   -moz-backface-visibility: hidden;

   -ms-backface-visibility: hidden;

   backface-visibility: hidden;

   -webkit-perspective: 1000;

   -moz-perspective: 1000;

   -ms-perspective: 1000;

   perspective: 1000;

   /* Other transform properties here */

}

在webkit内核的浏览器中,另一个行之有效的方法是

.cube {

   -webkit-transform: translate3d(0, 0, 0);

   -moz-transform: translate3d(0, 0, 0);

   -ms-transform: translate3d(0, 0, 0);

   transform: translate3d(0, 0, 0);

  /* Other transform properties here */

}

原生的移动端应用(Native mobile applications)总是可以很好的运用GPU,这是为什么它比网页应用(Web apps)表现更好的原因。硬件加速在移动端尤其有用,因为它可以有效的减少资源的利用(移动端本身资源有限)。

 

6.使用硬件加速的问题

使用硬件加速并不是十全十美的事情,比如:

1内存。如果GPU加载了大量的纹理,那么很容易就会发生内容问题,这一点在移动端浏览器上尤为明显,所以,一定要牢记不要让页面的每个元素都使用硬件加速。

2使用GPU渲染会影响字体的抗锯齿效果。这是因为GPU和CPU具有不同的渲染机制。即使最终硬件加速停止了,文本还是会在动画期间显示得很模糊。

 

总结

只对我们需要实现动画效果的元素应用以上方法,如果仅仅为了开启硬件加速而随便乱用,那是不明智的。

小心使用这些方法,如果通过你的测试,结果确是提高了性能,你才可以使用这些方法。使用GPU可能会导致严重的性能问题,因为它增加了内存的使用,而且它会减少移动端设备的电池寿命。

 

本文由金沙棋牌发布于金沙棋牌官方平台,转载请注明出处:金沙棋牌官方平台用CSS开启硬件加速来提高网站

关键词: