(移动)浏览器中针对CSS3硬件GPU加速优化基于SVG的精灵表

在过去的一周里,我一直在帮助朋友在浏览器中使用基于SVG的精灵表单进行实验。 我们想要提出一个理想的工作stream程 ,在浏览器中准备,发布和运行高质量的animationgraphics。 所以最好有一个animation数据源,可用于小型智能手机屏幕,平板电脑,视网膜显示器和桌面浏览器。

从理论上讲,基于vector的SVG应该是理想的,但是由于SVG通常不被使用,所以我们决定对它进行testing。 这个想法不是使用SMIL SVG(所以没有基于SVG的animation),而是创build一个animation精灵表(像通常的光栅数据PNG / JPG一样),但是用纯vector即SVG来做。 它有点大,但是如果这样做的话 – 甚至可以更好地进行工作。

加上逐帧的vectoranimation可以为我们的工作stream程做很多事情 – 它可以让我们使用Flash编辑器来做animation,然后将它们导出到SVG精灵表。

无论如何, 结果出人意料的好,但也在一些地区失败(请注意,为了testing目的,我们只使用基于Webkit的浏览器,例如Safari,Chrome,iOS上的移动Safari和Android ICS)。

在CSS中,像这样触发一个精灵表的硬件加速是非常容易的(至less在具有关键帧和步骤的现代浏览器中) – 你只需要这样做:

background-image: url(my.svg); -webkit-animation: walk 1s steps(12, end) infinite; 

调用此处显示的基于关键帧的animation:

 @-webkit-keyframes walk { from { -webkit-transform: translate3d(0, 0, 0); } to { -webkit-transform: translate3d(-100%, 0, 0); } } 

在iOS移动版Safari和Android ICS浏览器中,translate3d的使用应该让GPU能够使用硬件加速。

令人惊讶的是,考虑到这是一种蛮力技术和相当大的vectoranimation(600x600px的testing) – 整个事情飞行。 但它并不完美 – 它在起飞之前在Safari中闪烁。 而在ICS浏览器中它一直闪烁,所以它不是真正可用的。

所以我们尝试了通常的方法来摆脱闪烁,比如:

 -webkit-transform: translateZ(0); -webkit-backface-visibility: hidden; -webkit-perspective: 1000; 

但是这没有用。 于是我们试着在内存中dynamic地光栅化SVG,并用-webkit-transform:scale3d(1,1,0)作为纹理使用它但是这并没有帮助ether。

最后,我们用一个大小相同的PNG / JPG精灵表单replace了SVG,因为复杂的vector对于浏览器来说太多了 – 但是猜猜怎样? 它同样的问题 – 所以它不是SVG渲染 – 它的浏览器绘图问题。 进一步的certificate是,如果我们放慢animation到1FPS – 闪烁仍然存在。

GPU对于图像太大了吗? 我们是否达到了在浏览器(特别是移动设备)上能够轻松绘制/绘制animation的性能极限?

我真的很感激想法/黑客如何潜在摆脱闪烁(尤其是因为它的performance太快)。 它只是一个有前途的技术 – 高性能的浏览器animation,适应不同的屏幕尺寸 – HTML5圣杯 ;)

通过一些优化如

 <svg preserveAspectRatio="xMinYMax slice" viewBox="0 0 600 50"> 

和一些CSS魔术,我们可以让SVG完美地适应它的容器,并从一个CSS类改变它的大小。 这真的会创造奇迹 – 但唉,闪烁。

无论如何 – 请阅读更多关于它的地方 ,你也可以尝试一下

非常酷的想法。

如何更改帧的zindex,以便将图像层叠在一起? 这可能会解决闪烁,因为在重绘过程​​中,最后一帧仍然可见。 所以,你只是不断增加最新帧的zindex值。 当然,这是有限制的,你需要重新设置zindex,但是它可能会对减less闪烁产生很大的影响。

我没有ICS在这里检查出来,但在iPhone 5上的iOS 6和Galaxy Nexus上的Jelly Bean 4.1.1上,animation看起来非常平滑, 除了放大时,我会得到一些闪烁帧然后再安定下来。

这让我想起了一个类似的问题,我把它渲染到一个大的canvas上,并在屏幕上转换(大部分canvas在任何给定的时间)。

当时我的黑盒分析表明,在浏览器不打扰屏幕内容的情况下进行了一些优化,而是一直等到显示出来,这完全破坏了大图像和硬件加速的目的。

我的“解决scheme”是-webkit-transform:将整个图像缩小到足以保证所有图像都适合在屏幕上(因此浏览器别无select,只能渲染整个图像),让它渲染,然后扩展到我想要的大小。

(另外:为了隐藏用户的这个黑客,我最初尝试设置不透明度:0,所以预渲染将不可见,但它看起来和离屏渲染有相同的效果 – 它被优化了。最后,我设置的透明度非常低,并用几乎不透明的“加载”消息覆盖,这意味着背景渲染肉眼不可见,但浏览器没有绝对可见/不可见的优化。是过分的,但它似乎适用于我的设置。)

我很想知道是否有类似的技术可以为你工作。