大型同位素画廊非常缓慢

Large Isotope Gallery is Very Slow

本文关键字:非常 缓慢 同位素 大型      更新时间:2023-09-26

我有一个同位素图库(版本2),有近400个元素。一个典型的库项看起来像这样:

<div class="element hybrid a" data-category="hybrid">
    <p class="type">H</p>
    <h2 class="name">Name</h2>
    <p class="strain-info">No Info Available</p>
    <p class="review"><a class="button radius small black review-form-lb" href="#review-form-lightbox">Review</a></p>
</div>

例如,当我运行下面的代码时,它基本上是向所单击的元素添加一个类,元素需要几秒钟才能放大。

$container.on( 'click', '.element', function() {
  $( this ).toggleClass('large');
  $container.isotope('layout');
});

另一个例子是,如果我有一个按钮组,其中包含几个选项来筛选图库,同样需要几秒钟。JS过滤:

$('#filters').on( 'click', '.button', function() {
  var $this = $(this);
  // get group key
  var $buttonGroup = $this.parents('.button-group');
  var filterGroup = $buttonGroup.attr('data-filter-group');
  // set filter for group
  filters[ filterGroup ] = $this.attr('data-filter');
  // combine filters
  var filterValue = '';
  for ( var prop in filters ) {
    filterValue += filters[ prop ];
  }
  // set filter for Isotope
  $container.isotope({ filter: filterValue });
});

这是$container

的变量
// init Isotope
var $container = $('.isotope').isotope({
  itemSelector: '.element',
  layoutMode: 'fitRows',
  filter: function() {
    return qsRegex ? $(this).text().match( qsRegex ) : true;
  }
});
我应该注意到,上面的代码在有少量项时工作得很好。我怎样才能提高画廊的表现?

我应该注意到,在同位素的版本1中,我有相同的画廊,它工作得很好。我正在升级,因为v2的同位素能力增强了。

这里是直播网站-重要!-这个网站是在美国科罗拉多州的大麻药房。网站可能不适合工作。

更新

我尝试将所有div s更改为li元素。没有看到太大的改善。

我尝试打开硬件加速每mfirdaus的答案,但它似乎没有工作。

注意:上面的链接到现场的网站是一个剥离的版本,我删除了同位素画廊不需要的一切。它比我最初发布这个稍微快一点,但是,它需要更多的响应。尝试在平板电脑上使用它,同位素项目需要几秒钟才能响应。

更新2

同位素的版本1在大型图库中表现得更好,因此我最终使用了版本1。

我有个建议。首先,您可以将css属性transform:translate3d(0,0,0)添加到.element css选择器中。这将打开硬件加速,并加快页面流。这是一个经常用来使高度动画化的页面更流畅的技巧,尤其是在移动设备上。比如:

.element {
  ...
  /* add this. prefixes for compabtibility */
  transform:translate3d(0,0,0);
  -webkit-transform:translate3d(0,0,0);
  -moz-transform:translate3d(0,0,0);
}

在我的测试中,它似乎可以很好地加速。

另一个建议是将.on("click")替换为.on("mousedown")click在鼠标被释放后触发,而mousedown会在用户按下鼠标后立即触发。有大约0.2秒的差别,但有点明显。

这是同位素的默认例子,有400个元素。


更新

在测试了touchstart之后,它有点帮助,但即使在滚动时也会触发。所以这有助于只有当你禁用滚动/有固定的视口。也许你可以添加isroll,但我认为那样会更臃肿。

你可以尝试的一种选择是在等待同位素重新计算位置之前,先强制元素调整大小。我们可以通过在同位素刷新上使用setTimeout来实现这一点。我不确定这种行为是否可以接受,但这可以让用户更快地获得反馈。所以你的切换代码应该是这样的:

$container.on( 'click', '.element',function() {
  $( this ).toggleClass('large');
  setTimeout(function(){ $container.isotope('layout'); },20); //queue this later
});

演示。在我的安卓设备上进行了测试,似乎有所改善。

嗯,同位素插件的作者建议50项最大值,如果你正在进行过滤或排序。你有400!所以我恐怕你需要减少项目的数量以获得更好的性能。

附注:

  • 尝试touchstartmousedown事件而不是click,以便在手机上更快地响应。
  • 检查Object.keys(filters).forEach的性能在手机上(而不是for in).
  • jQuery的closest()方法可能在一些浏览器中比parents()更快。

与其使用toggleClass,不如直接操作样式。

$( this ).css({ /* styles for large */});

虽然我明白这可能不是一个与你的场景直接相关的问题,但我也有同样的经历(主要是在移动和平板设备上),我在同位素图库中只有36张图像,我在任何地方等待3-5秒的回流发生。

在我的例子中,这是因为我在'resize'事件上有多个(3)事件侦听器。糟糕的举动!resize事件会触发几百次,直到用户停止调整屏幕大小。

事实证明,iOS设备上的滚动也会触发调整大小事件,所以我有一个资源密集型功能(克隆一个复杂的mega菜单并为移动设备重新构建它)排队数百次,从而导致所有与js相关的任务锁定或变得非常慢。

在我的情况下,解决方案是实现一个debounce函数来debounce附加到'resize'事件的函数,从而只在resize完成时触发它们一次。

为了它的价值,我改编了Underscore.js的debounce函数,这样我就可以在本地和Underscore.js之外使用它,这个函数是从David Walsh的博客文章中借来的。下面是我如何实现它的一个例子:

  var debounce = function(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
};
var checkWindowWidthForNav = debounce(function(e) {
    sdWidth = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
    if(sdWidth <= 990){
        window.simulateMobileNav = true;
        sdMobileSnapMenus();
    }else{
        window.mobileScaffoldingDone = false;
        window.simulateMobileNav = false;
        sdMobileSnapMenus();
        $("[data-action='"hover-toggle'"]").bind("mouseenter", function(e){
            var $target = $(e.currentTarget).attr("data-target");
            var $hide = $(e.currentTarget).attr("data-hide");
            $($hide).hide();
            $($target).show();
        });
        $(".subMenuWrapper:visible").hide();
        $(".subMenuWrapper").bind("mouseleave", function(e){
            $(".subMenuWrapper").fadeOut(500, function(){
                $(".sdSubMenu .sdHideFilters, #sdArchitecturalFilters, #sdInteriorFilters, #sdUrbanFilters").hide();
            });
            return false;
            e.preventDefault();
            e.returnValue = false;
        });
        $(".sdMainMenu > ul li a[data-action], .sdSubMenu a[data-action]").bind("click", function(e){
            e.preventDefault();
            e.returnValue = false;
            return false;
        });
        $(".sdMainMenu > ul .sdSubMenu").hide();
    }
}, 600); // Debounced function occurs 600ms after event ends
window.addEventListener("resize", checkWindowWidthForNav, false);

取消我的事件导致所有JS相关事件的速度急剧增加。我不再有同位素滞后,我的回流是瞬间的。

这可能会帮助那些和我在同一条船上的人。