【问题标题】:Animations are slowing the performance of web page动画正在减慢网页的性能
【发布时间】:2019-11-03 02:47:08
【问题描述】:

我有一个用 html、javascript 和 css 设计的单页网站。网页上有很多图片,并且根据它们的类别都有不同的动画效果。我使用 wow.js 来制作窗口滚动的动画效果。在滚动图像时,CPU 和 GPU 的使用率非常高,由于其效果,滚动是生涩的,不流畅。任何人都可以看看这个。我创建了一个 codepen 示例。请看一下:-

(https://codepen.io/Sny220/pen/jjyEPj)

代码如下:-



<!-- HTML -->
<div class="foo foo-text foo-2 col-md-3 col-md-offset-3 over-hidden">
   <img class="wow zoominoutsingle" src="https://www.psychologies.co.uk/sites/default/files/field/image/feelgood%20chemicals.jpg" />
</div>
<div class="foo foo-text foo-2 col-md-3 over-hidden">
   <img class="wow zoominoutsingle" src="https://kajabi-storefronts-production.global.ssl.fastly.net/kajabi-storefronts-production/blogs/1049/images/BlH7rBrRFGdVF71lofox_TFmaDj07ReWp5C4zcHaw_alex-fergus-look-and-feel-amazing-health-wellness-fat-loss-natural-banner.jpg" />
</div>
<div class="foo foo-text foo-2 col-md-6 col-md-offset-3">
   <div class="inner">
      <h1 class="wow fadeInDown">Hello, world!</h1>
      <p class="wow fadeInUp">Whouaa !!!</p>
   </div>
</div>
<div class="foo foo-3 col-md-6 col-md-offset-3">
   <div class="inner">
      <button type="button" class="btn btn-success">Success</button>
   </div>
</div>
<div class="foo foo-4 col-md-6 col-md-offset-3 wow fadeInDown">
   <img class="" src="http://www.ponpokopon.net/livresillu/unenouvellemaison1.jpg" />
</div>
<div class="foo foo-5 col-md-6 col-md-offset-3">
   <div class="inner">RUBRIQUE 3</div>
</div>
<div data-wow-duration="2s" class="foo foo-1 col-md-3 col-md-offset-3 wow scale-in-ver-top">
   <div class="inner">
      <img class="" src="http://www.ponpokopon.net/livresillu/unenouvellemaison2.jpg" />
   </div>
</div>
<div data-wow-duration="2s" class="foo  foo-2 col-md-3 wow scale-in-ver-top">
   <div class="inner"><img class="" src="https://media.treehugger.com/assets/images/2018/07/nature-benefits.jpg.860x0_q70_crop-scale.jpg" /></div>
</div>
<div data-wow-duration="2s" class="col-md-3 col-md-offset-3 margin-top-20 swing">
   <div class="inner"><img class="wow swing-in-top-fwd" src="https://www.thewaltdisneycompany.com/wp-content/uploads/ENVIRONMENT_header-option_Disney_Conservation_Fund_0348HC.jpg" /></div>
</div>
<div class="col-md-6 col-md-offset-3 bg-color">
   <h1 class="wow fadeInDown">Next Section</h1>
</div>
<!-- HTML -->
<div class="foo foo-text foo-2 col-md-3 col-md-offset-3 over-hidden">
   <img class="wow zoominoutsingle" src="https://www.psychologies.co.uk/sites/default/files/field/image/feelgood%20chemicals.jpg" />
</div>
<div class="foo foo-text foo-2 col-md-3 over-hidden">
   <img class="wow zoominoutsingle" src="https://kajabi-storefronts-production.global.ssl.fastly.net/kajabi-storefronts-production/blogs/1049/images/BlH7rBrRFGdVF71lofox_TFmaDj07ReWp5C4zcHaw_alex-fergus-look-and-feel-amazing-health-wellness-fat-loss-natural-banner.jpg" />
</div>
<div class="foo foo-text foo-2 col-md-6 col-md-offset-3">
   <div class="inner">
      <h1 class="wow fadeInDown">Hello, world!</h1>
      <p class="wow fadeInUp">Whouaa !!!</p>
   </div>
</div>
<div class="foo foo-3 col-md-6 col-md-offset-3">
   <div class="inner">
      <button type="button" class="btn btn-success">Success</button>
   </div>
</div>
<div class="foo foo-4 col-md-6 col-md-offset-3 wow fadeInDown">
   <img class="" src="http://www.ponpokopon.net/livresillu/unenouvellemaison1.jpg" />
</div>
<div class="foo foo-5 col-md-6 col-md-offset-3">
   <div class="inner">RUBRIQUE 3</div>
</div>
<div data-wow-duration="2s" class="foo foo-1 col-md-3 col-md-offset-3 wow scale-in-ver-top">
   <div class="inner">
      <img class="" src="http://www.ponpokopon.net/livresillu/unenouvellemaison2.jpg" />
   </div>
</div>
<div data-wow-duration="2s" class="foo  foo-2 col-md-3 wow scale-in-ver-top">
   <div class="inner"><img class="" src="https://media.treehugger.com/assets/images/2018/07/nature-benefits.jpg.860x0_q70_crop-scale.jpg" /></div>
</div>
<div data-wow-duration="2s" class="col-md-3 col-md-offset-3 margin-top-20 swing">
   <div class="inner"><img class="wow swing-in-top-fwd" src="https://www.thewaltdisneycompany.com/wp-content/uploads/ENVIRONMENT_header-option_Disney_Conservation_Fund_0348HC.jpg" /></div>
</div>
<div class="col-md-6 col-md-offset-3 bg-color">
   <h1 class="wow fadeInDown">Next Section</h1>
</div>
<!-- HTML -->
<div class="foo foo-text foo-2 col-md-3 col-md-offset-3 over-hidden">
   <img class="wow zoominoutsingle" src="https://www.psychologies.co.uk/sites/default/files/field/image/feelgood%20chemicals.jpg" />
</div>
<div class="foo foo-text foo-2 col-md-3 over-hidden">
   <img class="wow zoominoutsingle" src="https://kajabi-storefronts-production.global.ssl.fastly.net/kajabi-storefronts-production/blogs/1049/images/BlH7rBrRFGdVF71lofox_TFmaDj07ReWp5C4zcHaw_alex-fergus-look-and-feel-amazing-health-wellness-fat-loss-natural-banner.jpg" />
</div>
<div class="foo foo-text foo-2 col-md-6 col-md-offset-3">
   <div class="inner">
      <h1 class="wow fadeInDown">Hello, world!</h1>
      <p class="wow fadeInUp">Whouaa !!!</p>
   </div>
</div>
<div class="foo foo-3 col-md-6 col-md-offset-3">
   <div class="inner">
      <button type="button" class="btn btn-success">Success</button>
   </div>
</div>
<div class="foo foo-4 col-md-6 col-md-offset-3 wow fadeInDown">
   <img class="" src="http://www.ponpokopon.net/livresillu/unenouvellemaison1.jpg" />
</div>
<div class="foo foo-5 col-md-6 col-md-offset-3">
   <div class="inner">RUBRIQUE 3</div>
</div>
<div data-wow-duration="2s" class="foo foo-1 col-md-3 col-md-offset-3 wow scale-in-ver-top">
   <div class="inner">
      <img class="" src="http://www.ponpokopon.net/livresillu/unenouvellemaison2.jpg" />
   </div>
</div>
<div data-wow-duration="2s" class="foo  foo-2 col-md-3 wow scale-in-ver-top">
   <div class="inner"><img class="" src="https://media.treehugger.com/assets/images/2018/07/nature-benefits.jpg.860x0_q70_crop-scale.jpg" /></div>
</div>
<div data-wow-duration="2s" class="col-md-3 col-md-offset-3 margin-top-20 swing">
   <div class="inner"><img class="wow swing-in-top-fwd" src="https://www.thewaltdisneycompany.com/wp-content/uploads/ENVIRONMENT_header-option_Disney_Conservation_Fund_0348HC.jpg" /></div>
</div>
<div class="col-md-6 col-md-offset-3 bg-color">
   <h1 class="wow fadeInDown">Next Section</h1>
</div>
<!-- HTML -->
<div class="foo foo-text foo-2 col-md-3 col-md-offset-3">
   <img class="wow scale-in-ver-top" src="https://www.psychologies.co.uk/sites/default/files/field/image/feelgood%20chemicals.jpg" />
</div>
<div class="foo foo-text foo-2 col-md-3">
   <img class="wow scale-in-ver-top" src="https://kajabi-storefronts-production.global.ssl.fastly.net/kajabi-storefronts-production/blogs/1049/images/BlH7rBrRFGdVF71lofox_TFmaDj07ReWp5C4zcHaw_alex-fergus-look-and-feel-amazing-health-wellness-fat-loss-natural-banner.jpg" />
</div>
<div class="foo foo-text foo-2 col-md-6 col-md-offset-3">
   <div class="inner">
      <h1 class="wow fadeInDown">Hello, world!</h1>
      <p class="wow fadeInUp">Whouaa !!!</p>
   </div>
</div>
<div class="foo foo-3 col-md-6 col-md-offset-3">
   <div class="inner">
      <button type="button" class="btn btn-success">Success</button>
   </div>
</div>
<div class="foo foo-4 col-md-6 col-md-offset-3 wow fadeInDown">
   <img class="" src="http://www.ponpokopon.net/livresillu/unenouvellemaison1.jpg" />
</div>
<div class="foo foo-5 col-md-6 col-md-offset-3">
   <div class="inner">RUBRIQUE 3</div>
</div>
<div data-wow-duration="2s" class="foo foo-1 col-md-3 col-md-offset-3 wow scale-in-ver-top">
   <div class="inner">
      <img class="" src="http://www.ponpokopon.net/livresillu/unenouvellemaison2.jpg" />
   </div>
</div>
<div data-wow-duration="2s" class="foo  foo-2 col-md-3 wow scale-in-ver-top">
   <div class="inner"><img class="" src="https://media.treehugger.com/assets/images/2018/07/nature-benefits.jpg.860x0_q70_crop-scale.jpg" /></div>
</div>
<div data-wow-duration="2s" class="col-md-3 col-md-offset-3 margin-top-20 swing">
   <div class="inner"><img class="wow swing-in-top-fwd" src="https://www.thewaltdisneycompany.com/wp-content/uploads/ENVIRONMENT_header-option_Disney_Conservation_Fund_0348HC.jpg" /></div>
</div>
<div class="col-md-6 col-md-offset-3 bg-color">
   <h1 class="wow fadeInDown">Next Section</h1>
</div>
<!-- HTML -->
<div class="foo foo-text foo-2 col-md-3 col-md-offset-3">
   <img class="wow scale-in-ver-top" src="https://www.psychologies.co.uk/sites/default/files/field/image/feelgood%20chemicals.jpg" />
</div>
<div class="foo foo-text foo-2 col-md-3">
   <img class="wow scale-in-ver-top" src="https://kajabi-storefronts-production.global.ssl.fastly.net/kajabi-storefronts-production/blogs/1049/images/BlH7rBrRFGdVF71lofox_TFmaDj07ReWp5C4zcHaw_alex-fergus-look-and-feel-amazing-health-wellness-fat-loss-natural-banner.jpg" />
</div>
<div class="foo foo-text foo-2 col-md-6 col-md-offset-3">
   <div class="inner">
      <h1 class="wow fadeInDown">Hello, world!</h1>
      <p class="wow fadeInUp">Whouaa !!!</p>
   </div>
</div>
<div class="foo foo-3 col-md-6 col-md-offset-3">
   <div class="inner">
      <button type="button" class="btn btn-success">Success</button>
   </div>
</div>
<div class="foo foo-4 col-md-6 col-md-offset-3 wow fadeInDown">
   <img class="" src="http://www.ponpokopon.net/livresillu/unenouvellemaison1.jpg" />
</div>
<div class="foo foo-5 col-md-6 col-md-offset-3">
   <div class="inner">RUBRIQUE 3</div>
</div>
<div data-wow-duration="2s" class="foo foo-1 col-md-3 col-md-offset-3 wow scale-in-ver-top">
   <div class="inner">
      <img class="" src="http://www.ponpokopon.net/livresillu/unenouvellemaison2.jpg" />
   </div>
</div>
<div data-wow-duration="2s" class="foo  foo-2 col-md-3 wow scale-in-ver-top">
   <div class="inner"><img class="" src="https://media.treehugger.com/assets/images/2018/07/nature-benefits.jpg.860x0_q70_crop-scale.jpg" /></div>
</div>
<div data-wow-duration="2s" class="col-md-3 col-md-offset-3 margin-top-20 swing">
   <div class="inner"><img class="wow swing-in-top-fwd" src="https://www.thewaltdisneycompany.com/wp-content/uploads/ENVIRONMENT_header-option_Disney_Conservation_Fund_0348HC.jpg" /></div>
</div>


body {
    padding-top: 20px;
}


/* set colors*/

 :root {
    --color-1: forestgreen;
    --color-2: lightskyblue;
    --color-3: darksalmon;
    --color-4: palegoldenrod;
    --color-5: mediumvioletred;
}

img {
    width: 100%;
}

.foo {
    margin-bottom: 10px;
    color: white;
}

.navbar {}

.foo .inner {
    padding: 5px;
    min-height: 20vh;
}

.foo-text .inner {
    min-height: 60vh !important;
}


/* apply colors */

.foo-1 .inner {
    background-color: var(--color-1);
}

.foo-2 .inner {
    background-color: var(--color-2);
}

.foo-3 .inner {
    background-color: var(--color-3);
}

.foo-4 .inner {
    background-color: var(--color-4);
}

.foo-5 .inner {
    background-color: var(--color-5);
}

.bg-color {
    background-color: var(--color-5);
    color: #fff;
    margin-top: 20px;
    margin-bottom: 20px;
}

.over-hidden {
    overflow: hidden;
}

.swing {
    overflow: hidden;
}

.scale-in-ver-top {
    -webkit-animation: scale-in-ver-top 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
    animation: scale-in-ver-top 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
}

@-webkit-keyframes scale-in-ver-top {
    0% {
        -webkit-transform: scaleY(0);
        transform: scaleY(0);
        -webkit-transform-origin: 100% 0%;
        transform-origin: 100% 0%;
        opacity: 1;
    }
    100% {
        -webkit-transform: scaleY(1);
        transform: scaleY(1);
        -webkit-transform-origin: 100% 0%;
        transform-origin: 100% 0%;
        opacity: 1;
    }
}

@keyframes scale-in-ver-top {
    0% {
        -webkit-transform: scaleY(0);
        transform: scaleY(0);
        -webkit-transform-origin: 100% 0%;
        transform-origin: 100% 0%;
        opacity: 1;
    }
    100% {
        -webkit-transform: scaleY(1);
        transform: scaleY(1);
        -webkit-transform-origin: 100% 0%;
        transform-origin: 100% 0%;
        opacity: 1;
    }
}

.swing-in-top-fwd {
    -webkit-animation-name: swing-in-top-fwd;
    animation-name: swing-in-top-fwd;
}

@-webkit-keyframes swing-in-top-fwd {
    0% {
        -webkit-transform: rotateX(-100deg);
        transform: rotateX(-100deg);
        -webkit-transform-origin: top;
        transform-origin: top;
        opacity: 0;
        -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.275);
        animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.275);
    }
    100% {
        -webkit-transform: rotateX(0deg);
        transform: rotateX(0deg);
        -webkit-transform-origin: top;
        transform-origin: top;
        opacity: 1;
        -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.275);
        animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.275);
    }
}

@keyframes swing-in-top-fwd {
    0% {
        -webkit-transform: rotateX(-100deg);
        transform: rotateX(-100deg);
        -webkit-transform-origin: top;
        transform-origin: top;
        opacity: 0;
        -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.275);
        animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.275);
    }
    100% {
        -webkit-transform: rotateX(0deg);
        transform: rotateX(0deg);
        -webkit-transform-origin: top;
        transform-origin: top;
        opacity: 1;
        -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.275);
        animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.275);
    }
}

@keyframes zoominoutsinglefeatured {
    0% {
        transform: scale(1, 1);
        webkit-transform: scale(1, 1);
    }
    50% {
        transform: scale(2, 2);
        webkit-transform: scale(2, 2);
    }
    100% {
        transform: scale(1, 1);
        webkit-transform: scale(1, 1);
    }
}

.zoominoutsingle {
    animation-name: zoominoutsinglefeatured;
    webkit-animation-name: zoominoutsinglefeatured;
    -webkit-animation-duration: 10s;
    animation-duration: 10s;
    -webkit-animation-fill-mode: both;
    animation-fill-mode: both;
}
wow = new WOW();
wow.init();

$(".foo-5").hover(function(e) {
    $(this).addClass('animated pulse');
}, function(e) {
    $(this).removeClass('animated pulse');
});
var $animation_elements = $('.wow');
var $window = $(window);

function check_if_in_view() {
    var window_height = $window.height();
    var window_top_position = $window.scrollTop();
    var window_bottom_position = (window_top_position + window_height);

    $.each($animation_elements, function() {
        var $element = $(this);
        var element_height = $element.outerHeight();
        var element_top_position = $element.offset().top;
        var element_bottom_position = (element_top_position + element_height);

        //check to see if this current container is within viewport
        if ((element_bottom_position >= window_top_position) &&
            (element_top_position <= window_bottom_position)) {
            $element.removeClass('animated');
            $element.addClass('animated');
        } else {
            $element.css({
                'visibility': 'hidden',
                'animation-name': 'none'
            }).removeClass('animated');
            wow.addBox(this);
        }
    });
}
WOW.prototype.addBox = function(element) {
    this.boxes.push(element);
};
$window.on('scroll resize', check_if_in_view);

更新:- 这只是我在网页中使用的一个示例。网页 大约有不同数量的部分。 20个部分,全部都是 有 10 个或更多图像。所以当我们运行那么多图像时 动画性能下降。

我在 mac Safari 11 & 12 上检查过,动画和滚动是 不光滑。滚动时有抖动,动画非常 慢吞吞的。

【问题讨论】:

  • 首先所有相关代码都应该在问题中。其次,主要问题是因为您使用的是 JS 动画。如果您想要更好的性能,请使用 CSS 过渡或关键帧来创建您想要的效果。第三,您为 UI 滚动时更新的 每个像素 执行一次 JS。研究事件去抖动以减轻这种情况。综上所述,值得注意的是,这些效果很容易在页面内被过度使用并分散注意力。
  • 同上,但实际上,链接中的页面几乎不会导致 CPU 或 GPU 使用率明显增加 - 也许您发布的代码不能代表您的问题的全部范围
  • @JaromandaX 感谢您的回复。这只是我在网页中使用的一个示例。网页有不同数量的部分。 20 个部分,所有部分都有 10 个或更多图像。因此,当我们运行这么多带有动画的图像时,性能会下降。
  • @RoryMcCrossan 感谢您的回复。我已经用更多细节和代码更新了我的问题。请查看 css 脚本,我已经尝试将 css 动画与“swing-in-top-fwd”等关键帧一起使用。

标签: javascript jquery cpu-usage wow.js


【解决方案1】:

由于您似乎只使用了animated pulse,并且已经添加和删除了animated 类,我强烈建议您使用CSS 动画。

CSS 动画使用 GPU 渲染,不像 JavaScript 那样使用主线程。它们超级流畅且性能卓越!

查看我在 Google 上找到的这个 Codepen,它创建了一个脉冲动画图标:https://codepen.io/igorsheg/pen/MBpwGw

【讨论】:

    【解决方案2】:

    您可以对动画使用延迟加载,并以更好的方式执行视图元素的加载。 JQuery Lazy

    【讨论】:

      【解决方案3】:

      通过使用Intersection Observer (IO) 而不是监听滚动事件,您可能会获得很多性能。引入 IO 是因为监听滚动事件和计算元素的高度/宽度会导致性能不佳。

      首先你必须创建一个新的观察者:

      var options = {
        rootMargin: '0px',
        threshold: 1.0
       }
      
      var observer = new IntersectionObserver(callback, options);
      

      这里我们指定一旦观察到的元素 100% 可见,就应该执行一些回调。

      然后你必须指定要观察的项目,在你的情况下,我认为这将是:

      var target = document.querySelector('.wow');
      observer.observe(target);
      

      所以我们定义,一旦页面上可见任何具有“wow”类的元素,回调就会被执行:

      var callback = function(entries, observer) { 
        entries.forEach(entry => {
        // Each entry describes an intersection change for one observed
        // target element:
        });
      };
      

      您可以在此处指定页面中每个可见的“哇”元素应该发生的情况。

      如果您在动画中使用 CSS 而不是 JS,那么动画现在应该是流畅的。 它还取决于您正在制作动画的参数,这里is a good list of properties 以避免使用 CSS 制作动画。

      我不会在这里复制整个列表,但最重要的是填充、宽度、高度和位置。

      编辑: 如果您需要支持较旧的浏览器而不是使用此(官方)polyfill from w3c,它会重新创建交叉点观察器并监听滚动事件。所以在旧浏览器上它仍然会变慢,你在这里无能为力。但是对于较新的,性能会有所提高。

      【讨论】:

      • 感谢您的回复。我检查了浏览器对 IO 的兼容性,这只支持最新版本的 Safari (12.1)。您能否推荐一个既适用于旧版 safari 版本也适用于新版的解决方案?
      • 编辑了我的答案并为旧版浏览器添加了一个 polyfill,我认为您无能为力。然后我想到的唯一一件事就是不在旧浏览器上显示这些动画。或者一起减少动画的数量。但这是我无法决定的。
      • 你至少可以为几百毫秒的滚动事件去抖动。如上所述,滚动监听器是性能杀手。
      • @cloned 谢谢你,你救了我的命。 Intersection Observer 解决方案就像一个魅力。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-15
      • 1970-01-01
      • 2012-08-16
      • 1970-01-01
      • 2014-09-14
      • 1970-01-01
      相关资源
      最近更新 更多