minzzl
[Javascript] async 와 defer의 차이점 본문
HTML 안에 Javascript를 포함 시킬 때 다양한 방법이 존재합니다.
크게 4가지가 있는데요, 이에 대해 알아보고 Javascript를 HTML에 포함할 때 어떻게 포함해야 가장 효율적으로 포함할 수 있는지 async와 defer의 차이점을 살펴보겠습니다.
1. <head> 태그 안에 <script src=" "> 태그로 Javascript를 포함시킨 경우
위의 코드는 head가 script를 포함하고 있는데요, 이렇게 포함했을 때 과연 어떤 순서대로 사용자에게 페이지가 보여지게될까요?
- 브라우저는 HTML을 쭉 읽다가 <script> 태그를 만나면 스크립트를 먼저 실행해야 되므로 HTML 파싱(DOM 생성)을 멈춥니다.
- 필요한 .js 파일을 서버에서 받아와 다운로드 후 실행합니다.
- 다시 HTML 파싱을 시작합니다.
- 모든 DOM 생성이 완료됩니다.
이렇게 하면 단점이 무엇일까요?
JS 파일의 크기가 크다면, 네트워크 상황이 좋지 않다면, 사용자가 웹사이트를 보는데까지 많은 시간이 소요될 것입니다.
2. <body> 태그 안에 <script src=" "> 태그로 Javascript를 포함시킨 경우
이와 같은 상황을 피하게 위해 body의 가장 끝 부분에 Script를 추가할 수도 있습니다. 그렇다면 해당 방식의 동작과정은 어떻게 될까요?
- 브라우저가 HTML을 파싱합니다.
- 모든 DOM 생성이 완료됩니다.
- .<script> 태그를 읽고 .js 파일을 서버에서 받아와 다운로드 후 실행합니다.
그리하여 JS를 받기 전에 Page가 준비가 되어 사용자가 Page Contents를 볼 수 있습니다. 그러나 이와 같은 방식은 사용자가 기본적인 HTML contents 빨리 볼 수 있다는 장점은 있지만 만약 웹사이트가 JS에 의존적일 경우, 즉 사용자가 의미 있는 Contents 보기 위해서는 이 JS를 이용해서 서버에서 데이터를 받아온다던지, DOM 요소를 더 예쁘게 꾸며준다던지의 과정이 필요하다면, 서버에서 JS를 다운받고 실행되는 시간을 기다려야합니다.
3. <head> 태그 안에 <script async src=" "> 태그로 포함시킨 경우
async 는 boolean 값의 속성값이기 때문에 선언하는 것만으로 true로 설정이되어 async를 사용할 수 있습니다. async를 사용하했을 경우 동작방식은 아래와 같습니다.
- 브라우저가 HTML을 파싱합니다.
- <script> 태그를 읽고 .js 파일을 서버에서 받아와 '백그라운드'에서 다운로드합니다. 따라서 스크립트 파일을 다운로드하는 도중에도 HTML 파싱이 멈추지 않습니다.
- JavaScript의 다운로드가 완료되면 HTML 파싱을 멈추고 JavaScript를 실행합니다.
- 실행 후 나머지 HTML을 파싱합니다.
- 모든 DOM 생성이 완료됩니다.
이렇게 하면 장단점이 무엇이 있을까요?
Body의 가장 아래에 사용하는 것보다는 JS Fetching이 HTML을 파싱 하는 동안 병렬적으로 일어나기 때문에 다운로드 받는 시간을 절약할 수 있습니다. 그러나 JS가 HTML이 파싱되기도 전에 실행되기 때문에 JavaScript파일 query selecter 를 이용하여 DOM 요소를 조작한다고 한다면, 조작하려는 시점에 우리가 원하는 요소가 아직 정의 되어있지 않을 수 있기 때문에 위험 할 수 있습니다. 또한 JavaScript의 다운로드가 완료되면 HTML 파싱을 멈추고 JavaScript를 실행하기 때문에 사용자가 페이지를 보는데 시간이 조금 더 걸린다는 단점이 아직까지 존재합니다. 또한 <script> 태그의 파일이 여러개인 경우, 그 실행 순서가 제각각일 수 있습니다.
4. <head> 태그 안에 <script defer src=" "> 태그를 포함시킨 경우
defer 태그를 사용할 경우 동작 방식은 아래와 같습니다.
- 브라우저가 HTML을 파싱합니다.
- async와 마찬가지로 <script> 태그를 읽고 .js 파일을 서버에서 받아와 '백그라운드'에서 다운로드합니다. 스크립트 파일을 다운로드하는 도중에도 HTML 파싱을 합니다.
- 모든 DOM 생성이 완료됩니다.
- JavaScript가 실행됩니다.
4가지의 경우 중에 defer 속성이 안정적이고 가장 효율적인 방법입니다.
[결론]
async
다운로드 시작 순서와는 상관 없이 다운로드가 완료된 것부터 시행JS가 순서에 의존적이라면 문제가 발생
defer
다운로드를 다 받은 다음 순서대로 시행
* 아래의 글들을 참고하여 작성하였습니다.
https://onlydev.tistory.com/16
https://www.youtube.com/watch?v=tJieVCgGzhs&list=PLv2d7VI9OotTVOL4QmPfvJWPJvkmv6h-2&index=2
'프로젝트 > 자바스크립트' 카테고리의 다른 글
[Javascript] 호이스팅 (0) | 2022.10.08 |
---|---|
[Javascript] 함수 선언문 vs 함수 표현식 (0) | 2022.10.08 |
[Javascript] 데이터타입 let var const (1) | 2022.10.07 |
[Javascript] Javascript 역사 (0) | 2022.10.06 |