滚动视差效果的实现及优化方案
前言
相信大家对页面滚动视差效果都有一定的了解,滚动视差就是利用多层背景加上利用鼠标拖动滚动条来形成一些像动画一样的视觉效果。
项目地址:http://nostos.163.com/
使用background-attachment:fixed及改变background-position去实现视差效果
接到要做一个视差滚动的效果需求时,脑海中立刻浮现了一个解决方案,通过background-attachment:fixed把背景固定,然后计算滚动条的拖动位置去改变不同背景图的background-position来实现。
然而,事情往往没那么简单,由于这次项目要兼容到2560px宽度的屏幕分辨率,图片质量要求又高,图片尺寸又大。在不同主流浏览器上明显出现了不同程度卡帧的情况。既然出现卡顿的情况,我们就要想办法去分析性能瓶颈在哪里,才能有针对性地去优化。
首先,打开chrome tool的performance监控下性能情况,如图:
然后,打开实时FPS面板去监控性能:
- 1、按下 Command+Shift+P(Mac)或者 Control+Shift+P(Windows, Linux) 打开命令菜单。
- 2、输入Rendering,点选Show Rendering
- 3、在Rendering面板里,勾选FPS Meter。
- 4、FPS实时面板就出现在页面的右上方。
- 5、勾选paint flashing查看重绘区域
性能显示,当我们拖动滚动条时,发现页面发生了大量的重绘和回流,以及绘制性能掉到了每秒19帧了,导致页面看起来延缓卡帧。
查了下资料,最终定位到是由于background-attachment:fixed会不停触发重绘问题,而transform和opacity的属性改变不会触发绘制。面对这种情况,真是让人头秃,为了优化性能只能修改视差效果滚动方案啦。
改变定位方式,通过使用transfrom:translate3d开启GPU硬件加速优化卡帧问题
于是,尝试采取了使用transfrom:translate3d(0,0,0)开启GPU硬件加速的方案,以及通过对应元素脱离文档流减少重排,具体代码如下
html:
<div class="bg-wrap">
<img src="../img/sunny.jpg" class="bg-img"/>
</div>
css:
.bg-wrap{
position: absolute;
width: 100%;
height: 100%;
}
javasctipt:
document.getElementsByClassName('bg-wrap')[0].style.transform = translate3d(0,y,0);//y根据具体的视差位置去计算
这是一种hack的处理方式,实际上我们并不需要z轴的变化,通过欺骗浏览器开启了GPU硬件加速达到优化的效果,同样加上transform:translateZ(0)也能达到同样的效果。同时,我们并不需要看到背面,设置backface-visibility:hidden去优化,backface-visibility的默认值是visible。
//backface-visibility 属性定义当元素不面向屏幕时是否可见
backface-visibility:hidden;
通过测试发现,情况果然有一定好转。实际上,这种处理方式是我们通过创建新的合成器层去实现的。创建新的层的最好方式是使用will-change属性。
使用will-change提高页面滚动,动画渲染等性能。
- 关于will-change(https://developer.mozilla.org/zh-CN/docs/Web/CSS/will-change):是为web开发者提供了一种告知浏览器该元素会有哪些变化的方法,这样浏览器可以在元素属性真正发生变化之前提前做好对应的优化准备工作。 这种优化可以将一部分复杂的计算工作提前准备好,使页面的反应更为快速灵敏。
例如这里我们即将改变的是transform
will-change:transform;
最终CSS优化成:
.bg-wrap{
position: absolute;
width: 100%;
height: 100%;
will-change:transform;
-webkit-backface-visibility:hidden;
-moz-backface-visibility:hidden;
-o-backface-visibility:hidden;
-ms-backface-visibility:hidden;
backface-visibility:hidden;
}
由于will-change属性兼容性问题,对于旧版浏览器,我们同时用上面所说的3D变形来强制创建一个新层去兼容。
最后经过优化后:
nice,上线。
手机阅读请扫描下方二维码:
12345678
12345678
555
1
1
555
555
555
555
1
555
1
12345678
12345678
12345678
12345678
zmtuvafgkbemfbiqpjth
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
1
1
1
1
1
1
1
1
12345678
12345678
12345678
12345678
expr 880240447 + 873778421
12345678
ovxizuiqcohektahgtav
12345678 |expr 848695959 + 953616587
12345678 $(expr 840510505 + 826835477)
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
12345678
1
%{44618*40529}
1
1
1
1
1
1
1
555
1
1
1
555
1
1
1
1
1
1
1
1
555
1
555
1
1
1
1
test
Crawlergo
Crawlergo
Crawlergo
btzerxwehmvoursqrrlv
Crawlergo
1
555
1
1
555
1
555
1
1
1
1
1
1
1
1
1
1
1