概要
Google Chromeを使って、document.write()で外部のJavaScriptを読み込んでいるページを開くと、いつの間にか開発者ツールのコンソールに以下のようなメッセージが出る状態になっていた
"A Parser-blocking, cross-origin script, スクリプトのURL, is invoked via document.write. This may be blocked by the browser if the device has poor network connectivity."
開発者ツールを開きながら適当なサイトを見ていると、広告っぽいURLが引っかかってることが多い
この警告が何を意味しているかというと、遅い携帯電話の通信だとページの読み込みが遅くなるので、以下のようにdocument.write()でクロスオリジンのスクリプトを読み込んでもChromeで実行されなくなる変更が入るらしい(今はまだ警告だけで実際にブロックされるのは2016年10月から)
document.write('<script src="スクリプトのURL"></script>');
詳細は以下のドキュメントに書かれている。重要そうなところだけ以下にメモした
実行されなくなる条件
以下の条件をすべて満たした場合スクリプトが実行されなくなる
- 通信が遅い(今は携帯電話の2Gが対象。将来的には遅い3Gや遅いWifiにも拡張されるかもしれないとのこと)
- トップレベルでのドキュメントでのdocument.write() (iframeの中ならば問題ない)
- scriptにasyncやdefer属性が指定されていない
- スクリプトがキャッシュされていない場合 (既にキャッシュされていれば問題ない)
- リロードではない
警告メッセージ
Chromeのバージョン53(2016年9月)からこの警告が出るようになった
通信の遅さ以外の条件を満たしたときに開発者ツールに出るようになっているらしい
(リロードでも警告が出ているような気がするけど……)
スクリプトのブロック
stable版でも10月半ばぐらい(Chrome 54)になったら実際にスクリプトを動かなくさせる予定
We will intervene to block injected scripts for 2G users tentatively starting in Chrome 54, which is estimated to be in a stable release for all users in mid-October 2016.
https://developers.google.com/web/updates/2016/08/removing-document-write
対策
回避策はdocument.write()を使うのをやめてdocument.appendChild()やparentNode.insertBefore()などを使うぐらい
あとはscriptにasync属性やdefer属性を付けるとか、iframeの中などでは問題ないらしいので、そっちに書いてみるとか……
Interventionヘッダー
実際にスクリプトがブロックされた場合、スクリプトへのGETリクエストのときに以下のようなヘッダーが送られるようになるらしい(今はまだ送ってなさそう?)
Intervention: https://shorturl/relevant/spec;
document.write()でスクリプトを読み込んでいて場合によってはブロックされるときは以下のヘッダー
Intervention: https://shorturl/relevant/spec; level="warning"
まとめ
10月半ばぐらいからdocument.write()で外部のスクリプトを読み込んでいるとChromeが実行してくれなくなるかもしれないので注意。
今のところ2G対象なのであまり影響はなさそうだけど、将来的には遅い3Gや遅いWifiも対象になるかもしれないので、開発者ツールで警告が出ていた場合には対策をしたほうがよいかも
追記
いつのまにか開発者ツールに表示されるメッセージの文言が変わっていた
sucrose.hatenablog.com