Javascriptの非同期読み込み(JavaScriptにおけるブラウザ読み込み方法)の詳しい解説_JavaScriptスキル

WBOY
リリース: 2016-05-16 17:53:45
オリジナル
1079 人が閲覧しました
1. 同期ロードと非同期ロードの形式
1. 同期ロード
最も一般的に使用される同期ロードの形式は次のとおりです:

ブロッキング モードとも呼ばれる同期モードは、ブラウザによる後続の処理を妨げ、後続の解析を停止するため、後続のファイル (画像など) の読み込みも停止します。 、レンダリング、コード実行。
js を同期的に実行する必要がある理由は、js では文書内容の出力、dom の変更、リダイレクトなどの動作が発生する可能性があるため、デフォルトでは同期実行が安全です。
以前の一般的な推奨事項は、このブロック動作を最小限に抑え、ページが最初に表示されるようにするために、ページの最後に を配置することでした。
簡単に言えば、ロードされたネットワーク タイムラインはウォーターフォール モデルであり、非同期的にロードされたタイムラインは同時実行モデルです。
2. 共通の非同期読み込み (スクリプト DOM 要素)
コードをコピー コードは次のとおりです:

(function() {
var s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
s .src = 'http://yourdomain.com/script.js';
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x); 🎜>} )();

非同期読み込みは、ノンブロッキングとも呼ばれ、ブラウザは js のダウンロードと実行中に後続のページの処理を続けます。
この方法では、js を使用してページ上の <script> タグ内に script 要素を作成し、それをドキュメントに挿入します。これにより、js コードのノンブロッキングダウンロードが実現します。 <br>async 属性は HTML5 の新しい非同期サポートです。以下の説明を参照してください (追加しなくても影響しません)。 <br>このメソッドはスクリプト DOM 要素メソッドと呼ばれ、js が同じオリジンを持つ必要はありません。 <br>js コードを匿名関数でラップしてすぐに実行する方法は、変数名が外部に漏洩しないようにするためのもので、特に js ライブラリでよく使用される方法です。 <br>たとえば、Google Analytics と Google Badge はどちらも次の非同期読み込みコードを使用します: <br><br><div class="codetitle"> <span><a style="CURSOR: pointer" data="81787" class="copybut" id="copybut81787" onclick="doCopy('code81787')">コードをコピーします<u></u></a> コードは次のとおりです。 :</span> </div> <div class="codebody" id="code81787">(function() { <br>var ga = document.createElement('script'); <br>ga.type = 'text/javascript'; ga.async = true; <br>ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') '.google-analytics.com/ga.js'; >var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s)(); <br><br>(function() <br>{var po = document.createElement("script"); <br>po.async = true;po.src = "https://apis.google.com/js/plusone.js "; <br>var s = document.getElementsByTagName("script")[0]; <br>s.parentNode.insertBefore(po, s); <br>})(); <br><br> <br>ただし、このロード方法では、ロードが完了する前に onload イベントがトリガーされるのを防ぎますが、多くのページのコードは onload 中に追加のレンダリング作業を実行する必要があるため、依然として一部のページの初期化処理がブロックされます。 <br> </div> <br>3. オンロード中の非同期ロード<br><br><br><br><div class="codetitle">コードをコピーします<span><a style="CURSOR: pointer" data="59761" class="copybut" id="copybut59761" onclick="doCopy('code59761')"><u> コードは次のとおりです:</u> </a> </span>(function() { </div>function async_load(){ <div class="codebody" id="code59761">var s = document.createElement('script'); <br>s.type = 'text/javascript'; <br> s. async = true; <br>s.src = 'http://yourdomain.com/script.js'; <br>var x = document.getElementsByTagName('script')[0]; parentNode.insertBefore(s, x); <br>if (window.attachEvent) <br>else <br>window.addEventListener('load' 、 async_load 、 false); <br>})();<br>これは前のメソッドと似ていますが、重要なのは、js の非同期読み込みをすぐに開始するのではなく、onload 時にのみ非同期読み込みを開始することです。これにより、onload イベントのトリガーがブロックされるという問題が解決されます。 <br>追加: DOMContentLoaded および OnLoad イベント <br>DOMContentLoaded: ページ (ドキュメント) が解析され、ページ内の dom 要素が使用可能になりました。ただし、ページ内で参照されている画像とサブフレームはまだ読み込まれていない可能性があります。 <br>OnLoad: ページのすべてのリソースがロードされました (画像を含む)。ブラウザの読み込みの進行はこの時点で停止します。 <br>これら 2 つの時点は、ページ読み込みタイムラインを 3 つの段階に分割します。 <br>4. 非同期読み込みのその他の方法 <br>JavaScript の動的な性質により、次のような非同期読み込み方法が多数あります。 <br>XHR Eval <br>XHR Injection <br>Iframe のスクリプト <br>Script Defer <br> document.write スクリプト タグ <br>もう 1 つの方法は、setTimeout を他のメソッドと組み合わせて使用​​し、0 秒遅らせることです。 <br>XHR Eval: ajax を通じて js のコンテンツを取得し、eval を通じて実行します。 <br>var xhrObj = getXHRObject(); <br><div class="codetitle"> <span><a style="CURSOR: pointer" data="99282" class="copybut" id="copybut99282" onclick="doCopy('code99282')"><u>コードをコピーします </u></a></span> コードは次のとおりです: </div> <div class="codebody" id="code99282"> <br>xhrObj.onreadystatechange = <br>function() { <br>if (xhrObj.readyState != 4 ) return; <br>xhrObj.open('GET) ', ' A.js', true); <br>xhrObj.send(''); <br><br> <br>Iframe のスクリプト: js を非同期で実行できるように iframe 要素を作成して挿入します。 </div> <br><br><div class="codetitle"> <span>コードをコピー <a style="CURSOR: pointer" data="80719" class="copybut" id="copybut80719" onclick="doCopy('code80719')"><u></u> コードは次のとおりです。 </a></span> </div>var iframe = document.createElement('iframe '); <div class="codebody" id="code80719">document.body.appendChild(iframe); <br>var doc = iframe.contentWindow.write(' ;') ; <br>doc.close(); <br><br> <br>GMail モバイル: ページ内の js の内容はコメント化されているため、必要に応じてテキストを取得します。 script 要素の内容を変更し、コメントを削除します。その後、eval が実行されます。 <br> </div> <br><br><div class="codetitle">コードをコピー<span><a style="CURSOR: pointer" data="62965" class="copybut" id="copybut62965" onclick="doCopy('code62965')"><u> コードは次のとおりです:</u></a> </span><script type="text/javascript "> </div>/* <div class="codebody" id="code62965">var ... <br>*/ <br></script>


詳細については、参考資料の 2010 Velocity Conference で Steve Souders と Taobao が提供した 2 つの配布資料を参照してください。

2. 非同期属性と遅延属性

1. 遅延属性
>defer 属性は、このスクリプトに document.write または dom の変更がないことを宣言します。
ブラウザは、ページの後続の処理をブロックすることなく、file.js と defer 属性を持つ他のスクリプトを並行してダウンロードします。
defer 属性は 13 年以上前の IE 4.0 に実装されました。 Firefox は 3.5 から defer 属性をサポートします。
注: すべての遅延スクリプトは、順番に実行されることが保証されています。
2. async 属性

async 属性は HTML5 の新機能です。この関数は defer に似ていますが、ダウンロード後できるだけ早く実行されます。スクリプトが順番に実行されるという保証はありません。これらは onload イベントの前に完了します。
Firefox 3.6、Opera 10.5、IE 9、および最新の Chrome と Safari はすべて、async 属性をサポートしています。 async と defer を同時に使用できるため、IE 4 以降のすべての IE で非同期読み込みがサポートされます。
3. HTML 4.01 と HTML5 の
<script> タグの違いの詳細な説明: <BR>type 属性は HTML 4 では必須ですが、HTML5 ではオプションです。 <BR>async 属性は HTML5 の新しい属性です。 <BR>一部の属性 (xml:space) は HTML5 ではサポートされていません。 <BR>注: <BR>async 属性がないと、後続の処理を続行する直前にスクリプトが取得 (ダウンロード) され、実行されるため、ブラウザーの後続の処理がブロックされます。 <BR>async 属性がある場合、スクリプトは非同期でダウンロードおよび実行され、ブラウザは後続の処理を続行します。 <BR>HTML4 には defer 属性があり、このスクリプトがドキュメント要素 (document.write なし) を生成しないことをブラウザーに通知するため、ブラウザーは後続の処理とレンダリングを続行します。 <BR>async 属性がなく、defer 属性がある場合、ページが解析された後にスクリプトが実行されます。 <BR>両方が同時に設定されている場合、defer 属性は主に、async 属性をサポートしていない古いブラウザが同期メソッドではなく元の defer メソッドで処理できるようにするためのものです。 <BR>公式の説明も参照してください: script async <BR>個人的な補足: <BR>HTML5 はすでに非同期ロードをサポートしているのに、なぜ以前に推奨された面倒な方法 (スクリプト要素を動的に作成する) を使用する必要があるのでしょうか? <BR>答え: 古いブラウザは互換性のために非同期をサポートしていません。将来的にすべてのブラウザーがこれをサポートする場合、スクリプトに async 属性を直接追加するのが最も簡単な方法です。 <BR><br><br>3. 遅延ロード <STRONG> <br>以前に非同期ロード (非同期ロード) の問題を解決しました。遅延ロードとは何かについて説明します。 <br>遅延読み込み: 一部の JS コードは、ページの初期化時にすぐには必要ありませんが、後で特定の状況で必要になります。遅延読み込みとは、これらの一時的に使用されていない js が最初には読み込まれず、必要なときまたは後で js コントロールを通じて非同期的に読み込まれることを意味します。 <BR>つまり、js は多くのモジュールに分割されており、ページの初期化時にすぐに実行する必要がある js のみがロードされ、他の js のロードは最初に必要になるまで遅延されます。 <BR>特にページが多数の異なるモジュールで構成されており、その多くが一時的に使用されないか、まったく使用されない場合があります。 <BR> 画像の遅延読み込みと同様に、画像が表示領域に表示されるとき (スクロール バーが引き下げられるとき)、画像が読み込まれて表示されます。 <BR><br><br>4. スクリプトの 2 段階の読み込みと遅延実行 <STRONG><BR>JS の読み込みは、実際にはバイトのダウンロードと実行 (解析と実行) の 2 段階で構成されます。 <BR>ブラウザは、同期的にロードされたか非同期的にロードされたかに関係なく、ダウンロード直後に js コンテンツを解析して実行します。 <BR>前述の非同期読み込みはダウンロード段階での問題のみを解決しますが、コードはダウンロード直後に実行されます。 <BR>ブラウザは、JS の解析および実行フェーズ中にすべての操作をブロックし、現時点ではブラウザは応答しない状態になります。 <BR>インターネット経由でスクリプトをダウンロードするにはかなりの時間がかかることは誰もが知っていますが、解析と実行にも時間がかかる第 2 段階は見落とされがちです。スクリプトの解析と実行には、特に大規模なスクリプトが多数ある場合、思っているよりも時間がかかります。すぐに実行する必要があるものもあれば、そうでないものもあります (たとえば、特定のインターフェイスを表示するときや操作を実行するときにのみ必要となるものなど)。 <BR>これらのスクリプトは遅延実行し、最初に非同期でダウンロードしてキャッシュすることができますが、すぐには実行されず、初めて必要になったときに 1 回実行されます。 <BR>ダウンロードと実行を分離するために特別なテクニックを使用できます (これも JavaScript の動的な性質のおかげです)。たとえば、JS コンテンツは画像またはオブジェクト オブジェクトとしてロードおよびキャッシュされるため、すぐには実行されず、初めて必要になったときに実行されます。 <BR>このセクションの詳細については、最後の「リソース」にある ControlJS への関連リンクを参照してください。 <BR>ヒント: <BR>1. 長いダウンロード時間をシミュレートします: <BR>バックエンド スクリプトを作成し、一定期間スリープさせます。たとえば、jsp の Thread.sleep(5000); とすると、5 秒後にコンテンツを受信できるようになります。 <BR>2. 模拟较长的 js 代码执行时间(因为这步一般比较快不容易观察到): <BR>var t_start = Number(new Date()); <BR>while ( t_start + 5000 > Number(new Date()) ) {} <BR>这个代码将使 js 执行5秒才能完成! <br><br><STRONG>五、script 标签使用的历史 <BR><BR>1. script 放在 HEAD 中 <BR><div class="codetitle"><span><a style="CURSOR: pointer" data="89669" class="copybut" id="copybut89669" onclick="doCopy('code89669')"><U>复制代码 代码如下:</script>





阻止了后续的下载;
在IE 6-7 中 script 是顺序下载的,而不是现在的 “并行下载、顺序执行” 的方式;
在下载和解析执行阶段阻止渲染(rendering);
2. script 放在页面底部(2007)
...



不阻止其它下载;
在IE 6-7 中 script 是顺序下载的;
在下载和解析执行阶段阻止渲染(rendering);
3. 异步加载script(2009)
复制代码 代码如下:

var se = document.createElement('script');
se.src = 'http://anydomain.com/A.js';
document.getElementsByTagName('head')
[0].appendChild(se);


这就是本文主要说的方式。
不阻止其它下载;
在所有浏览器中,script都是并行下载;
只在解析执行阶段阻止渲染(rendering);
4. 异步下载 + 按需执行 (2010)
复制代码 代码如下:

var se = new Image();
se.onload = registerScript();
se.src = 'http://anydomain.com/A.js';

把下载 js 与 解析执行 js 分离出来
不阻止其它下载;
在所有浏览器中,script都是并行下载;
不阻止渲染(rendering)直到真正需要时;
六、异步加载的问题
在异步加载的时候,无法使用 document.write 输出文档内容。
在同步模式下,document.write 是在当前 script 所在的位置输 出文档的。而在异步模式下,浏览器继续处理后续页面内容,根本无法确定 document.write 应该输出到什么位置,所以异步模式下 document.write 不可行。而到了页面已经 onload 之后,再执行 document.write 将导致当前页面的内容被清空,因为它会自动触发 document.open 方法。
实际上document.write的名声并不好,最好少用。
替代方法:
1. 虽然异步加载不能用 document.write,但还是可以onload之后执行操作dom(创建dom或修改dom)的,这样可以实现一些自己的动态输出。比如要在页面异步创建一个浮动元素,这和它在页面中的位置就没关系了,只要创建出该dom元素添加到 document 中即可。
2. 如果需要在固定位置异步生成元素的内容,那么可以在该固定位置设置一个dom元素作为目标,这样就知道位置了,异步加载之后就可以对这个元素进行修改。
六、JS 模块化管理
异步加载,需要将所有 js 内容按模块化的方式来切分组织,其中就存在依赖关系,而异步加载不保证执行顺序。
另外,namespace 如何管理 等相关问题。这部分已超出本文内容,可参考:
RequireJS 、 CommonJS 以及 王保平(淘宝)的 SeaJS 及其博客 。
七、JS最佳实践:
1. 最小化 js 文件,利用压缩工具将其最小化,同时开启http gzip压缩。工具:
2. 尽量不要放在 中,尽量放在页面底部,最好是之前的位置
3. 避免使用 document.write 方法
4. 异步加载 js ,使用非阻塞方式,就是此文内容。
5. 尽量不直接在页面元素上使用 Inline Javascript,如onClick 。有利于统一维护和缓存处理。
参考资料:
Velocity China 2010 からの 2 つの配布物:
Steve Souders(Google) の さらに高速な Web サイト (pdf)
関連ラベル:
ソース:php.cn
前の記事:jQueryのループスクロール表示コードをtextとpictures_jqueryに適用可能 次の記事:jQuery_jqueryをベースにした無限ループスクロール実装コードのお知らせ
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
最新の問題
関連トピック
詳細>
人気のおすすめ
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート