いつか作ります RSSフィード

2009-03-10

[]ニコニコの検索結果応答が遅い件と、scriptタグがあった場合のブラウザの挙動 19:46 ニコニコの検索結果応答が遅い件と、scriptタグがあった場合のブラウザの挙動 - いつか作ります を含むブックマーク はてなブックマーク - ニコニコの検索結果応答が遅い件と、scriptタグがあった場合のブラウザの挙動 - いつか作ります ニコニコの検索結果応答が遅い件と、scriptタグがあった場合のブラウザの挙動 - いつか作ります のブックマークコメント

神書籍『ハイパフォーマンスwebサイト』を読めばそれで済むのだが。

タグ検索結果ページを開くとレンダリングが途中で止まるが、そこに何があるかというと、これがある。インデントは見やすく調整してある。

<!--↓ニコニ広告↓-->
<div class="mb8p4" id="nicoads">
 <p><img src="http://res.nicovideo.jp/img/tag/nicoads/frm_top.gif" alt="ニコニ広告"></p>
 <div class="nicoads_bg">
  <table width="100%" border="0" cellpadding="0" cellspacing="4">
    <tr valign="top">
    <!--↓出力範囲↓-->
      <script type='text/javascript'><!--//<![CDATA[
      (引用者により中略)
        document.write ("'><\/scr"+"ipt>");
      //]]>--></script>
    <!--↑出力範囲↑-->
    </tr>
  </table>

ニコニ広告のHTMLを書き出すスクリプトである事は通信を分捕ればすぐ分かるのだが、こいつが原因。

仕様が決まらないのでサボる

ブラウザは、上から順にHTMLをパースしレンダリングしていくが、scriptタグがあると、そこでレンダリングを中断する。

何故かというと、scriptタグによってページが書き換えられるかもしれないから(実際、このスクリプトはページを書き換えているわけだ)。

スクリプトの実行を後回しにしたら、最後の最後で「…と、以上のHTMLをこのスクリプトの生成したdivの中に入れてね!」と言われ、レンダリングのやり直しになるかもしれない。だから、ブラウザはスクリプト実行を優先する。

どうすればいいか

  • scriptタグはなるべく後ろに置く

script以前の部分はレンダリングされるので、ユーザーから見た体感時間が短くなる。ページの上の方に書き出したいならdocument.writeじゃなくてDOM操作を使えばいい。レンダリング完了後、スクリプトが実行された瞬間に再レンダリングが発生する事になるが、はるかにマシな状況になるはずだ。

たとえば、twitterの自分の最新書き込み内容が遅れてロードされるのなんかもコレ。

(事前に書き出すものの大きさが分かっているなら、あらかじめ大きさを決めたボックス内に新しい内容が描画されるようにしておくと、再レンダリングの際にユーザーから見たほかのものの位置がズレなくてよい。これをしないと、検索結果をクリックしようとした瞬間に広告ロードが完了し、検索結果がピョイっと下に逃げるような事が起きる)

  • defer属性を指定する

deferというのは「このscriptは描画内容を変更しないので実行を後回しにしていいですよ」という指定。まあ、書き換えるわけなので使うべきではない、というのは尤もな話だが、とりあえずこれを指定しておくとscriptタグを最後にしたのと同じような効果が得られる。

追記

ものすごい速度で修正されてしまったので、現在は再発しない。

しかし、この修正方法もなかなかに面白い(多分すぐ別の方法に書き直されると思うので説明はパス)

新着エントリは上に追加。コメントは「はてなユーザのみ」、公開設定はパブリック (だれでも閲覧ができます)。