メインコンテンツへ移動

非ブロック型スクリプト読み込みの最適解

無料2015-11-27#JS#Solution#script的defer#defer属性#JavaScript无阻塞加载脚本#js并行加载脚本

外部スクリプトを非ブロックで読み込み、ページのレンダリング速度を向上させる

最適解

独立した「唯一の」最適解というものは存在しません。真の最適解は要件によって決まります。最適なスクリプト読み込み技術を選択するための決定木は以下の通りです:

[caption id="attachment_860" align="alignnone" width="300"]最適なスクリプト読み込み技術を選択するための決定木 最適なスクリプト読み込み技術を選択するための決定木[/caption]

決定木には6つの考えられる結果があります:

  • 異なるドメイン、順序不問

    XHR Eval、XHR注入、Script in Iframe技術は、メインページのドメインとスクリプトのドメインが異なる場合には使用できません。Script Defer技術はスクリプトを強制的に順序立てて読み込ませるため、使用すべきではありません。逆に、スクリプトが到着次第すぐに実行されれば、ページの読み込みは速くなります。この場合、Script DOM Element技術が最適ですが、Firefoxでは意図に反して順序が維持されることがあります。なお、これら2つの技術はいずれもビジーインジケーター(ステータスバー、プログレスバー、アイコン、カーソル)をトリガーしますが、この問題を回避する方法はありません。

    JavaScriptの広告やコントロールを含むウェブページがこのケースに該当します。広告やコントロールのスクリプトはメインページとは異なるドメインにあることが多いですが、それらの間に依存関係はないため、読み込み順序は重要ではありません。

  • 異なるドメイン、順序維持

    前述と同様に、メインページのドメインとスクリプトのドメインが異なるため、XHR Eval、XHR注入、Script in Iframe技術は機能しません。読み込み順序を確保するために、Internet ExplorerではScript Defer技術を、FirefoxではScript DOM Element技術を使用する必要があります。これらの技術はビジーインジケーターをトリガーすることに注意してください。

    このケースに該当するのは、異なるサーバーから依存関係のある複数のJavaScriptファイルをダウンロードするページです。

  • 同一ドメイン、順序不問、ビジーインジケーターなし

    XHR EvalとXHR注入は、ビジーインジケーターをトリガーしない唯一の2つの技術です。これら2つのXHR技術のうち、スクリプトの再構成が不要なXHR注入の方をお勧めします。

    バックグラウンドでJavaScriptファイルをダウンロードしたいウェブページに適用できます。

  • 同一ドメイン、順序不問、ビジーインジケーターあり

    XHR Eval、XHR注入、Script in Iframeは、Internet ExplorerとFirefoxの両方で読み込み順序を維持しない唯一の技術です。Script in Iframe技術はビジーインジケーターをトリガーし、ページサイズがわずかに増加するだけなので、最良の選択肢のように見えます。しかし、私はXHR注入を好みます。なぜなら、その技術ではスクリプトを再構成せずに使用でき、また決定木の他のブランチでも選択肢となるからです。ビジーインジケーターを有効にするには追加のJavaScriptが必要です。XHRの送信時にステータスバーとカーソルをアクティブにし、XHRの完了時に復元します。これをManaged XHR Injectionと呼びます。

  • 同一ドメイン、順序維持、ビジーインジケーターなし

    XHR EvalとXHR注入は、ビジーインジケーターをトリガーしない2つの技術です。これら2つのXHR技術のうち、スクリプトの再構成が不要なXHR注入を好みます。読み込み順序を維持するには、別のタイプのManaged XHR Injectionが必要です。この場合、必要に応じてXHRのレスポンスをキューに入れ、順番に実行します。遅延読み込みされるスクリプトは、その前のすべてのスクリプトがダウンロードおよび実行された後にのみ実行を開始する必要があります。

    バックグラウンドで内部依存関係のある複数のスクリプトをダウンロードするページがこのケースに該当します。

  • 同一ドメイン、順序維持、ビジーインジケーターあり

    Internet ExplorerでのScript Defer技術とFirefoxでのScript DOM Element技術が推奨される解決策です。Managed XHR InjectionやManaged XHR Eval技術も実行可能です。ただし、これらはメインページに追加のコードを増やし、実装がより複雑になります。

P.S. 以上の内容は参考資料からの抜粋です。

XHR Eval

xhrでスクリプトstrを取得し、eval(str)で実行します。

利点:非ブロック(他のリソースのダウンロードを妨げない)。

欠点:同一生成元ポリシー(Same Origin Policy)の制限により、外部スクリプトは実行中のスクリプトと同じドメイン(プロトコル、ポート番号、ドメイン名)である必要があります。また、外部スクリプトの再構成が必要になる場合があります。

XHR注入

xhrでスクリプトstrを取得し、それをscript要素に挿入してからDOMツリーに追加して実行します。

利点:非ブロック。

欠点:SOP制限。

Script in Iframe

ページ内のiframeと他のリソースは「並列に読み込まれる」ため、この特徴を利用して非ブロックでスクリプトを読み込むことができます:

<!-- 在主页面中内包含iframe,jsWrapper.html应该与主页面同域 -->
<iframe src="jsWrapper.html" frameborder="0" width="0" height="0" id="myIframe"></iframe>

//---js通信
// 主页面 -> iframe
var winIframe = window.frames['myIframe'].contentWindow;
winIframe.fun();    // winFrame是iframe中的window对象
// iframe -> 主页面
var winMain = window.parent;
winMain.fun();      // winMain是主页面中的window对象

注意srcx.jsではなくx.htmlです。iframeはHTMLドキュメントが返されると想定するため、スクリプトをHTMLでラップしてインラインスクリプトにする必要があります。

利点:非ブロック。

欠点:SOP制限があり、かつ外部スクリプトの再構成が必要です。

Script DOM Element

script要素を動的に作成してsrcを設定し、DOMツリーに挿入します。

利点:非ブロック、クロスドメインを許可、外部スクリプトの再構成が不要、スクリプトの実行順序を保証できる。

欠点:IEではスク���プトの実行順序を保証できません。

Script Defer

IEはscriptタグのdefer属性をサポートしており、他のリソースの並列ダウンロードを許可します。

利点:容易(scriptタグに属性を追加するだけ)、かつスクリプトの実行順序を保証できる。

欠点:一部のブラウザ(古いバージョンのFirefoxなど)はこの属性をサポートしていない可能性があります。しかし、HTML5標準でdeferasyncの地位が確立され、onloadコールバックも追加されたため、現在互換性の問題はそれほど深刻ではありません。詳細についてはHTML5 <script>元素async,defer异步加载を参照してください。

document.write Script Tag

document.writeを使ってscriptタグをページに書き込みます。

利点:IEではdocument.writeで書き込まれた複数のスクリプトを並列に読み込めます。

欠点:IEのみ非ブロックであり、これらのスクリプトを読み込む際、他のリソース(画像、DOM)がブロックされます。

参考資料

  • 『ハイパフォーマンスWebサイト ―さらに速くするための14のルール』

コメント

コメントはまだありません

コメントを書く