2

私のサイトはバックボーン上に構築されています。フィード ベースの UI を備えているため、フィードには大量のコンテンツが表示されることがよくあります。大まかに、約 30 のイベントが各項目にバインドされます。

数ページ下にスクロールすると動作が遅くなります。

スクロール アウトされたアイテムのバインドを解除し、スクロール インされたときに再度バインドすることは理にかなっていますか?

  • もしそうなら、いくつかの助け(サンプルコード/リソースへのポインタは素晴らしいでしょう)
  • 速度低下の原因は何かありますか?
4

1 に答える 1

2

動きが鈍いのは、イベント ハンドラーが原因なのか、ブラウザーがページ上の膨大な量の DOM ノードを処理できないためなのか、またはその他の理由によるものなのかを判断するのは困難です。

現在のビューポートにないビューのイベントの委任を解除するための簡単な解決策を次に示します。本番環境に完全に対応しているわけではありませんが、イベント ハンドラーがパフォーマンスの問題の原因であるかどうかをテストするのに役立ちます。

(ここで JSFiddleを操作し、ブラウザ コンソールも確認してください)

var View = Backbone.View.extend({

  onScroll: function() {

    var wasInView = this.isInView;
    var isInView = this.checkIsInView();

    if(wasInView === true) {
      if(!isInView) {
         this.undelegateEvents(); 
      }
    } 
    else if(wasInView === false) {
      if(isInView) {
        this.delegateEvents();
      }
    }
    else {
      //first pass
      if(!isInView) {
        this.undelegateEvents();
      }
    }

    this.isInView = isInView;
  },

  checkIsInView: function() {
    var $el = this.$el,
        top = $el.offset().top,
        bottom = top + $el.height(),
        windowTop = $(window).scrollTop(),
        windowBottom = windowTop + $(window).height();

    return ((bottom <= windowBottom) && (top >= windowTop));
  },

  render: function () {

    //rendering code here...

    if(!this.lazyScroll) {
      //wait for scroll events to stop before triggering scroll handler
      this.lazyScroll = _.debounce(_.bind(this.onScroll, this), 50);
      $(window).bind('scroll', this.lazyScroll)
               .bind('resize', this.lazyScroll); 
    }

    return this;
  },

  remove: function() {
    if(this.lazyScroll) {
      $(window).unbind('scroll', this.lazyScroll)
               .unbind('resize', this.lazyScroll); 
      delete this.lazyScroll;
    }
    Backbone.View.prototype.remove.apply(this, arguments);
  }
});
于 2013-01-07T16:53:29.503 に答える