[TIL#2] Front-end

이트루·2023년 12월 26일
0

🌵TIL

목록 보기
4/17

1. Application of JS on HTML

<script type="text/javascript" src="./script.js"></script>

현대 웹 브라우저에서 돌아가는 스크립트들은 대부분 HTML 보다 무겁다.
용량이 커서 이를 다운로드 받거나 처리하는 데 오랜 시간이 걸리게 된다.

웹 브라우저는 HTML의 앞부분 부터 읽다가 <script> 태그를 마주하면 DOM 생성을 멈춘다. src 속성이 있는 script 태그를 만났을 때도 마찬가지로 외부에서 스크립트를 다운 받고 실행한 후에 남은 페이지를 처리한다.

[이로 인해 발생할 수 있는 이슈들]

  1. script 태그를 만나면 DOM 생성을 멈추기 때문에, 스크립트 다운 및 실행이 끝나기 전까지 스크립트에서는 스크립트 아래에 있는 DOM 요소에 접근할 수 없다. 따라서 DOM 요소에 핸들러를 추가하는 것과 같은 여러 행위가 불가능해진다
  2. 페이지 위쪽에 용량이 큰 스크립트가 있는 경우 스크립트가 페이지를 막아버린다. 페이지에 접속하는 사용자들은 스크립트를 다운받고 실행할 때까지 스크립트 아래쪽 페이지를 볼 수 없게 된다.

이 글을 보고 가장 먼저 생각해볼 수 있는 간단한 해결 방법은, script 태그를 페이지의 맨 아래에 놓는 것이다. DOM 생성도 막지 않고, 스크립트 또한 위에 있는 요소에 접근할 수 있다.
그러나, HTML문서 자체가 아주 큰 경우를 가정해보자. 브라우저가 HTML 문서 전체를 다운로드 하도록 한 후에, script를 다운 받도록 한다면 페이지는 굉장히 느려질 것이다. 네트워크 속도가 빠른 경우에는 크게 문제가 되지 않겠지만, 네트워크 환경이 열약한 경우 이러한 지연이 눈에 굉장히 잘 띌 것이다.

[해결 방법]
다행히도, script 태그가 가지고 있는 속성 defer , async 을 이용해 이러한 문제를 해결할 수 있다.

[1] defer

우선, 브라우저는 defer 속성이 있는 스크립트(defer script 또는 지연 script 라고 부른다.)를 백그라운드에서 다운로드 한다.
따라서 script를 다운로드 하는 도중에도 DOM 생성(HTML 파싱)은 멈추지 않는다.
또한, defer script 실행은 페이지 구성이 모두 끝날 때 까지 지연된다.
다만 defer 속성은 외부 스크립트에만 유효하므로, src 속성이 없다면 defer 속성은 무시된다.

<p>...스크립트 앞 콘텐츠...</p>

<script defer src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>

<!-- 바로 볼 수 있네요! -->
<p>...스크립트 뒤 콘텐츠...</p>
  • 위처럼, defer 속성이 부여된 스크립트는 페이지 생성을 막지 않고, DOM이 준비된 후에 실행된다.
  • 다만, 아래와 같은 경우 DOMContentLoaded 이벤트 발생 전에 실행된다.(왜?)
<p>...스크립트 앞 콘텐츠...</p>

<script>
  document.addEventListener('DOMContentLoaded', () => alert("`defer` 스크립트가 실행된 후, DOM이 준비되었습니다!")); // (2)
</script>

<script defer src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>

<p>...스크립트 뒤 콘텐츠...</p>

[2] async

async 속성이 있는 script(async script 또는 비동기 script 라고 부른다.)는 페이지와 완전히 독립적으로 동작한다.
async script는 defer script처럼 백그라운드에서 다운로드 되며, HTML 페이지는 async 스크립트 다운이 완료되길 기다리지 않고 페이지 내 콘텐츠를 처리, 출력한다.(HTML parsing, DOM 생성)

<p>...스크립트 앞 콘텐츠...</p>

<script>
  document.addEventListener('DOMContentLoaded', () => alert("DOM이 준비 되었습니다!"));
</script>

<script async src="https://javascript.info/article/script-async-defer/long.js"></script>
<script async src="https://javascript.info/article/script-async-defer/small.js"></script>

<p>...스크립트 뒤 콘텐츠...</p>

2. HTMLCollection, NodeList


[참고문헌]
profile
내 꿈은 세계정복🧐

0개의 댓글