HTML에서 스크립트를 직접 작성하지 않고 외부 스크립트 파일을 로드할 때 로드 방법에 대해 알아보도록 한다.
스크립트 삽입
HTML페이지에서 외부 스크립트 파일은 보통 아래와 같은 코드를 삽입하여 가져오게 된다.
<script src="script.js"></script>
HTML 페이지를 파싱(Parsing) 하는 중 위와 같은 코드를 만나게 되면 DOM 생성을 멈추고 스크립트파일 다운로드를 진행하게 된다. 그리고 스크립트 파일 다운로드가 완료되고 나서야 다시 파싱을 재개하게 되는데 여기서 중요한 건 스크립트 삽입 위치에 따라 렌더링 시간이 달라진다는 사실이다. 각기 다른 삽입 위치와 속성에 따른 렌더링 시간의 차이에 대해 알아보자.
1. <body>에 포함시킬 경우
2. <head>에 포함시킬 경우
1) 속성이 없는 경우
2) async 속성을 사용한 경우
3) defer 속성을 사용한 경우
1. <body> 에 포함시킬 경우
처음으로는 DOM을 먼저 생성할 수 있도록 <body>의 하단에 스크립트태그를 넣어주는 경우이다.
<!DOCTYPE html>
<html lang="ko">
<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=""></script>
</body>
</html>
위와 같이 HTML 페이지를 파싱을 먼저 진행하고 JS파일을 받아오고 실행하게 된다.
<body>에 삽입하게 될 경우 화면 렌더링에서는 좀 더 효과적일 수 있으나
HTML파일 크기가 큰 경우에는 JS가 포함된 의미있는 콘텐츠를 보기 위해서는 너무 오래 걸릴 것이다.
2-1. <head> 에 포함시킬 경우(속성 설정 없음)
다음으로는 HTML <head>에 속성 설정없이 삽입했을 경우이다.
<!DOCTYPE html>
<html lang="ko">
<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=""></script>
</head>
<body>
<div>
<div>
</body>
</html>
위와 같이 <head>에 삽입할 경우, 아래의 그림과 같이 HTML 페이지를 파싱하던 중 js파일을 받아오고(Fetching), 실행(Executing)한 뒤 다시 페이지를 파싱하게 된다.
이럴 경우, JS파일 크기가 엄청나게 클 경우 렌더링이 너무 오래 걸리게 되어 사용자가 페이지를 보기까지 너무 오래걸리게 될 것이다. 그러므로 <head>에 스크립트 파일을 포함하는 것은 좋은 방법이라고 할 수 없다.
async와 defer은 HTML5에 새로 추가된 <script> 속성이다.
이 두가지 속성은 HTML파싱과 스크립트 다운로드를 병렬로 진행한다.
2-2. <head> 에 포함시킬 경우(async 속성 사용)
async 속성은 아래와 같이 <head>에 <script>를 async 속성과 함께 사용하게 된다.
<!DOCTYPE html>
<html lang="ko">
<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 async src=""></script>
</head>
<body>
<div>
<div>
</body>
</html>
async 속성은 파싱과 JS 불러오기를 병렬적으로 진행한다.
병렬적으로 진행하기에 기존 방법보다는 다운로드 시간이 절약되어 효율적이다. 하지만 JS를 실행하는 단계에서는 파싱을 중지하게 되고 JS실행이 끝나면 다시 파싱을 재시작 하게 되기 때문에 HTML이 모두 실행되기 전에 JS가 실행되게 된다.
다수의 스크립트 파일을 다운로드 받게되면 다운로드가 완료되는 순으로 JS파일을 실행하기 때문에 순서에 상관없이 실행하게 된다. 만약 순서에 의존적인 페이지라면 문제가 될 수 있기 때문에 유의해야한다.
2-3. <head> 에 포함시킬 경우(defer 속성 사용)
defer 속성은 async 속성과 마찬가지로 <head>에 <script>를 defer 속성과 함께 사용하게 된다.
병렬적으로 파싱과 JS 불러오기를 진행하게 되고 파싱이 모두 끝나면 JS를 실행한다.
<!DOCTYPE html>
<html lang="ko">
<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 defer src=""></script>
</head>
<body>
<div>
<div>
</body>
</html>
병렬적으로 진행되기 때문에 다운로드 시간이 절약되고 async 속성과는 다르게 파싱하는 중에 JS파일을 모두 다운로드 받아놓고 파싱이 끝난 후 순서대로 JS파일을 실행하기 때문에 원하는 방향대로 스크립트를 실행할 수 있다.
결론 : 외부 스크립트를 불러올 때는 defer 속성을 사용
* 참조 *
'Frontend > Javascript' 카테고리의 다른 글
[JavaScript] Strict Mode(엄격 모드) 적용하기 (0) | 2022.07.07 |
---|---|
[Javascript] for in VS for of (0) | 2022.06.18 |
[Javascript] for문 (0) | 2022.06.18 |
[Javascript] 모든 자식 엘레멘트 삭제하기(Removing all children using Dom) (0) | 2022.06.18 |
[Javascript] 문(statement)와 표현식(expression)이란? (0) | 2022.02.08 |
최근댓글