자바스크립트 비동기 로딩(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> 태그 내에 스크립트 요소를 생성하고 이를 문서에 삽입하는 것입니다. 이를 통해 js 코드의 비차단 다운로드가 달성됩니다. <br>async 속성은 HTML5의 새로운 비동기 지원입니다. 아래 설명을 참조하여 추가하는 것이 좋습니다(추가하지 않아도 영향을 미치지 않습니다). <br>이 방법은 Script DOM Element 방법이라고 하며 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><br>(function() <br>{var po = document.createElement("script"); <br>po.type = "text/javascript"; 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 중에 추가 렌더링 작업을 수행해야 하므로 여전히 일부 페이지의 초기화 처리가 차단됩니다. </div> <br><br>3. 온로드 중 비동기 로딩<br><br><br><div class="codetitle"> <span>코드 복사<a style="CURSOR: pointer" data="59761" class="copybut" id="copybut59761" onclick="doCopy('code59761')"><u></u> 코드는 다음과 같습니다.</a> </span> </div>(function() { <div class="codebody" id="code59761">function async_load(){ <br>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>} <br>if (window.attachEvent) <br>window.attachEvent('onload', async_load) <br>else <br>window.addEventListener('load' , async_load , false) <br>})();<br>이전 방법과 비슷하지만, js의 비동기 로딩을 바로 시작하지 않고 onload시에만 비동기 로딩을 시작한다는 점이 핵심입니다. 이는 onload 이벤트가 트리거되는 것을 차단하는 문제를 해결합니다. <br>추가됨: DOMContentLoaded 및 OnLoad 이벤트 <br>DOMContentLoaded: 페이지(문서)가 구문 분석되었으며 페이지의 dom 요소를 사용할 수 있습니다. 그러나 페이지에서 참조된 이미지와 하위 프레임이 아직 로드되지 않았을 수 있습니다. <br>OnLoad: 페이지의 모든 리소스가 로드되었습니다(이미지 포함). 이 시점에서 브라우저의 로딩 진행이 중지됩니다. <br>이 두 시점은 페이지 로딩 타임라인을 세 단계로 나눕니다. <br>4. 기타 비동기 로딩 방법 <br>Javascript의 동적 특성으로 인해 다음과 같은 비동기 로딩 방법이 많이 있습니다. <br>XHR 평가 <br>XHR 삽입 <br>Iframe의 스크립트 <br>스크립트 연기 <br> document.write 스크립트 태그 <br>또 다른 방법은 다른 방법과 결합하여 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>eval(xhrObj.responseText) <br>xhrObj.open('GET ', ' A.js', true); <br>xhrObj.send(''); <br><br> </div>Iframe의 스크립트: js를 비동기적으로 실행할 수 있도록 iframe 요소를 생성하고 삽입합니다. <br><br><div class="codetitle"><span><a style="CURSOR: pointer" data="80719" class="copybut" id="copybut80719" onclick="doCopy('code80719')">코드 복사 <u></u></a> 코드는 다음과 같습니다. </span></div> <div class="codebody" id="code80719">var iframe = document.createElement('iframe '); <br>document.body.appendChild(iframe); <br>var doc = iframe.contentWindow.document; <br>doc.open().write('<body onload="insertJS()"&gt ;') ; <BR>doc.close(); <BR><BR> </div>GMail Mobile: 페이지의 js 내용이 주석 처리되어 실행되지 않습니다. 그런 다음 필요할 때 텍스트를 가져옵니다. 스크립트 요소의 내용을 삭제하고 주석을 제거한 다음 eval이 실행됩니다. <BR><BR><div class="codetitle"><span><a style="CURSOR: pointer" data="62965" class="copybut" id="copybut62965" onclick="doCopy('code62965')">코드 복사<U></U></a> 코드는 다음과 같습니다.</span></div> <div class="codebody" id="code62965"><script type="text/javascript "> <br>/* <br>var ... <br>*/ <br></script>


자세한 내용은 참고 자료에서 2010 Velocity Conference에서 Steve Souders와 Taobao가 발표한 두 유인물을 참조하세요.

2. 비동기 및 연기 속성

1. 연기 속성
>defer 속성은 이 스크립트에 document.write 또는 dom 수정이 없음을 선언합니다.
브라우저는 페이지의 후속 처리를 차단하지 않고 defer 속성이 있는 file.js 및 기타 스크립트를 병렬로 다운로드합니다.
defer 속성은 13년 전 IE 4.0에서 구현되었습니다! Firefox는 3.5부터 defer 속성을 지원합니다.
참고: 모든 연기 스크립트는 순서대로 실행됩니다.
2. 비동기 속성

비동기 속성은 HTML5에 새로 추가되었습니다. 이 기능은 defer와 비슷하지만, 다운로드 후 바로 실행됩니다. 스크립트가 순서대로 실행된다는 보장은 없습니다. onload 이벤트 전에 완료됩니다.
Firefox 3.6, Opera 10.5, IE 9, 최신 Chrome 및 Safari는 모두 비동기 속성을 지원합니다. async와 defer를 동시에 사용할 수 있으므로 IE 4 이후의 모든 IE는 비동기 로딩을 지원합니다.
3. HTML 4.01과 HTML5의
<script> 태그 사이의 차이점에 대한 자세한 설명: <br>type 속성은 HTML 4에서는 필수이고 HTML5에서는 선택 사항입니다. <br>비동기 속성은 HTML5의 새로운 기능입니다. <br>일부 속성(xml:space)은 HTML5에서 지원되지 않습니다. <br>참고: <br>비동기 속성이 없으면 후속 처리를 계속하기 직전에 스크립트를 획득(다운로드)하고 실행하여 브라우저의 후속 처리를 차단합니다. <br>비동기 속성이 있는 경우 브라우저가 후속 처리를 계속하는 동안 스크립트가 비동기적으로 다운로드되어 실행됩니다. <br>HTML4에는 defer 속성이 있는데, 이 스크립트는 문서 요소(document.write 없음)를 생성하지 않으므로 브라우저가 후속 처리 및 렌더링을 계속한다는 메시지를 브라우저에 표시합니다. <br>async 속성은 없지만 defer 속성이 있는 경우 페이지를 구문 분석한 후 스크립트가 실행됩니다. <br>두 가지를 동시에 설정하는 경우 defer 속성은 주로 async 속성을 지원하지 않는 오래된 브라우저에서 동기 방식이 아닌 원래 defer 방식으로 처리할 수 있도록 하기 위한 것입니다. <br>공식 설명도 참고하세요: script async <br>개인 보충: <br>HTML5는 이미 비동기 로딩을 지원하는데 왜 앞서 권장했던 번거로운 방법(스크립트 요소를 동적으로 생성)을 계속 사용해야 할까요? <br>답변: 이전 브라우저는 호환성을 위해 비동기를 지원하지 않습니다. 앞으로 모든 브라우저가 이를 지원한다면 비동기 속성을 스크립트에 직접 추가하는 것이 가장 쉬운 방법입니다. <br><br><br>3. 지연 로딩 <strong> </strong><br> 앞서 비동기 로딩(async loading) 문제를 해결했는데, 지연 로딩이 무엇인지 알아보겠습니다. <br>지연 로딩: 일부 js 코드는 페이지가 초기화될 때 즉시 필요하지 않지만 나중에 특정 상황에서는 필요합니다. 지연 로딩은 일시적으로 사용되지 않는 js가 처음에는 로드되지 않지만 필요할 때 또는 나중에 js 제어를 통해 비동기적으로 로드된다는 것을 의미합니다. <br>즉, js는 여러 모듈로 나누어 페이지가 초기화되면 바로 실행해야 하는 js만 로드되고, 이후에는 처음 필요할 때까지 다른 js의 로딩이 지연됩니다. <br>특히 페이지가 다양한 모듈로 구성되어 있는 경우에는 그 중 다수가 일시적으로 사용되지 않거나 전혀 사용되지 않을 수 있습니다. <br> 이미지 지연 로딩과 마찬가지로 이미지가 가시 영역에 나타날 때(스크롤 막대를 아래로 당길 때) 이미지가 로드되어 표시됩니다. <br><br><br>4. 스크립트의 2단계 로딩 및 지연 실행 <strong><br></strong>JS 로딩은 실제로 바이트 다운로드와 실행(파싱 및 실행)의 두 단계로 구성됩니다. <br>브라우저는 동기식 또는 비동기식 로드 여부에 관계없이 다운로드한 후 즉시 js 콘텐츠를 구문 분석하고 실행합니다. <br>앞서 언급한 비동기 로딩은 다운로드 단계에서만 문제를 해결하지만, 다운로드 직후 코드가 실행됩니다. <br>JS 구문 분석 및 실행 단계에서는 브라우저가 모든 작업을 차단하며 현재 브라우저는 응답하지 않는 상태입니다. <br>우리 모두는 인터넷을 통해 스크립트를 다운로드하는 데 상당한 시간이 걸린다는 것을 알고 있지만, 구문 분석 및 실행에도 시간이 걸리는 두 번째 단계를 간과하기 쉽습니다. 스크립트를 파싱하고 실행하는 데에는 생각보다 시간이 오래 걸립니다. 특히 대규모 스크립트가 많은 경우에는 더욱 그렇습니다. 일부는 즉시 실행되어야 하지만 일부는 그렇지 않습니다(예를 들어 특정 인터페이스를 표시하거나 작업을 수행할 때만 필요함). <br>이러한 스크립트는 느리게 실행되고 먼저 비동기식으로 다운로드 및 캐시될 수 있지만 즉시 실행되지는 않지만 처음 필요할 때 한 번 실행됩니다. <br>특수 기술을 사용하여 다운로드와 실행을 분리할 수 있습니다(다시 한번 자바스크립트의 동적 특성 덕분에). 예를 들어 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></strong><br>1. script 放在 HEAD 中 <br><div class="codetitle"> <span><a style="CURSOR: pointer" data="89669" class="copybut" id="copybut89669" onclick="doCopy('code89669')"><u>复制代码</u></a></span> 代码如下:</div> <div class="codebody" id="code89669"> <br><head> <br><script src=“…”></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)의 더 빨라진 웹사이트(pdf)
관련 라벨:
원천:php.cn
이전 기사:jQuery 루프 스크롤 표시 코드를 text 및 Pictures_jquery에 적용할 수 있습니다. 다음 기사:jQuery_jquery 기반의 무한 루프 스크롤 구현 코드 발표
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
최신 이슈
관련 주제
더>
인기 추천
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿