performance - CSS 动画会使 CPU 过载

标签 performance css 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>

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);
    }
}

还有 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();
});

有什么想法可以减少 CPU 过载吗?

最佳答案

答案是 css 的属性。

will-change is a property that optimizes animations by letting the browser know which properties and elements are just about to be manipulated, potentially increasing the performance of that particular operation.

Article Source: will-change - css tricks

will-change 属性将使用硬件加速,以减少您的CPU 负载并将您的 CSS3 动画/转换分配给GPU>.

The Old: The translateZ() or translate3d() Hack

For quite some time now, we’ve been using what has been known as the translateZ() (or translate3d()) hack (sometimes also called the null transform hack) to trick the browser into pushing our animations and transforms into hardware acceleration. We’ve been doing that by adding a simple 3D transformation to an element that will not be transforming in three-dimensional space. For example, an element that’s animated in two-dimensional space can be hardware-accelerated by adding this simple rule to it:

transform: translate3d(0, 0, 0);

Hardware-accelerating an operation results in the creation of what is known as a compositor layer that is uploaded to and composited by the GPU. However, force-hacking layer creation may not always be the solution to certain performance bottlenecks on a page. Layer creation techniques can boost page speed, but they come with a cost: they take up memory in system RAM and on the GPU (particularly limited on mobile devices) and having lots of them can have a bad impact (especially on mobile devices), so they must be used wisely and you need to make sure that hardware-accelerating your operation will really help the performance of your page, and that a performance bottleneck is not being caused by another operation on your page.

In order to avoid layer-creation hacks, a new CSS property has been introduced, that allows us to inform the browser ahead of time of what kinds of changes we are likely to make to an element, thus allowing it to optimize how it handles the element ahead of time, performing potentially-expensive work preparing for an operation such as an animation, for example, before the animation actually begins. This property is the new will-change property.

The New: The Glorious will-change Property

The will-change property allows you to inform the browser ahead of time of what kinds of changes you are likely to make to an element, so that it can set up the appropriate optimizations before they’re needed, therefore avoiding a non-trivial start-up cost which can have a negative effect on the responsiveness of a page. The elements can be changed and rendered faster, and the page will be able to update snappily, resulting in a smoother experience.

For example, when using CSS 3D Transforms on an element, the element and its contents might be promoted to a layer, as we mentioned earlier, before they are composited in (drawn onto the screen) later. However, setting up the element in a fresh layer is a relatively expensive operation, which can delay the start of a transform animation by a noticeable fraction of a second, causing that noticeable “flicker”.

In order to avoid this delay, you can inform the browser about the changes some time before they actually happen. That way, it will have some time to prepare for these changes, so that when these changes occur, the element’s layer will be ready and the transform animation can be performed and then the element can be rendered and the page updated in quickly.

Using will-change, hinting to the browser about an upcoming transformation can be as simple as adding this rule to the element that you’re expecting to be transformed:

will-change: transform;

You can also declare to the browser your intention to change an element’s scroll position (the element’s position in the visible scroll window and how much of it is visible within that window), its contents, or one or more of its CSS property values by specifying the name of the properties you’re expecting to change. If you expect or plan to change multiple values/aspects of an element, you can provide a list of comma-separated values. For example, if you’re expecting the element to be animated and moved (its position changed), you can declare that to the browser like so:

will-change: transform, opacity;

Specifying what exactly you want to change allows the browser to make better decisions about the optimizations that it needs to make for these particular changes. This is obviously a better way to achieve a speed boost without resorting to hacks and forcing the browser into layer creations that may or may not be necessary or useful.

Article Source - Everything You Need to Know About the CSS will-change Property

你的CSS将是

.wallpaper {
    width: 100%;
    height: 100%;
    position: absolute;
    opacity: 0;
    background-repeat: no-repeat;
    background-position: center;
    background-size: cover;
    will-change: transform, opacity;
    -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);
    }
}

其他有用的资源:

关于performance - CSS 动画会使 CPU 过载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35533836/

相关文章:

c# - 调用方法会降低性能吗?

iphone - Sqlite + 80K 行 + LIKE = 键盘延迟

java - Log4j DailyRollingFileAppender 与 ConsoleAppender 性能对比

javascript - HighCharts - 尝试创建一个 'thin' 圆环图

javascript - 删除 :active & :focus but not on :focus only 上的轮廓

css - 我的动画在 IE 和 Edge 中速度较慢/有问题

java - 录制屏幕 Java 磁盘速度

javascript - Css - 添加 &lt;!DOCTYPE html> 让浏览器忽略我的动画

javascript - 帧中的动画持续时间是什么意思?

html - 如何为 SVG 元素中定义的剪切路径设置动画?