anti scroll

ブラウザと小説の新しい関係を模索する

HTMLの閉じタグを省略する記法について、パフォーマンスの検証と考察

nehan readerで長文エントリーを読むときに、少し前まで正常にパースできていたページが、ある日から突然レイアウト崩れを起こしてしまったりすることがあります。

で、調べてみたら、閉じタグの省略を使ったマークアップに変更されたことが原因のようでした。

この閉じタグの省略ルール、ルールが割と複雑で、パーサーが作りにくいので好きではないのですが、書き手にとっては読みやすいし、字数が減るので帯域は削減されるのはもちろん、ブラウザの表示パフォーマンスも(それなりには)速くなるはずです(理由は後述)。

検証コード

ただ、どのぐらい高速になるのかが少し気になったので検証してみました。

閉じタグを省略しないケースの検証コードはこんな感じで…

$(function(){
  var parts = [], node = "<li>hoge</li>";
  for(var i = 0; i < 10000; i++){
    parts.push(node);
  }
  var text = parts.join("\n");
  console.time("no abbr");
  document.getElementById("dst").innerHTML = text;
});

省略した場合はこういう感じのコードで検証しました。

$(function(){
  var parts = [], node = "<li>hoge12345";
  for(var i = 0; i < 10000; i++){
    parts.push(node);
  }
  var text = parts.join("\n");
  console.time("with abbr");
  document.getElementById("dst").innerHTML = text;
});

省略したバージョンでは、入力データのサイズを同じにする為、12345という文字をリストの文字列に追加しています。

そして、いずれもbody.onloadのタイミングでタイマーを止めています。

 <!-- 省略なし -->
<body onload="console.timeEnd('no abbr')">

<!-- 省略あり -->
<body onload="console.timeEnd('with abbr')">

検証結果

結果はこんな感じです。

time(msec)
閉じタグなし 224
閉じタグあり 2159

閉じタグを省略したケースが、10倍ほど高速という結果に。

速度差が出る理由の考察

閉じタグがある場合は、再帰的な入れ子を考慮して、対応する正しい閉じタグの位置を検索するロジックが入るから遅くなるのではないかと。

例えば、

<div>aaa<div>bbb</div>ccc</div>

では、aaaの位置から閉じタグを探すと、最初にbbbの右にある/divが見つかりますが、そこに至る前に入れ子divが開かれているので、スキップしてcccの位置から再び/divを探さなければなりません。

一方で閉じタグの省略と見なせるパターンでは、こういう再検索は不要で、もうそこがタグの終了位置だと確定して次のパースに進むことが出来るので速いのだと思います。

トレードオフ

グーグル検索のトップページみたいに、とんでもないアクセスがあるけど、ページの内容そのものにはドキュメント的な意味が少ない場合なら、帯域を削減するマークアップは意味がありそうです。

けれども、ページにきちんとした内容(文章)がある場合は、マークアップのルールが厳密な方がパーサーは作りやすいので、クライアントがパースしやすいマークアップで配信した方が、ドキュメントの利用価値は上がるような気がします。