티스토리 뷰
브라우저가 웹페이지를 읽을 때 HTML을 순서대로 읽으면서 CSS와 병합해서 DOM 요소로 변환을 하게 된다.
이 과정을 거쳐 만들어진 DOM을 JS를 통해 사용할 수가 있다.
(자세한 내용은 DOM에 대해 올린 글을 참조하면 된다.)
쉽게 설명하자면 HTML을 작성한 뒤 JS를 통해 코드를 작성하고자 할 때는 HTML과 JS를 연결시켜야 한다는 것이다.
HTML과 JS를 연결하는 방식은 아래와 같다.
-body 안에 script 태그를 넣기.
-head 안에 script 태그를 넣기.
-head 안에 async를 사용하기.
-head 안에 defer을 사용하기.
body 안에 script 태그를 넣기
아래 코드와 같이 HTML의 script 태그를 사용해서 src에 JS 파일의 경로를 작성하면 HTML과 JS를 연결시킬 수 있다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script src="practise.js"></script>
</body>
</html>
//practise.js 라는 파일을 연결 시켰다.
//이를 통해 이제 practise.js 파일에서 HTML의 요소를 가져오고 추가하고 삭제하면서 코드를 구현할 수 있게 된다.
*위와 같이 script 태그의 위치를 body에 넣는 경우 HTML을 먼저 전부 다 parsing 한 뒤에 JS를 불러온다.
이렇게 body 안에 넣는 케이스에는 장단점이 존재한다.
-장점: 사용자에게 웹사이트가 보여지는 속도가 빠르다.
-단점: 하지만 만약 해당 웹페이지가 js에게 의존적이어서 의미있는 컨텐츠를 보거나 사용자와 상호작용이 필요한 컨텐츠인 경우에는 정상적으로 동작하기까지 시간이 걸리게 된다. 그리고 JS를 읽기 전에 HTML을 읽기 때문에 JS에서 코드를 작성할 때 함수의 위치를 더욱 신경써서 배치해야 한다.
고로 이렇게 body 안에 넣는건 가장 좋은 방법이라고 할 수는 없다.
head 안에 script 태그를 넣기
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="practise.js"></script>
</head>
<body>
</body>
</html>
//이번에는 script 태그를 body가 아닌 head 안에 넣어줬다.
*위와 같이 body가 아닌 head에 script를 위치시킨 경우 HTML를 전부 parsing 한 뒤 JS를 불러오는 과정이 아닌 다른 과정을 통해 불러오게 된다.
브라우저가 HTML을 parsing → 도중에 head에 있는 script를 인식하게 되면 → HTML parsing을 잠시 멈추고 JS 내용을 fetching(다운로드), executing(실행)을 한 뒤에 → 다시 HTML parsing 재개 후 마무리를 한다.
즉 HTML을 먼저 읽어오는건 맞지만 중간에 JS를 만나면 parsing을 멈추고 JS를 불러온 뒤 나머지 HTML을 읽어오는 과정을 거치게 된다.
-장점: body에 넣을 때 보다는 JS의 요소를 더 빠르게 불러오기 때문에 JS에 의존적인 경우에 조금 더 유리할 수 있다.
-단점: JS의 파일의 용량이 클 경우 사용자가 완전한 웹페이지를 보기까지 시간이 엄청 오래 걸린다.
고로 이렇게 body가 아닌 head에 넣는다고 무조건 좋은 것은 아니다.
head 안에 async를 사용하기
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script async src="practise.js"></script>
</head>
<body>
</body>
</html>
//head 안에 script 태그에 acync를 추가해줬다.
//async는 boolean 타입의 속성 값이기 때문에 이렇게 선언하는 것만으로도 true로 설정이 되어서 위와 같이 선언만 하면 사용이 가능하다.
이렇게 acync를 추가하면 브라우저가 HTML을 parsing 하다가 script를 만나면 병렬적으로 JS를 fetching 시키고 동시에 HTML을 계속 읽는다. 읽는 도중에 JS의 fetching(다운)이 끝나면 그 때 HTML의 parsing을 멈추고 executing(실행)을 시킨다. 그 후에 나머지 HTML을 parsing 하게 된다.
즉 head에 acync를 넣었을 때와 비슷하지만 '병렬적으로' 동작하여 조금 더 빠르게 사용자에게 보여질 수 있게 된다.
-장점: body에 넣는 것보다는 빠르고 그냥 head에만 넣었을 때보다는 빠르다.
-단점: querySelector 같은 요소를 사용한 웹페이지면 HTML에서 해당 요소를 불러와야 하기 때문에 이를 기다리게 된다면 여전히 시간이 오래 걸리게 되고, HTML에서 이미 parsing이 끝난 부분에 JS가 필요한 코드였다면 제대로 동작하지 않을 위험이 있다. 그리고 script가 여러개일 경우 코드를 작성한 순서대로 실행이 되는게 아니라 먼저 다운받은 순서대로 실행이 되기 때문에 만약 순서에 의존적이라면 이는 문제가 될 수 있다.
head 안에 defer을 사용하기
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script defer src="practise.js"></script>
</head>
<body>
</body>
</html>
//head 안에 script 태그에 defer을 추가해줬다.
이렇게 defer을 넣으면 브라우저가 HTML을 parsing 하다가 script를 만나면 JS를 fetching 시켜놓고 HTML parsing을 전부 마무리 한 뒤에, JS를 executing 하게 된다. acync과 달리 JS의 fetching이 완료되었다고 해서 HTML parsing을 도중에 또 멈추지 않는다.
-장점: script가 여러개일 경우에도 어차피 HTML parsing이 다 끝난 뒤에 executing을 하기 때문에 먼저 fetching이 되는 것과 상관 없이 작성된 순서대로 실행이 된다.
*한 줄 요약
=> defer을 사용할 때 가장 효율적이고 코드를 작성하기 편리하다는 것을 알 수 있다.
'기술 노트' 카테고리의 다른 글
DB Index란? (0) | 2023.03.28 |
---|---|
컴퓨터의 구조와 OS의 관계 (0) | 2023.03.21 |
모듈을 Import 할 때 { }(중괄호)를 쓰는 경우와 아닌 경우(Node.js) (0) | 2023.03.15 |
DOM이란? (0) | 2023.03.11 |
IP란? (0) | 2023.03.09 |