Iga*_*gal 5 css performance css3 css-animations will-change
我有一个动画和JS用于交替2个div并改变他们的背景图像(来自几十个图像的数组),有点可互换的div.一切正常,但是当动画运行时,我可以看到我的CPU处于100%.起初我认为这可能是由于setInterval,但是当我将代码从交替图像更改为每次迭代时只增加一个数字并将其记录到控制台时 - 我看到CPU过载减少了大约40-50%.所以我明白这可能是因为动画.
这是我的HTML代码:
<div class="wallpaper wallpaper-1" id="wallpaper-1"></div>
<div class="wallpaper wallpaper-2" id="wallpaper-2"></div>
Run Code Online (Sandbox Code Playgroud)
CSS:
.wallpaper {
width: 100%;
height: 100%;
position: absolute;
opacity: 0;
background-repeat: no-repeat;
background-position: center;
background-size: cover;
-webkit-transform: translateZ(0);
-webkit-animation-timing-function: linear;
}
.animate {
-webkit-animation-name: fadeInOut;
-webkit-animation-duration: 6s;
}
@-webkit-keyframes fadeInOut {
0% {
opacity: 0;
-webkit-transform: scale(1);
}
16% {
opacity: 1;
}
90% {
opacity: 1;
}
100% {
opacity: 0;
-webkit-transform: scale(1.1);
}
}
Run Code Online (Sandbox Code Playgroud)
和JS一起打勾:
Wallpapers.get().then(function(list) {
var wp1, wp2, divs = [], path, bgs = [], counterBgs = 0, bgsLength, currentId, doInterval;
wp1 = document.getElementById('wallpaper-1');
wp2 = document.getElementById('wallpaper-2');
divs = [ wp1, wp2 ];
path = 'assets/img/wallpapers/';
bgs = list.data;
bgsLength = bgs.length;
//Preload images
for(var i = 0; i < bgsLength-1; i++) {
var wp = new Image();
wp.src = path+list.data[i];
}
function manageBg() {
setInterval(function(){
doInterval();
}, 4000);
}
doInterval = function doInterval() {
currentId = counterBgs % bgsLength;
if (counterBgs % 2 === 0) {
wp1.style.backgroundImage = "url(" + path + bgs[currentId] + ")";
wp1.classList.add('animate');
wp1.style.zIndex = 1;
wp2.style.zIndex = 0;
setTimeout(function() {
wp1.classList.remove('animate');
}, 5950);
} else {
wp2.style.backgroundImage = "url(" + path + bgs[currentId] + ")";
wp2.classList.add('animate');
wp1.style.zIndex = 0;
wp2.style.zIndex = 1;
setTimeout(function() {
wp2.classList.remove('animate');
}, 5950);
}
counterBgs++;
};
doInterval();
manageBg();
});
Run Code Online (Sandbox Code Playgroud)
有任何想法如何减少CPU过载?
答案是CSS的will-change属性。
\n\n\n\n\nwill-change是一个属性,它通过让浏览器知道哪些属性和元素即将被操作来优化动画,从而可能提高该特定操作的性能。
\n\n文章来源:will-change - css 技巧
\n
will-change 属性将使用硬件加速来减少CPU的负载并将 CSS3 动画/转换分配给GPU。
\n\n\n\n\n旧的:The
\n\ntranslateZ()ortranslate3d()Hack相当长一段时间以来,我们\xe2\x80\x99一直在使用所谓的\ntranslateZ()(或translate3d())黑客(有时也称为空\n变换黑客)来欺骗浏览器推送我们的动画并\n 转换为硬件加速。我们\xe2\x80\x99 一直通过向\n 不会在三维空间中进行变换的元素添加\n 简单的3D 变换来做到这一点。例如,在二维空间中进行动画处理的元素可以通过添加以下简单规则来进行硬件加速:
\n\nRun Code Online (Sandbox Code Playgroud)\n\ntransform: translate3d(0, 0, 0);\n硬件加速操作会创建所谓的合成器层,该层上传到 GPU 并由 GPU 进行合成。然而,强制破解层创建可能并不总是解决页面上某些性能瓶颈的方法。层创建技术可以提高页面速度,但也有一定的代价:它们会占用系统 RAM 和 GPU 中的内存(特别是在移动设备上受到限制),并且层创建技术过多可能会产生不良影响(尤其是在移动设备上),因此必须明智地使用它们,并且您需要确保硬件加速您的操作确实有助于提高页面的性能,并且不会造成性能瓶颈通过页面上的另一个操作。
\n\n为了避免层创建黑客,引入了一个新的 CSS 属性\n,它允许我们提前通知浏览器我们可能对元素进行\n 类型的更改,从而允许\n提前优化其处理元素的方式,例如在动画实际开始之前执行可能昂贵的工作,为动画等操作做准备。此\n 属性是新的将更改的属性。
\n\n新:光荣的将改变财产
\n\nwill-change 属性允许您提前通知浏览器您可能对元素进行哪些类型的更改,以便浏览器可以在更改之前设置适当的优化\xe2\x80\x99re\需要,因此避免了不小的启动成本,这可能会对页面的响应能力产生负面影响。可以更快地更改和渲染元素,并且页面将能够快速更新,从而带来更流畅的体验。
\n\n例如,当在元素上使用 CSS 3D 变换时,元素及其内容可能会被提升到一个图层,正如我们前面提到的,然后再将它们合成(绘制到屏幕上)。\n 但是,在新图层中设置元素是一项相对昂贵的操作,这可能会导致变换动画的开始延迟明显的几分之一秒,导致\n 明显\xe2\x80\x9cflicker\xe2\x80 \x9d。
\n\n为了避免这种延迟,您可以在更改实际发生之前的某个时间通知浏览器\n。这样,它将有一些时间来准备这些更改,以便当这些更改发生时,元素 xe2x80x99s 层将准备就绪,并且可以执行变换动画,然后元素可以快速呈现并更新页面。
\n\n使用 will-change,向浏览器暗示即将进行的转换就像将此规则添加到您希望转换的元素中一样简单:
\n\nRun Code Online (Sandbox Code Playgroud)\n\nwill-change: transform;\n您还可以向浏览器声明您打算更改元素\xe2\x80\x99s 的滚动位置(元素\xe2\x80\x99s 在可见滚动窗口中的位置以及该窗口中可见的部分) )、其\n 内容、或一个或多个CSS 属性值,方法是指定您\xe2\x80\x99 想要更改的属性的名称。\n 如果您期望或计划更改元素的多个值/方面,您可以提供逗号分隔值的列表。例如,如果您\xe2\x80\x99 期望\n 元素被动画化并移动(其位置已更改),则可以\n 向浏览器声明,如下所示:
\n\nRun Code Online (Sandbox Code Playgroud)\n\nwill-change: transform, opacity;\n指定您想要更改的具体内容可以让浏览器针对这些特定更改所需的优化做出\n 更好的决策。这显然是实现速度提升的更好方法,而无需诉诸黑客手段并强制浏览器创建可能或可能不需要或有用的图层。
\n\n \n
你的CSS将是
\n\n.wallpaper {\n width: 100%;\n height: 100%;\n position: absolute;\n opacity: 0;\n background-repeat: no-repeat;\n background-position: center;\n background-size: cover;\n will-change: transform, opacity;\n -webkit-animation-timing-function: linear;\n}\n\n.animate {\n -webkit-animation-name: fadeInOut;\n -webkit-animation-duration: 6s;\n}\n\n@-webkit-keyframes fadeInOut {\n 0% {\n opacity: 0;\n -webkit-transform: scale(1);\n }\n 16% {\n opacity: 1;\n }\n 90% {\n opacity: 1;\n }\n 100% {\n opacity: 0;\n -webkit-transform: scale(1.1);\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n