스크립트 순서로드 및 실행
html 페이지에 JavaScript를 포함시키는 방법에는 여러 가지가 있습니다. 다음 옵션에 대해 알고 있습니다.
- 인라인 코드 또는 외부 URI에서로드
- <head> 또는 <body> 태그에 포함됨 [ 1 , 2 ]
- 없음
defer
또는async
속성이있는 경우 (외부 스크립트 만 해당) - 정적 소스에 포함되거나 다른 스크립트에 의해 동적으로 추가됨 (다른 구문 분석 상태에서 다른 방법으로)
하드 디스크, javascript : URIs 및 onEvent
-attributes [ 3 ] 에서 브라우저 스크립트를 계산하지 않고 이미 JS를 실행하는 16 가지 대안이 있으며 무언가를 잊어 버린 것 같습니다.
나는 빠른 (병렬) 로딩에 관심이 없으며 실행 순서 (로드 순서 및 문서 순서 에 따라 다름)에 대해 더 궁금합니다 . 실제로 모든 경우를 다루는 좋은 (크로스 브라우저) 참조가 있습니까? 예를 들어 http://www.websiteoptimization.com/speed/tweak/defer/ 는 6 개만 처리하며 대부분 오래된 브라우저를 테스트합니다.
그렇지 않다는 것을 두려워하면서 여기에 내 질문이 있습니다. 초기화 및 스크립트로드를위한 (외부) 헤드 스크립트가 있습니다. 그런 다음 본문 끝에 두 개의 정적 인라인 스크립트가 있습니다. 첫 번째 것은 스크립트 로더가 다른 스크립트 요소 (외부 js 참조)를 본문에 동적으로 추가 할 수있게합니다. 정적 인라인 스크립트 중 두 번째는 추가 된 외부 스크립트의 js를 사용하려고합니다. 다른 사람이 실행 된 것에 의존 할 수 있습니까 (그리고 왜 :-)?
동적 스크립트를로드하거나 그들을 표시하지 않는 경우 defer
또는 async
, 다음 스크립트는 페이지에서 발생하는 순서로로드됩니다. 외부 스크립트인지 인라인 스크립트인지는 중요하지 않습니다. 페이지에서 발견 된 순서대로 실행됩니다. 외부 스크립트 뒤에 오는 인라인 스크립트는 이전에 온 모든 외부 스크립트가로드되어 실행될 때까지 유지됩니다.
비동기 스크립트 (비동기 화로 지정되는 방법에 관계없이)는 예기치 않은 순서로로드 및 실행됩니다. 브라우저는 그것들을 병렬로로드하며 원하는 순서대로 자유롭게 실행할 수 있습니다.
여러 비동기 항목 중에서 예측 가능한 순서는 없습니다. 예측 가능한 순서가 필요한 경우 비동기 스크립트에서로드 알림을 등록하고 적절한 항목이로드 될 때 수동으로 javascript 호출을 시퀀싱하여 코딩해야합니다.
스크립트 태그가 동적으로 삽입되면 실행 순서는 브라우저에 따라 다릅니다. 이 참조 기사 에서 Firefox의 동작을 확인할 수 있습니다 . 간단히 말해서, 최신 버전의 Firefox는 스크립트 태그가 다르게 설정되어 있지 않으면 기본적으로 비동기로 추가 된 스크립트 태그를 비동기로 설정합니다.
스크립트 태그 async
가로드 되 자마자 실행될 수 있습니다. 실제로 브라우저는 파서가 다른 작업을 중단하고 해당 스크립트를 실행할 수 있습니다. 따라서 거의 언제든지 실행할 수 있습니다. 스크립트가 캐시 된 경우 거의 즉시 실행될 수 있습니다. 스크립트를로드하는 데 시간이 걸리면 파서가 완료된 후에 실행될 수 있습니다. 기억해야 할 한 가지는 async
언제든지 실행할 수 있으며 그 시간은 예측할 수 없다는 것입니다.
스크립트 defer
파서는 전체 파서가 완료 될 때까지 기다렸다가 표시된 defer
순서대로 표시된 모든 스크립트를 실행합니다 . 이를 통해 서로 의존하는 여러 스크립트를로 표시 할 수 있습니다 defer
. 문서 파서가 완료 될 때까지 모두 연기되지만, 종속성을 유지하는 순서대로 실행됩니다. defer
스크립트가 파서가 완료된 후에 처리 될 대기열에 놓인 것처럼 생각 합니다. 기술적으로 브라우저는 언제든지 백그라운드에서 스크립트를 다운로드 할 수 있지만 파서가 페이지를 구문 분석하고 defer
또는 로 표시되지 않은 인라인 스크립트를 구문 분석하고 실행할 때까지 파서를 실행하거나 차단하지 않습니다 async
.
이 기사의 인용문은 다음과 같습니다.
스크립트 삽입 스크립트는 IE 및 WebKit에서 비동기 적으로 실행되지만 Opera 및 4.0 이전 Firefox에서는 동 기적으로 실행됩니다.
HTML5 사양의 관련 부분 (최신 호환 브라우저 용)은 여기에 있습니다 . 비동기 동작에 대해 많은 글이 있습니다. 분명히이 사양은 동작을 확인하기 위해 테스트해야 할 구형 브라우저 (또는 잘못된 확인 브라우저)에는 적용되지 않습니다.
HTML5 사양에서 인용 한 내용 :
그런 다음 상황을 설명하는 다음 옵션 중 첫 번째 옵션을 따라야합니다.
요소에 src 속성이 있고 요소에 지연 속성이 있고 요소에 "parser-inserted"로 플래그가 지정되고 요소에 비동기 속성 이 없는 경우 요소는 목록의 끝에 추가되어야합니다. 문서가 요소를 만든 파서의 문서와 관련된 구문 분석을 마쳤을 때 실행될 스크립트.
페치 알고리즘이 완료되면 네트워킹 태스크 소스가 태스크 큐에 배치하는 태스크는 요소의 "구문 분석기 실행 준비"플래그를 설정해야합니다. 파서는 스크립트 실행을 처리합니다.
요소에 src 속성이 있고 요소에 "parser-inserted"로 플래그가 지정되고 요소에 비동기 속성 이 없는 경우 요소는 요소를 작성한 구문 분석기 문서의 보류중인 구문 분석 차단 스크립트입니다. (문서 당 한 번에 하나의 스크립트 만있을 수 있습니다.)
페치 알고리즘이 완료되면 네트워킹 태스크 소스가 태스크 큐에 배치하는 태스크는 요소의 "구문 분석기 실행 준비"플래그를 설정해야합니다. 파서는 스크립트 실행을 처리합니다.
요소에 src 속성이없고 요소가 "parser-inserted"로 플래그가 지정되고 스크립트 요소를 작성한 HTML 구문 분석기 또는 XML 구문 분석기의 문서에 스크립트를 차단하는 스타일 시트 가있는 경우 요소는 요소를 만든 파서의 Document에 대한 보류중인 파싱 차단 스크립트 (문서 당 한 번에 하나의 스크립트 만있을 수 있습니다.)
요소의 "파서 실행 준비"플래그를 설정하십시오. 파서는 스크립트 실행을 처리합니다.
요소에 src 속성이 있고 async 속성이없고 "force-async"플래그가 설정되어 있지 않은 경우 가능한 빨리 연관된 순서대로 실행할 스크립트 목록 끝에 요소를 추가해야합니다. 스크립트 알고리즘 준비가 시작될 때 스크립트 요소의 문서와 함께.
페치 알고리즘이 완료되면 네트워킹 태스크 소스가 태스크 큐에 배치하는 태스크는 다음 단계를 실행해야합니다.
요소가 이제 스크립트 목록에서 첫 번째 요소가 아닌 경우 위에 추가 된 순서대로 실행되는 경우 요소를 준비된 것으로 표시하지만 아직 스크립트를 실행하지 않고이 단계를 중단하십시오.
실행 :이 스크립트 목록에서 첫 번째 스크립트 요소에 해당하는 스크립트 블록을 가능한 빨리 순서대로 실행하십시오.
이 스크립트 목록에서 가능한 빨리 순서대로 실행될 첫 번째 요소를 제거하십시오.
가능한 빨리 순서대로 실행할이 스크립트 목록이 여전히 비어 있지 않고 첫 번째 항목이 이미 준비된 것으로 표시되어 있으면 실행 레이블이 지정된 단계로 건너 뜁니다.
요소에 src 속성 이있는 경우 스크립트 알고리즘 준비가 시작될 때 스크립트 요소의 문서에서 가능한 빨리 실행되는 스크립트 세트에 요소를 추가해야합니다.
페치 알고리즘이 완료되면 네트워킹 태스크 소스가 태스크 큐에 배치하는 태스크는 스크립트 블록을 실행 한 다음 가능한 빨리 실행되는 스크립트 세트에서 요소를 제거해야합니다.
그렇지 않으면 다른 스크립트가 이미 실행중인 경우에도 사용자 에이전트가 즉시 스크립트 블록을 실행해야합니다.
Javascript 모듈 스크립트는 type="module"
어떻습니까?
Javascript는 이제 다음과 같은 구문으로 모듈 로딩을 지원합니다.
<script type="module">
import {addTextToBody} from './utils.mjs';
addTextToBody('Modules are pretty cool.');
</script>
또는 src
속성이있는 경우 :
<script type="module" src="http://somedomain.com/somescript.mjs">
</script>
모든 스크립트 type="module"
에는 defer
속성 이 자동으로 부여됩니다 . 그러면 페이지를로드 할 때 병렬로 (인라인이 아닌 경우) 다운로드 한 다음 파서가 완료된 후 순서대로 실행됩니다.
모듈 스크립트 async
에는 파서가 완료 될 때까지 기다리지 않고 async
다른 스크립트와 비교하여 특정 순서로 스크립트 를 실행하지 않고 가능한 빨리 인라인 모듈 스크립트를 실행 하는 속성이 제공 될 수 있습니다 .
이 기사의 Javascript Module Loading 에서 모듈 스크립트를 포함하여 다양한 스크립트 조합의 페치 및 실행을 보여주는 매우 유용한 타임 라인 차트가 있습니다.
브라우저는 스크립트를 찾은 순서대로 실행합니다. 외부 스크립트를 호출하면 스크립트가로드되고 실행될 때까지 페이지가 차단됩니다.
이 사실을 테스트하려면 :
// file: test.php
sleep(10);
die("alert('Done!');");
// HTML file:
<script type="text/javascript" src="test.php"></script>
동적으로 추가 된 스크립트는 문서에 추가 되 자마자 실행됩니다.
이 사실을 테스트하려면 :
<!DOCTYPE HTML>
<html>
<head>
<title>Test</title>
</head>
<body>
<script type="text/javascript">
var s = document.createElement('script');
s.type = "text/javascript";
s.src = "link.js"; // file contains alert("hello!");
document.body.appendChild(s);
alert("appended");
</script>
<script type="text/javascript">
alert("final");
</script>
</body>
</html>
경고의 순서는 "추가"-> "hello!"입니다. -> "최종"
스크립트에서 아직 도달하지 않은 요소 (예 :)에 액세스하려고 <script>do something with #blah</script><div id="blah"></div>
하면 오류가 발생합니다.
전반적으로 예, 외부 스크립트를 포함시킨 다음 해당 함수 및 변수에 액세스 할 수 있지만 현재 <script>
태그 를 종료하고 새 태그를 시작하는 경우에만 가능합니다 .
@addyosmani 의 훌륭한 요약
https://addyosmani.com/blog/script-priorities/ 에서 뻔뻔스럽게 복사
많은 옵션을 테스트 한 후 다음과 같은 간단한 솔루션이 모든 최신 브라우저에서 추가 된 순서대로 동적으로로드 된 스크립트를로드하는 것으로 나타났습니다
loadScripts(sources) {
sources.forEach(src => {
var script = document.createElement('script');
script.src = src;
script.async = false; //<-- the important part
document.body.appendChild( script ); //<-- make sure to append to body instead of head
});
}
loadScripts(['/scr/script1.js','src/script2.js'])
참고 URL : https://stackoverflow.com/questions/8996852/load-and-execute-order-of-scripts
'IT story' 카테고리의 다른 글
MongoDB의 쉘에서 20 개 이상의 항목 (문서)을 인쇄하는 방법은 무엇입니까? (0) | 2020.04.10 |
---|---|
Java에서 해시 맵을 JSON 객체로 변환하는 방법 (0) | 2020.04.10 |
FOR 루프와 IF 문을 결합하는 파이썬 방식 (0) | 2020.04.09 |
ValueError : 기본 10 인 int ()에 대한 잘못된 리터럴 : '' (0) | 2020.04.09 |
요소에 BOTH 클래스가있는 경우에만 적용 할 CSS 규칙 (0) | 2020.04.09 |