大型同位素画廊非常慢

时间:2014-05-23 01:36:37

标签: javascript jquery jquery-isotope

我有一个Isotope图库(版本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;
  }
});

我应该注意,上面的代码在有少量项目时效果很好。我怎样才能提高画廊的表现?

我应该注意,在Isotopes的第1版中,我有相同的画廊,它工作正常。我正在升级,因为同位素v2的能力增强。

Here is the live site - 重要! - 这个网站是在美国科罗拉多州的大麻药房。网站可能不适合工作。

更新

我尝试将所有div更改为li元素。没有看到太多改进。

我尝试按照mfirdaus的答案启用硬件加速,但它似乎没有效果。

注意:上面的实际网站链接是一个精简版本,我删除了同位素库不需要的所有内容。它比我最初发布它时略快,但它需要更具响应性。尝试在平板电脑上使用它,Isotope项目需要几秒钟才能响应。

更新2

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

4 个答案:

答案 0 :(得分:13)

我有个建议。首先,您可以将css属性transform:translate3d(0,0,0)添加到.element css选择器。这会打开硬件加速并加速页面重排。这是一个经常用于使高度动画的页面更流畅的提示,尤其是在移动设备上。有点像ilke:

.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.2s的差异,但它有点明显。

Here's an example made from isotope's default example which has 400 elements.

<小时/> 更新

在测试touchstart之后,它有点帮助,但即使在滚动时也会触发。因此,仅当您禁用滚动/具有固定视口时,这才有用。也许你可以添加iScroll,但我认为这更加臃肿。

您可以尝试的一个选项是在等待同位素重新计算位置之前强制元素先调整大小。我们可以通过在同位素更新上使用setTimeout来实现此目的。不确定行为是否可以接受,但这将允许用户更快地获得反馈。因此,您的切换代码将类似于:

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

Demo。在我的Android设备上测试过,似乎有了改进。

答案 1 :(得分:1)

嗯,如果您正在进行过滤或排序,同位素插件的author建议最多 50 项。你有 400 !所以我担心你需要减少数量。用于提高性能的项目。

一些旁注:

  • 尝试touchstartmousedown个事件而不是click,以便在移动设备上获得更快速的响应。
  • 检查移动设备上的Object.keys(filters).forEach效果(而不是for in)..
  • 某些浏览器中,jQuery的closest()方法可能比parents()更快。

答案 2 :(得分:1)

尝试直接操作样式,而不是使用toggleClass。

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

答案 3 :(得分:0)

虽然我知道这可能不是与您的场景直接相关的问题,但我有相同的体验(主要是在移动设备和平板电脑设备上),我在Isotope画廊中只有36张图片,而我在等待3回流发生的时间为-5秒。

在我的情况下,这是因为我在&#39; resize&#39;上有多个(3)事件监听器。事件。不好动! resize事件会一直触发几百次,直到用户停止调整屏幕大小。

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

在我的情况下,解决方案是实现去抖功能以去除附加到&#39; resize&#39;事件,因此只有在调整大小完成时才会触发它们。

为了它的价值,我调整了Underscore.js去抖功能,以便我可以在本地和Underscore.js之外使用它,这是borrowed from this blog post by 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相关活动的速度增加。我不再有同位素滞后,我的回流是瞬间的。

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