본문 바로가기
Computer Science/FAQ

DOMContentLoaded 이벤트와 load 이벤트의 차이점은 무엇인가요?

by minhi 2024. 10. 5.
DOMContentLoaded 이벤트
웹 브라우저가 HTML 문서를 전부 읽고 DOM 트리를 완성하면 발생하는 이벤트

 

DOMContentLoaded 이벤트는 이미지 파일, 스타일 시트 등 기타 자원의 로드를 기다리지 않고 DOM 트리만 완성되면 발생한다.

 

즉, DOMContentLoaded 이벤트 발생 시점에서 기타 자원은 로드되었을 수도, 되지 않았을 수도 있다.*

 

DOMContentLoaded 이벤트는 document 객체에서 발생한다.

<script>
  document.addEventListener("DOMContentLoaded", () => {
    alert('DOM 트리 완성')
    alert(`이미지 사이즈: ${img.offsetWidth}x${img.offsetHeight}`)
  })
</script>
<body>
  <img id="img" src="https://en.js.cx/clipart/train.gif?speed=1&cache=0">
</body>

 

DOMContentLoaded 이벤트 발생 시점에서 아직 이미지는 로드되지 않았으므로 이미지 사이즈로 0x0을 출력한다.

 

실제로 alert 발생 시점에는 이미지가 존재하지 않는 것을 확인할 수 있다.

 

* DOMContentLoaded 이벤트는 기타 자원의 로드를 기다리지 않을 뿐, 기타 자원의 로드 속도가 빠를 경우 DOMContentLoaded 이벤트 발생 시점에서 이미 기타 자원이 로드되었을 수 있다.

 

load 이벤트
DOMContentLoaded 이벤트 발생 후 기타 자원 로드를 완료하면 발생하는 이벤트

 

load 이벤트는 DOM 트리 완성 후 이미지 파일, 스타일 시트 등 기타 자원의 로드가 완료되어야 발생한다.

 

즉, load 이벤트 발생 시점에서 기타 자원은 무조건 로드되어있다.

 

load 이벤트는 window 객체에서 발생한다.

<script>
  window.addEventListener('load', (event) => {
    alert('DOM 트리 완성')
    alert(`이미지 사이즈: ${img.offsetWidth}x${img.offsetHeight}`)
  })
</script>
<body>
  <img id="img" src="https://en.js.cx/clipart/train.gif?speed=1&cache=0">
</body>

 

load 이벤트 발생 시점에서 이미 이미지가 로드되었으므로 이미지 사이즈로 171x160을 출력한다.

 

실제로 alert 발생 시점에도 이미지가 이미 존재하는 것을 확인할 수 있다.

 

DOM 트리

 

앞서 DOMContentLoaded 이벤트와 load 이벤트는 공통적으로 DOM 트리 완성 후 발생한다고 했으며

 

이전에 웹 사이트 로딩 과정을 알아보면서도 DOM 트리, CSSOM 트리를 간단하게 알아본 바가 있다.

 

이렇게 자주 등장하는 DOM 트리를 이번 기회에 한 번 정리해보자.

 

먼저 DOM이란 Document Object Model의 약자로, 영문 그대로 문서 객체 모델을 뜻한다.

 

문서 객체

 

HTML 문서의 <head>, <body>, <title>, <div>, <span>, <h1> 태그를 HTML에서는 요소라고 불렀지만

 

이를 JavaScript에서는 문서 객체라고 부른다.

 

예를 들어 HTML의 <body> 태그는 JavaScript에서 document.body가 된다.

 

이때, 비단 태그 뿐만 아니라 주석, 텍스트 등 HTML 문서를 구성하는 모든 것이 JavaScript에서는 문서 객체가 된다.

 

문서 객체 모델

 

HTML 문서를 문서 객체를 토대로 이해한 것을 문서 객체 모델이라고 한다.

 

문서 객체 모델은 넓게는 웹 브라우저가 HTML 문서를 인식하는 방식을, 좁게는 문서 객체 집합을 의미한다.

 

이때 웹 브라우저는 HTML 문서를 트리 구조로 인식하므로

 

다르게 설명하면 웹 브라우저가 HTML 문서를 트리 구조로 인식하는 과정이자 그 결과로 나온 트리 구조라고도 할 수 있다.

 

DOM 트리

 

DOM은 문서 객체를 노드로 가지는 트리 구조를 가진다.

 

앞서 HTML 문서를 구성하는 모든 것이 문서 객체가 된다고 한 것처럼 DOM의 노드로는 12가지 유형이 있다.

 

일반적으로는 다음의 4가지가 자주 등장한다.

  • 문서 노드
  • 요소 노드
  • 텍스트 노드
  • 주석 노드

예를 들어 아래의 코드는

<!DOCTYPE HTML>
<html>
<head>
  <title>키보드 이벤트</title>
</head>
<body>
  <!-- 주석 -->
  <ol>
    <li>keyup</li>
    <li>keydown</li>
  </ol>
</body>
</html>

 

아래의 DOM 트리를 가진다.

 

줄바꿈, 공백도 유효한 텍스트로 처리되므로 줄바꿈, 공백 또한 텍스트 노드로 생성된다.

 

DOM 트리는 Live DOM Viewer와 개발자 도구-Elemenets에서 확인할 수 있으며

 

이때 개발자 도구는 줄바꿈, 공백 텍스트 노드는 표시하지 않고 그 외 텍스트 노드는 그냥 텍스트로 표시하는 등 생략된 DOM 트리를 제공한다.

 

더 공부가 필요한 부분

 

위 내용을 공부하던 중, 아래의 설명을 읽게 되었다.

브라우저는 HTML 문서를 처리하는 도중에 <script> 태그를 만나면, DOM 트리 구성을 멈추고 <script> 를 실행합니다. 스크립트 실행이 끝난 후에야 나머지 HTML 문서를 처리하죠. <script>에 있는 스크립트가 DOM 조작 관련 로직을 담고 있을 수 있기 때문에 이런 방지책이 만들어 졌습니다. 따라서 DOMContentLoaded 이벤트 역시 <script> 안에 있는 스크립트가 처리되고 난 후에 발생합니다.

 

문서 객체 모델 ① 문서 객체 조작하기에서 DOMContentLoaded 이벤트에 대해 공부하며

 

<script> 태그 실행 전 <body> 태그까지 다 읽어들이도록 하기 위한 이벤트가 DOMContentLoaded 이벤트라고 이해했었는데

 

오히려 위 설명은 실행 순서에 있어 <body> 태그보다 <script> 태그의 우선순위가 더 높다는 뉘앙스로 설명하고 있다.

 

최대한 이해해서 정리해보려고 했는데 아무리 생각해도 이해가 안 돼서 일단 기록만 해둔다.

 

 

 

 

 


다음 자료를 공부하여 정리한 글로, 아직 많이 부족해 틀린 내용이 있을 수도 있습니다.

 

혹시 있다면 댓글로 알려주세요. 수정하고 더 공부해나가겠습니다-

 

DOM 트리

DOMContentLoaded, load, beforeunload, unload 이벤트