初心者向けのjQuery入門講座|デザイナー向けのJavaScriptライブラリ

このエントリーをはてなブックマークに追加
索引
1章:jQuery入門
2章:jQuery基礎
3章:jQuery発展
番外編:研究

jQueryの高速化

セレクタはclassよりもid

jQueryではセレクタにマッチする要素を選択するのに負荷が掛かります(要素数の多いページほど顕著になります)。このような負荷がたまると処理に時間が掛かりアニメがカクつく原因などになります。ですから、なるべく負荷の掛からないように配慮しましょう。

セレクタのマッチングにかかる負荷を計測するため、サンプル(04/01_01.html)を用意しました。jQueryは以下の様になっており、startButtonのdivをクリックすると開始時間を記憶し(以下のソース2行目)、classがtestAreaのdivにappend(val)メソッドを利用して文字を追加する処理をfor文でで1000回繰り返していきます(3〜5行目)。1000回の繰り返しが完了した後で終了時間を記憶し(6行目)、開始時間と終了時間から処理に掛かった時間を算出(7行目)してidがtimeAreaのdivに時間(ミリ秒)を表示(8行目)します。

$("#startButton").click(function(){
	var startTime = new Date();//---測定開始
	for (i = 0; i < 1000; i++) {
		$(".testArea").append(' ' + i);
	}
	var endTime = new Date();//---計測終了
	var msec = endTime - startTime;
	$("#timeArea").text(msec);
});

実際に青いdivをクリックすると、私の環境では48ミリ秒と表示されました。皆さんの環境では異なる値が出ていると思いますが、その値を覚えておいて下さい。

つづいてサンプル(04/01_02.html)を開いて下さい。ほとんど04/01_01.htmlと同じなのですが、body内の文字を追加するdivのtestAreaがclassからidに変更されています。これに伴い以下4行目のようにセレクタがclassからidに変更されています。

$("#startButton").click(function(){
	var startTime = new Date();//---測定開始
	for (i = 0; i < 1000; i++) {
		$("#testArea").append(' ' + i);
	}
	var endTime = new Date();//---計測終了
	var msec = endTime - startTime;
	$("#timeArea").text(msec+"ミリ秒");
});

このサンプルでも同じように計測して下さい。私の環境では24ミリ秒と表示されました。皆さんの環境でもサンプル04/01_01.htmlよりも速かったと思います。

なぜidとclassで速度に差が出るかというと、idは「ページ内に1つしか設置できない」という前提のためです。そのためjQueryのセレクタマッチングで、マッチするidを見つけたら、残りのページは調査しません。classは複数設置しても良い前提なので、必ずページ末まで調査します。これが速度の差として現れるのです。

サンプル(04/01_03.html)を開いて、body内にidがtestAreaのdivが3つ有ることを確認してください。本来は同じidを設置してはいけないのですが実験サンプルとして用意しました。このサンプルで計測してみて下さい。testAreaは3つあるのに、最初のtestAreaにしか文字が表示されていないはずです。この結果からもidの場合は1つマッチしたら残りのページを調べていないことが確認できます。ついでに同じclassを3つ設置したサンプル(04/01_04.html)も確認してください。こちらはclassなので、3つのdiv全てに文字が追加されています。

jQueryの高速化(セレクタは可能な限りidを利用する)
セレクタのマッチング処理はidの方が高速なため、ページ内に1つしかないものはclassではなくidにして高速化をするようにしましょう。

jQueryオブジェクトにして記憶しておく

同じセレクタを何度も利用する場合は、jQueryオブジェクトにして変数に入れて処理するようにします。jQueryオブジェクトはjQueryのメソッドを直接利用できるオブジェクトで、1章のメソッドと返値の後半で説明しています。

サンプル(04/01_05.html)を開いてjQueryを確認してください。ポイントは以下の1行目です。ここでセレクタにマッチしたjQueryオブジェクトを変数myTargetに代入し、5行目で利用するようにしました。

myTarget = $("#testArea");//---jQueryオブジェクトを代入
$("#startButton").click(function(){
	var startTime = new Date();
	for (i = 0; i < 1000; i++) {
		myTarget.append(' ' + i);//---jQueryオブジェクトを利用
	}
	var endTime = new Date();
	var msec = endTime - startTime;
	$("#timeArea").text(msec+"ミリ秒");
});

この方法であれば、セレクタのマッチングは1行目の1回しか行われません(これまでのサンプルは同じセレクタのマッチングを1000回も繰り返していたのです!)。結果として、これまでのサンプルの中では最速の結果となるはずです(私の環境では16ミリ秒となりました)。

このことはメソッドチェーンが高速に処理される理由にもつながります。メソッドチェーンは最初に作成したjQueryオブジェクトを、ほかのメソッドで共用して利用するため、マッチングは最初の1回しか実行されません。参考:stopメソッド(1)-メソッドチェーン

jQueryの高速化(何度も利用するセレクタはjQueryオブジェクトしておく)
セレクタのマッチングに時間が掛かるので、セレクタのマッチング回数を減らすため、繰り返し利用するセレクタはあらかじめjQueryオブジェクトにして変数に入れておく。またはメソッドチェーンを利用する。

捕捉:描画負荷を考慮する

現段階ではjQueryでFlashコンテンツのようなハデな演出をすることは少ないと思います。しかしjQueryでも、段々とFlashのようなハデな演出が登場してくるのではないでしょうか?
そうなった時を考え、描画負荷も簡単に説明しておこうと思います。

描画負荷とはディスプレイに何か表示するときにかかる負荷のことです。この描画負荷はPCの中でも大きく、これを効率よく処理するために大抵のPCにはCPUの他にグラフィックボード/GPUを載せています。負荷に内応できないと、アニメーションがカクついたりコマ落ちする事になります。ですから余分な負荷をかけずに、可能な限り描画負荷を軽くするように心がける必要があります。

jQueryでのポイントは書き換え面積と半透明の描画になるとおもいます。大きな画像を移動させる場合はグラフィックメモリを大量に書き換える必要があるため負荷が大きくなります。また、半透明の画像は下の画像と計算して最終的な色を表示するため、通常よりも負荷がかかります。また今はほとんど利用されていませんが、SVGのようなベクターデータはレンダリングに負荷がかかることになるでしょう。

ですから、大きなグラフィックを動かしたり、小さくてもたくさんのグラフィックを動かすのは避けるようにします。また、不用意に半透明のオブジェクトを利用するのも避けましょう。

次回は画像のプリロードについて説明したいと思います。