中級レベルの jQuery

パフォーマンスを評価する指標とパフォーマンスの調整

jQuery は素晴らしい JavaScript ライブラリーですが、そのパフォーマンスについてはどうでしょう。Web ページに余分な負荷がかかったとしても、その使い易さをとるだけの価値はあるのでしょうか。それとも、そのようなパフォーマンス・ヒットはまったくないのでしょうか。この記事ではそんな jQuery のパフォーマンスに関する疑問に答え、読者それぞれのアプリケーションでパフォーマンスを向上させるためのヒントを提供します。

Michael Abernethy, Product Development Manager, Optimal Auctions

Mike AbernethyMichael Abernethy はこの 11 年間の技術生活の中で多種多様な技術を扱い、また多種多様な顧客と共に作業を行ってきました。彼は現在、オークション・ソフトウェアの会社である Optimal Auctions の製品開発マネージャーとして働いています。彼は最近、RIA に焦点を当てており、RIA をもっと複雑にすると同時にもっと簡単にすることに取り組んでいます。コンピューターに向かっている時間以外には、彼はメキシコのビーチでためになる本を読みながら時間を過ごしています。



2009年 6月 16日

はじめに

この記事を書くきっかけとなったのは、以前に書いた記事のフィードバックとして受け取った E メールです。その E メールにはこう書いてありました。「jQuery は単純なページで使うにはいいのですが、複雑なページではパフォーマンスが極端に悪くなります。パフォーマンスの問題が修正されるまでは、複雑なページには通常の JavaScript を使用するべきです」。この意見を見て私は即座に思いました。「どのようにして jQuery のパフォーマンスと JavaScript のパフォーマンスを比較するのだろうか?」実際、パフォーマンスを話題にした記事で、jQuery ライブラリーを JavaScript や他の JavaScript ライブラリーと比較した内容を見掛けたことはめったにありません。多分ほとんどの人々と同じく、私は jQuery を使ったクライアント・サイドのコーディングがどんなに簡単であるかに目を奪われていて、パフォーマンス・ヒットの可能性をまったく無視していました。簡単さと引き換えにパフォーマンス・ヒットがあったとしても、私にとってこのトレードオフには間違いなく価値があります。しかし、そもそも検討すべきトレードオフはあるのでしょうか。jQuery は「通常」の JavaScript (それが何であれ) よりも遅いのでしょうか。jQuery は他のライブラリーよりも遅いのでしょうか。この記事で、これらの疑問に答えたいと思います。

JavaScript のパフォーマンスを測定するときに最も重要になる検討事項の 1 つは、JavaScript を実行している環境です。JavaScript コードはクライアントで実行されることから、コードの実行を任せるクライアントのコンピューターが最も重要なパフォーマンス要因となります。当然、クアッドコアの最新サーバーであれば、古い 400 MHz のプロセッサーよりもコードの実行速度は速くなります。それは言うまでもありませんが、皆さんが作成した Web アプリケーションのユーザーがどんなマシンを使ってサイトにアクセスするかを制御することは不可能です。したがって、パフォーマンスを測定する際にハードウェアを考慮に入れる理由はあまりありません。

JavaScript のパフォーマンスにはもう 1 つ、非常に重要な側面があります。JavaScript コードの作成を始めたばかりの初心者にとっては明らかでないかもしれませんが、それは、JavaScript を実行するときに使用するブラウザーが極めて大きな要因となることです。あらゆるブラウザーの「内部」には JavaScript エンジンがあります。つまり、作成された JavaScript コードを解釈して実行し、Web アプリケーションのページでアクションを起こすネイティブ・コードです。そのため、パフォーマンスはクライアントが使用するブラウザーによって大きく左右されます。ユーザーが使用するブラウザーに関しては、場合によっては制御することが可能です。この記事では、JavaScript のパフォーマンスに関するガイドラインを提供し、ブラウザーによってパフォーマンスがどのように異なってくるかを説明します。

記事の最後では、JavaScript、特に jQuery のパフォーマンスについて結論を出した後、最も速いと判断したパーツを利用し、遅いと指摘したパーツを使わないようにして、jQuery コードのパフォーマンスを向上させるベスト・プラクティスを定義します。この記事を読み終える頃には、「jQuery のパフォーマンスは優れているのだろうか」という疑問に対する答えが見つかるはずです。そして最初に紹介した E メールの送信者も、彼の主張が正当なものであるかどうかわかるはずです。

パフォーマンス・テストの作成

パフォーマンスをテストする際の最初のステップは、適切なパフォーマンス・テストを作成することです。jQuery だけでなく、あらゆる JavaScript ライブラリーがコーディングで果たす最大の役割の 1 つは、セレクターを使用して特定のページ要素を見つけることです。そこで、最初のパフォーマンス・テストではこの側面を使用することにします。この記事の目的にふさわしいパフォーマンス・テストとは、種類ごとに何百とある合計何千ものページ要素を持つページに対して JavaScript ライブラリーをテストすることによって、そのパフォーマンスを試すというものです。どのセレクターのメソッドが速く、どれが遅いかを確認できるように、JavaScript ライブラリーがこのページですべてのセレクターのメソッドを実行します。また、正しい答えが前もってわかっているので、JavaScript ライブラリーがそのセレクターのメソッドを正しく実行しているかどうかを判断することができるテストです。そして最後に結果のすべてが測定時間とともに提示されれば、簡単にすべてのライブラリーの結果を比較することができます。

おっと、このパフォーマンス・テストの最も重要な点を言い忘れていました。このテストはすでに存在していて、無料で入手できます。結局のところ、この jQuery に関する一連の記事を通じて共通するテーマは他の人々の優れた業績を利用することなので、今回もこのテーマに従って、すでに作成されている JavaScript ライブラリーのパフォーマンス・テストを利用することにします。それは SlickSpeed Selectors Test (「参考文献」を参照) という名前のテストで、ここでのニーズにぴったり合っています。このテストは jQuery 1.2.6 (この記事を執筆している時点で最新のバージョン) を、よく使われている他の 4 つの JavaScript ライブラリー (MooTools、Prototype、YUI、Dojo) と比較します。次に何千ものページ要素を持つページに対してセレクターのメソッドに関する 40 のテストを実行します。つまり、私が探し求めていた理想的なパフォーマンス・テストです。次のセクションでは、このテストを利用して最初のパフォーマンス・テストを行い、その結果を分析します。

JavaScript ライブラリーのパフォーマンスの比較

この最初のパフォーマンス・テストは、 2.2 GHz のプロセッサー、2 GB の RAM、(そして最も重要な点として) Firefox 3.0.3 で実行します。このセットアップでテストを 5 回実行した結果、実行時間の平均は図 1 のようになりました。

図 1. パフォーマンス・テスト 1 の結果
パフォーマンス・テスト 1 の結果

この最初のテストから、どのような結果を引き出せるでしょうか。この時点では、テストで実行した個々のテストではなく、全体的な結果を重点に検討します。個別のテストについては、大まかな結論を出してから詳細を検討することにします。

  • 結論 1: YUI ではかなり時間がかかります。
    まさにその通りで、YUI は他のライブラリーに比べ、大幅に速度が劣っています。個々のテストでその理由を調べてみると、このライブラリーは要素のグループ (“p, a” など) の選択を非常に苦手としていることがわかります。つまり、パフォーマンスに依存する複雑なページには、このライブラリーは誤った選択となります。
  • 結論 2: Mootools、jQuery、Dojo の結果はほとんど同じです。
    この 3 つのライブラリーは他の 2 つと比べ、いずれもかなり高速です。見てのとおり 3 つのなかで最も早いのは Dojo で、最も遅いのは jQuery となっていますが、総合的に検討するとおおよそ同じ速度と言えます。
  • 結論 3: ライブラリー間の相対的な差異がかなり顕著です。
    速度の相対的な差異を判断するために最低速度と最高速度を測定すると、そこには 332% の差があることがわかります。この顕著な差は、どの JavaScript ライブラリーを選択するかによって、Firefox ブラウザーでのパフォーマンスに影響を与えることを示しています。

ただし念頭に置いておかなければならない点は、以上は 1 つのブラウザーで実行したテストから得た結論であるということです。Firefox 3.0.3 でのテストから至ったこの結論を参考に、次のセクションでは異なるブラウザーで同じテストを実行してみます。

異なるブラウザーでの JavaScript のパフォーマンス

駆け出しの Web プログラマーの多くは、JavaScript を実行するブラウザーによって、そのパフォーマンスを表す実行時間も異なれば、結果も異なるということを知って驚くものです。この事実は、複数の異なるブラウザーに対応するために余分にコードを作成しなければならないことを恐れている初心者にとってはストレスの種になるはずですが、ベテランの Web プログラマーにとって、これは Netscape と Internet Explorer が争っていた初期の頃からのお馴染みの問題です。また、この問題は JavaScript ライブラリーを使用する大きなメリットの 1 つでもあります。JavaScript ライブラリーは、ブラウザーによる違いの多く、あるいはそのほとんどに対処するからです。

ブラウザーによって JavaScript の実行速度が異なる一番の理由は、ブラウザーのそれぞれが独自の JavaScript エンジンを使用しているからです。JavaScript エンジンは、JavaScript を解釈し、そのコードを Web アプリケーションに対して実行するネイティブ・コードです。そのため JavaScript の実行速度には、使用されているエンジンと、そのエンジンのパフォーマンスにどれだけの努力が注ぎ込まれているかが直接影響します。この数ヶ月で、JavaScript エンジンのパフォーマンスについて検討するブラウザー会社の数が確実に増えてきましたが、これには妥当な理由があります。特定のページでの JavaScript の複雑さが増すにつれ、JavaScript エンジンが高速か低速かによって、Web アプリケーションの応答性が良くなるか、あるいは動作が遅くなるかを左右するからです。したがって、Google や Firefox などの企業は自分たちの JavaScript エンジンを話題に取り上げ、次世代のエンジンは今よりも 10 倍の速度となることを語っていますが、これは Web アプリケーションにとって重要なことです。Web アプリケーションの実行に使われる JavaScript エンジンの速度が、より複雑で込み入った Web アプリケーションの成長に直接つながるからです。

JavaScript エンジンが JavaScript の実行速度の要因となることがわかったところで、Firefox で実行したテストを今度は複数の異なるブラウザーで実行して、それぞれのエンジンが JavaScript パフォーマンスに及ぼす影響を数値で表してみます。このテストは Firefox で実行したテストと同じで、テストを実行するラップトップも同じです。つまり、JavaScript エンジンが異なるという以外はすべて同じ条件であることを念頭に置いてください。図 2 に、その結果を示します。

図 2. パフォーマンス・テスト 2 の結果
パフォーマンス・テスト 2 の結果

上記の結果を見て最初に気付くのは、ブラウザーによって実行時間に大きな差があることです。とりあえず jQuery だけに注目すると、Chrome 1.0 での jQuery テストは 168 ミリ秒で完了している一方、IE6 では 1728 ミリ秒もかかっています。これは驚くべき時間の差で、IE6 での jQuery セレクターの実行時間は、Chrome で実行した場合の 10 倍です。これで、Google がその JavaScript エンジンの速度を自慢している理由、そして他のブラウザーの JavaScript エンジンの噂はあまり耳にしない理由がおわかりでしょう。この差は極めて顕著です。

もう 1 つ目に飛び込んでくる点は、jQueryは Firefox では 3 番目に実行速度の速いライブラリーでしたが、一部のブラウザーでは最も高速なライブラリーで、その他のブラウザーでは 3 番目になっていることです。この結果は実際のところブラウザーとは関係なく、ライブラリーはパフォーマンスという点で 2 つのグループに分かれることを示します。Mootools、Dojo、jQuery は常に 1 つのグループとして括られ、このグループは Prototype と YUI が含まれるもう一方のグループよりも遙かに高速です。

パフォーマンス・テストから導かれる結論

パフォーマンス・テストの結論を 1 つの独立したセクションにした理由は、これらの結論は JavaScript 開発者にとって非常に重要だからです。ここでも上記のパフォーマンスの結果から結論を引き出したいと思います。私が投稿している一連の記事は jQuery を話題にしたものですが、そのために jQuery をひいきすることはありません (そうならないことを願います)。

結論 1: Mootools、jQuery、Dojo のパフォーマンスはほとんど変わりません。
5 つのブラウザーでの結果を全体的に見た場合、結果を正規化すると上記の 3 つのライブラリーはパフォーマンスの点ではほとんど同じであることがわかります (理想的には、各ブラウザーの市場占有率に応じた正規化の重みを付けたかったところですが、これらの数値を調整するとなると厄介なことになります。JavaScript ライブラリーを使用する傾向のあるサイトは、概して「普通の人」がアクセスするサイトではないからです)。

図 3. 正規化したテスト結果 (Mootools、jQuery、Dojo)
正規化したテスト結果 (Mootools、jQuery、Dojo)

結論 2: Prototype と YUI のパフォーマンスは大幅に劣ります。
5 つのブラウザーでの Prototype と YUI の結果を jQuery と比べると、正規化した結果から、この 2 つのライブラリーによってもたらされるパフォーマンスの違いがどれほどのものかは一目瞭然です。平均すると、これらのライブラリーの実行速度は jQuery の 3 倍遅くなります。

図 4. 正規化したテスト結果 (jQuery、Prototype、YUI)
正規化したテスト結果 (jQuery、Prototype、YUI)

結論 3: パフォーマンスが重要な場合、Mootools、jQuery、Dojo のどれを選んでも変わりはありません。
上記の正規化した結果を基にすると、Mootools、jQuery、Dojo のどれを選択しても、他の 2 つを選択した場合に比べてパフォーマンスが優位になるわけではありません。すべてのブラウザーを考慮してみても、この 3 つのライブラリーのパフォーマンスはほとんど同じです。したがって、JavaScript ライブラリーを選択するときには、この 3 つのライブラリーのいずれかを選べば間違いはありません。

結論 4: パフォーマンスが重要な場合には、Prototype や YUI を選択してはなりません。
JavaScript ライブラリーを使用する際にパフォーマンスが懸念される場合、あるいは大規模な JavaScript プロジェクトの作成を計画している場合には、恐らく Prototype または YUI を選択するべきではないでしょう。この 2 つのライブラリーのいずれかを選択した場合のパフォーマンス・ヒットは、他のライブラリーに比べて顕著です。

結論 5: ブラウザーは、どの JavaScript ライブラリーを選択するかの 9 倍重要です。
これは、このパフォーマンス・テストで最も重要な結論だと思います。特定の状況で、どの JavaScript ライブラリーが最も速いかについて討議してくれても構いませんが、結局のところ、ライブラリーの速度は問題にもなりません。速度とパフォーマンスという点では、実際のライブラリーよりもブラウザー自体のほうが遙かに重要な要因となります。図 3 と図 4 の正規化した結果をもう一度見てみると、3 つの「高速」なライブラリーのうち平均して最も遅いライブラリー (Dojo) は、このなかで最も早いライブラリー (jQuery) に比べて速度が 15% 劣るだけです。たったの 15% です。その一方、最も高速に動作するブラウザー (Chrome 1.0) と最も速度が劣るブラウザー (IE 6) での jQuery の結果を見てみると、その差は 1000% にも上ることがわかります。この 2 つの数値を考え併せると、15% の差は 1000% の差の比ではありません。この結論が、3 つのライブラリーのうちのどれが最も高速かについての議論に終止符を打つことになって欲しいと思います。結局、それは大した問題ではないからです。

結論 6: JavaScript のパフォーマンスが Web アプリケーションにとって重要な場合、ユーザーの使用するブラウザーを制御できるのであれば是非そうしてください。
場合によって、そして Web アプリケーションによっては、サイトにアクセスするときに使用するブラウザーを制御することができます。この記事を読んでいる読者も運よく、そのような環境にいるかもしれません。私も、その幸運に恵まれたプロジェクトを手掛けたことがあります。ブラウザーを制御することが可能な環境であれば、JavaScript アプリケーションが複雑な場合、あるいはパフォーマンスが問題になると考えられる場合には、ユーザーが Web アプリケーションにアクセスするときに使用するブラウザーを制御するよう努めなければなりません。パフォーマンス・テストの結果が、このことを証明しています。JavaScript を多用しているアプリケーションで、ユーザーに Chrome を使用するように指定できるとしたら、その機会を逃したくはないはずです。

結論 7: ユーザーが使用するブラウザーを制御できないとしたら、IE6 でのパフォーマンスに留意してください。
その一方、私たちのほとんどは、ユーザーがサイトにアクセスするときに使用するブラウザーを制御できない環境にいます。また Web サーフィンに IE 6 を使用しているユーザーは相変わらず大勢いるのが悲しい現実です。テストから明らかなように、このブラウザーの JavaScript エンジンは、テストしたブラウザーのなかで最も、しかも大幅に実行速度が劣っています。しかし多くの人々がまだこのブラウザーを使用していること、そして優れた Web 設計には「最も遅い共通項に合わせた設計」が必要となることから、JavaScript アプリケーションを設計するときには常に IE 6 を念頭に置いて行ってください。

jQuery のパフォーマンスの調整

この記事の後半では、jQuery コードのパフォーマンスを改善する方法を詳しく検討します。前のセクションでの結論から、JavaScript ライブラリーに jQuery を選択することがパフォーマンスの面では賢い選択であることは明らかです。この記事を読んでいる読者は jQuery を試したことがあると思いますが、使用するライブラリーが高速であるからと言って、作成するコードのすべてが高品質になるとは限りません。一歩離れて何をしようとしているのかを客観的に考えなければ、jQuery を使っていても、かなり遅いコードを作成してしまう可能性は間違いなくあります。

このセクションでは、パフォーマンスの調整方法と jQuery コードの実行速度を向上させるためのベスト・プラクティスを順に説明します。

ヒント 1 – クラスではなく、できるだけ ID を使用して検索すること
jQuery コードでは、要素をその ID で検索するという手法と、要素のクラスで検索するという手法の 2 つが一般に使用されます。JavaScript ライブラリーが登場する以前でも、通常の JavaScript を使ってページ要素を ID で検索するのは至って簡単なことで、getElementById() メソッドを使用すれば要素を素早く検索できました。しかしクラスの検索となると、JavaScript ライブラリーなしで検索するのは大変だったため、必要な場合には ID を付した要素で該当部分をラップするという方法でコーディングする傾向がありました。jQuery を使用すると、ページ上のクラスの検索は ID を検索する場合と同じように簡単に行えます。そのため、この 2 つの検索手法はどちらを使っても変わりがないように思えますが、実際にはまったくそんなことはありません。ID による検索はクラスによる検索よりも断然高速だからです。ID による検索では、jQuery は単に組み込みの getElementById() メソッドを使うだけですが、クラスによる検索ではすべてのページ要素に対して一致しないかどうかを繰り返し処理して探します。そのため当然、サイズが大きくて複雑なページでは、クラスによる検索では応答がかなり遅くなる一方、ID による検索ではページのサイズが大きくなってもパフォーマンスが劣化することはありません。

このデータは、これまで実行してきたパフォーマンス・テストでの jQuery の結果で裏付けられています。ここからは、jQuery コードで注意を要する点を調べるために、個々のテスト結果を検討していきます。この場合に比較するのは、ID で検索したときのテスト結果とクラスで検索したときのテスト結果です (図 5)。

図 5. ID による検索とクラスによる検索の比較
ID による検索とクラスによる検索の比較

上記のテストはまったく同じではありませんが、ID による検索のほうが、クラスによる検索よりも際立って高速であることが数値によって証明されています。これは、jQuery コードにはどう影響するのでしょうか。それは、要素を検索するコードを作成するときに ID とクラスのどちらかを選ぶとしたら、必ず ID を選択するようにしなければならないことを意味します。また、コードのどこかで検索で使用される可能性のあるすべての要素には、ID を指定する必要があることも意味します。

リスト 1 に実際の jQuery テストを記載します。このテストを実行すると、ご自分のマシンで上述の内容を確認することができます。

リスト 1. クラスと ID の比較
$(document).ready(function() {

  console.info("Start Test");
  var d = new Date();
  console.info(d.getSeconds() + " " + d.getMilliseconds());

  var testBody = "";
  for (var i=0; i<1000; i++)
  {
     testBody += "<div class='testable"+i+"'>";
  }
  $("body").append(testBody);
  for (var i=0; i<1000; i++)
  {
    $(".testable"+i);
  }

  var d = new Date();
  console.info(d.getSeconds() + " " + d.getMilliseconds());
  console.time("Start ID Test");

  testBody = "";
  for (var i=0; i<1000; i++)
  {
    testBody += "<div id='testable"+i+"'>";
  }
  $("body").append(testBody);
  for (var i=0; i<1000; i++)
  {
    $("#testable"+i);
  }
  var d = new Date();
  console.info(d.getSeconds() + " " + d.getMilliseconds());
  console.info("End Test");
  });

ID のテストではわずか 218 ミリ秒しかかからなかった一方、クラスのテストでは 19.9 秒もかかりました。このテスト用に作成した単純なページでさえも、ID による検索は約 100 倍も高速です。

ヒント 2 – できる限り多くの検索情報を提供すること
jQuery でページの要素を検索するには、あまりにも多くの方法が考えられるため、目的のページ要素をどの方法で検索するのが最適かを判断しかねることがあります。どんな場合にでも当てはまる 1 つの規則は、持っている限りの情報を検索パラメーターに提供することです。したがって、例えば “clickable” というクラスを持つすべてのページ要素を検索するときに、このクラスが付加されているのは DIV だけであることが前もってわかっているとしたら、検索パフォーマンスを改善することができます。つまり、”div.clickable” を検索するほうがずっと短時間で検索できるということです。図 6 に、これを裏付ける数値による結果を示します。

図 6. できる限り多くの情報を提供した場合
できる限り多くの情報を提供した場合

ベースに使用している JavaScript コードを考えれば、この結果は当然と言えます。要素タグを指定することによってクラスの引数で一致の検索対象となる要素の数が大幅に減るため、パフォーマンスが向上し、この例では ID による検索とほぼ同じくらいにまで実行速度が速くなります。

開発者は jQuery セレクターを作成するときに手を抜いてはなりませんが、その単純さゆえに、そうしたくなるものです。単純さは、開発者の気を緩めるものです。検索メカニズムを簡易化して、単純に 1 つの情報だけを入力すればいいようにしたくなるものですが、情報がわかっている場合には尚更のこと、できるだけ多くの情報を使用するように努めなければなりません。リスト 2 がその好例です

リスト 2. 十分な情報の提供
// Assume there are 50 of these in some giant form, and you need to validate
// these fields before they are submitted, and there are hundreds of other
// elements on the page as well
<input type=text class="notBlank">

// the "bad" way to validate these fields
$(".notBlank").each(function(){
   if ($(this).val()=="")
      $(this).addClass("error");
});

// the "good" way to validate these fields
$("input.notBlank").each(function(){
   if ($(this).val()=="")
      $(this).addClass("error");
});

// the "best" way to validate these fields
$("input:text.notBlank").each(function(){
   if ($(this).val()=="")
      $(this).addClass("error");
      });

ヒント 3 – セレクターによる検索結果をキャッシュすること
最後に紹介するパフォーマンスのヒントは、ほとんどすべての jQuery セレクターが jQuery オブジェクトを返すという事実を利用したヒントです。つまり、関数をチェーンする機能、または結果を後で使えるようにキャッシュする機能を使用すれば、理想的な状況下ではセレクターを一度実行するだけで済ませられます。キャッシュによってメモリーが制約されると心配する必要もありません。実際のオブジェクト自体のサイズは、ストレージに使用できるメモリーの全体量に比べれば、ほんのわずかだからです。

リスト 3 に、キャッシング方法の例をいくつか記載します。

リスト 3. キャッシング
// Imagine a function that hides all the div's with a class of "hideable" 
// when a button is pressed.  These DIV's might reappear later when 
// working with the page,  so the button can be pressed any number of 
// times, and the DIV's that have reappeared
// will again be made to be hidden.

$("#ourHideButton").click(function(){
   $(".hideable").hide();
});

// As you saw in the CLASS versus ID example, though, a search for 
// CLASS is very inefficient
// If this button is pressed often, it could lead to a slow response
// Instead of the above example, you should write your code like this

var hideable;

$("#ourHideButton").click(function(){
   if (hideable)
       hideable.hide();
   else
       hideable = $(".hideable").hide();
});

// You can cache your search in a JavaScript variable and reuse it every time
// the button is pressed.  Because jQuery almost always returns the
// jQuery object, you can save it the first time it is called for future use

パフォーマンスに関する最後のサンプル・コードについては、連載「jQuery を扱う」第 1 回の記事で説明したウィジェットを参照してください (「参考文献」を参照)。このウィジェットはテーブルの一番左上に表示されるチェック・ボックスで、このチェック・ボックスを選択/選択解除すると、その列にあるすべてのチェック・ボックスが選択/選択解除されます。このように、すべてのメッセージを選択/選択解除するためのチェック・ボックスは、E メール・アプリケーションではかなり一般的に使用されています。

リスト 4. パフォーマンスの改善
// Here is the code as I originally presented it in that article.  Let's see
// if we can improve the performance in any way from the things we learned here

function selectAll()
{
    var checked = $("#selectall").attr("checked");
    $(".selectable").each(function(){
       var subChecked = $(this).attr("checked");
       if (subChecked != checked)
       	  $(this).click();
    });
}

// Here's the improved function.  The search for the ID of "selectall" is
// OK as-is, because we saw how fast the ID search is.
// The search for the CLASS of "selectable" was not well-designed though,
// because we saw a search by CLASS is very inefficient.
// First step was improving the search by supplying as much information as we know.
// We narrowed the search to only checkboxes with the CLASS of selectable.
// This should improve our search
// Further, we can cache this search because we will only need to perform it once
// Finally, we can perform this search before the selectall checkbox is even
// checked (when the page is finished loading), so that the search is completed
// and cached before the user even uses it.
// These 3 simple performance steps gave me a 200% increase in speed when tested
// on a page with 200 rows of data.

var selectable = $(":checkbox.selectable");
function selectAll()
{
    var checked = $("#selectall").attr("checked");
    selectable.each(function(){
       var subChecked = $(this).attr("checked");
       if (subChecked != checked)
       	  $(this).click();
    });
}

パフォーマンスに関する最後のポイント

JavaScript を使用する場合には、速度とパフォーマンスの問題は決して小さな問題ではありません。そして上記のテストによる証拠から明らかなように、jQuery を作成した開発者も、ブラウザーの組み込み JavaScript エンジンに取り組んでいる開発者も、この事実を把握しています。事実この 6 ヶ月間というもの、ブラウザー開発で最も重要視されてきた問題は JavaScript エンジンの実行速度でした。来年は jQuery コードと JavaScript エンジン両方の実行速度が飛躍的に向上し、JavaScript 実行時のパフォーマンスが極めて急速に向上するということを、すべての兆候が示唆しています。実際、jQuery と JavaScript エンジンの両陣営とも、まさにそうなると報じています。jQuery プロジェクトのリーダーである John Resig は、彼が新たに開発している「Sizzle」セレクター・エンジンについて語っています。彼はセレクター・エンジンを一から作成し、予備段階の結果では Firefox での速度が 4 倍速くなったと主張しています。この速度の向上は極めて注目に値するものです。この最後のセクションを執筆している時点で実際にリリースされた jQuery 1.3 バージョンには、この Sizzle セレクター・エンジンが組み込まれています。jQuery では、すべてのブラウザーを考慮に入れても、jQuery 1.3 バージョンのセレクター・エンジンは 1.2.6 バージョンに比べて速度が 49% 増加すると明言しています。1.3 リリースの宣伝文句としては、他にも HTML インジェクション (新規要素を DOM に追加すること) の処理速度が 6 倍になっていること、そして位置決め関数の処理速度も 3 倍になっていることが挙げられます。私がこの記事を書き終えようとしているその日にリリースされた jQuery のこのメジャー・アップデートに、期待が高まります。

JavaScript のパフォーマンスに関するもう 1 つの側面はブラウザーです。指摘したように、ブラウザーにはどのライブラリーを選択するかの 9 倍の重要性があります。Firefox と Chrome は、どちらの JavaScript エンジンが高速になるかという点でしのぎを削ってきましたが、この勝負には Safari も加わってきています。上記のテストでは、現時点では Chrome が大幅に Firefox に勝っているという結果になりましたが、Firefox 3.1 に組み込まれる予定の新しい Tracemonkey JavaScript エンジンは、Firefox 3.0 に組み込まれている現行の JavaScript エンジンに比べ、20 倍から 40 倍高速になると見込まれています (これは私の作り話ではなく、彼らが主張していることです)。20 倍から 40 倍の速さとは、まさに圧倒的です。

今後 1、2 年で、JavaScript エンジンとライブラリー自体に実行速度の面で、根本的にさまざまな改善がなされ、JavaScript 主導の Web アプリケーションが極めて複雑なアプリケーションにも対応できるだけの速度になるはずです (もちろん、IE6 はその例外です)。

JavaScript ライブラリーを使用するか、それとも JavaScript を自分でハンド・コーディングするかを決める際にもう 1 つ検討しなければならないことは、JavaScript ライブラリーに注がれてきたすべての作業とデバッグです。JavaScript ライブラリーには、そこに含まれるあらゆる関数を数年間にわたって調べてきたユーザーが何百人といます。あなた自身もカフェイン入りの大量のコーヒーを飲みながら作成して午前 2 時に完成した関数を自分で調べるはずですが、一人と大勢のどちらを信用しますか?さらに、jQuery ライブラリーよりも高速なコードをどうにか自分で作成できると思ったとしても、jQuery ライブラリーを使用するあらゆる利点が、考えられるパフォーマンス・ヒットを上回ることはないと思いますか?あなたは、jQuery とその関数ライブラリーを使用することによってもたらされる、大きな利便性のすべてを進んで投げ捨てることでしょう。なぜなら、独自のコードを作成するのに伴う作業と悩みの種が欲しいからですが、それによって作成時間が長くなり、より多くのバグが発生し、そして「やり過ぎだったかも」と感じてくるはずです。私は遠慮します。

最後に指摘する点は、一部の開発者を落胆させてしまうかもしれませんが、これらの jQuery ライブラリーを作成している開発者たちについて考える必要があるということです。彼らは世界でも指折りの優秀なプログラマーであり、自分では作成できなくても、彼らには作成できる抜群に優れたコードのすべてが jQuery ライブラリーに組み込まれていくことになります。jQuery ライブラリーを作成している人々が自分よりも遙かに優秀なプログラマーだと認めることを誇りには思いませんが、彼らが作成したコードよりも高速に動作する優れたコードを作成できると考えるのは馬鹿げています。自分の知性の代わりに彼らの知性を利用しない手はありません。

まとめ

この記事では、jQuery、そして JavaScript ライブラリー全般のパフォーマンスについて検討しました。さまざまなセレクターのメソッドのテストをした結果、それぞれのライブラリーの間でも実行速度に大きな違いがあることがわかりました。jQuery は最も高速なライブラリーの 1 つとして選択することができます。ただし、高速な JavaScript ライブラリーを選んだとしても、ユーザーが Web アプリケーションにアクセスするときに使用するブラウザーのほうが、選択したライブラリーの 9 倍の影響を Web アプリケーションのパフォーマンスに与えます。ユーザーに特定の Web ブラウザーを使用させることができるのであれば、是非そうするべきです。Web アプリケーションを最も高速に実行するブラウザーを選択して、Web アプリケーションのユーザーがそのアプリケーションに本来備わる利点を実感できるようにしてください。できることならば、JavaScript の実行速度が遅いブラウザーを除外して、今までにない Web アプリケーションの境地を現実のものにしてください。

さらに、jQuery を使用する場合のパフォーマンスに関する 3 つのヒントも紹介しました。確かにもっと多くのヒントを提供しているサイトもいくつかありますが、パフォーマンスの向上という点では、ここで紹介した3 つのヒントにとびきり大きな「努力に見合う価値」があります。しかも 3 つのことを覚えるほうが、50 のことを覚えるより簡単です。その他のヒントも有効なので、そのうちのいくつかを「参考文献」で紹介しておきますが、この記事の 3 つのヒントを念頭にコードを監査すれば、パフォーマンスに著しい向上が見られるはずです。ID で検索した方がクラスで検索するより 100 倍高速であること、検索には常にできるだけ多くの情報を提供すること、そして可能な限りセレクターによる検索結果をキャッシュすること。この 3 つの jQuery のヒントは、常に覚えておいてください。

最後に、jQuery とブラウザーの JavaScript エンジンで今後予定されている変更内容を簡単に説明しました。前述のとおり、この記事の最後のセクションを書いている最中にリリースされた jQuery 1.3 は、セレクターやその他のコードの側面で著しいパフォーマンスの改善を約束しています。また、Firefox では 20 倍から 40 倍も高速な次世代の JavaScript エンジンを積む見込みであることも紹介しました。すべての兆候は、今後 1、2 年の間に JavaScript 環境が極めて高速になることを示唆しています。その結果、極めて大規模で複雑な Web アプリケーションを実行することが現実になれば、そのような Web アプリケーションがより一般的になってくるはずです。

締めくくりとして、この記事を書くきっかけとなったコメントを見直さなければなりません。すべての証拠を提示し終わった今、「jQuery は単純なページで使うにはいいのですが、複雑なページではパフォーマンスが極端に悪くなります。パフォーマンスの問題が修正されるまでは、複雑なページには通常の JavaScript を使用するべきです」という主張を再検証する必要があります。これまでの検討内容に基づいて考えると、jQueryの「パフォーマンスの問題」は「通常の JavaScript」自体にも存在すると思います。実のところ、真のパフォーマンスの問題は jQuery にも JavaScript にもありません。それは、ブラウザー自体にあります。ページが複雑で、jQuery コードの設計が不完全で、しかもブラウザーに IE6 を使用しているとしたら、極端にパフォーマンスが悪くなることは私も同意します。しかしこの記事では、優れた jQuery にわずかなパフォーマンスのヒントを適用すれば、パフォーマンスに目立った問題のない優れたブラウザー上で、非常に複雑なページでも実行できることを示したつもりです。

参考文献

学ぶために

製品や技術を入手するために

  • この記事を書いている時点で最新の安定版、1.3.2 jQuery 最小版をダウンロードして、独自のコードに組み込んでください。

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Web development
ArticleID=412297
ArticleTitle=中級レベルの jQuery
publish-date=06162009