HTML, CSS까지 배우고, JavaScript를 배우기 시작한 분이라면 누구나 한번쯤은 이런 고민을 해보았을 것이다. 필자도 매번 궁금해했던 것이었다 ! 🙄
HTML과 JavaScript를 연결하는 방법은 다양하다. 보통 이 두가지 방법을 사용한다.
1. HTML 파일 내에서 <script> </script>
태그를 이용하여 JavaScript 코드를 작성하는 방법
2. 따로 .js
파일을 만들고 JavaScript 파일과 HTML 파일을 연결하는 방법
그런데, 공부를 하다보면 누구는 <head> </head>
태그 안에서 연결을 하기도 하고, 또 누구는 <body> </body>
안에서 연결하기도 한다.
정답부터 말하자면 달라진다. 연결 위치가 은근히 큰 영향을 미친다.
<head></head>
안에 script가 포함된 경우<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 이곳에서 포함됨 -->
<script src="./main.js"></script>
</head>
<body>
</body>
</html>
script 태그
를 만나면 파싱을 멈추고 main.js
파일을 다운받음.js
를 바로 실행하고, 실행이 끝나면 다시 HTML 파일을 파싱만약 인터넷이 굉장히 느리고, .js
의 용량이 굉장히 크면 사용자가 내 웹사이트를 보기까지 굉장히 오랜 시간이 걸릴 것
⇒ 때문에 <head>
안에 script를 포함하는 것은 좋지 않은 방법
<body>
태그 안쪽 마지막 부분에 script를 추가한 경우<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div></div>
<!-- 이곳에서 포함됨 -->
<script src="./main.js"></script>
</body>
</html>
script
태그를 만나면 서버에서 .js
를 다운로드받고 다운이 끝나면 .js
를 실행함.js
를 받기도 전에 이미 페이지가 준비되어 있기 때문만약 내 웹사이트가 .js
에 굉장히 의존적인 경우
(사용자가 의미있는 컨텐츠를 보려면 .js
를 이용해 서버에서 데이터를 받아오는 경우)
(.js
에서 DOM 요소를 꾸며주는 게 많은 경우)
⇒ 사용자가 정상적으로 웹사이트를 보기까지 오랜 시간이 소요됨
<head>
+ async
이용 시📢
async
는 boolean 타입의 속성값이기 때문에 선언하는 것만으로도 true로 설정되어async
를 사용할 수 있음
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- async 추가 부분-->
<script async src="./main.js"></script>
</head>
<body>
</body>
</html>
script 태그
에서 async
를 만나면, 병렬로 .js
파일을 다운로드 받기 시작.js
파일을 다운로드 받다가, .js
파일의 다운로드가 끝나면, html 파싱을 잠시 멈춤.js
를 실행하고, 실행이 끝나면 다시 남은 html 파일을 파싱html 파싱이 완료되기 전에 .js
파일이 실행되므로, .js
에서 querySelector로 DOM요소 조작 시 우리가 원하는 시점에 DOM 요소가 아직 정의되지 않았을 수도 있음
html을 파싱하는 동안 언제든지 .js
를 실행하기 위해 멈출 수 있음
→ 사용자가 페이지를 보기 전까지 또 다소 시간이 걸릴 수 있음
<head>
+ defer
이용 시<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- defer을 추가한 부분 -->
<script defer src="./main.js"></script>
</head>
<body>
</body>
</html>
script 태그
의 defer
을 만나면 .js
파일 다운로드를 시작하고, 계속 html 파일을 파싱함.js
를 실행async
와 defer
의 차이 🚨async
로 가져올 때📢 async를 사용하면 정의된 스크립트의 순서와 상관없이, 먼저 다운로드 된
.js
파일부터 실행함
⇒ 만약 내 프로그램이.js
실행 순서에 의존된다면 문제 발생 가능
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- async 추가한 부분 -->
<script async src="./a.js"></script>
<script async src="./b.js"></script>
<script async src="./c.js"></script>
</head>
<body>
</body>
</html>
defer
로 가져올 때📢 html을 파싱하다가 defer를 만나면 각
.js
파일을 다운로드하고, 파싱이 끝나면 정의된 순서대로 다운로드한.js
파일들을 실행함
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- defer 추가한 부분 -->
<script defer src="./a.js"></script>
<script defer src="./b.js"></script>
<script defer src="./c.js"></script>
</head>
<body>
</body>
</html>