12時45分52秒 [Web関連]
読み込みが凄まじく遅い外部スクリプトを、何もかも読み終えた最後に読み込ませる方法
アクセス解析スクリプトやブログパーツ追加スクリプトなど、外部から提供されるスクリプトをウェブページ内で読み込みたい場合があります。
その外部サーバの反応速度が速ければ何も問題はないのですが、混雑していたり非力だったりして数十秒くらい経たないとデータが送られてこないような反応速度の遅いサービスもあります。
そのような読み込み速度の遅いスクリプトを普通にscript要素を使って読み込ませていると、ウェブページの読み込み完了までに時間がかかってしまいます。
HTML末尾に書いたりasync属性を付加しても、ブラウザの「読み込み中」アニメーションは続いてしまう
その手のスクリプトは、たいてい </body> タグの直前あたり(=HTMLの最後の方)に記述していたり、script要素にasync属性を付加して非同期で読み込むよう指定しているでしょうから(下記ソース参照)、実際にウェブページを閲覧しているユーザには何ら影響はないかも知れません。
<script type="text/javascript" src="超遅い外部スクリプトのURL" async></script>
しかし、たとえそれらの方法で読み込むように記述していても、「ウェブページ全体の読み込みがなかなか完了しない」という状況では、ブラウザが「読み込み中」のアニメーション(※)をずっと表示し続けるために「なんか重たいページだな」と思われてしまう可能性もあります。
もしかしたら、検索サイトから「遅いページ」だと認識されてしまって何らかの検索上の不利益もあるかも知れません。
※最近のブラウザであれば、ウェブページ名が表示されるタブの左端で、くるくる回転する円形のアイコンが見えますよね。読み込みが完了した時点で、そのページのファビコン(favion)に変わるアイコンです。あのくるくる回転するアニメーションが見えているうちは「読み込みが完了していない」と認識しますよね? なので、たとえ見える範囲の描画が完了していたとしても「なんか重たいページだな」と思われる可能性がありそうです。
画像などのオブジェクトも含めた全ての読み込みが完了した後で、遅い外部スクリプトの読み込みを開始する
というわけで、そのような凄まじく遅いスクリプトは、ウェブ上の画像なども含めたあらゆるオブジェクトを全て読み込み終えた後で読み込み始めるように記述しておくと良さげな気がします。
例えば、以下のように記述します。(jQueryを使う場合)
<script> $(window).load(function () { var tooheavy = document.createElement("script"); tooheavy.setAttribute("src", 'http://超遅い外部スクリプトのURL/'); tooheavy.setAttribute("type", "text/javascript"); tooheavy.setAttribute("async", "async"); document.getElementsByTagName("head")[0].appendChild(tooheavy); }); </script>
上記のように、jQueryで $(window).load(function () {; ~~~ }); のように記述すると、この内側に書いたスクリプトはウェブ上の画像などのオブジェクトも含めた全てを読み込み終えてから実行されます。
この方法で読み込ませると、このスクリプトの読み込みが始まるよりも前にブラウザは「読み込み中」のアニメーションを終わらせるので(たぶん)、このスクリプト自体の読み込みが遅くても「重たいページ」には見られないと思います。
もちろん、このスクリプトが生成する何らかの要素が表示されるのは遅いわけですけども。(^_^;) そこはどうしようもないので、せめてブラウザの「読み込み中」アニメーションが終わったあとから読み込ませることで、「なかなか読み込みが完了しないページだな」とは思われないようにすると、気分的に良い気がします。(^_^;)
(補足) jQueryを使わずにJavaScriptだけで書く場合
なお、jQueryを使わずに以下のように記述しても同じです。
<script> window.onload = function(){ var tooheavy = document.createElement("script"); tooheavy.setAttribute("src", 'http://超遅い外部スクリプトのURL/'); tooheavy.setAttribute("type", "text/javascript"); tooheavy.setAttribute("async", "async"); document.getElementsByTagName("head")[0].appendChild(tooheavy); } </script>
ただ、上記の場合はwindowのloadイベントで実行される内容を上書きすることになるので、同じページで読み込まれている他のスクリプトに同様の記述(window.onload = ~)があった場合には、最後に記述された1つしか実行されない(参考)ので注意が必要です。(jQueryの方なら全部実行してくれます。)