2016.02.22 下記コードでは動作しない可能性もあることが判明。良い方法が分からないので、追って更新します。
Google PageSpeed Insightsでwebサイトをチェックするとjqueryなどのjsを</body>
タグ直前で読み込んでも次のようなチェックが入ることがあります。
スクロールせずに見えるコンテンツのレンダリングをブロックしている JavaScript/CSS を排除する
普通に非同期に読み込む例
次のようにasync
を使用し非同期に読み込めば、上記チェックにひっかかることはありません。
<script src="jquery.min.js" async></script>
しかし、jqueryに依存するその他のコードが実行できずエラーになったりするので、非同期かつ順序を考慮した読み込みを可能にさせる生javascriptを書くことにしました。
生javascriptでhtmlへ直接書き込みます。
第一引数にurl、第二引数にコールバックを渡します。
function loadJs (url, cb) {
var req = new XMLHttpRequest();
req.open('GET', url);
req.send();
req.onreadystatechange = function() {
if (req.readyState === 4 && req.status === 200) {
var script = document.createElement('script');
script.src = url;
document.getElementsByTagName('head')[0].appendChild(script);
if (cb) cb();
}
};
}
次のコードのように、直接htmlに書き込んで使います。
loadJs('/jquery.min.js', function({
loadJs('//cdnjs.cloudflare.com/ajax/libs/materialize/0.97.3/js/materialize.min.js', function(){
loadJs('/myscript.js');
});
});
myscript
はjquery
とmaterialize
に依存しており、materialize
はjquery
に依存していますが、上記のように書けばうまく動作します。(コールバック地獄ごめんなさい)
他の方法もありますが
今回掲載した方法はちょっとめんどくさいのですが、webpackやbrowserifyを使う環境を整えるよりは楽かなと思います。
同様のエラーがcssにも出るので、解決したい
のですが、こちらの良い解決方法はまだ検討中です。
普段gulpを使っているので、criticalというパッケージが魅力的で使ってみたのですが、良い感じなのですが、google先生のOKをもらえるまで使いこなせていません。おそらくcritical
を使いこなせば問題解決できるので、できたらメモがてら記事掲載するかもしれません。
参考サイト
XMLHttpRequest MDN
JavaScriptの読み込みにおける非同期スクリプト注入の悪影響
リファクタリングや他の方法などコメントお待ちしております
自分のメモのための記事ですが、詳しい方からのアドバイスを期待してqiitaに書き込みました。気になる点やご指摘お気軽にお願いいたします。