• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:標準準拠モードと後方互換モードのJavaScriptのパフォーマンスに)

標準準拠モードと後方互換モードのJavaScriptのパフォーマンスについて

このQ&Aのポイント
  • HTMLファイルのDOCTYPE宣言によって標準準拠/後方互換モードを切り替えられますが、下記JavaScriptをそれぞれで走らせた場合、明らかに標準準拠モードが遅いです。
  • 後方互換モード程度にまで速度を改善することはできないのでしょうか。
  • 後方互換モードのJavaScriptは、古いバージョンのブラウザで正しく動作するために、新しい機能や仕様をサポートしていないことがあります。そのため、標準準拠モードのJavaScriptと比較して処理速度が遅くなることがあります。

質問者が選んだベストアンサー

  • ベストアンサー
  • think49
  • ベストアンサー率59% (285/482)
回答No.6

#2,3,4,5 です。 改めて考えたら、JavaScriptによるDOM操作時間で比較していたので、window.onload で比較検証してみました。 (全角空白は半角空白に置換してください) --------- <!DOCTYPE html> <html lang="ja"> <head>  <meta charset="utf-8" />  <title>test2</title> <script type="text/javascript"><!-- (function () {  var start = new Date();  function init (event) {   var doc = this.document,     time = (new Date().getTime() - start.getTime()) / 1000;   doc.getElementById('Time').appendChild(doc.createTextNode(time + ' seconds'));  }  attachEvent ('onload', function (event) { init.call(this, event); }); }) (); //--></script> </head> <body> <p id="Time"></p> <table id="Test">  <tbody>   <tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td><td>11</td><td>12</td><td>13</td><td>14</td><td>15</td><td>16</td><td>17</td><td>18</td><td>19</td><td>20</td><td>21</td><td>22</td><td>23</td><td>24</td><td>25</td><td>26</td><td>27</td><td>28</td><td>29</td><td>30</td></tr>  </tbody> </table> <script type="text/javascript"><!-- (function () {  var doc  = document,    df  = doc.createDocumentFragment (),    tbody = doc.getElementById('Test').tBodies.item(0),    tr  = tbody.rows.item(0),    i;  for (i = 0; i < 1000; i++) { df.appendChild(tr.cloneNode(true)); }  tbody.appendChild (df); }) (); //--></script> </body> </html> --------- // --- DOCTYPE有り 4.703 4.484 4.625 4.407 4.375 平均: 4.5188 (sec) // --- DOCTYPEなし 2.109 2.703 2.938 2.5 2.453 平均: 2.5406 (sec) 「平均 1.9782秒 後方互換モードが高速」という結果になりました。 <style>table { table-layout: fixed; } td { width: 2em; } </style> を入れても、あまり変わらないようです。 > 後方互換モード程度にまで速度を改善することはできないのでしょうか。 table要素は最後まで読み込まれなければ描画できず、描画に関わる計算量も多いので、あまりに長い記述だと描画速度は著しく低下します。 特に、IEは描画速度が遅いですから尚更に…。(GoogleChrome5 なら標準準拠モードでも 1秒 で描画完了します) ・tableを出来るだけ使わない ・1ページにあまり多くを詰め込みすぎない が最善だと思いますが、どうしても1ページに詰め込みたいのなら遅延読み込みを利用して負荷を下げる工夫があるといいと思います。 例えば、JSONにデータを格納して、Autopagerize的なスクリプトを組むとか、検索フォームから検索できるようにするとか。

mokpok
質問者

お礼

回答ありがとうございます。 やはりこれ以上の描画高速化を狙うなら、描画要素数自体を減らすしか無さそうですね。 実際のページも、後方互換モードなら問題の無い速度なのですが・・・ 何度もご丁寧にありがとうございました。

その他の回答 (5)

  • think49
  • ベストアンサー率59% (285/482)
回答No.5

#2,3,4 です。 > 検証に使用したコードですが、tableの方は以下のものです。 さすがに1000行にわたるHTMLをそのまま記載するわけにはいかなかったので、JavaScriptで生成してみました。 (全角空白は半角空白に置換してください) -------------- <!DOCTYPE html> <html lang="ja"> <head>  <meta charset="utf-8" />  <title>test2</title> </head> <body> <p id="Time"></p> <table id="Test">  <tbody>   <tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td><td>11</td><td>12</td><td>13</td><td>14</td><td>15</td><td>16</td><td>17</td><td>18</td><td>19</td><td>20</td><td>21</td><td>22</td><td>23</td><td>24</td><td>25</td><td>26</td><td>27</td><td>28</td><td>29</td><td>30</td></tr>  </tbody> </table> <script type="text/javascript"><!-- (function () {  var doc  = document,    df  = doc.createDocumentFragment (),    tbody = doc.getElementById('Test').tBodies.item(0),    tr  = tbody.rows.item(0),    start = new Date(),    time, i;  for (i = 0; i < 1000; i++) { df.appendChild(tr.cloneNode(true)); }  tbody.appendChild (df);  time = (new Date().getTime() - start.getTime()) / 1000;  doc.getElementById('Time').appendChild(doc.createTextNode(time + ' seconds')); }) (); //--></script> </body> </html> -------------- DOCTYPE宣言の有無でスイッチを入れ替えて検証しました。 // --- DOCTYPE有り 0.625 0.656 0.657 0.656 0.64 平均: 0.6468 (sec) // --- DOCTYPEなし 0.969 1.313 1.235 0.906 1.141 平均: 1.1128 (sec) 「平均 0.466秒 標準準拠モードが高速」という結果になりました。 > tableの代わりに<span>a</span>を数万並べただけのものです。 1000行ならまだわかりますが、数万はさすがに大すぎじゃないでしょうか。 > できれば標準準拠にしたいのですが・・・ 何となく、DOCTYPEスイッチではない部分に原因があるような気がします。 #4 でも触れましたが、書き方一つで描画速度はかなり変わります。 「HTML-lint」「The W3C Markup Validation Service」でHTMLが正しい記述かどうか確認してみたり、HTMLはシンプルにしてCSSで可能な限りレイアウト、デザインを指定する、だけでも大分変わるのではないかと想像します。 Another HTML-lint gateway http://openlab.ring.gr.jp/k16/htmllint/htmllint.html The W3C Markup Validation Service http://validator.w3.org/

  • think49
  • ベストアンサー率59% (285/482)
回答No.4

#2,3 です。 > 例えば膨大な要素数のHTMLファイル(大きなtableだったり、spanタグを数万個並べたり)でも、 実際のHTML,CSSを見てみないと確かなことはいえませんが、そこまで極端なHTMLで検証するっていうことは、元のHTMLも同じような状況なのでしょうか? 書き方に問題があるのかもしれませんね。 Webサイトの高速化 フロントエンドのパフォーマンスの重要性 (Yahoo! developer netoworkより翻訳) | 株式会社インターオフィス http://www.inter-office.co.jp/contents/177/ Web ページを高速化する http://www.ibm.com/developerworks/jp/web/library/wa-speedweb/ 表示のスピードアップ http://kasayan86.hp.infoseek.co.jp/hp/speedup.htm 17.5.2 表幅アルゴリズム ('table-layout'特性) http://www.y-adagio.com/public/standards/tr_css2/tables.html#width-layout table要素のレンダリングの速度 - クライアント・サイド・スクリプティング with Web Standards http://d.hatena.ne.jp/vwxyz/20081030/1225361077 > この現象が私の環境限定なのか、一般にそうなのかが分かりません。 再現条件を特定するか、全コードを記載(あるいは、URLを開示)しないことには、私も検証できませんので…。

mokpok
質問者

お礼

回答ありがとうございます。 検証に使用したコードですが、tableの方は以下のものです。 <html> <body> <table> <tr><td>0</td><td>1</td> ... <td>30</td></tr> <!-- ↑これを1000行とか --> </table> </body> </html> 1行目にはDOCTYPE宣言を入れます。 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"> ここで、前者の方をいれた方が表示が速い、という結果でした。 <span>タグの検証も、tableの代わりに<span>a</span>を数万並べただけのものです。 こちらの方が差は顕著でした。 こうなると両レンダリングモードのパフォーマンスに差がある、としか思えないのですが・・・ IE8は3つのモードがあるようですが、正確にはIE8モードに限って遅い、という結果です。 今回の質問は、大きな表を操作するDHTMLページの作成において、 DOCTYPEスイッチを後方互換にした方が遥かにパフォーマンスが向上した、というのが発端です。 DOCTYPE宣言の変更についてググッてみても、「○○というコードが動かない」という情報は大量に見つかるのですが、 「パフォーマンスが落ちた」という情報がちっとも見つからず・・・ できれば標準準拠にしたいのですが・・・

  • think49
  • ベストアンサー率59% (285/482)
回答No.3

#2 です。 投稿後、#1さんの回答を見ました。確かにそうですね。 テキストノードを1万回生成するより、1万回の繰り返し処理でテキスト型の変数を生成して、最後にノードを挿入する方が速いです。 <script type="text/javascript"><!-- (function () {  var doc = document,    str = '',    i;  for (i = 0; i < 10000; i++) { str += i + ', '; }  doc.getElementById('test').appendChild(doc.createTextNode(str)); }) (); //--></script> ただ、innerHTMLは低速です…。 -------- すでに多くの人が、element.innerHTML を使用すると遅くて仕方がないということを知っています。どれぐらい遅いかを調べるために、私は innerText の代わりに innerHTML を使用して "Text" をセルに挿入するテスト ページを作成しました。パフォーマンスは文字どおり、がた落ちでした。合計時間は 3375 ミリ秒になり、前回のテストより 80 パーセントも遅くなりました。このたった 1 つの変更で、最初のバージョンより -5 パーセントに逆戻りしてしまいました。明らかに、innerHTML はかなり低速です。 http://msdn.microsoft.com/ja-jp/library/bb263997%28VS.85%29.aspx -------- ## …とここまで書いたところで、#2の補足を読みました。 > このコードはただのベンチマークですので、この処理自体の速度改善は望みません。 原因を探りたいのですよね? 検証なくして、原因を知ることは難しいと思うのですが…。 > レンダリングモードの違いによるパフォーマンスの変化というのは、「あったらおかしい」現象なのでしょうか。 にわかには信じがたいですが、絶対にないとも言い切れません。 ですので、検証が必要だと思い、いろいろなコードを書いています。 率直にいって、質問者さんの環境を再現できるほどの情報が揃っていないので、いろいろと環境を推測しないと私の環境で再現できないと思います。 HTMLなどを省略せず、現象を再現できる全ての記述を開示されれば、検証できると思うのですが…。

mokpok
質問者

お礼

回答ありがとうございます。 私の方でも実験をしてみたのですが、 例えば膨大な要素数のHTMLファイル(大きなtableだったり、spanタグを数万個並べたり)でも、 レンダリングモードの違いで明らかな速度差が出ました。 後方互換モードの方が速いです。 こうなると質問の表題自体が間違ってますね・・・ JavaScriptのパフォーマンスの問題ではないようです。 ただ現在、他の環境を用意できない状態ですので、 この現象が私の環境限定なのか、一般にそうなのかが分かりません。

mokpok
質問者

補足

申し訳ありません、下記のお礼の言葉が不足しているので、一応補足します。 下記にある実験は、JavaScriptを使わない純粋なHTMLファイルでの実験です。 明らかな速度差とは、画面の表示が完了するまでの時間です。

  • think49
  • ベストアンサー率59% (285/482)
回答No.2

DOCTYPE宣言の有無でIE8にて検証しましたが、有意な差は確認できませんでした。 ----------- <!DOCTYPE html> <html lang="ja"> <head> <title>test</title> </head> <body> <div id="test"></div> <script type="text/javascript"><!-- for (var i = 0; i < 10000; i++) { var t = document.createTextNode(i + ", "); var o = document.createElement("div").appendChild(t); document.getElementById("test").appendChild(o); } //--></script> </body> </html> ----------- > 下記JavaScriptをそれぞれで走らせた場合、明らかに標準準拠モードが遅いです。 標準準拠モード 云々はともかく、遅い理由は appendChild() を10000回起こしていることにあるんじゃないでしょうか。 ----------- var doc = document,   test = doc.getElementById('test'),   df  = doc.createDocumentFragment(),   i; for (i = 0; i < 10000; i++) { df.appendChild (doc.createTextNode(i + ', ')); } test.appendChild(df); ----------- Script雑感: Javascript:appendChild のタイミングで処理速度が変わる http://zombiebook.seesaa.net/article/33247314.html DocumentFragmentの考察 - Personnel http://members.jcom.home.ne.jp/jintrick/Personal/documentFragment.html > var o = document.createElement("div").appendChild(t); 返り値がテキストノードなので、createElementが無駄な処理になってしまっていますね。 Node.appendChild - MDC https://developer.mozilla.org/ja/DOM/element.appendChild

mokpok
質問者

お礼

回答ありがとうございます。 言葉が足りず申し訳ありません。 このコードはただのベンチマークですので、この処理自体の速度改善は望みません。 レンダリングモードの違いによるパフォーマンスの変化というのは、 「あったらおかしい」現象なのでしょうか。 私の環境では顕著な差が出ているのですが・・・

  • yyr446
  • ベストアンサー率65% (870/1330)
回答No.1

ご提示のコードは単なるベンチマーク用でしょうか、 そうでなく、本当にテキストノードの多量追加がしたいなら、DOMじゃなく 文字列としてまず作ってしまって、最後にinnerHTMLで ごそっと書き換えてしまった方が早いと思います。 var t =""; for (var i = 0; i < 10000; i++) {t+="<div>"+i+", "+</div>";} document.getElementById("test").innerHTML=t;

関連するQ&A

専門家に質問してみよう