JavaScriptでHTMLをダイナミックに書き換える 後編DOMの基本を学ぼう(7)(3/3 ページ)

» 2008年08月04日 00時00分 公開
[羽田野太巳@IT]
前のページへ 1|2|3       

まとめて更新を行う(DocumentFragment)

 これまで、HTMLの要素をDOMを使って自由に操る方法を学んできました。基本はすでに身についていますので、あとは応用で、いろいろなWebアプリケーションを作ることができるはずです。しかし、Webアプリケーションを作り込むうえで、パフォーマンスという問題から逃れることはできません。

 サーバー上で動作するアプリケーションの場合は、サーバーの負荷を軽減するためにさまざまな工夫をしますが、JavaScriptといえども例外ではありません。近年のWebアプリケーションにおいては、ブラウザ側で実行されるJavaScriptの役割が重要になり、複雑な処理が求められるようになってきました。JavaScriptの書き方によって、表示速度が大きく変わってしまうことがあります。この処理時間とは、ブラウザのレンダリング時間のことです。この点を考慮に入れてJavaScriptを組む必要があります。

 appendChildメソッドは、既存の要素ノードに対して実行すると、その場でブラウザはHTML画面をレンダリングし直します。1つや2つ程度の追加であればまったく問題ないのですが、もし100個の要素を追加するとなると、レンダリング時間も無視できなくなります。要素を追加することで、ブラウザ上の表示レイアウトがずれる場合は、表示時間にさらに大きく影響を与えます。

 これを解決するのが、DocumentFragmentと呼ばれるDOMインタフェースです。DocumentFragmentは、ノード要素を収容するための器とお考えください。本来であれば、HTML上に存在する要素ノードに対して、必要なノードを1つずつ追加していく手法でした。つまりブラウザは、ノードを追加するたびにレンダリングを行うのです。それに対してDocumentFragmentを使う場合は、DocumentFragmentで作った器に、追加したいすべてのノードを事前に入れておきます。最後に、DocumentFragmentの器をまるごと一気に実際のHTML上に追加するのです。こうすることで、ブラウザ側のレンダリング処理は1回で済むので、パフォーマンスの改善になります。

 まずはこれまで学んできた手法で10個の要素を追加するサンプルを試しましょう。

DocumentFragment1.html
<div id="frame" style="width:300px; color:white;"></div>
<script type="text/javascript">
/*DIVタグのノードオブジェクト*/
var frameNode = document.getElementById('frame');
/*10回の繰り返し*/
for(var i=1; i<=10; i++) {
/*DIVタグ要素を新たに生成*/
var newDivNode = document.createElement('div');
/*新たに生成したDIVタグ要素にスタイルを適用*/
newDivNode.style.width = '100%';
newDivNode.style.borderBottom = '1px solid #000000';
newDivNode.style.backgroundColor = 'rgb(0,' + (i*10+100).toString() +
',0)';
/*新たに生成したDIVタグ要素のテキストノードを追加*/
newDivNode.appendChild( document.createTextNode(i.toString()) );
/*frameNodeに、新たに生成したDIVタグ要素を追加*/
frameNode.appendChild(newDivNode);
}
</script>

 このサンプルは、HTML上に初めから用意されていたDIVタグの中に、10個のDIVタグを追加します。追加するDIVタグには、グラデーション表示となるようにスタイルを適用しています。そして、1〜10のインデックス番号をテキストノードとして追加します。新たなDIVタグ要素ノードが完成した段階で、appendChildメソッドを使ってHTML画面上に反映させます。

 では、このサンプルをDocumentFragmentを使って書き換えてみましょう。まず、DocumentFragmentインタフェースの使い方を学びます。DocumentFragmentインタフェースにはcreateDocumentFragmentメソッドが定義されています。実は、覚えるのはこのメソッドだけで大丈夫です。

var flgmntNode = document.createDocumentFragment();

 createDocumentFragmentメソッドは、documentオブジェクトに対して定義されたメソッドですので、document.createDocumentFragment()という具合に使います。引数は必要ありませんので、なにも指定しないでください。document.createDocumentFragment()は呼び出されると、DocumentFragment型のオブジェクトを返します。とはいっても、空の要素ノードと思っていただいてかまいません。ここで新たに作ったDocumentFragmentを、要素ノードオブジェクトと同じように扱います。

 では、実際の使い方を見てみましょう。

DocumentFragment2.html
<div id="frame" style="width:300px; color:white;"></div>
<script type="text/javascript">
  /*DIVタグのノードオブジェクト*/
  var frameNode = document.getElementById('frame');
  /*DocumentFragmentを新たに生成*/
  var flgmntNode = document.createDocumentFragment();
  /*10回の繰り返し*/
  for(var i=1; i<=10; i++) {
   /*DIVタグ要素を新たに生成*/ 
   var newDivNode = document.createElement('div');
   /*新たに生成したDIVタグ要素にスタイルを適用*/
   newDivNode.style.width = '100%';
   newDivNode.style.borderBottom = '1px solid #000000';
   newDivNode.style.backgroundColor = 'rgb(0,' + (i*10+100).toString() +
   ',0)';
   /*新たに生成したDIVタグ要素のテキストノードを追加*/
   newDivNode.appendChild( document.createTextNode(i.toString()) );
   /*frameNodeに、新たに生成したDIVタグ要素を追加*/
   flgmntNode.appendChild(newDivNode);
  }
  /*DocumentFragmentをframeNodeに追加*/
  frameNode.appendChild(flgmntNode);
</script>

 まず、10回の繰り返し処理の前に、器となるDocumentFragmentを作っておきます。

 var flgmntNode = document.createDocumentFragment();

 次に、for文による10回の繰り返し処理で、新たに追加するDIVタグ要素ノードを作るのですが、最後にappendChildメソッドで要素を追加する先が異なります。先ほどの例ではframeNodeに対して追加しましたが、ここではflgmntNodeに追加します。

 flgmntNode.appendChild(newDivNode);

 この段階では、flgmntNodeという器の中に要素を追加しただけですので、画面上には反映されません。まだ仮想的に作られているだけで、宙に浮いた状態です。for文の処理が完了した時点で新たに追加したいDIVタグがすべて完成しているのですが、あくまでもflgmntNodeに組み込まれただけにすぎません。

 for文の処理が終わってから最後に、appendChildメソッドを使ってframeNodeに対してflgmntNodeを組み込みます。この時点で、初めてブラウザ上に反映されるのです。

 このサンプルは非常に簡単なHTMLに対して適用していますので、パフォーマンスの違いはほとんどわかりません。ただ、実際のHTMLでは、表組みなどが入った複雑なレイアウト構造となっているはずです。そのようなHTMLにおいては効果が大きく表れる場合がありますので、テクニックの1つとしてぜひ覚えておいてください。

 『標準DOMスクリプティング』の2章を転載した連載、「DOMの基本を学ぼう」は今回で終了です。7回にわたりご愛読ありがとうございました。

標準DOMスクリプティング

羽田野太巳

ソフトバンククリエイティブ 2007年1月

2730円(税込み)

978-4-7973-3638-2

【注文ページへ】


前のページへ 1|2|3       

Copyright © ITmedia, Inc. All Rights Reserved.

スポンサーからのお知らせPR

注目のテーマ

AI for エンジニアリング
「サプライチェーン攻撃」対策
1P情シスのための脆弱性管理/対策の現実解
OSSのサプライチェーン管理、取るべきアクションとは
Microsoft & Windows最前線2024
システム開発ノウハウ 【発注ナビ】PR
あなたにおすすめの記事PR

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。