当咱们经过某些行为(点击、移动或滚动)触发页面进行大面积绘制的时候,浏览器每每是没有准备的,只能被动使用CPU去计算与重绘,因为没有事先准备,应付渲染够呛,因而掉帧卡顿。而CSS属性will-change为web开发者提供了一种告知浏览器该元素会有哪些变化的方法,这样浏览器能够在元素属性真正发生变化以前提早作好对应的优化准备工做。这种优化能够将一部分复杂的计算工做提早准备好,使页面的反应更为快速灵敏。本文将介绍CSS属性will-changejavascript
GPU是图形处理器,专门处理和绘制图形相关的硬件。GPU是专为执行复杂的数学和几何计算而设计的,使得CPU从图形处理的任务中解放出来,能够执行其余更多的系统任务css
所谓硬件加速,就是在计算机中把计算量很是大的工做分配给专门的硬件来处理,减轻CPU的工做量java
CSS的动画、变形、渐变并不会自动触发GPU加速,而是使用浏览器稍慢的软件渲染引擎。在transition
、transform
和animation
的世界里,应该卸载进程到GPU以加速速度。只有3D变形会有本身的layer,而2D变形则不会web
【Hack】chrome
使用translateZ()
或translate3d()
方法为元素添加没有变化的3D变形,骗取浏览器触发硬件加速。可是,代价是这种状况经过向它本身的层叠加元素,占用了RAM和GPU的存储空间,且没法肯定空间释放时间浏览器
will-changeide
功能: 提早通知浏览器元素将要作什么动画,让浏览器提早准备合适的优化设置性能
值: auto | <animateable-feature>
优化
初始值: auto动画
应用于: 全部元素
继承性: 无
兼容性: IE13+、chrome49+、safari9.1+、IOS9.3+、Android52+
auto表示没有特别指定哪些属性会变化,浏览器须要本身去猜,而后使用浏览器常用的一些常规方法优化
<animateable-feature>
能够是如下值:
scroll-position
表示开发者但愿在不久后改变滚动条的位置或者使之产生动画
contents
表示开发者但愿在不久后改变元素内容中的某些东西,或者使它们产生动画
<custom-ident>
表示开发者但愿在不久后改变指定的属性名或者使之产生动画。若是属性名是简写,则表明全部与之对应的简写或者全写的属性
【使用hover】
不要像下面这样直接写在默认状态中,由于will-change会一直挂着:
.will-change { will-change: transform; transition: transform 0.3s; } .will-change:hover { transform: scale(1.5); }
可让父元素hover的时候,声明will-change,这样,移出的时候就会自动remove,触发的范围基本上是有效元素范围
.will-change-parent:hover .will-change { will-change: transform; } .will-change { transition: transform 0.3s; } .will-change:hover { transform: scale(1.5); }
【使用javascript脚本】
.sidebar { will-change: transform; }
以上示例在样式表中直接添加了will-change属性,会致使浏览器将对应的优化工做一直保存在内存中,这实际上是没必要要的。下面展现如何使用脚本正确地应用will-change
属性
var el = document.getElementById('element'); // 当鼠标移动到该元素上时给该元素设置 will-change 属性 el.addEventListener('mouseenter', hintBrowser); // 当 CSS 动画结束后清除 will-change 属性 el.addEventListener('animationEnd', removeHint); function hintBrowser() { // 填写在CSS动画中发生改变的CSS属性名 this.style.willChange = 'transform, opacity'; } function removeHint() { this.style.willChange = 'auto'; }
【直接使用】
可是,若是某个应用在按下键盘的时候会翻页,好比相册或者幻灯片一类,它的页面很大很复杂,此时在样式表中写上will-change是合适的。这会使浏览器提早准备好过渡动画,当键盘按下的时候就能即看到灵活轻快的动画
.slide { will-change: transform; }
一、不要将will-change应用到太多元素上:浏览器已经尽力尝试去优化一切能够优化的东西了。有一些更强力的优化,若是与will-change结合在一块儿的话,有可能会消耗不少机器资源,若是过分使用的话,可能致使页面响应缓慢或者消耗很是多的资源
二、有节制地使用:一般,当元素恢复到初始状态时,浏览器会丢弃掉以前作的优化工做。可是若是直接在样式表中显式声明了will-change属性,则表示目标元素可能会常常变化,浏览器会将优化工做保存得比以前更久。因此最佳实践是当元素变化以前和以后经过脚原本切换will-change的值
三、不要过早应用will-change优化:若是页面在性能方面没什么问题,则不要添加will-change属性来榨取一丁点的速度。will-change的设计初衷是做为最后的优化手段,用来尝试解决现有的性能问题。它不该该被用来预防性能问题。过分使用will-change会致使大量的内存占用,并会致使更复杂的渲染过程,由于浏览器会试图准备可能存在的变化过程。这会致使更严重的性能问题
四、给它足够的工做时间:这个属性是用来让页面开发者告知浏览器哪些属性可能会变化的。而后浏览器能够选择在变化发生前提早去作一些优化工做。因此给浏览器一点时间去真正作这些优化工做是很是重要的。使用时须要尝试去找到一些方法提早必定时间获知元素可能发生的变化,而后为它加上will-change属性