<script defer =“defer”>는 정확히 어떻게 작동합니까?


208

몇 가지 <script>요소 가 있으며 일부 요소의 코드는 다른 <script>요소의 코드에 따라 다릅니다 . defer코드 블록이 실행에서 연기되도록 속성이 유용 할 수 있음을 보았습니다 .

그것을 테스트하기 위해 Chrome에서 이것을 실행했습니다 : http://jsfiddle.net/xXZMN/ .

<script defer="defer">alert(2);</script>
<script>alert(1)</script>
<script defer="defer">alert(3);</script>

그러나 경고합니다 2 - 1 - 3. 왜 경고하지 1 - 2 - 3않습니까?


2
이 기사를 확인 하십시오 . 그리고 항상 그렇듯이 IE는 자체적으로 의미가있는 것을 취하고 스크립트를 먼저로드하기로 결정했지만 본문이로드 될 때까지 실행을 지연시킵니다 (일반적으로).
Brad Christie

감사합니다. 그러나 테스트 페이지는 Chrome에서 다른 결과를 습니다 : websiteoptimization.com/speed/tweak/defer/test 스크린 샷은 내가 어떻게 기대하는지 보여줍니다 .Chrome은 지연된 것을 먼저 실행하는 것처럼 보입니다.
pimvdb

1
IE의 지연 정의를 찾을 수 있다고 생각합니다. DOM 레벨 1 사양에서 지연하려는 W3C의 의도와 일치합니다.
Mark At Ramp51

41
Alohci가 그의 답변에서 이미 지적했듯이 HTML 표준 에 따르면을 defer지정할 때만 유효합니다 src. 대부분의 브라우저에서 예제가 예상대로 작동하지 않는 이유 일 수 있습니다.
Pankrat

2
@Pankrat 실화! 보십시오 jsfiddle.net/xXZMN/50는 Firefox24에 테스트
m93a

답변:


51

업데이트 된 날짜 : 2016 년 2 월 19 일

이 답변이 구식이라고 생각하십시오. 최신 브라우저 버전과 관련된 정보는이 게시물의 다른 답변을 참조하십시오.


기본적으로 defer는 해당 스크립트 블록에서 자바 스크립트를 실행하기 전에 브라우저가 "준비 될 때까지"기다리도록 지시합니다. 일반적으로 DOM로드 및 document.readyState == 4가 완료된 후입니다.

연기 속성은 인터넷 익스플로러에만 해당됩니다. Internet Explorer 8의 Windows 7에서 JS Fiddle 테스트 페이지에 표시되는 결과는 1-2-3입니다.

결과는 브라우저마다 다를 수 있습니다.

http://msdn.microsoft.com/en-us/library/ms533719(v=vs.85).aspx

일반적인 믿음과는 달리 IE는 사람들이 생각하는 것보다 더 자주 표준을 따릅니다. 실제로 "지연"속성은 DOM 레벨 1 사양 http://www.w3.org/TR/REC-DOM-Level-1/level에 정의되어 있습니다 . -one-html.html

W3C의 연기 정의 : http://www.w3.org/TR/REC-html40/interact/scripts.html#adef-defer :

"설정된 경우,이 부울 속성은 스크립트가 문서 컨텐츠를 생성하지 않을 것 (예 : 자바 스크립트에서"document.write "가 없음)을 사용자 에이전트에 힌트를 제공하므로 사용자 에이전트는 구문 분석 및 렌더링을 계속할 수 있습니다."


8
@ MarkAtRamp51-답변이 구식 인 경우 다른 답변에 대한 의견의 다운 보트에 대해 불평하는 대신 편집해야합니다. 다운 보트는 "유용하지 않은"답변입니다.
Christian Conkle

10
@ChristianConkle 나는 에티켓 레슨에 감사하지만 다른 답변은 최신입니다. 나는 질문을 받았을 때 틀린 답이 선택되지 않았다는 사실을 언급하고 있었다. 아마도 사람들은 시간이 지남에 따라 변화하고 상황이 중요하다는 것을 사람들에게 상기 시키려고 노력하는 대신, 부적절하게 답변을 선택하는 커뮤니티에 대한 잘못된 평가를 퍼뜨리는 사람들을 경찰해야합니다. 역사적 정보도 중요하기 때문에 답변을 제거하는 데 가치가 없습니다.
Mark At Ramp51

3
"이력 정보도 중요하기 때문에 답변을 삭제해도 가치가 없습니다." 최신) 답변? 그것은 당신에게 많은 문제를 덜어 줄 것입니다.
mgibsonbr

3
@Leo 다음에 플래그를 지정해서는 안됩니까? "html5 지연 스크립트"를 검색하면 이것이 Google의 세 번째 결과입니다. 이 답변은 많은 사용자에게 오래되고 잘못된 정의를 제공합니다. (현재 정의 : "사용자 에이전트가 스크립트 처리를 연기 할 수 있음을 나타냅니다. HTML 4.0의 연기 속성 정의를 참조하십시오.").
Malavos

2
답변을 업데이트해야한다고 생각합니다. 이 질문을 찾은 사람은 귀하의 답변이 과거 정보를 인식하지 못합니다. 그것은 오늘날의 정답 인 것처럼 그들에게 보일 것입니다. 인터넷이 작동하는 방식입니다. 따라서 답을 편집하고 한 번에 한 번 정확하다는 것을 기억하고 정답을 참조하십시오.
Juuro

167

HTML5 사양의 일부 스 니펫 : http://w3c.github.io/html/semantics-scripting.html#element-attrdef-script-async

src 속성이 없으면 지연 및 비동기 속성을 지정하지 않아야합니다.


이러한 속성을 사용하여 선택할 수있는 세 가지 가능한 모드가 있습니다 [비동기 및 지연]. async 속성이 있으면 스크립트는 사용 가능한 즉시 비동기식으로 실행됩니다. 비동기 속성이 없지만 지연 속성이 있으면 페이지 구문 분석이 완료되면 스크립트가 실행됩니다. 속성이 없으면 사용자 에이전트가 페이지 구문 분석을 계속하기 전에 스크립트를 즉시 가져 와서 실행합니다.


이러한 속성에 대한 정확한 처리 세부 사항은 대부분 역사적으로 인해 HTML의 여러 측면을 포함하는 다소 사소한 것입니다. 그러므로 구현 요구 사항은 본 명세서 전반에 걸쳐 산재해야 할 필요성이있다. 아래의 알고리즘 (이 섹션에서)은이 처리의 핵심을 설명하지만 이러한 알고리즘은 HTML, 외부 콘텐츠 및 XML의 문서 규칙에 대한 스크립트 시작 및 끝 태그에 대한 구문 분석 규칙에 의해 참조되고 참조됩니다. () 방법, 스크립팅 처리 등


요소에 src 속성이 있고 요소에 지연 속성이 있고 요소가 "parser-inserted"로 플래그 지정되고 요소에 비동기 속성이없는 경우 :

요소가 작성된 구문 분석기의 문서와 연관된 문서 분석이 완료되면 실행할 스크립트 목록 끝에 요소를 추가해야합니다.


37
어쩌면 도움이되지 않은 의견으로 인해 내 답변이 사람들이 내 답변을 투표하지 못하게 할 수 있습니다. 2011 년 초 HTML5 사양이 현재보다 메인 스트림 웹 브라우저와 관련성이 적었 기 때문에 허용 된 답변이 틀리지 않습니다. 답변이 다릅니다. 이 답변은 더 나아질 수 있지만 허용되는 답변은 표준에 의해 틀리지 않습니다 .
Mark At Ramp51

3
이 사양의 말씀을 알고 유용하지만, 일부 밝혀 IE <9와 같은 브라우저 구현 defer심하게 . 를 사용 defer하면 일부 브라우저에서 순서대로 실행중인 스크립트 파일에 의존 할 수 없습니다.
Flimm

2
@Flimm IE뿐만 아니라 Firefox에서도 실행 순서가 보장되지 않는 것 같습니다 .
Franklin Yu

첫 번째 견적은 더 이상 유효하지 않습니까? 이제 이것을 읽을 수 있습니다. "src 속성이 없거나 스크립트가 클래식 스크립트가 아닌 경우 속성을 지정하면 안됩니다." 클래식 스크립트도 src = ""가없는 스크립트입니다.
Félix Sanz

158

진정한 답은 연기 할 수 없기 때문입니다.

개념적으로 지연 및 비동기는 다음과 같이 다릅니다.

async를 사용하면 스크립트를 차단하지 않고 백그라운드에서 다운로드 할 수 있습니다. 그런 다음 다운로드가 완료되는 순간 렌더링이 차단되고 해당 스크립트가 실행됩니다. 스크립트가 실행되면 렌더링이 다시 시작됩니다.

연기는 스크립트가 페이지에 지정된 순서대로 실행을 보장하는 주장을 제외하고, 같은 일을, 그들이 문서 후에 실행됩니다 완성 된 구문 분석이있다. 따라서 일부 스크립트는 다운로드가 완료된 후 나중에 다운로드했지만 그 앞에 나타나는 스크립트를 기다렸다가 기다릴 수 있습니다.

불행히도, 실제로 고양이 싸움의 표준으로 인해 연기자의 정의는 사양에 따라 다양하며 최신 사양에서도 유용한 보증을 제공하지 않습니다. 답변으로 여기에이 문제를 보여, 브라우저는 연기 다르게 구현 :

  • 특정 상황에서 일부 브라우저에는 defer스크립트 순서 가 잘못 되는 버그가 있습니다.
  • 일부 브라우저 DOMContentLoadeddefer스크립트가로드 될 때까지 이벤트를 지연 시키고 일부는 그렇지 않습니다.
  • 일부 브라우저는 순종 defer<script>인라인 코드와없는 요소 src속성, 일부는 그것을 무시합니다.

다행히도 스펙은 비동기 오버라이드가 지연되도록 지정합니다. 따라서 모든 스크립트를 비동기로 처리하고 다음과 같이 광범위한 브라우저 지원을 얻을 수 있습니다.

<script defer async src="..."></script>

전 세계에서 사용중인 브라우저의 98 %와 미국에서 99 %는이 접근 방식으로 차단을 피할 것입니다.

(문서 파싱이 끝날 때까지 기다려야하는 경우 이벤트 DOMContentLoaded이벤트를 듣 거나 jQuery의 편리한 .ready()기능을 사용하십시오. 어쨌든이 기능을 사용 하여 전혀 구현하지 않는 브라우저에서 정상적으로 돌아가고 싶습니다 defer.)


13
감사합니다. 귀하의 답변이 저에게 가장 도움이되었습니다!
markus December

5
나는 이것이 틀렸다고 믿는다. 지연의 이점은 페이지 구문 분석이 완료 될 때까지 실행되지 않는다는 것입니다. 이 페이지는 비동기와 지연의 차이점을 설명 할 수있는 좋은 시각을 제공합니다. peter.sh/experiments/…
tinkerr

1
@tinkerr 개념 상 당신은 맞습니다; 실제로 이것은 사실이 아닙니다. 그것이 일관되게 구현되지 않기 때문에, 시퀀스 보증은 보편적이지 않으므로 보증이 아닙니다. 실행에 관심이있는 것을 구현할 때. 디자인의 의도는 귀엽지 만 특별히 도움이되지는 않습니다.
Chris Moschini

Opera가 2013 년 6 월 2 일 에 릴리스 된 버전 15defer 이후로 속성 을 지원했음을 지적하고 싶었습니다 .

1
@VikasBansal 비동기를 지원하지 않는 구형 브라우저, 즉 구형 IE.
Chris Moschini

13

defer외부 스크립트 포함을 <script>위해 태그 에서만 사용할 수 있습니다 . 따라서- 섹션 의 -tags에 사용하는 것이 좋습니다 .<script><head>


8

지연 속성은 src가있는 scripts 태그에서만 작동합니다. 인라인 스크립트 지연을 모방하는 방법을 찾았습니다. DOMContentLoaded 이벤트를 사용하십시오.

<script defer src="external-script.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function(event) {
    // Your inline scripts which uses methods from external-scripts.
});
</script>

지연된 스크립트가 완전히로드 된 후 DOMContentLoaded 이벤트가 발생하기 때문입니다.


6

지연 속성은 외부 스크립트에만 사용됩니다 (src 속성이있는 경우에만 사용해야 함).



4

2013 년에 작성된 Google 개발자 Jake Archibald가 작성한 스크립트로드의 어두운 물을 살펴 보는이 훌륭한 기사를 살펴보십시오 .

해당 기사에서 관련 섹션 인용 :

연기

<script src="//other-domain.com/1.js" defer></script>
<script src="2.js" defer></script>

Spec says : 함께 다운로드하여 DOMContentLoaded 직전에 순서대로 실행하십시오. "src"가없는 스크립트에서는 "지연"을 무시하십시오.

IE <10 말한다 : 1.js 실행 중 절반에 2.js를 실행할 수 있습니다. 재미 있지 않습니까?

빨간색 브라우저는 말합니다 : 나는이 "지연"이 무엇인지 전혀 모른다. 스크립트가 존재하지 않는 것처럼 스크립트를로드 할 것이다.

다른 브라우저는 다음과 같이 말합니다 . 그러나“src”가없는 스크립트에서는“지연”을 무시하지 않을 수 있습니다.

( 이 의견에 따르면 초기 버전의 Firefox는 defer스크립트 실행 완료 되기 전에 DOMContentLoaded를 트리거 합니다.)

최신 브라우저는 async제대로 지원하는 것처럼 보이지만 스크립트가 제대로 작동하지 않으면 DOMContentLoaded 이전에 정상이어야합니다.


1

이 부울 속성은 문서가 구문 분석 된 후 스크립트가 실행되도록 브라우저에 표시하도록 설정됩니다. 이 기능은 다른 모든 주요 브라우저에서 아직 구현되지 않았기 때문에 작성자는 스크립트의 실행이 실제로 지연 될 것이라고 가정해서는 안됩니다. 지연 스크립트에서 document.write ()를 호출하지 마십시오 (Gecko 1.9.2부터 문서가 날아갑니다). src 속성이없는 스크립트에는 defer 속성을 사용하지 않아야합니다. Gecko 1.9.2부터 src 속성이없는 스크립트에서는 지연 속성이 무시됩니다. 그러나 Gecko 1.9.1에서 defer 속성이 설정되면 인라인 스크립트조차 지연됩니다.

연기는 크롬, 파이어 폭스, 즉> 7, 사파리와 함께 작동

심판 : https://developer.mozilla.org/en-US/docs/HTML/Element/script


0

연기 속성은 부울 속성입니다.

존재하는 경우 페이지 구문 분석이 완료되면 스크립트가 실행되도록 지정합니다.

참고 : 지연 속성은 외부 스크립트에만 사용됩니다 (src 속성이있는 경우에만 사용해야 함).

참고 : 외부 스크립트를 실행할 수있는 몇 가지 방법이 있습니다.

비동기가있는 경우 : 스크립트가 나머지 페이지와 비동기 적으로 실행됩니다 (페이지가 구문 분석을 계속하는 동안 스크립트가 실행 됨) 비동기가없고 지연이있는 경우 : 페이지가 구문 분석을 완료하면 스크립트가 실행됩니다. 비동기 또는 지연이 존재하지 않음 : 브라우저가 페이지 구문 분석을 계속하기 전에 스크립트를 즉시 가져 와서 실행합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.