読み書きプログラミング

日常のプログラミングで気づいたことを綴っています

JavaScriptパフォーマンスベストプラクティスその10を飛ばしてその11

Nokia Developerより

jQuery固有

注意せよ!これらの最適化パターンはjQuery 1.2.6を対象にしている。最近のバージョンやSizzleセレクタエンジンはこれらのボトルネックのいくつかを軽減している。

NB! These optimization patterns are aimed at jQuery 1.2.6. Recent versions and the Sizzle selector engine alleviate some of these bottlenecks.

ソース Advanced jQuery with John Resig JavaScript Function Call Profiling

遅いjQueryメソッドの使用を最小化すること

remove(), hmtl(), empty() はn2倍のオーダーの複雑性を持つ。すなわちT(n) = O(n2)。これらのメソッドの使用の最小化は1.3.3より前のjQueryバージョンで推奨されている。

remove(), hmtl() and empty() have order of n2 time complexity, that is T(n) = O(n2). Minimizing the use of these methods is recommended in jQuery versions prior to 1.3.3. .

大量のHTMLを取ったり、それをシリアル化すること$("Hello World!"))はもちろん、append, prepend, before, afterメソッドは高価だ。
これらの操作メソッドの背後のプロセスは以下の通り: 入力文字列を掃除して、文字列をDOM断片に変換して、それをDOMに挿入する。

append, prepend, before, after methods are expensive as well as taking a chunk of HTML and serializing it ($("
Hello World!
")).
The process behind these manipulations methods is the following: cleaning the input string, converting the string into a DOM fragment and injecting it into the DOM.

セレクタを最適化すること

使用するセレクタに注意を払うこと。例えば、div要素の直接の子どもであるパラグラフを隠したいなら、そうする複数の方法がある。

Pay attention to the selectors you use. E.g. if you want to hide paragraphs which are direct children of div elements there are multiple ways to do it.


以下のセレクタの使用は、すべてのdiv要素を見つけ、それらすべてをループして、divに関連したpをすべて見つけて、マージし、重複のない結果を明らかにすることだ。返された集合に重複がないことを確認することが最も時間を費やすところで、大きなDOMツリーでは特に非常に遅い。

Using the selector below will try to find all div elements, loops thought all of them and find all p relative to the div, merge and figure out unique results. Making sure that the returned set is unique is where the most time is spent, and is very slow especially with a large DOM tree.

遅い:

$("div p").hide();

セレクタを最適化する1つの方法は、divの直接の子どもをマッチさせることだ。(このためにはアプリのDOM構造をリファクタする必要があるかもしれない。すべてのシナリオで可能かどうかわからない。)代わりのフラットなセレクタはすべてのdiv要素を見つけ、すべての子要素をループ氏、要素がpか確認する。

A one way to optimize the selector is to match direct children of div (this may require you to re-factor the DOM structure of your app and may not be feasible in every scenario). This alternative flatter selector will try to find all div elements, loops thought all child elements and verifies if element is p.

速い:

$("div > p").hide();
jQuery.each()の代わりを検討すること

配列のサイズに依存して、jQuery.each(myArray)の代わりに{{{1}}}を使って配列全体をループする方が速いかもしれない。

Depending on the size of the array, looping through it using {{{1}}} instead of jQuery.each(myArray) may be faster.

.show(), .hide(), .toggle()の代わりを検討すること

.css({'display':'none'}) と .css({'display':'block'})を使って要素の可視性をトグルするほうが、従来の.show(), .hide() and toggle()を使うより速い。特にたくさんの要素でする時には。また、使うレンダリングエンジンによっては、addClass()と.removeClass()を使うより.css()が速い。

Toggling element visibility via .css({'display':'none'}) and .css({'display':'block'}); is faster than using convenience functions .show(), .hide() and toggle(), especially while working with large number of elements. Depending on the rendering engine used, .css() is also faster than using .addClass() and .removeClass().

遅い:

$('#elementToHide').hide();
$('#elementToShow').show();

速い:

$('#elementToHide').css({'display':'none'});
$('#elementToShow').css({'display':'block'});

極端に大きなDOM要素の集合を扱うには、以下のようにスタイルシートを無効にすることを検討したいかもしれない:

For dealing with extremely large set of DOM elements, you may want to consider disabling stylesheets as follows:

<style id="special_hide">.special_hide { display: none; }</style>
<!--  ...  -->
<div class="special_hide">Special hide DIV</div>
// show all elements with a class of “special_hide”
$('#special_hide').attr('disabled', 'true');
 
// hide all elements with a class of “special_hide”
$('#special_hide').attr('disabled', 'false');

ソース