HTML 문서에 JavaScript를 포함시킬 때 <script>
태그와 포함 된 JavaScript 를 넣을 적절한 위치는 어디 입니까? 나는 당신이 <head>
섹션에 이것을 배치해서는 안된다는 것을 기억하는 것 같지만 <body>
, 페이지가 완전히 렌더링되기 전에 JavaScript를 파싱해야하기 때문에 섹션 의 시작 부분에 배치하는 것도 좋지 않습니다. 이것은 떠날 것으로 보인다 끝 의 <body>
에 대한 논리적 장소로 섹션 <script>
태그를.
그렇다면 태그 를 넣을 올바른 장소 는 어디 <script>
입니까?
(이 질문은 참고 문헌 이 질문 은 자바 스크립트 함수 호출에서 이동해야한다고 제안되었던, <a>
에 태그 <script>
내가 특별히 jQuery를 사용하고 있습니다. 태그하지만,보다 일반적인 답변은 또한 적절한됩니다.)
답변
브라우저가 <script>
태그가 있는 웹 사이트를로드하면 어떻게됩니까 ?
- HTML 페이지를 가져옵니다 (예 : index.html)
- HTML 파싱 시작
- 파서가
<script>
외부 스크립트 파일을 참조하는 태그를 발견했습니다 . - 브라우저가 스크립트 파일을 요청합니다. 그 동안 파서는 페이지의 다른 HTML 파싱을 차단하고 중지합니다.
- 얼마 후 스크립트가 다운로드되어 실행됩니다.
- 구문 분석기는 나머지 HTML 문서를 계속 구문 분석합니다.
4 단계는 사용자 경험을 저하시킵니다. 웹 사이트는 기본적으로 모든 스크립트를 다운로드 할 때까지로드를 중지합니다. 사용자가 싫어하는 것이 있다면 웹 사이트가로드되기를 기다리는 것입니다.
왜 이런 일이 발생합니까?
모든 스크립트는 document.write()
다른 DOM 조작을 통해 자체 HTML을 삽입 할 수 있습니다 . 이는 파서가 스크립트가 다운로드되어 실행될 때까지 기다려야 문서의 나머지 부분을 안전하게 파싱 할 수 있습니다. 결국, 스크립트 는 문서에 자체 HTML을 삽입했을 수 있습니다.
그러나 대부분의 JavaScript 개발자 는 문서가로드 되는 동안 더 이상 DOM 을 조작하지 않습니다 . 대신 문서를로드하기 전에 문서를 수정하기 전에 기다립니다. 예를 들면 다음과 같습니다.
<!-- index.html -->
<html>
<head>
<title>My Page</title>
<script src="my-script.js"></script>
</head>
<body>
<div id="user-greeting">Welcome back, user</div>
</body>
</html>
자바 스크립트 :
// my-script.js
document.addEventListener("DOMContentLoaded", function() {
// this function runs when the DOM is ready, i.e. when the document has been parsed
document.getElementById("user-greeting").textContent = "Welcome back, Bart";
});
브라우저가 my-script.js가 문서를 다운로드하여 실행할 때까지 문서를 수정하지 않는다는 것을 모르기 때문에 파서는 구문 분석을 중지합니다.
낡은 추천
이 문제를 해결하는 기존의 접근 방식 <script>
은의 맨 아래에 태그 를 넣는 <body>
것이 었습니다. 이는 파서가 끝날 때까지 차단되지 않기 때문입니다.
이 방법에는 자체 문제가 있습니다. 전체 문서를 파싱 할 때까지 브라우저에서 스크립트 다운로드를 시작할 수 없습니다. 큰 스크립트 및 스타일 시트가있는 더 큰 웹 사이트의 경우 가능한 빨리 스크립트를 다운로드 할 수 있어야 성능이 매우 중요합니다. 웹 사이트가 2 초 이내에로드되지 않으면 사람들은 다른 웹 사이트로 이동합니다.
최적의 솔루션에서 브라우저는 가능한 한 빨리 스크립트를 다운로드하기 시작하면서 동시에 나머지 문서를 구문 분석합니다.
현대적인 접근
오늘날 브라우저 는 스크립트 에서 async
및 defer
속성을 지원합니다 . 이러한 속성은 스크립트가 다운로드되는 동안 브라우저를 구문 분석하는 것이 안전하다는 것을 브라우저에 알려줍니다.
비동기
<script src="path/to/script1.js" async></script>
<script src="path/to/script2.js" async></script>
async 속성을 가진 스크립트는 비동기 적으로 실행됩니다. 즉, 스크립트는 다운로드하는 즉시 브라우저를 차단하지 않고 실행됩니다.
이는 스크립트 1보다 먼저 스크립트 2를 다운로드하여 실행할 수 있음을 의미합니다.
http://caniuse.com/#feat=script-async 에 따르면 모든 브라우저의 97.78 %가이를 지원합니다.
연기하다
<script src="path/to/script1.js" defer></script>
<script src="path/to/script2.js" defer></script>
defer 속성을 가진 스크립트가 순서대로 실행됩니다 (즉, 첫 번째 스크립트 1, 그런 다음 스크립트 2). 또한 브라우저를 차단하지 않습니다.
비동기 스크립트와 달리 지연 스크립트는 전체 문서가로드 된 후에 만 실행됩니다.
http://caniuse.com/#feat=script-defer 에 따르면 모든 브라우저의 97.79 %가이를 지원합니다. 98.06 %가 최소한 부분적으로 지원합니다.
브라우저 호환성에 대한 중요한 참고 사항 : 일부 상황에서 IE <= 9는 지연된 스크립트를 순서대로 실행할 수 있습니다. 당신이 그 브라우저를 지원해야하는 경우, 읽어 보시기 바랍니다 이 처음!
결론
현재의 최신 기술은 <head>
태그 에 스크립트를 넣고 async
또는 defer
속성을 사용하는 것입니다. 이를 통해 브라우저를 차단하지 않고도 스크립트를 최대한 빨리 다운로드 할 수 있습니다.
좋은 점은 웹 사이트가 이러한 속성을 지원하지 않는 다른 2 %의 브라우저에서 여전히 98 %의 속도를 유지하면서 올바르게로드되어야한다는 것입니다.
답변
에 표시된대로 닫는 본문 태그 바로 앞에
http://developer.yahoo.com/performance/rules.html#js_bottom
스크립트를 맨 아래에 놓으십시오
스크립트로 인한 문제는 병렬 다운로드를 차단한다는 것입니다. HTTP / 1.1 사양은 브라우저가 호스트 이름 당 2 개 이하의 구성 요소를 동시에 다운로드 할 것을 제안합니다. 여러 호스트 이름에서 이미지를 제공하는 경우 두 개 이상의 다운로드가 동시에 발생할 수 있습니다. 그러나 스크립트를 다운로드하는 동안 브라우저는 다른 호스트 이름에서도 다른 다운로드를 시작하지 않습니다.
답변
비 차단 스크립트 태그는 다음과 같은 곳에 배치 할 수 있습니다.
<script src="script.js" async></script>
<script src="script.js" defer></script>
<script src="script.js" async defer></script>
async
스크립트는 사용 가능한 즉시 비동기식으로 실행됩니다defer
문서 파싱이 끝나면 스크립트가 실행됩니다.async defer
비동기가 지원되지 않으면 스크립트가 지연 동작으로 폴백
이러한 스크립트는 문서 준비 후 / 비동기 적으로 실행되므로 다음을 수행 할 수 없습니다.
<script src="jquery.js" async></script>
<script>jQuery(something);</script>
<!--
* might throw "jQuery is not defined" error
* defer will not work either
-->
아니면 이거:
<script src="document.write(something).js" async></script>
<!--
* might issue "cannot write into document from an asynchronous script" warning
* defer will not work either
-->
아니면 이거:
<script src="jquery.js" async></script>
<script src="jQuery(something).js" async></script>
<!--
* might throw "jQuery is not defined" error (no guarantee which script runs first)
* defer will work in sane browsers
-->
아니면 이거:
<script src="document.getElementById(header).js" async></script>
<div id="header"></div>
<!--
* might not locate #header (script could fire before parser looks at the next line)
* defer will work in sane browsers
-->
그러나 비동기 스크립트는 다음과 같은 장점을 제공합니다.
- 리소스의 병렬 다운로드 :
브라우저는 스크립트가 다운로드되어 실행될 때까지 기다리지 않고도 스타일 시트, 이미지 및 기타 스크립트를 병렬로 다운로드 할 수 있습니다. - 소스 순서 독립성 :
차단에 대해 걱정하지 않고 스크립트를 헤드 나 바디에 배치 할 수 있습니다 (CMS를 사용하는 경우 유용). 그래도 실행 순서는 중요합니다.
콜백을 지원하는 외부 스크립트를 사용하여 실행 순서 문제를 피할 수 있습니다. 많은 타사 JavaScript API는 이제 비 차단 실행을 지원합니다. 다음은 Google Maps API를 비동기 적 으로 로드 하는 예입니다 .
답변
야후! 뛰어난 성능 팀은 <script>
태그를 문서 본문의 끝에 배치 하여 페이지 렌더링을 차단하지 않는 것입니다.
그러나 Google 웹 로그 분석 자바 스크립트 파일의로드 시간에 대한 이 답변 에 설명 된 것처럼 더 나은 성능을 제공하는 몇 가지 새로운 방법이 있습니다 .
Steve Souders (클라이언트 측 성능 전문가)의 다음과 같은 훌륭한 슬라이드 가 있습니다.
- 외부 JavaScript 파일을 병렬로로드하는 다양한 기술
- 로딩 시간 및 페이지 렌더링에 미치는 영향
- 브라우저에 표시되는 “진행 중”표시기 (예 : 상태 표시 줄에 ‘로드 중’, 모래 시계 마우스 커서)
답변
JQuery를 사용 $(document).ready()
하는 경우 가장 좋은 곳에 자바 스크립트를 배치하고 함수를 실행하기 전에 항목이 올바르게로드되는지 확인하십시오.
참고 사항 : <head>
섹션의 모든 스크립트 태그 가 가장 깨끗한 위치 인 것처럼 보입니다.
답변
2019 년의 최신 접근 방식은 ES6 모듈 유형 스크립트를 사용하는 것 입니다.
<script type="module" src="..."></script>
기본적으로 모듈은 비동기 적으로로드되고 지연됩니다. 즉, 어느 곳에 나 배치 할 수 있으며 페이지로드가 끝나면 병렬로로드되어 실행됩니다.
스크립트와 모듈의 차이점은 다음과 같습니다.
https://stackoverflow.com/a/53821485/731548
스크립트와 비교 한 모듈 실행은 다음과 같습니다.
https://developers.google.com/web/fundamentals/primers/modules#defer
지원은 다음과 같습니다.
답변
스크립트가 head 요소 이외의 다른 곳에 있으면 XHTML은 유효성을 검사하지 않습니다. 그것은 어디에나있을 수 있습니다.
jQuery와 같은 것을 사용하여 실행을 연기 할 수 있으므로 구문 분석 중 약간의 성능 저하를 제외하고는 위치에 관계가 없습니다.