Javascript性能-如何提高小脚本的性能

Javascript性能-如何提高小脚本的性能,javascript,jquery,performance,parallax,Javascript,Jquery,Performance,Parallax,我最近制作了一个网站,它使用window.scroll向元素中添加一类“活动”元素来触发css3动画。这些动画虽然有时没有开火,但总的来说,脚本的表现非常缓慢。今天我在看 我注意到他们从来没有错过过一个“触发点”,而且表现很好,但我不知道他们是如何做到这一点的——有人对这样的网站有经验吗 我的代码现在看起来像这样 $(window).scroll(function(){ if ( $('.trigger:in-viewport:first.trigger5').length )

我最近制作了一个网站,它使用window.scroll向元素中添加一类“活动”元素来触发css3动画。这些动画虽然有时没有开火,但总的来说,脚本的表现非常缓慢。今天我在看 我注意到他们从来没有错过过一个“触发点”,而且表现很好,但我不知道他们是如何做到这一点的——有人对这样的网站有经验吗

我的代码现在看起来像这样

$(window).scroll(function(){    
    if ( $('.trigger:in-viewport:first.trigger5').length )
    {
        $('[rel=counter]').addClass('active');
        $('[rel=discover]').removeClass('active');
        $('[rel=follow]').removeClass('active');
        $('[rel=sync]').removeClass('active');
    }

我觉得这是使用jQuery和viewport插件的结果。

时间都花在jQuery选择器上了。只需首先执行选择器并将其存储在变量中。然后在将来使用这些变量。例如:

var $firstTrigger = $('.trigger:in-viewport:first.trigger5');
var $counter = $('[rel=counter]');
var $discover = $('[rel=discover]');
var $follow = $('[rel=follow]');
var $sync = $('[rel=sync]');

$(window).scroll(function(){    
    if ( $firstTrigger.length )
    {
        $counter.addClass('active');
        $discover.removeClass('active');
        $follow.removeClass('active');
        $sync.removeClass('active');
    }

第一件显而易见的事情:

var $window = $( window );
var DOM = {
    counter: $( '[rel=counter]' ),
    discover: $( '[rel=discover]' ),
    follow: $( '[rel=follow]' ),
    sync: $( '[rel=sync] ')
};

function doThingsOnScroll() {    
    if ( $( '.trigger:in-viewport:first.trigger5' ).length ) {
        DOM.counter.addClass('active');
        DOM.discover.removeClass('active');
        DOM.follow.removeClass('active');
        DOM.sync.removeClass('active');
    }
}

$window.scroll( doThingsOnScroll );
与注释类似:必须缓存查询。DOM上的操作非常繁重。一次获取元素并使用它们

另一件有帮助的事情是强调功能节流。

不久前,保罗·刘易斯写了一篇关于在HTML5上滚动的文章。我建议在修复之前阅读:


编辑:已修复
:在视口中
。感谢Bergi。

现在忽略大量dom调用,由于scroll()的快速启动功能,您的总体模式非常需要CPU

我们可以称之为“经常”,而不是“总是”,以大幅降低cpu,特别是在移动设备或其他弱小设备上:

function doScroll(){    
    if ( $('.trigger:in-viewport:first.trigger5').length )
    {
        $('[rel=counter]').addClass('active');
        $('[rel=discover]').removeClass('active');
        $('[rel=follow]').removeClass('active');
        $('[rel=sync]').removeClass('active');
    }
}

$(window).scroll(function dome(){
  clearTimeout(dome.timer);
  dome.timer=setTimeout(doScroll, 100);
})
这适用于10FPS的帧速率,可以通过更改setTimeout持续时间进行调整


缓存jQuery选择器可能也会有一些帮助,但如果您过度触发了scroll(),则每次执行节省25%可能是不够的,但是,无论进行进一步优化,消除工作都会更快地执行代码。

属于codereview.stackexchange.comPerforming DOM查询,该查询位于scroll和mousemove等rapid fire事件中。典型错误。请尝试在
.scroll()
回调函数之外的变量中缓存
$()
查询。现在,每次启动scroll事件并执行回调函数时,DOM都会被查询五次。您可能会发现这种方法很有用。为什么每次,注释中的好建议和由不同的人编写的完全相同的答案?
$firstTrigger
都有一个非常不同的选择器。谢谢。我不知道这是怎么搞砸的。我不知道是什么插件启用了
:在viewport
选择器,但它似乎是唯一值得从滚动事件中查询的动态插件。如果所有jQuery选择都是静态的,那么就不需要
doThingsOnScroll
。关于油门。它会将函数调用缓存100ms,对吗?@Bergi,
[rel=xxx]
如何在没有额外js的情况下保持动态?同意
:在viewport
@vp_-arth:是的,没错。
function doScroll(){    
    if ( $('.trigger:in-viewport:first.trigger5').length )
    {
        $('[rel=counter]').addClass('active');
        $('[rel=discover]').removeClass('active');
        $('[rel=follow]').removeClass('active');
        $('[rel=sync]').removeClass('active');
    }
}

$(window).scroll(function dome(){
  clearTimeout(dome.timer);
  dome.timer=setTimeout(doScroll, 100);
})