나는 보통 html파일에 .js파일을 연결시킬때 태그 맨 밑에 사용한다. 하지만 태그 맨 밑에 넣는 이유를 정확히 모르고 사용했기 때문에 이를 정리해보았다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="main.js"></script>
</head>
<body>
</body>
</html>
head 태그 맨 밑에 포함될 경우는 html파일이 파싱을 하다가 script 파일을 발견하면 parsing을 멈추고 .js파일을 다운받게 된다. 이 때 .js파일 다운을 완료한 후에 html파일이 실행 되므로 사용자가 내 웹사이트를 보는데 까지 시간이 오래 걸린다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script src="main.js"></script>
</body>
</html>
body태그 마지막에 js파일을 추가하는 방법의 작동순서는 html파일이 파싱하다가 js파일을 마지막에 실행하는 순서로 자신의 웹사이트가 동적이고 많이 꾸며준 웹사이트일수록 js실행되는 시간이 오래걸리는 단점이 있다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="main.js" async></script>
</head>
<body>
</body>
</html>
async 속성은 스크립트가 나머지 페이지와는 비동기적으로 실행됨을 나타내는 속성이며 불리언 타입이기 때문에 선언하는 것만으로도 true값을 얻는다.
async속성이 있으면 html이 파싱하다가 js파일이 있으면 다운을 받으라는 명령을 내리고 js파일이 다운 완료되면 html 파싱을 멈추고 다운된 js파일을 실행한다.
장점: 파싱과 js다운이 동시에 되므로 다운받는 시간을 절약할 수 있다.
단점: js다운이 완료되면 실행을 먼저 시키기 때문에 파싱이 완료되기도 전에 js파일이 실행되어 js파일 안에 querySeletor로 지정된 html파일 을 못찾을 수도 있다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="main.js" defer></script>
</head>
<body>
</body>
</html>
defer속성은 async속성과 마찬가지로 불리언 타입이며 html이 파싱을 하다가 js파일을 발견하면 다운을 받으라는 명령만 내린 후 파싱을 계속 한다.
파싱이 끝날때 쯤이면 명령을 내린 .js파일 다운이 완료되게 된다.
js파일을 다운받는 시간도 절약하고 html파싱도 완료되었기 때문에 defer 속성이 가장 효율적이다.