스크립트 태그-비동기 및 지연


547

나는 속성에 대한 몇 가지 질문이 async& defer를위한 <script>HTML5 브라우저에 대한 이해에만 작업에 태그를.

내 사이트 중 하나에 현재 </body>태그 바로 위에있는 두 개의 외부 JavaScript 파일이 있습니다 . 첫 번째는 구글에서 공급하고 두 번째는 로컬 외부 스크립트입니다.

사이트로드 속도와 관련하여

  1. async페이지 하단에있는 두 개의 스크립트 를 추가 하면 어떤 이점이 있습니까?

  2. async옵션을 두 스크립트 에 추가 하고 페이지 상단에 <head>?

  3. 이것이 페이지가로드 될 때 다운로드한다는 의미입니까?
  4. HTML4 브라우저에서 지연이 발생한다고 가정하지만 HTML5 브라우저에서 페이지로드 속도가 빨라 집니까?

사용 <script defer src=...

  1. <head>속성으로 두 스크립트를로드하면 이전에 스크립트를 사용 defer하는 것과 동일한 영향을 미칩니 </body>까?
  2. 다시 한 번 나는 이것이 HTML4 브라우저를 느리게 할 것이라고 가정합니다.

사용 <script async src=...

async활성화 된 두 개의 스크립트가있는 경우

  1. 동시에 다운로드됩니까?
  2. 아니면 나머지 페이지와 함께 한 번에 하나씩?
  3. 그러면 스크립트 순서가 문제가됩니까? 예를 들어 하나의 스크립트는 다른 스크립트에 의존하므로 하나의 다운로드가 더 빠르면 두 번째 스크립트가 제대로 실행되지 않을 수 있습니다.

마지막으로 HTML5가 더 일반적으로 사용될 때까지 그대로 두는 것이 가장 좋습니까?


5
async새로운 (ish)이지만 deferIE4 이후 IE의 일부였습니다. defer최근에 다른 브라우저에 추가되었지만 이전 버전의 브라우저는 훨씬 덜 매달려 있습니다.
Alohci

3
이제 HTML5가 매우 인기를 얻었습니다!
sept08

2
defer몇 년 동안 일반적으로 사용되는 HTML 의 맨 아래 에 스크립트를 배치하는 것과 같습니다 .
vsync

1
@vsync가 반드시 참일 필요는 없으며, 브라우저는 스크립트 태그를 구문 분석 할 때 defer 태그가있는 JS를 다운로드하지만 DOMContentLoaded 직전까지 실행을 연기합니다. 다운로드는 차단되지 않습니다. HTML의 맨 아래에 배치하면 DOM이 구성 될 때까지 JS의 다운로드 및 실행이 지연되지만 다운로드를 기다리면 추가 지연이 발생합니다.
브래드 프로스트

@BradFrost-다운로드가 내 관점에서 차단되고 있습니다. 인터넷 대역폭을 사용한다는 점에서 연결 속도가 느린 사람들은 문서를 먼저로드 한 다음 렌더링 될 때만 자바 스크립트 파일 다운로드를 시작해야합니다. . 내용이 없습니다 (같은 모든 렌더링 자바 스크립트에 밀접하게 연결되어있는 곳의 경우 사실이다 SPA를 )
수직 동기화

답변:


405

스크립트를 바로 유지하십시오 </body>. 비동기는 몇 가지 상황에서 스크립트와 함께 사용할 수 있습니다 (아래 설명 참조). DOM 구문 분석 작업은 이미 거의 완료되었으므로 지연은 거기에있는 스크립트에 큰 차이를 만들지 않습니다.

다음은 비동기와 지연의 차이점을 설명하는 기사입니다. http://peter.sh/experiments/asynchronous-and-deferred-javascript-execution-explained/ .

스크립트를 본문 바로 앞에 스크립트를 유지하면 이전 브라우저에서 HTML이 더 빨리 표시됩니다 </body>. 따라서 구형 브라우저에서로드 속도를 유지하기 위해 다른 곳에두기를 원하지 않습니다.

두 번째 스크립트가 첫 번째 스크립트에 의존하는 경우 (예 : 두 번째 스크립트가 첫 번째 스크립트에로드 된 jQuery를 사용하는 경우) 실행 순서를 제어하기 위해 추가 코드없이 비 동기화 할 수는 없지만 지연 스크립트는 지연 될 수 있습니다. 문서가 구문 분석 된 후에야 순서대로 실행됩니다. 해당 코드가 있고 스크립트를 즉시 실행할 필요가없는 경우 비동기 또는 지연으로 만들 수 있습니다.

스크립트를 <head>태그에 넣고 설정할 수 defer있으며 DOM이 구문 분석되고 지연을 지원하는 새로운 브라우저에서 페이지가 빠르게 표시 될 때까지 스크립트 로딩이 지연되지만 전혀 도움이되지 않습니다. 구형 브라우저 </body>에서는 모든 브라우저에서 작동 하는 스크립트를 바로 넣는 것보다 빠르지는 않습니다 . 따라서 바로 앞에 배치하는 것이 가장 좋은 이유를 알 수 있습니다 </body>.

비동기는 스크립트가로드 될 때 실제로 신경 쓰지 않고 사용자 의존적 인 것이 스크립트로드에 의존하지 않을 때 더 유용합니다. 비동기를 사용하는 가장 자주 인용되는 예는 Google Analytics와 같은 분석 스크립트로, 기다릴 필요가 없으며 곧 실행되는 것이 긴급하지 않으며 독립적이므로 다른 것에 의존하지 않습니다.

일반적으로 jQuery 라이브러리는 다른 스크립트가 의존하고 이벤트 핸들러를 설치하여 페이지가 사용자 이벤트에 응답하기 시작하고 초기 상태를 설정하기 위해 jQuery 기반 초기화 코드를 실행해야하기 때문에 비동기에 적합하지 않습니다. 페이지의. 비동기식으로 사용될 수 있지만 jQuery가로드 될 때까지 실행되지 않도록 다른 스크립트를 코딩해야합니다.


8
지연은 여전히 ​​순서대로 실행해야하지만 dom-contentloaded 전에 실행해야합니다. 그것은 html이 파싱되기 전에 다운로드를 시작할 수 있기 때문에 머리에 넣는 것이 더 빠르다는 것을 의미하지 않습니까?
Kevin

9
스크립트를 넣고 head그것을 설정하는 defer것이 이전에 넣는 것보다 빠르지는 </body>않지만 내가 읽은 내용이 잘못되었습니다. 생각해보십시오-스크립트를에 넣으면 <head>즉시 다운로드가 시작되지만 바로 앞에 있으면 </body>다른 모든 요소가 먼저 다운로드됩니다.
Nate

12
@Nate-내 문서가 더 빨리로드되지 않습니다. 스크립트 로딩 속도가 빨라질 수 있지만 문서의 로딩 속도가 느려질 수 있습니다. 또한 대역폭을 사용하고 있으며 브라우저가 지정된 서버에 연결하는 제한된 연결 중 하나를 사용하기 때문에 내용 및 내용이 느려질 수 있습니다 콘텐츠를로드하는 동안 스크립트를로드하십시오.
jfriend00

4
"두 번째 스크립트가 첫 번째 스크립트에 의존한다면 ... 당신은 그것들을 비동기 나 지연으로 만들 수 없습니다."
DisgruntledGoat

2
현재이 답변이 게시 된 2012 년 이후의 브라우저 개발에는 </ body> 요구 사항이 필요하지 않습니다.
bgcode

843

이 이미지는 일반적인 스크립트 태그, 비동기 및 지연을 설명합니다.

여기에 이미지 설명을 입력하십시오

  • 비동기 스크립트는 스크립트가로드 되 자마자 실행되므로 실행 순서를 보장하지 않습니다 (끝에 포함 된 스크립트가 첫 번째 스크립트 파일 전에 실행될 수 있음)

  • 지연 스크립트는 페이지에 나타나는 실행 순서를 보장합니다.

이 링크를 참조하십시오 : http://www.growingwiththeweb.com/2014/02/async-vs-defer-attributes.html


여러 개의 스크립트 예를 들어 자신의 순서를 설명하기 위해 더 좋았을 것이라고 생각
수직 동기화

4
@writofmandamus async이길 것 같습니다 . 참조 stackoverflow.com/questions/13821151/...
몬 시뇨

좋은 설명 감사합니다. 그러나 이미지 크기가 조정되지 않습니다. <script>태그 만있는 경우 총 페이지로드 길이는 스크립트 파일을 다운로드하는 데 걸리는 시간이 길어집니다.
arni September

@BhavikHirani 이 사이트 에 따르면 , 동일한 스크립트 태그에서 async와 defer를 모두 사용하면 브라우저가 지원하는 경우 async를 사용하거나 비동기를 지원하지 않지만 지연을 지원하는 경우 지연됩니다. 동작은 매우 다르므로 결과를 예측할 수 없으며 버그의 큰 원천이 될 수 있으므로 두 가지를 모두 사용하지 않는 것이 좋습니다.
Adrian Wiik

@arni 대역폭이 완전히 활용되는 경우에만 사용됩니다. 그리고 두 다운로드 모두 하나를 차단하지 않고 대역폭을 공유합니다 .— 추가 :이 이미지는 다운로드가 아니라 녹색으로 구문 분석됩니다.
Robert Siemer

213

HTML5 : async ,defer

HTML5에서는 JavaScript 코드를 언제 실행할지 브라우저에 알릴 수 있습니다. 3 가지 가능성이 있습니다 :

<script       src="myscript.js"></script>

<script async src="myscript.js"></script>

<script defer src="myscript.js"></script>
  1. 없이 async또는 defer브라우저는 스크립트 태그 아래의 요소를 렌더링하기 전에, 즉시 스크립트를 실행합니다.

  2. async(비동기식)을 사용하면 브라우저가 HTML 페이지를 계속로드하여 브라우저가 동시에 스크립트를로드하고 실행하는 동안 HTML 페이지를 렌더링합니다.

  3. 를 사용 defer하면 페이지 구문 분석이 완료되면 브라우저가 스크립트를 실행합니다. (모든 이미지 파일 다운로드를 마칠 필요는 없습니다. 좋습니다.)


blogger.com 템플릿 async=""은 템플릿 변경 사항을 확인하고 저장하기 전에 필요합니다 .
noobninja

1
참고 : 스크립트가 비동기를 사용하여 지정된 순서대로 실행된다는 보장은 없습니다. "따라서 두 번째 스크립트가 첫 번째 스크립트에 의존하는 경우 비동기를 피하십시오."
파이살 나시어

2
async-스크립트는 HTML 파일의 순서를 고려하지 않고 다운로드 한 순간 에 실행 됩니다.
vsync

30

파서를 일시 중지하지 않고 스크립트 asyncdefer스크립트가 모두 즉시 다운로드되기 시작하고onload 따라 초기화를 수행해야하는 일반적인 요구를 해결 처리기를 .

스크립트가 실행될 때 asyncdefer중심 의 차이점 . 각 async스크립트는 다운로드가 완료된 후 및 창의로드 이벤트 전에 첫 번째 기회에서 실행됩니다. 이는 async스크립트가 페이지에서 발생하는 순서대로 실행되지 않을 수 있음을 의미합니다. 반면에 defer스크립트는 페이지에서 발생하는 순서대로 실행되도록 보장됩니다. 구문 분석이 완료된 후 문서 DOMContentLoaded이벤트 전에 실행이 시작됩니다 .

출처 및 추가 정보 : here .


24

같은 종류의 문제에 직면하여 이제 어떻게 작동하는지 분명히 이해했습니다.이 참조 링크가 도움이 될 것입니다 ...

비동기

스크립트 태그에 비동기 속성을 추가하면 다음이 발생합니다.

<script src="myfile1.js" async></script>
<script src="myfile2.js" async></script>
  1. 파일을 가져 오기 위해 병렬 요청을하십시오.
  2. 문서가 중단되지 않은 것처럼 계속 구문 분석하십시오.
  3. 파일이 다운로드되는 순간 개별 스크립트를 실행하십시오.

연기

지연은 하나의 주요 차이점을 가진 비동기와 매우 유사합니다. 브라우저가 defer 속성을 가진 스크립트를 만나면 어떻게됩니까?

<script src="myfile1.js" defer></script>
<script src="myfile2.js" defer></script>
  1. 개별 파일을 가져 오기 위해 병렬 요청을합니다.
  2. 문서가 중단되지 않은 것처럼 계속 구문 분석하십시오.
  3. 스크립트 파일이 다운로드 된 경우에도 문서 구문 분석을 완료하십시오.
  4. 문서에서 찾은 순서대로 각 스크립트를 실행하십시오.

참조 : 비동기와 지연의 차이점


7

asyncdeferHTML 구문 분석하는 동안 파일을 다운로드합니다. 둘 다 파서를 방해하지 않습니다.

  • async속성이있는 스크립트 는 다운로드되면 실행됩니다. deferDOM 구문 분석을 완료 한 후 속성이있는 스크립트 가 실행됩니다.

  • 로드 된 스크립트 async는 어떤 순서도 보장하지 않습니다. deferattribute 와 함께로드 된 스크립트 는 DOM에 표시되는 순서를 유지합니다.

<script async>스크립트가 아무것도 의존하지 않을 때 사용하십시오 . 스크립트가 use에 의존 할 때.

가장 좋은 해결책은 바디 하단에 추가하는 것입니다. 차단 또는 렌더링에는 문제가 없습니다.


여기에 몇 가지 설명이 필요합니다. 여기에서 두 가지 일이 일어나고 있습니다. 1. 리소스 다운로드 2. 리소스 실행. 두 경우 (비동기 및 지연) 모두에서 리소스 다운로드가 차단되지 않습니다. 즉, HTML 구문 분석을 차단하지 않습니다. 비동기에서 실행하면 구문 분석이 차단되고 지연의 경우 html 마크 업이 구문 분석 된 후 실행이 발생합니다. 따라서이 경우 비 차단입니다.
pOoOf

5

제이크 아치 볼드는 2013 년에이 주제에 더 긍정적 인 내용을 추가 할 수있는 통찰력을 제공했다고 생각합니다.

https://www.html5rocks.com/en/tutorials/speed/script-loading/

성배는 렌더링을 차단하지 않고 즉시 스크립트 세트를 다운로드하여 추가 된 순서대로 가능한 빨리 실행합니다. 불행히도 HTML은 당신을 미워하고 그렇게 할 수 없습니다.

(...)

대답은 실제로 스크립트로드 섹션의 맨 아래에 숨겨져 있지만 실제로 HTML5 사양에 있습니다. " 비동기 IDL 속성은 요소가 비동기 적으로 실행 될지 여부를 제어합니다. 요소의"force-async "플래그가 설정되면 비동기 IDL 속성이 true를 리턴하고 설정시"force-async "를 리턴해야합니다. 플래그를 먼저 설정 해제해야합니다… ".

(...)

문서에 동적으로 생성되고 추가 된 스크립트는 기본적으로 비동기 적이며 렌더링을 차단하지 않고 다운로드하자마자 실행되지 않아 잘못된 순서로 나올 수 있습니다. 그러나 명시 적으로 비동기가 아닌 것으로 표시 할 수 있습니다.

[
    '//other-domain.com/1.js',
    '2.js'
].forEach(function(src) {
    var script = document.createElement('script');
    script.src = src;
    script.async = false;
    document.head.appendChild(script);
});

이를 통해 스크립트에 일반 HTML로는 달성 할 수없는 동작이 혼합됩니다. 명시 적으로 비동기 적이 지 않기 때문에 스크립트는 첫 번째 일반 HTML 예제에서 추가 된 것과 동일한 대기열과 실행 대기열에 추가됩니다. 그러나 동적으로 생성되면 문서 파싱 외부에서 실행되므로 렌더링하는 동안 렌더링이 차단되지 않습니다 (비 동기화 스크립트로드와 동기화 XHR을 혼동하지 마십시오).

위의 스크립트는 페이지 헤드에 인라인으로 포함되어 점진적 렌더링을 방해하지 않으면 서 최대한 빨리 스크립트 다운로드를 큐에 넣고 지정한 순서대로 가능한 빨리 실행합니다. “2.js”는“1.js”이전에 무료로 다운로드 할 수 있지만“1.js”가 성공적으로 다운로드되어 실행되거나 실패 할 때까지는 실행되지 않습니다. 만세! 비동기 다운로드하지만 명령 실행 !

여전히 스크립트를로드하는 가장 빠른 방법이 아닐 수도 있습니다.

(...) 위의 예제에서 브라우저는 스크립트를 구문 분석하고 실행하여 다운로드 할 스크립트를 찾아야합니다. 사전로드 스캐너에서 스크립트를 숨 깁니다. 브라우저는이 스캐너를 사용하여 다음에 방문 할 가능성이있는 페이지의 리소스를 찾거나 파서가 다른 리소스에 의해 차단 된 동안 페이지 리소스를 검색합니다.

이것을 문서의 머리 부분에 넣으면 검색 가능성을 다시 추가 할 수 있습니다.

<link rel="subresource" href="//other-domain.com/1.js">
<link rel="subresource" href="2.js">

이것은 브라우저가 페이지에 1.js와 2.js가 필요하다는 것을 알려줍니다. link [rel = subresource]는 link [rel = prefetch]와 유사하지만 의미가 다릅니다. 불행히도 현재 Chrome에서만 지원되며 링크 요소를 통해 한 번, 스크립트에서 다시 두 번로드 할 스크립트를 선언해야합니다.

수정 : 원래는 사전로드 스캐너에서 가져 왔지만 일반 파서에서 가져 오지 않았습니다. 그러나 사전로드 스캐너는 이러한 기능을 선택할 수 있지만 아직 실행되지는 않았지만 실행 코드에 포함 된 스크립트는 사전로드 할 수 없습니다. 의견을 수정 한 Yoav Weiss에게 감사드립니다.


1

연기 및 비동기의 동작은 적어도 실행 단계에 따라 브라우저에 따라 다릅니다. 참고, 지연은 외부 스크립트에만 적용됩니다. 비동기가 동일한 패턴을 따르는 것으로 가정합니다.

IE 11 이하에서는 순서가 다음과 같습니다.

  • 비동기 (페이지를로드하는 동안 부분적으로 실행될 수 있음)
  • 없음 (페이지를로드하는 동안 실행할 수 있음)
  • 지연 (페이지가로드 된 후 실행, 모두 파일의 배치 순서에 따라 지연)

Edge, Webkit 등에서 async 속성은 무시되거나 끝에 배치되는 것으로 보입니다.

  • data-pagespeed-no-defer (페이지가로드되는 동안 다른 스크립트보다 먼저 실행 됨)
  • 없음 (페이지를로드하는 동안 실행할 수 없음)
  • 연기 (DOM이로드 될 때까지 대기, 모두 파일에 배치 된 순서대로 연기)
  • 비동기 (DOM이로드 될 때까지 대기하는 것으로 보임)

최신 브라우저에서는 data-pagespeed-no-defer 속성이 다른 외부 스크립트보다 먼저 실행됩니다. 이것은 DOM에 의존하지 않는 스크립트를위한 것입니다.

참고 : 외부 스크립트를 명시 적으로 실행해야하는 경우 연기를 사용하십시오. 브라우저가 파일에 배치 된 순서대로 모든 지연된 스크립트를 실행하도록 지시합니다.

ASIDE : 외부 자바 스크립트의 크기는로드 할 때 중요했지만 실행 순서에는 영향을 미치지 않았습니다.

스크립트의 성능이 걱정된다면 최소화를 고려하거나 XMLHttpRequest를 사용하여 동적으로로드하는 것이 좋습니다.


data-pagespeed-no-defer서버 측 PageSpeed ​​모듈 에서 사용 하는 속성 입니다. data-pagespeed-no-defer그 자체에 의해 속성은 모든 브라우저에 영향을주지 않습니다.
Qtax
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.