안녕하세요, 20년 차 자바스크립트 개발자 ‘코딩하는곰’입니다. 오늘은 자바스크립트 초보자부터 중급자까지 꼭 알고 넘어가야 할, 하지만 종종 혼동하는 두 가지 이벤트 DOMContentLoaded와 load에 대해 깊이 있게 파헤쳐보겠습니다. 웹 페이지가 사용자에게 보여지는 그 순간, 뒤에서는 어떤 일들이 벌어지고 있을까요? 단순히 ‘문서가 준비되었다’는 개념을 넘어, 리소스와 렌더링의 관점에서 정확한 시점을 이해하는 것은 효율적인 스크립트 작성과 웹 성능 최적화의 첫걸음입니다. 이 포스팅을 통해 여러분의 코드가 ‘언제’ 실행되어야 가장 안전하고 빠른지 명확히 알 수 있게 될 거예요.
🌐 웹 개발에 관심이 있다면, (스프링 vs Java EE) 20년 차 개발자가 분석하는 구조와 개발 방식 차이를 참고해보세요.
DOMContentLoaded와 load 이벤트는 모두 브라우저가 페이지를 로드하는 과정에서 발생하는 중요한 신호입니다. 그러나 그 시점과 의미는 근본적으로 다릅니다.
DOMContentLoaded: 이름 그대로 DOM(Document Object Model) 콘텐츠가 로드되고 파싱(해석)되었을 때 발생합니다. 쉽게 말해, HTML 문서의 구조(태그, 요소들)가 메모리에 완전히 올라가서 자바스크립트가 접근하고 조작할 수 있는 상태가 되었음을 알립니다. 이 시점에서는 스타일시트(CSS), 이미지, 하위 프레임 등의 외부 리소스가 아직 다 로드되지 않았을 수 있습니다. 마치 책 의 목차와 본문 글은 준비되었지만, 책 속의 그림은 아직 인쇄되지 않은 상태라고 비유할 수 있죠.load: 페이지와 모든 종속 리소스(스타일시트, 스크립트, 이미지, iframe 등)가 완전히 로드되었을 때 발생합니다. DOMContentLoaded 이후에, 남은 모든 것들이 준비된 최종 완성 시점입니다. 위의 비유로 치면 책의 글과 모든 그림이 완벽하게 인쇄되어 독자에게 전달될 준비가 된 상태입니다.
이 차이를 코드로 간단히 확인해보겠습니다.<!DOCTYPE html><html><head><title>이벤트 테스트</title><!-- 큰 용량의 스타일시트 --><link rel="stylesheet" href="large-style.css"></head><body><h1>테스트 페이지</h1><!-- 큰 용량의 이미지 --><img src="large-image.jpg" alt="테스트 이미지"><script>document.addEventListener('DOMContentLoaded', function() {console.log('DOMContentLoaded 발생: DOM 준비 완료!');// 이 시점에 h1 요소를 조작하는 것은 안전합니다.document.querySelector('h1').style.color = 'blue';});window.addEventListener('load', function() {console.log('load 발생: 페이지와 모든 리소스 준비 완료!');// 이 시점에서는 이미지의 실제 크기 등을 안전하게 확인할 수 있습니다.console.log('이미지 너비:', document.querySelector('img').naturalWidth);});console.log('인라인 스크립트 실행 중...');</script></body></html>
위 예제를 실행하면 콘솔에는 일반적으로 다음과 같은 순서로 로그가 출력됩니다.
인라인 스크립트 실행 중...DOMContentLoaded 발생: DOM 준비 완료! (HTML 파싱이 끝난 직후)load 발생: 페이지와 모든 리소스 준비 완료! (large-image.jpg와 large-style.css 로딩이 끝난 후)
📱 앱 개발에 도전하고 싶다면, React onClick 이벤트 완벽 가이드 20년 경력자의 핵심 노하우를 참고해보세요.
이 두 이벤트의 시점 차이는 웹 페이지의 성능(Performance) 과 사용자 경험(UX) 에 직접적인 영향을 미칩니다.
DOMContentLoaded의 중요성: 초기 상호작용 시간
사용자가 페이지를 열었을 때, 글자와 버튼 같은 기본적인 콘텐츠와 기능이 얼마나 빨리 반응하는지가 중요합니다. DOMContentLoaded 이벤트는 초기 렌더링이 가능한 시점과 깊이 연관되어 있습니다. 구글의 핵심 웹 핵심 지표(Core Web Vitals) 중 하나인 FCP(First Contentful Paint, 최초 콘텐츠풀 페인트) 와도 맥락을 같이합니다. 따라서, DOM 조작이 필요한 스크립트(예: 버튼에 이벤트 리스너 추가, 동적 콘텐츠 생성)는 DOMContentLoaded 시점에 실행되도록 하는 것이 좋습니다. 이렇게 하면 사용자가 빈 화면을 보는 시간을 줄이고, 가능한 한 빠르게 페이지와 상호작용할 수 있게 합니다.load의 중요성: 완전한 로딩과 리소스 의존성
반면, 페이지의 완전한 준비 상태를 알아야 할 때는 load 이벤트를 사용합니다. 예를 들어:실전 팁:* 이미지 갤러리에서 모든 이미지의 크기를 계산해 레이아웃을 정확히 배치할 때.* 차트 라이브러리를 사용하는데, 모든 데이터와 스크립트가 로드된 후에 차트를 그려야 할 때.* 페이지 로딩 시간을 정확히 측정할 때 (Navigation Timing API의 `loadEventEnd`).하지만, `load` 이벤트는 모든 리소스를 기다리므로 발생 시점이 상대적으로 늦습니다. 모든 스크립트를 여기에 묶어두면 사용자는 모든 것이 다 로드될 때까지 기다려야 하므로 초기 반응성이 떨어질 수 있습니다.
async와 defer 속성의 영향<script> 태그의 async나 defer 속성은 이 이벤트 발생 시점에 큰 영향을 줍니다.defer 스크립트는 HTML 파싱을 차단하지 않고, 파싱이 완료된 후(DOMContentLoaded 발생 직전)에 실행됩니다.async 스크립트는 다운로드가 끝나는 즉시 실행되며, 이 실행 시점이 DOMContentLoaded 발생 전후가 될 수 있어 예측이 어렵습니다.async 스크립트의 다운로드와 실행은 DOMContentLoaded 이벤트를 차단하지 않습니다. 하지만, async 스크립트가 아직 실행 중이면 load 이벤트는 지연될 수 있습니다.
매일 두뇌 운동을 위한 스도쿠가 필요하다면, 한국어와 영어를 지원하는 스도쿠 저니를 다운로드하세요.
지금까지의 개념을 바탕으로, 실전에서 어떻게 적용해야 하는지 시나리오별로 정리해보겠습니다.
✅ DOMContentLoaded 를 사용해야 할 때 (대부분의 경우 여기 해당!)
document.addEventListener('DOMContentLoaded', function() {// 1. DOM 요소 조작: 버튼, 폼, 리스트 등에 이벤트 핸들러 부착document.getElementById('submitBtn').addEventListener('click', handleSubmit);// 2. 동적 콘텐츠 초기화: 라우터, 상태 관리자, 컴포넌트 렌더링 함수 호출initializeApp();// 3. 사용자에게 빠른 피드백 제공: 로딩 스피너 숨기기, 기본 데이터 표시hideLoadingSpinner();renderInitialData();// 4. CSS에 의존하지 않는 간단한 스타일 변경// (CSS가 로드되기 전이라면 예상과 다른 결과가 나올 수 있음에 주의)});
✅ load 를 사용해야 할 때
window.addEventListener('load', function() {// 1. 리소스 크기/위치 계산: 이미지, 동영상, iframe이 로드된 후의 실제 크기 측정const img = document.querySelector('.hero-image');console.log(`이미지 실제 크기: ${img.naturalWidth}x${img.naturalHeight}`);adjustLayoutBasedOnImageSize();// 2. 외부 스크립트/위젯 완전 로드 확인: 광고 스크립트, 소셜 미디어 위젯, 지도 APIif (window.AdLibrary) {window.AdLibrary.init();}// 3. 페이지 "완전" 로딩 후 분석 코드 실행 (최종 페이지뷰 트래킹)sendFinalPageViewToAnalytics();});// 참고: 특정 리소스(예: 이미지) 하나의 로드만 기다릴 때는 해당 요소의 `load` 이벤트를 사용할 수도 있습니다.const specificImage = new Image();specificImage.addEventListener('load', function() {console.log('특정 이미지 로드 완료!');});specificImage.src = 'path/to/image.jpg';
❌ 주의사항: window.onload vs document.addEventListener('load')
window.onload 또는 window.addEventListener('load', ...)는 정상적으로 동작합니다.document.addEventListener('load', ...)는 의도한 대로 동작하지 않을 수 있습니다. load 이벤트는 window 객체에서 발생하는 것이 표준입니다. 특정 상황(이미지 등)을 제외하고는 document가 아닌 window에 리스너를 추가하세요.
✨ 감성과 열정이 만나는 현장을 직접 보고 싶다면, 의왕왕송호수 겨울축제(날짜미정)를 참고해보세요.
정리하자면, DOMContentLoaded는 “구조가 준비된 시점”, load는 “모든 것이 완비된 시점” 의 신호입니다. 현대 웹 개발에서 사용자에게 빠른 첫인상을 주는 것은 무엇보다 중요합니다. 따라서, 기본 원칙은 가능한 한 DOMContentLoaded 시점에 필요한 초기화 작업을 끝내는 것입니다. 리소스 의존성이 높은 특수한 경우에만 load 이벤트를 활용하세요. 이 차이를 이해하고 적용하는 것만으로도 여러분의 웹 페이지 반응성은 눈에 띄게 개선될 것입니다.
다음 시간에는 이 이 벤트들의 발생 시점을 정밀하게 측정할 수 있는 PerformanceNavigationTiming API에 대해 알아보겠습니다. ‘코딩하는곰’과 함께 자바스크립트의 깊은 바다로 계속 항해해 보아요! 질문이나 원하는 주제가 있다면 댓글로 남겨주세요.
📊 성분, 효능, 가격까지 비교해보고 싶은 분들을 위한, 케이밸런스(K-BALANCE)를 참고해보세요.
