一 三个基友一起玩,一人不举

人总是会无聊的~某天心血来潮突然想试试实现通过鼠标移动实现多图层视差移动的伪3D效果~于是就直接从之前做的比赛用PPT中扒了几张云鸟图出来,就是下面几张~除了第一张其它都是透明背景的~

01

要如何实现呢?想都没想(其实还是想了想的~)就决定把图片设置为position:fixed,然后用JS通过获取鼠标位置来对四张图片的定位进行修改,没多久就写好了

02
点我看demo啦~
(其实写了挺久,一开始只是想鼠标指哪到哪,后来觉得不满意就实现了加速度,再后来想加行文字吧~文字得会发光~哦对了~鸟不能只移动,还得加点旋转效果…………)

写好了当然要测试啦~~

编写时测试用的是IE10,1080P分辨率下看起来很顺滑流畅很好玩根本停不下来;

然后试了试Firefox,1080P分辨率下看起来很顺滑流畅很好玩根本停不下来;

最后试了试Chrome,1080P分辨率下看起来…………诶好卡!简直是幻灯片!(不,现在幻灯片都有60fps了……)

怎么会这样呢?这么好玩的东西怎么可以不兼容我大Chrome?

二 “你们这样帮我都没用,看来我是真的不行了”

当时道行尚浅(现在依旧不深……),百思不得其解,简化算法、降低刷新率(一开始我用的是setTimeout()函数来递归循环,刷新间隔是16ms,约等于60fps的速度),均得不到良好的效果,使用Chrome自带的dev tools发现帧率连15fps都不到……

然后呢?各种百度都无结果,于是只好厚脸皮去CSDN论坛上发帖啦~不过和以往的结果一样,一些人提出了一些建议,但没有效果,另一些人说亲测没有问题……陷入死胡同了呢……

1135545574118914d8o

嘛~也不能说发帖完全没有用吧~有人说没有问题,于是考虑到分辨率,我试着缩小窗口,然后还真的不卡了,于是顿时明白了,问题不是js执行太慢,而是页面绘制太慢……

(果然道行太浅,这么明显的问题怎么都想不到QQ图片20140729234218

既然小屏幕上不卡就说明速度是慢在绘制上咯?有没啥能查看绘制速度的工具呢?瞎猫摸鱼,还真给我找到了= -……Chrome自带的Dev tools有个叫Timeline的功能,可以检测页面性能(咳咳~),以时间轴图表的方式很形象的呈现出来:

03

测试结果还挺符合猜想,处理脚本和应用样式只花了几毫秒,而绘制居然花费了70毫秒……Chrome你当真不会画画么,好吧,也许几个这么大的透明图层的确比较复杂,可我在试着减少一半图层后依旧会卡,这就不科学了,连人家IE和Firefox一半的速度都达不到(连我的WP8手机开这个都不会卡啊= -),简直不能再做朋友啊……

三 “没有你在怎么行!别担心,我有新的玩法~”

问题一定是有解的,毕竟之前也看过国外一些有大面积动画的页面,一点都不卡~于是试着Google了一下Chrome的重绘问题,还真有所发现,有人建议使用CSS3的transform属性来实现动画,而不是top、left等定位属性,因为修改定会属性会影响布局,导致回流(不是说绝对定位不会发生回流么……)和重绘,而transform仅仅只是对元素的“像”进行变换(我猜的,因为看起来的确是这样……)不会影响布局,只需要重绘图像就可以了,性能会好挺多~

于是我就把所有的定位操作变成修改transform属性啦~
点我看demo啦~

然后再次测试,果然Chrome也可以1080P分辨率下看起来很顺滑流畅很好玩根本停不下来了!

04

为了对比一下渲染时间,再次测试了一下,惊呆了,不仅没有Layout(回流),这回连Paint(重绘)都省了~好厉害,其原因应该是transform变化是可以使用硬件加速的,如果有启用硬件加速的话就相当于直接通过显卡类移动纹理之类的操作进行渲染,直接重新混合图层就可以了,连重绘都免了,速度甩CPU好几条街……

不过不知道Chrome为什么重绘速度这么慢,后来我使用IE11的F12工具进行性能监测,发现之前通过修改绝对定位的方法在IE上也是会引起回流和重绘的(Firefox应该也是一样,另外虽然IE前后的呈现时间都在16ms以内,但通过新方法的速度还是比旧方法高了不止2倍),但同样是重绘,IE和Firefox的重绘速度比Chrome快了10倍左右,这实在难以解释,我有怀疑过是webkit核心的原因,可是经过测试Safari并没有问题……所以只能说是Chrome本身的问题了,嗯太高深了不想了不想了……

xes_46a9dd70d8b15cac55feb8ff6bfdab52不想再想了啦_(:3」∠)_

 

现在硬件加速在浏览器页面呈现过程中越来越重要,将网页元素作为图像使用显卡进行渲染可以大幅度提升页面呈现速度和滚动效率,尽管使用新的方法不兼容IE10以下的浏览器,不过向前看总是好的,老一辈浏览器们就好好休息啦~

更新!

在最新的Chrome37上测试发现老方法的新能比以前提高了很多,虽然还是存在丢帧现象,但相对已经不明显了~