jQuery の最適化に関する提案

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
リリース: 2016-05-16 15:45:23
オリジナル
1113 人が閲覧しました

ループ内で毎回配列の長さプロパティにアクセスするのではなく、ループの開始前にキャッシュしてください:

var myLength = myArray.length;

for (var i = 0; i < myLength; i++) {
  // do stuff
}

ログイン後にコピー

ループ外で追加操作を実行します

DOM の直接操作はパフォーマンスに非常に負荷がかかります。特にループ内で DOM を直接操作しないでください。

// 这样性能很差
$.each(myArray, function(i, item) {
  var newListItem = '<li>' + item + '</li>';
  $('#ballers').append(newListItem);
});
<p>// 这样性能较好<br />var frag = document.createDocumentFragment();</p><p>$.each(myArray, function(i, item) {<br />    var newListItem = '<li>' + item + '</li>';<br />    frag.appendChild(newListItem);<br />});<br />$('#ballers')[0].appendChild(frag);</p><p>// 这样也很好<br />var myHtml = '';</p><p>$.each(myArray, function(i, item) {<br />    html += '<li>' + item + '</li>';<br />});<br />$('#ballers').html(myHtml);</p>
ログイン後にコピー

コードは簡潔にしてください

繰り返しの作業は避けてください。同じことを続ける場合は、何かが間違っている可能性があります:

// 丑
if ($eventfade.data('currently') != 'showing') {
  $eventfade.stop();
}

if ($eventhover.data('currently') != 'showing') {
  $eventhover.stop();
}

if ($spans.data('currently') != 'showing') {
  $spans.stop();
}

// 漂亮!!
var $elems = [$eventfade, $eventhover, $spans];
$.each($elems, function(i,elem) {
  if (elem.data('currently') != 'showing') {
    elem.stop();
  }
});

ログイン後にコピー

匿名関数には注意してください

匿名関数があちこちに飛び回るのは非常に面倒で、デバッグ、保守、テスト、再利用が困難です。効果的な管理を実装するには、関数にできるだけ名前を付けてオブジェクトにカプセル化する必要があります。 >

// 不好
$(document).ready(function() {
  $('#magic').click(function(e) {
    $('#yayeffects').slideUp(function() {
      // ...
    });
  });

  $('#happiness').load(url + ' #unicorns', function() {
    // ...
  });
});

// 好
var PI = {
  onReady : function() {
    $('#magic').click(PI.candyMtn);
    $('#happiness').load(PI.url + ' #unicorns', PI.unicornCb);
  },

  candyMtn : function(e) {
    $('#yayeffects').slideUp(PI.slideCb);
  },

  slideCb : function() { ... },

  unicornCb : function() { ... }
};

$(document).ready(PI.onReady);

ログイン後にコピー

セレクターの最適化

document.querySelectorAll() をサポートするブラウザーが増えるにつれて、セレクターの負担は徐々にブラウザーに移ってきましたが、注意すべきヒントがまだいくつかあります。

可能な限り ID セレクターを優先して使用します:

// 快
$('#container div.robotarm');

// 相当快
$('#container').find('div.robotarm');

使用 $.fn.find 的方式更快,因为在 $.fn.find 之前的选择器并没有使用 jQuery 自带的 Sizzle 选择器引擎,而是使用了浏览器 document.getElementById() 方法,浏览器原生的方法自然更快。

使用组合选择器时,尽可能使右端更明确,而左端不尽量不明确:

// 未优化
$('div.data .gonzalez');

// 已优化
$('.data td.gonzalez');

ログイン後にコピー
セレクターの右端では tag.class を使用し、可能であれば左端では tag または .class のみを使用するようにしてください。

過度に具体的なものは避けてください:

$('.data table.attendees td.gonzalez');

// 在不影响结果的情况下尽量删掉中间多余部分
$('.data td.gonzalez');

ログイン後にコピー
簡潔な DOM 構造は、セレクターがこれらの要素を見つけるために必要な迂回を少なくできるため、セレクターのパフォーマンスの向上にも役立ちます。

ワイルドカードの使用は避けてください。明示的または暗黙的にワイルドカードを使用すると、セレクターのパフォーマンスが低下します。

$('.buttons > *');    // 极慢
$('.buttons').children(); // 好多了

$('.gender :radio');   // 隐式地使用通配符,慢
$('.gender *:radio');   // 显式地使用通配符,同上,慢
$('.gender input:radio'); // 嗯,快多了

ログイン後にコピー
イベントプロキシを使用する

イベント プロキシを使用すると、イベントをコンテナ内のすべての要素 (リスト要素 li など) ではなく、コンテナ (順序なしリスト ul など) にバインドできます。 $.fn.live と $.fn.delegate はどちらもイベントをコンテナにバインドしますが、($.fn.live ドキュメントのコンテキストと比較して) コンテキストが明確であるため、$.fn.delegate を可能な限り使用する必要があります。 ) ははるかに小さくなり、多くの不必要なフィルタリングが回避されます。

パフォーマンスの向上に加えて、イベントにバインドされたコンテナに新しい要素を追加した場合、これらの新しい要素を再度イベントにバインドする必要がなくなり、これも利点です。

// 不好 (如果列表元素非常多,你就悲剧了)
$('li.trigger').click(handlerFn);

// 好些:使用 $.fn.live 进行事件代理
$('li.trigger').live('click', handlerFn);

// 最好:使用 $.fn.delegate 进行事件代理
// 因为这样可以明确的指定一个上下文
$('#myList').delegate('li.trigger', 'click', handlerFn);

ログイン後にコピー
DOM から要素をアンロードして操作します

DOM の操作は比較的遅いため、DOM を直接操作することは避ける必要があります。 jQuery は、バージョン 1.4 で $.fn.detach メソッドを導入しました。これにより、DOM から要素をアンロードして操作できるようになり、操作の完了後に要素を DOM に追加できます。

var $table = $('#myTable');
var $parent = $table.parent();

$table.detach();
// ... 例如这里给表格添加了很多很多行
$parent.append(table);

ログイン後にコピー
外部スタイル シートを使用して多数の要素のスタイルを変更する

$.fn.css を使用して 20 を超える要素のスタイルを変更する場合は、スタイル タグをページに直接追加することを検討する必要があります。これにより、パフォーマンスが 60% 向上すると言われています。

// 当元素少于 20 个时使用这个方法,多余 20 个时,速度就慢了
$('a.swedberg').css('color', '#asd123');

// 多余 20 个元素时,应考虑直接在页面中添加 style 标签
$('<style type="text/css">a.swedberg { color : #asd123 }</style>')
  .appendTo('head');

ログイン後にコピー
$.fn.data の代わりに $.data を使用してください

$.data を DOM 要素に適用することは、セレクターで $.fn.data を直接呼び出すよりも 10 倍高速です。もちろん、前提として、まず DOM 要素と jQuery 結果セットの違いを理解する必要があります。

// 速度一般
$(elem).data(key,value);

// 速度提升 10 倍
$.data(elem,key,value);

ログイン後にコピー
空の要素に時間を無駄にしないでください

jQuery は、空の結果セットに対してコードを実行していることを積極的に通知しません。また、実行中にエラーは発生しません。したがって、場合によっては、コードを実行する前に、まず結果セットが空かどうかを判断する必要があります:

結果セットに要素が含まれていない場合でもオーバーヘッドが大きくなる可能性があるため、このアプローチは jQuery UI の側面で特に役立ちます。
// 不好:执行了三个函数之后
// 才发现结果集上没有任何元素
$('#nosuchthing').slideUp();

// 好
var $mySelection = $('#nosuchthing');
if ($mySelection.length) { $mySelection.slideUp(); }

// 最好:增加一个 doOnce 插件
jQuery.fn.doOnce = function(func){
  this.length && func.apply(this);
  return this;
}

$('li.cartitems').doOnce(function(){
  // 这里可以确保结果集不是空的
});

ログイン後にコピー
変数の定義


1 つのステートメントで複数の変数を定義できます:

自己実行関数では、変数を定義する必要さえありません:
// 老掉牙的写法
var test = 1;
var test2 = function() { ... };
var test3 = test2(test);

// 新写法
var test = 1,
  test2 = function() { ... },
  test3 = test2(test);

ログイン後にコピー

(function(foo, bar) { ... })(1, 2);

ログイン後にコピー
条件付き判定

// 土方法
if (type == 'foo' || type == 'bar') { ... }

// 较先进的方法
if (/^(foo|bar)$/.test(type)) { ... }

// 使用对象查找
if (({ foo : 1, bar : 1 })[type]) { ... }

ログイン後にコピー
関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
jQueryファイルをインポートする
から 1970-01-01 08:00:00
0
0
0
jQueryのプロトタイプチェーン
から 1970-01-01 08:00:00
0
0
0
Nuxt.js に jQuery をインストールする手順
から 1970-01-01 08:00:00
0
0
0
php+jqueryの問題
から 1970-01-01 08:00:00
0
0
0
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート