스크립트 로드 및 실행 순서
HTML 페이지에 JavaScript를 포함시키는 방법은 매우 다양합니다.다음 옵션에 대해 알고 있습니다.
- 인라인 코드 또는 외부 URI에서 로드됨
- <head> 또는 <body> 태그에 포함됨[1,2]
- , 없다
defer
★★★★★★★★★★★★★★★★★」async
만)(「」) - 정적 소스에 포함되거나 다른 스크립트에 의해 동적으로 추가됨(다른 해석 상태, 다른 메서드로)
javascript: 및 URI »onEvent
- 속성 [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"라는 플래그가 붙어 있고 요소에 비동기 속성이 없는 경우 이 요소는 문서가 작성한 파서의 문서와 연관된 해석을 완료했을 때 실행될 스크립트 목록의 끝에 추가해야 합니다.d 요소
가져오기 알고리즘이 완료되면 네트워킹 작업 원본이 작업 대기열에 배치하는 작업은 요소의 "파서 실행 준비 완료" 플래그를 설정해야 합니다.파서는 스크립트의 실행을 처리합니다.
요소에 src 속성이 있고 요소에 "parser-inserted" 플래그가 붙어 있고 요소에 비동기 속성이 없는 경우 요소는 요소를 만든 파서의 Document의 보류 중인 구문 분석 차단 스크립트입니다(한 번에 Document당 하나의 스크립트만 있을 수 있습니다).
가져오기 알고리즘이 완료되면 네트워킹 작업 원본이 작업 대기열에 배치하는 작업은 요소의 "파서 실행 준비 완료" 플래그를 설정해야 합니다.파서는 스크립트의 실행을 처리합니다.
요소에 src 속성이 없고 요소에 "parser-inserted" 플래그가 붙어 있고 스크립트 요소를 작성한 HTML 파서 또는 XML 파서의 문서에 스크립트를 차단하는 스타일시트가 있는 경우 요소는 요소를 생성한 파서의 문서의 보류 중인 구문 분석 차단 스크립트입니다(b만 가능).e 한 번에 문서당 1개의 스크립트가 있습니다.)
요소의 "Ready to be parser-executed" 플래그를 설정합니다.파서는 스크립트의 실행을 처리합니다.
요소에 src 속성이 있고 비동기 속성이 없으며 "force-async" 플래그가 설정되어 있지 않은 경우 스크립트알고리즘 준비 시작 시 스크립트 요소의 Document와 관련된 스크립트 목록의 끝에 가능한 한 빨리 요소를 추가해야 합니다.
가져오기 알고리즘이 완료되면 네트워킹 태스크 원본이 태스크 대기열에 배치하는 태스크는 다음 단계를 실행해야 합니다.
요소가 위에서 추가된 스크립트 목록에서 가능한 한 빨리 실행되는 첫 번째 요소가 아닌 경우 요소를 ready로 표시하지만 스크립트를 실행하지 않고 이러한 단계를 중단합니다.
실행:이 스크립트 목록의 첫 번째 스크립트 요소에 대응하는 스크립트블록을 가능한 한 빨리 실행합니다.
가능한 한 빨리 이 스크립트목록에서 첫 번째 요소를 삭제합니다.
가능한 한 빨리 실행되는 스크립트 목록이 아직 비어 있지 않고 첫 번째 엔트리가 이미 ready로 표시되어 있는 경우 execution이라는 라벨이 붙은 스텝으로 돌아갑니다.
요소에 src 속성이 있는 경우 스크립트알고리즘 준비 시작 시 스크립트 요소의 Document를 가능한 한 빨리 실행하는 스크립트세트에 요소를 추가해야 합니다.
취득 알고리즘이 완료되면 네트워킹태스크 소스가 태스크큐에 배치하는 태스크는 스크립트블록을 실행한 후 가능한 한 빨리 실행할 스크립트세트에서 요소를 삭제해야 합니다.
그렇지 않으면 다른 스크립트가 이미 실행되고 있는 경우에도 사용자 에이전트는 스크립트 블록을 즉시 실행해야 합니다.
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을 포함한 다양한 스크립트 조합의 가져오기 및 실행을 보여주는 매우 유용한 타임라인 차트가 있습니다.
@addyosmani의 훌륭한 요약
https://addyosmani.com/blog/script-priorities/에서 뻔뻔하게 복사
브라우저는 검색된 순서대로 스크립트를 실행합니다.외부 스크립트를 호출하면 스크립트가 로드되어 실행될 때까지 페이지가 차단됩니다.
이 사실을 테스트하려면:
// 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>
경보 순서는 "appended" -> "hello!" -> "final" 입니다.
하지 않은 " " " " " " " " " " " " " " " " " " " " " " " " ( ) :<script>do something with #blah</script><div id="blah"></div>
에러가 표시됩니다.
후 그 및 수 , 에만 해당 에 액세스할 수 있습니다.<script>
이치노
많은 옵션을 테스트한 결과, 다음의 간단한 솔루션이 최신 브라우저에 추가된 순서대로 동적으로 로드된 스크립트를 로드하고 있음을 알 수 있었습니다.
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'])
온로드 이벤트가 발생하기 전에 임베디드 모듈 스크립트를 실행하는 방법을 이해할 수 없었습니다.위의 답변은 많은 도움이 되었지만, "스크립트의 로드 및 실행 순서"를 오해하는 저의 특별한 문제를 해결한 부분에 대해 부분적인 답변을 추가하겠습니다.
처음 사용했을 때는...정상적으로 페이지를 로드할 때는 정상적으로 동작하지만 FireFox의 디버거에서는 동작하지 않는 이상한 문제가 발생했습니다.이로 인해 디버깅이 매우 어려워졌습니다.
주의: 타입이 "module"인 스크립트에는 항상 암묵적인 "deferred" 속성이 있습니다.즉, html의 해석은 중지되지 않습니다.즉, 스크립트가 실행되기 전에 onload 이벤트가 발생할 수 있습니다.난 그걸 원하지 않았다.그러나 type="discript"를 사용하여 복구되지 않은 JavaScript 함수와 변수를 같은 페이지의 다른 스크립트에 보이지 않게 만들고 싶었습니다.
다른 옵션을 시도했지만 위의 답변 덕분에 유형 모듈의 스크립트에 비동기 속성을 추가하면 스크립트가 비동기적으로 로드되지만 로드되면 즉시 실행된다는 통찰력을 얻었습니다.
하지만 제 경우에는 HTML 페이지에 내장된 스크립트였습니다.따라서 "비동기적으로" 로딩할 필요가 없습니다.페이지는 이미 로딩되어 있었습니다.페이지가 내장되어 있었기 때문입니다.그래서 이 변경과 함께 즉시 실행이 되었습니다.그게 제가 원하던 것입니다.
따라서 이 구체적인 사례는 다소 직관에 반하기 때문에 지적할 가치가 있다고 생각합니다.내장된 스크립트를 즉시 실행하려면 태그에 ASynC 속성을 추가해야 합니다.
일반적으로 "async"는 즉시가 아니라 비동기적으로 어떤 일이 일어나는 것을 의미한다고 생각할 수 있습니다.그러나 "async"는 비동기 로딩의 원인이 되지만 로딩이 완료된 후 즉시 실행된다는 것을 깨달아야 합니다.스크립트가 내장되어 있으면 로딩이 필요 없기 때문에 즉시 실행할 수 있습니다.
요약:.사용하다
<script type="module" async> ... </script>
모듈 스크립트를 HTML 페이지에 삽입하여 즉시 실행할 수 있습니다.
당신의 질문에 딱 들어맞는군요!
만약 어떤 해결책도 효과가 없다면, 제가 제 쪽에서 개발한 아래의 솔루션을 참조해 주십시오.
저도 해결책을 찾고 있었습니다만, 많이 검색한 결과, 아래와 같이 코드를 정리했습니다만, 저에게 딱 맞는 코드입니다!!
이 기능은 이전 스크립트가 완전히 로드된 후 다음 스크립트만 로드하는 기능을 원할 때 유용합니다.
jsLoadScripts.js라는 이름의 파일을 생성하여 머리 또는 본문 하단에 삽입하기만 하면 됩니다.
//From Shree Aum Software Solutions
//aumsoftwaresolutions@gmail.com
//script incrementor for array
scriptIncrementor = 0;
//define your script urls here
let scripts = [
"https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js",
"jsGlobalFunctions.js",
"jsDateParser.js",
"jsErrorLogger.js",
"jsGlobalVariables.js",
"jsAjaxCalls.js",
"jsFieldsValidator.js",
"jsTableClickEvent.js",
"index.js",
"jsOnDocumentReady.js",
];
//it starts with the first script and then adds event listener to it. which will load another script on load of it. then this chain goes on and on by adding dynamic event listeners to the next scripts!
function initializeScripts() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = scripts[scriptIncrementor];
document.head.appendChild(script);
script.addEventListener("load", function () {
loadNextScript();
scriptIncrementor++;
});
}
// this function adds event listener to the scripts passed to it and does not allow next script load until previous one has been loaded!
function loadNextScript() {
if (scriptIncrementor != scripts.length - 1) {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = scripts[scriptIncrementor + 1];
document.head.appendChild(script);
script.addEventListener("load", function () {
loadNextScript();
scriptIncrementor++;
});
}
}
// start fetching your scripts
window.onload = function () {
initializeScripts();
};
로 인해 관련 할 수 "를 할 수 .initializeScripts()
★★★★★★★★★★★★★★★★★!
이 방법으로 문제가 해결되지 않으면 솔루션을 업그레이드하십시오.
감사해요!
언급URL : https://stackoverflow.com/questions/8996852/load-and-execute-order-of-scripts
'programing' 카테고리의 다른 글
변수 이름을 문자열로 가져오기 (0) | 2023.01.15 |
---|---|
로그인 폼에 CSRF 공격에 대한 토큰이 필요합니까? (0) | 2023.01.15 |
열 수가 행 1의 값 수와 일치하지 않습니다. (0) | 2023.01.15 |
PHP를 사용한 가장 간단한 양방향 암호화 (0) | 2023.01.15 |
Java에서 현재 날짜에 1개월을 추가하려면 어떻게 해야 하나요? (0) | 2023.01.15 |