JavaScript 비동기 로드 문제 요약

질문
기본 적 인 js 는 동기 화 로드 입 니 다.이곳 의'로드'는'다운로드'가 아니 라 해석,실행 으로 이해 할 수 있 습 니 다.최신 버 전의 브 라 우 저 에서 브 라 우 저 는 코드 에 요청 한 자원 을 차단 식 이 아니 라 폭포 식 으로 불 러 옵 니 다.그러나 js 의 실행 은 항상 막 힙 니 다.이것 은 어떤 문 제 를 일 으 킬 수 있 습 니까?만약 에 제 index 페이지 에 js 를 불 러 오 려 고 하지만 그 중의 한 요청 이 응답 을 받 지 못 해서 뒤의 js 코드 의 실행(동기 화 로드)을 막 았 습 니 다.또한 페이지 렌 더 링 도 계속 할 수 없습니다.

<script type="text/javascript" src='http://china-addthis.googlecode.com/svn/trunk/addthis.js'></script>
<script type="text/javascript" src='http://libs.baidu.com/jquery/2.0.0/jquery.min.js'></script>
this is a test
예 를 들 어 위의 이 코드 는 index.html 파일 로 저 장 됩 니 다.페이지 의 주 체 는 간단 한 문자열 이지 만 코드 가 실 행 된 후에 페이지 가 늦게 비어 있 습 니 다.왜 요?요청 한 js 가 늦게 불 러 올 수 없 기 때문에(구 글 이 벽 에 걸 렸 을 수도 있 습 니 다)뒤에 있 는 코드 의 실행 을 막 았 고 페이지 가 렌 더 링 되 지 않 았 습 니 다.js 코드 를앞 에 놓 으 면 페이지 를 먼저 렌 더 링 할 수 있 지 않 습 니까?좋 은 방법,우 리 는 js 를 뒤에 놓 으 려 고 시도 했다.

this is a test
<script type="text/javascript" src='http://china-addthis.googlecode.com/svn/trunk/addthis.js'></script>
<script type="text/javascript" src='http://libs.baidu.com/jquery/2.0.0/jquery.min.js'></script>
페이지 가 순식간에 렌 더 링 되 었 습 니 다."this is a test"도 곧 프론트 에 나 타 났 습 니 다.세상 은 평온 한 것 같 습 니 다.하지만:

this is a test
<script type="text/javascript" src='http://china-addthis.googlecode.com/svn/trunk/addthis.js'></script>
<script type="text/javascript" src='http://libs.baidu.com/jquery/2.0.0/jquery.min.js'></script>
<script type="text/javascript">
 console.log('hello world');
</script>
앞의 코드 를 바탕 으로 코드 를 간단하게 추 가 했 지만'hello World'는 콘 솔 에서 출력 할 수 없 었 습 니 다.분명히 앞의 js 요청 이 뒤의 코드 의 로드 를 막 았 습 니 다.우 리 는 js 의 로드 위 치 를 바 꾸 면 페이지 의 렌 더 링 만 바 꿀 수 있다 는 것 을 깨 달 았 습 니 다.그러나 js 의 로드 에 대해 아무런 소 용이 없 었 고 js 는 막 혔 습 니 다.
js 비동기 로드 실현
우리 의 요 구 는 매우 간단 한 것 같 습 니 다.페이지 에 불 러 오 는 동시에 콘 솔 에서 문자열 을 출력 하면 됩 니 다.다시 말하자면 첫 번 째 구 글 이 제공 하 는 js 를 요청 하 는 동시에 아래 의 js 를 계속 실행 하 는 것 입 니 다.즉,js 의 비동기 로 딩 을 실현 하 는 것 입 니 다.
가장 흔히 볼 수 있 는 방법 은 동적 으로 script 라벨 을 생 성 하 는 것 입 니 다.

<body>
 this is a test
 <script type="text/javascript">
  ~function() {
   var s = document.createElement('script');
   s.src = 'http://china-addthis.googlecode.com/svn/trunk/addthis.js';
   document.body.appendChild(s);
  }();
 </script>
 <script type="text/javascript" src='http://libs.baidu.com/jquery/2.0.0/jquery.min.js'></script>
 <script type="text/javascript">
  console.log('hello world');
 </script>
</body>
그러나 문제 가 있 습 니 다.이러한 로 딩 방식 은 로 딩 이 완료 되 기 전에 onload 이벤트 의 트리거 를 막 을 수 있 습 니 다.현재 많은 페이지 의 코드 가 onload 에 있 을 때 추가 로 렌 더 링 작업 을 수행 해 야 하기 때문에 일부 페이지 의 초기 화 처 리 를 막 을 수 있 습 니 다.

<body>
 this is a test
 <script type="text/javascript">
  ~function() {
   // function async_load() {
    var s = document.createElement('script');
    s.src = 'http://china-addthis.googlecode.com/svn/trunk/addthis.js';
    document.body.appendChild(s);
   // }
   // window.addEventListener('load', async_load, false);
  }();

  window.onload = function() {
   var txt = document.createTextNode(' hello world');
   document.body.appendChild(txt);
  };
 </script>
 <script type="text/javascript" src='http://libs.baidu.com/jquery/2.0.0/jquery.min.js'></script>
</body>
예 를 들 어 위의 코드 는'hello World'를 잘 나타 내지 못 합 니 다.우 리 는 주석 을 없 애 면 됩 니 다.구 글 이 제공 하 는 js 가 onload 에 있 을 때 비동기 로 불 러 오기 시작 합 니 다.이렇게 해서 onload 사건 의 촉발 을 막 는 문 제 를 해결 하 였 다.
DOMContentLoaded 와 OnLoad 이벤트 DOMContentLoaded:페이지(document)가 해석 되 었 고 페이지 의 dom 요 소 를 사용 할 수 있 습 니 다.그러나 페이지 에 인 용 된 그림,subframe 은 아직 불 러 오지 않 았 을 수도 있 습 니 다.OnLoad:페이지 의 모든 자원 을 불 러 옵 니 다(그림 포함).브 라 우 저의 불 러 오 는 진행 이 이때 서 야 중단 되 었 습 니 다.이 두 시간 은 페이지 에 불 러 온 타임 라인 을 세 단계 로 나 누 었 다.
이상 은 이 문 제 를 잘 해결 할 수 있 을 것 같 지만 html 5 는 더욱 간편 한 방법 을 제공 합 니 다.async 속성!

this is a test
<script type="text/javascript" src='http://china-addthis.googlecode.com/svn/trunk/addthis.js' async='async'></script>
<script type="text/javascript" src='http://libs.baidu.com/jquery/2.0.0/jquery.min.js'></script>
<script type="text/javascript">
 console.log('hello world');
</script>
async 는 html 5 의 새로운 속성 입 니 다.async 속성 은 스 크 립 트 가 사용 가능 하면 비동기 로 실 행 됩 니 다(다운로드 가 완료 되면 즉시 실 행 됩 니 다).
주의해 야 할 것 은 async 속성 은 외부 스 크 립 트 에 만 적 용 됩 니 다(src 속성 을 사용 할 때 만)
defer 속성 은 항상 async 와 함께 언급 합 니 다:

this is a test
<script type="text/javascript" src='http://china-addthis.googlecode.com/svn/trunk/addthis.js' defer='defer'></script>
<script type="text/javascript" src='http://libs.baidu.com/jquery/2.0.0/jquery.min.js'></script>
<script type="text/javascript">
 console.log('hello world');
</script>
실현 효과 가 별로 없 는 것 같은 데 정말 같 나 요?defer 속성의 정 의 를 살 펴 보 자.
이전의 defer 는 ie 의 hack 만 지 원 했 는데,현재 html 5 의 출현 은 defer 를 전면적으로 지원 하기 시작 했다.defer 속성 은 페이지 가 불 러 온 후에 야 스 크 립 트 를 실행 할 수 있 도록 규정 합 니 다.defer 속성 은 외부 스 크 립 트 에 만 적 용 됩 니 다(src 속성 을 사용 할 때 만 적 용 됩 니 다).ps:ie 가 지원 하 는 defer 는 그렇지 않 은 것 같 습 니 다.ie 에 대해 관심 이 없고 깊이 연구 하지 않 기 때문에 관심 이 있 는 사람 은 관련 자 료 를 찾 아 볼 수 있 습 니 다.
async 와 defer 가 자주 나타 나 니까 분석 해 보 세 요!
async 와 defer 속성 이 없 으 면 브 라 우 저 는 현재 js 스 크 립 트 를 즉시 실행 하여 뒤의 스 크 립 트 를 막 습 니 다.async 속성 이 있 으 면 후속 문서 요 소 를 불 러 오고 렌 더 링 하 는 과정 은 현재 js 의 불 러 오기 와 실행 을 병행 합 니 다(비동기).defer 속성 이 있 으 면 후속 문서 요 소 를 불 러 오 는 과정 은 script.js 의 불 러 오 는 것 과 병행 합 니 다(비동기).그러나 script.js 의 실행 은 모든 요소(DOM)분석 이 끝 난 후에 DOMContentLoaded 이벤트 가 발생 하기 전에 이 루어 집 니 다.
인터넷 에서 훔 친 그림 을 보 세 요.

파란색 선 은 네트워크 읽 기 를 대표 하고 빨간색 선 은 실행 시간 을 대표 합 니 다.이 두 가 지 는 모두 스 크 립 트 를 대상 으로 합 니 다.녹색 선 은 HTML 해석 을 대표 합 니 다.
이 그림 은 다음 과 같은 몇 가지 요점 을 알려 줍 니 다.
4.567917.defer 와 async 는 인터넷 에서 읽 기(다운로드)이 부분 은 똑 같 습 니 다.모두 비동기 적 입 니 다(HTML 해석 에 비해)4.567917.이 두 가지 차 이 는 스 크 립 트 를 다운로드 한 후에 언제 실행 하 느 냐 에 있다.분명히 defer 는 우리 가 응용 스 크 립 트 의 로드 와 실행 에 대한 요구 에 가장 가깝다4.567917.defer 에 대해 이 그림 은 불 러 오 는 순서에 따라 스 크 립 트 를 실행 하 는 데 있 습 니 다.이 점 은 잘 활용 해 야 합 니 다
  • async 는 무질서 하 게 실 행 된 주 입 니 다.어쨌든 스 크 립 트 의 로드 와 실행 은 밀접 한 관 계 를 가지 기 때문에 성명 의 순서 가 어떻든 로드 가 끝나 면 바로 실 행 됩 니 다
  • 자세히 생각해 보면 async 는 스 크 립 트 를 사용 하 는 데 큰 도움 이 되 지 않 습 니 다.의존 도 를 전혀 고려 하지 않 기 때 문 입 니 다.(최소한 의 순서 로 실행 하 더 라 도)그러나 스 크 립 트 에 의존 하지 않 거나 스 크 립 트 에 의존 하지 않 을 수 있 는 스 크 립 트 에 있어 서 는 매우 적합 합 니 다.가장 전형 적 인 예 는 Google Analytics 입 니 다.
  • 그러나 제 가 보기 에는(아래 의 개인 적 인 이해,만약 에 차이 가 있 으 면 지적 해 주 십시오)defer 가 비동기 로 딩 에서 의 응용 이 async 보다 넓 지 않 습 니 다.async 의 영문 해석 은 비동기 입 니 다.이 속성 은 스 크 립 트 에 작용 하여 스 크 립 트 를 불 러 오기(다운로드)한 후에 실행 합 니 다.동적 삽입 script 태그 와 유사 합 니 다(async 는 h5 만 지원 하고 후 자 는 브 라 우 저 를 호 환 할 수 있 습 니 다).한편,defer 의 영문 해석 은 지연 이 고 역할 도 글자 해석 과 유사 하 며 지연 스 크 립 트 의 실행 으로 인해 dom 요 소 를 불 러 온 후에 야 스 크 립 트 를 질서 있 게 실행 하기 시 작 했 습 니 다.질서 가 있 기 때문에 또 다른 문 제 를 가 져 올 수 있 습 니 다.
    
    this is a test
    <script type="text/javascript" src='http://china-addthis.googlecode.com/svn/trunk/addthis.js' defer='defer'></script>
    <script type="text/javascript" src='http://libs.baidu.com/jquery/2.0.0/jquery.min.js' defer='defer'></script>
    <script type="text/javascript" src='index.js' defer='defer'></script>
    console.log('hello world');
    이 코드 를 실행 하면 콘 솔 의'hello World'도 결 과 를 얻 지 못 할 것 이다.그래서 저 는 async 가 좋 은 것 같 습 니 다.의존 을 고려 하려 면 requirejs,seajs 등 모듈 로 더 를 선택 할 수 있 습 니 다.
    총결산
    JavaScript 의 비동기 로 딩 방법 도 있 습 니 다.예 를 들 어 AJAX eval(AJAX 를 사용 하여 스 크 립 트 내용 을 얻 은 다음 에 eval(xmlhttp.responseText)을 통 해 스 크 립 트 를 실행 합 니 다),iframe 방식 등 입 니 다.
    이상 의 이해 에 차이 가 있 으 시 면 지적 해 주시 기 바 랍 니 다.저희 에 대한 지지 에 감 사 드 립 니 다.

    좋은 웹페이지 즐겨찾기