몽탁이의 개발일기
script 태그 속성 async와 defer의 차이점 본문
script 태그는 javascrtip를 html에 작성하지 않고
따로 작성한 JS파일을 다운로드하고 실행시켜주는 태그입니다.
기본적인 script 태그의 동작은
브라우저가 HTML을 파싱을 하기되면 위에서부터 한 줄씩 파싱을 하게 됩니다.
그러다 script 태그를 만나게되면 HTML 파싱을 중단하고 JS파일을 다운로드하고 실행시켜준 뒤 다시 HTML을 파싱 하게 됩니다.
아래 그림은 script태그를 상단부분 <head></head> 사이에 정의했을 때 실행되는 순서입니다.
여기에는 문제점이 있습니다.
만약 JS파일의 크기가 크다면 HTML을 파싱을 하다가 중간에 JS파일 받는 틈이 생기기 때문에 사용자가 보는 화면이
완벽하게 출력이 되지않는 상황이 발생됩니다.
ex)
<head>
<script src="main.js"></script>
</head>
....
위와 같은 문제점을 해결하기 위해 몇가지 방법이 있습니다.
첫 번째, script 태그를 body 끝에 작성한다.
두 번째, script 속성인 async를 사용한다.
세 번째, script 속성인 defer를 사용한다.
이 세가지는 서로 차이점이 있습니다.
우선 첫번째인 body끝에 script를 작성하는 것은
ex)
....
<body>
<div class="container">
</div>
<script src="main.js"></script>
</body>
이 방식대로 한다면 HTML 파싱이 끝난 뒤 JS파일 다운로드하고 실행하게 됩니다.
하지만 여기에도 문제가 생길수 있습니다.
만약 웹사이트가 JavaScript에 의존적인 사이트라면
예를 들어, 사용자에게 의미 있는 데이터가 동적으로 변화해야 되거나 사용자가 요청했을 시 동적으로 데이터를 받아와야 되는 경우 등등
사용자가 JS파일을 다 받기 전까지는 문제가 생길 위험이 큽니다.
JS파일을 HTML 파싱을 끝 마친후 다운로드하는 걸로 보이는 부분에서는 해결이 되었지만 동적인 요소가 많다면 아직 문제가 생깁니다.
이번엔 이를 개선하기 위해
두번째 방법인 async 속성을 이용하는 방식은
ex)
<head>
<script async src="main.js"></script>
</head>
....
우선 async는 불리언 타입으로 true와 false로 값을 설정할 수 있습니다.
기본값은 true로 async라고만 작성하게 되면 적용이 되는 걸 볼 수 있습니다.
async 속성은 asynchronous(비동기)의 줄임말로 순차적으로 하나씩 진행되는것이 아닌 동시에 작업이 진행이 됩니다.
위 그림과 같이 HTML을 파싱을 하다가 async속성을 지닌 script를 만나게 되면 JS파일을 다운받는 동시에 HTML의 parsing도 같이 진행이 됩니다.
그리고 JS파일을 전부 다운받게되면 parsing을 잠깐 멈추고 JS파일을 실행시킨 후 다시 parsing을 하여 마무리를 짓게 됩니다.
JS파일을 다운과 HTML 파싱을 동시에 진행하여 속도적인 측면에서 기본방식과 첫 번째 방식에 비해 빨라집니다.
이 방식에도 여전히 문제점이 있습니다.
예를들어 HTML파싱이 끝나지 않은 상태에서 사용자가 돔 요소를 동적으로 바꾸게 된다면 아직 파싱이 되지 않은
HTML을 건드리게 되는 문제점이 발생하게 됩니다.
이제 마지막으로
세 번째 방식인 defer속성을 이용하는 방법은
ex)
<head>
<script defer src="main.js"></script>
</head>
defer 속성도 async와 마찬가지로 불리언 타입이면서 기본값을 true을 가지고 있습니다.
defer 속성은 위 그림과 같이 HTML parsing과 JS파일 다운이 동시에 진행됩니다.
그 후 async와 다르게 HTML 파싱을 모두 끝낸 후 JS파일을 실행하게 됩니다.
이런 방식으로 하게 되면 사용자에게 완전히 파싱 된 HTML을 보여주게 되어 기본적인 방식에서 나타나는 문제점을 해결하게 됩니다.
또 JS파일을 미리 받기 때문에 첫 번째 방식에서 나타나는 문제점이 해결되고
마지막으로 JS파일의 실행을 모든 파싱과 다운로드가 끝난 시점에서 하기 때문에 두 번째 방식에서 나타나는 문제점 또한 해결이 됩니다.
결론적으로는,
defer속성이 가장 안전하며 현재 가장 많이 사용되고 있습니다.
앞으로는 defer를 이용하여 javascript 파일을 실행시키는 것이 좋습니다.
추가적으로,
JS파일이 여러 개여서 script태그를 여러개 쓰는 경우
async와 defer의 차이점
async는 HTML 파싱이 끝나기 전에 JS파일이 다운로드가 완료가 되면 바로 실행되기 때문에
JS파일의 크기에 따라 실행되는 순서가 달라질 수 있습니다.
하지만 defer는 HTML 파싱이 끝나는 시점에서 JS파일이 실행이 됩니다.
그렇기 때문에 script태그로 나열된 순서대로 JS파일이 실행이 됩니다.
'Javascript 정리' 카테고리의 다른 글
자바스크립트에서의 변수타입 (0) | 2020.09.01 |
---|---|
use strict 를 사용하는 이유 (0) | 2020.09.01 |
Javascript의 데이터 타입 (0) | 2020.07.20 |
Wrapper 객체 (0) | 2020.07.02 |
Object 객체 (0) | 2020.07.02 |