
일반적으로 html에 script를 추가한 코드들을 보면 body태그 안의 마지막 child로 들어가 있는 것을 자주 봐 왔을 것이다. 그 이유가 뭘까?
html 안의 body에서는 위에서부터 파싱을 시작한다.
여기서 Script를 만나면 Script 내부 설정한 요소에 따라서 파싱의 순서가 바뀌게 된다.
Script 요소로는 공백, async, defer 이 있고 각각의 특징으로는 다음과 같다.
공백 : html 파싱을 중단하고 js를 먼저 불러온다.
async : html 파싱과 js를 병렬적으로 가져온다.
defer : async와 마찬가지로 병렬적으로 가져오지만 html 파싱이 끝나야 js가 실행된다.
빈 js 파일을 만들고 html을 구성하였다.
<body>
<script src="./index.js"></script>
<h1>안녕하세요.</h1>
<h1>두 번 안녕하세요.</h1>
</body>
그 후 js를 개발자 모드로 break를 걸어준 후 결과값을 보면
Script를 만나 파싱이 중단되어 아무것도 출력되지 않는다. 한 번 더 테스트를 해보자 이번엔 중간에 Script를 넣어보았다.
<body>
<h1>안녕하세요.</h1>
<script src="./index.js"></script>
<h1>두 번 안녕하세요.</h1>
</body>
코드를 이렇게 바꾸고 결괏값을 보면
위와 값이 첫 번째 태그만 파싱이 된 후 파싱이 중단되는 것을 확인할 수 있다.
이번엔 async를 붙이고 테스트를 해보았다.
<body>
<h1>안녕하세요.</h1>
<script async src="./index.js"></script>
<h1>두 번 안녕하세요.</h1>
</body>
결괏값을 보면
위와 같이 Script 코드가 있었음에도 병렬적으로 파싱이 되어 모든 태그가 출력이 되는 것을 확인 할 수 있다.
마지막으로 defer을 테스트 해보자.
<body>
<h1>안녕하세요.</h1>
<script defer src="./index.js"></script>
<h1>두 번 안녕하세요.</h1>
</body>
결괏값을 보면
async와 마찬가지로 병렬적으로 파싱이 되기 때문에 출력은 똑같이 되는 것을 확인 할 수 있다.
그러면 async, defer의 차이는 뭘까?
그 둘의 차이는 js파일이 여러 개일 때 나타난다.
index.js, index2.js .... 등등 여러개의 js가 있다고 가정할 때 async는 다운 받아지는 순서로 js를 로더하고 defer은 적은 Script 순서대로 로더한다.
기본적인 script를 사용할 때에 아무 문제 없이 사용하려면 script를 body 맨 마지막에 적거나 defer를 이용해야 한다. 여기서 async는 js끼리 순서관계를 명확히 힘들기 때문에 html가 관련된 js에서는 사용하지 않고 관련이 없는 애널리틱스 같은 거에 사용하면 좋을거 같다.