Google+ プラットフォームで配布されている、「+1 ボタン」 や、「バッジ」 などを Web サイトに設置する際に使用される JavaScript のソースコードがありますが、これらソースコードに、script 要素の async / defer 属性が付与されるようになりました。
Googleの Ilya Grigorik 氏が自身の Google+ に投稿しているほか、実際のソースコードにもすでに反映されています。
実際のソースコードは下記のようになっています。
<!-- head 内か、body 終了タグの直前に次のタグを貼り付けてください。 --> <script src="https://apis.google.com/js/platform.js" async defer> {lang: 'ja'} </script> <!-- +1 ボタン を表示したい位置に次のタグを貼り付けてください。 --> <div class="g-plusone" data-annotation="inline" data-width="300"></div>
2行目の script 要素に async / defer 属性が付与されているのがわかります。XHTML 文書で使用する場合は、
<script src="https://apis.google.com/js/platform.js" async="" defer=""> ...中略... </script>
もしくは、
<script src="https://apis.google.com/js/platform.js" async="async" defer="defer"> ...中略... </script>
のように修正する必要がありますので、注意しましょう。
async / defer 属性とは
両属性とも、script 要素に付与することで、スクリプトの実行タイミングを指定することができます。両属性ともに、src 属性を持った script 要素にのみ指定可能です。つまりインラインで記述されたスクリプトには指定できません。また、これら属性を持った script 要素においては、document.write()
の使用はできません。
厳密にはインラインスクリプトでの使用不可は HTML5 仕様でのみ明記されています。また、逆に document.write()
の使用不可は HTML 4.01 仕様などでは明記されていますが、HTML5 仕様では 「意味がないからやめとけ」 的な記述になっています。
async / defer 属性を持たない script 要素により読み込まれたスクリプトは、ブラウザが Web ページをパースし終わっているかどうかに関わらず、読み込まれた時点で実行されます。これはインラインスクリプトも同様ですが、この結果、場合によってはページの読み込みをスクリプトの実行がブロックしてしまい、ページ全体の表示速度が低下することがあります。
そのためによく、「script 要素は body 要素の終了タグ直前にまとめて書け」 なんて言われるわけですが、async / defer 属性に対応したブラウザであれば、スクリプトの実行をパース完了まで送らせたり、非同期で行うことができます。
ちなみに、両方の属性が併記された場合 (今回の Google のソースコードがそうですが)、async 属性に対応する環境では async 属性が有効になり、async 属性に対応しない環境では defer 属性がフォールバックとなります。
async 属性
async 属性を付与された script 要素は、文書読み込み時、「実行可能になった時点」 でスクリプトを実行しますが、その際にページの読み込みをブロックせず、非同期で実行されます。この属性は HTML5 で新たに追加されました。
ただし、async 属性を付与された script 要素に対応したブラウザは、ページの読み込みを行いながら、ダウンロード済みのスクリプトを 「可能な限り早く」 実行しようとするため、スクリプトの実行順序は保証されません。なので、例えば jQuery ライブラリとそのプラグインのように、スクリプト同士に依存関係がある場合は注意が必要です。
defer 属性
defer 属性を付与された script 要素は、文書読み込み時、「文書の読み込みが完了した時点 (DOMContentLoaded
イベントの前)」 でスクリプトを実行します。
defer 属性をもつスクリプトを読み込んだ順に実行していくので、async 属性とは異なり、実行順序は保証されます。つまり、依存関係のあるスクリプトに使っても大丈夫。
defer 属性は元々 IE の独自拡張だったこともあってかなり以前から存在し、HTML 4.01 や XHTML 1.0 仕様においても定義されています。
async / defer 属性へのブラウザ対応状況
async / defer 属性は、現状ほぼすべてのモダンブラウザで実装されています。
- async attribute for external scripts : Can I use...
- defer attribute for external scripts : Can I use...
前述の通り、defer 属性は IE の独自拡張だったこともあって、IE ではかなり前から実装されているのですが、IE9 以前で defer 属性の動作に問題があるという報告もあるので使わない方が無難。
ということで新しいコードに差し替えると多少は Web ページの表示速度が改善されるかもしれませんよ。