KKUSVERSEJavaScript | JavaScript 기본기 총정리 3편

JavaScriptJavaScript 기본기 총정리 3편
JavaScript 기본기 총정리 3편

기초부터 다시 살펴보는 JavaScript 공부 기록

2025-10-26
12 min

🌐 브라우저 요청 처리 과정

1. 브라우저 주소창에 URL을 입력하고 엔터키를 누릅니다.

2. 브라우저가 URL를 분석해 프로토콜(HTTP/HTTPS), 도메인, 경로 등을 구분합니다.

3. 도메인 이름을 실제 IP 주소로 변환하기 위해 DNS 서버에 요청을 보냅니다. 브라우저 캐시에 IP 정보가 있다면 이를 우선 사용합니다.

4. 브라우저가 IP 주소를 통해 서버와 TCP 연결을 맺습니다. HTTPS 프로토콜인 경우, TLS(SSL) 핸드셰이크를 추가로 수행해 암호화된 통신을 설정합니다.

5. 브라우저가 서버에 GET 요청을 보내 HTML, CSS, 자바스크립트, 이미지 등 필요한 리소스를 요청합니다.

6. 서버는 요청받은 리소스를 HTTP 응답으로 전달하고, 브라우저는 이를 수신하여 렌더링 엔진으로 전달합니다.

TCP(Transmission Control Protocol)

인터넷에서 데이터를 안전하고 순서대로 전송하기 위한 프로토콜입니다. 브라우저와 서버가 데이터를 주고받을 때, 단순히 IP 주소만으로는 데이터가 손실되거나 순서가 뒤바뀔 수 있기 때문에 TCP는 이를 보완해 신뢰성 있는 연결 기반 통신을 제공합니다.

TLS(Transport Layer Security, 구 SSL)

브라우저와 서버가 서버 인증서를 검증하고 세션 키를 안전하게 교환하여, 이후의 모든 통신 데이터를 암호화된 형태로 주고받을 수 있도록 보장하는 보안 프로토콜입니다. 이를 통해 제3자가 데이터를 가로채더라도 내용을 해독할 수 없는 안전한 통신 환경이 구축됩니다.

🎨 브라우저의 렌더링 과정

1. 브라우저는 렌더링에 필요한 HTML, CSS, 자바스크립트, 이미지, 폰트 파일 등을 요청하고 서버로부터 응답을 받습니다.

2. 브라우저의 렌더링 엔진은 HTML과 CSS를 파싱하여 DOM과 CSSOM을 생성하고, 이를 결합해 렌더 트리를 만듭니다.

3. 브라우저의 자바스크립트 엔진은 자바스크립트를 파싱해 AST(Abstract Syntax Tree)를 생성하고 바이트코드로 변환하여 실행합니다. 이때 자바스크립트는 DOM API를 통해 DOM이나 CSSOM을 변경할 수 있습니다.

4. 렌더 트리를 기반으로 HTML 요소의 레이아웃(위치와 크기)를 계산하고 브라우저 화면에 HTML 요소를 페인팅합니다.

Reflow

레이아웃 계산을 다시 수행하는 과정입니다. 노드 추가/삭제, 요소의 크기/위치 변경, 윈도우 리사이징 등 레이아웃에 영향을 주는 변경이 발생했을 때 실행됩니다.

👉 CSS에서 translate3D를 사용하면 GPU를 활용하여 위치를 변경하므로, absolutetop, left를 사용하는 것보다 성능이 빠릅니다. top, left는 레이아웃에 영향을 주어 Reflow를 유발할 수 있습니다.

Repaint

렌더 트리를 기반으로 화면을 다시 그리는 과정입니다. 레이아웃에 영향을 주지 않는 스타일 변경(색상, 배경 등)은 Reflow 없이 Repaint만 실행됩니다.

📝 script 태그

브라우저는 위에서 아래 방향으로 순차적으로 HTML, CSS, 자바스크립트를 파싱하고 실행합니다. 즉, script 태그의 위치에 따라 HTML 파싱이 일시적으로 블로킹되어 DOM 생성이 지연될 수 있습니다. 따라서 script 태그의 위치는 매우 중요합니다.

이 문제를 회피하기 위해 자바스크립트를 body 요소의 가장 아래에 위치시키는 방법이 권장됩니다.

👉 asyncdefer 속성을 사용하면 HTML 파싱과 외부 자바스크립트 파일의 로딩이 비동기적으로 동시에 진행됩니다. 단, 자바스크립트 실행 시점에는 차이가 있습니다.

<script async src="extern.js"></script>
<script defer src="extern.js"></script>

async

async 속성을 사용하면 브라우저가 HTML 파싱과 스크립트 다운로드를 동시에 진행하며, 스크립트는 다운로드가 완료되는 즉시 실행됩니다. 따라서 여러 개의 async 스크립트가 있을 경우 실행 순서는 HTML에 작성된 순서와 달라질 수 있습니다. 다른 스크립트나 DOM에 의존하는 코드가 있을 경우 주의가 필요합니다.

defer

defer 속성을 사용하면 브라우저가 HTML 파싱과 스크립트 다운로드를 동시에 진행하지만, 스크립트는 HTML 파싱이 완료되고 DOM이 모두 준비된 후 작성된 순서대로 실행됩니다. 따라서 여러 개의 defer 스크립트가 있을 경우에도 실행 순서가 보장됩니다. 다운로드가 늦게 끝난 스크립트가 있어도, 브라우저는 실행 순서를 지키기 위해 해당 스크립트가 준비될 때까지 기다립니다.

🏷️ HTML Attribute와 DOM Property 비교

구분HTML AttributeDOM Property
정의HTML 문서에 작성된 초기값브라우저가 생성한 실제 DOM 객체의 속성 값
접근element.getAttribute('속성명')element.속성명
값 변경❌ HTML 문서 상에서는 변경되지 않음✅ 자바스크립트로 언제든 변경 가능
목적요소의 초기 상태 관리요소의 최신 상태 관리

🌊 이벤트 전파(Event Propagation)

DOM 트리 상에 존재하는 DOM 요소 노드에서 발생한 이벤트는 DOM 트리를 통해 전파됩니다. 이벤트 전파는 이벤트 객체가 전파되는 방향에 따라 3단계로 구분할 수 있습니다.

1. 캡처링(Capturing)

이벤트가 루트 요소(window)에서 시작하여 목표 요소(target)으로 내려가는 단계입니다. 부모 요소 → 자식 요소 순서로 이벤트가 전파됩니다. 기본적으로 대부분 이벤트 리스너는 이 단계가 아닌 버블링 단계에서 실행되지만, addEventListener의 세 번째 인자(capture)를 true로 설정하면 캡처링 단계에서 이벤트를 잡을 수 있습니다.

element.addEventListener('click', () => console.log('캡처링 단계'), true)

2. 타깃(Target)

이벤트가 실제 이벤트가 발생한 요소(target)에 도달한 단계입니다. 타겟 요소에서 등록된 이벤트 리스너는 항상 이 단계에서 실행됩니다.

3. 버블링(Bubbling)

이벤트가 타겟 요소에서 시작하여 다시 상위 요소로 올라가는 단계입니다. 자식 요소 → 부모 요소 순서로 이벤트가 전파됩니다. 기본적으로 대부분의 이벤트는 버블링 단계를 통해 상위 요소로 전달됩니다. 필요에 따라 event.stopPropagation()을 사용하여 전파를 막을 수 있습니다.

element.addEventListener('click', (event) => {
  console.log('버블링 단계')
  // event.stopPropagation(); // 전파 중단
})

버블링되지 않는 이벤트

대부분의 이벤트는 캡처링과 버블링을 통해 전파됩니다. 하지만 일부 이벤트는 버블링되지 않아 상위 요소로 전달되지 않습니다.

이벤트대체 가능한 이벤트
focus/blurfocusin/focusout
mouseenter/mouseleavemouseover/mouseout
load/unload/abort/error-

이벤트 위임(Event Delegation)

이벤트 위임이란, 여러 개의 하위 요소에 각각 이벤트 리스너를 등록하지 않고, 상위 요소 하나에 이벤트 리스너를 등록하여 이벤트를 처리하는 기법을 말합니다.

이 방식은 버블링 단계를 활용합니다. 하위 요소에서 이벤트가 발생하면 이벤트는 상위 요소로 전파되고, 상위 요소에 등록된 이벤트 리스너에서 이벤트 객체의 target 속성을 확인하여 실제 이벤트가 발생한 요소를 식별할 수 있습니다.

👉 하위 요소마다 리스너를 등록할 필요가 없어 메모리와 렌더링 부담을 줄일 수 있으며, 동적으로 추가된 요소도 상위 요소 리스너로 처리할 수 있습니다.

// ul 요소에 이벤트 리스너 등록
const ul = document.querySelector('ul')
 
ul.addEventListener('click', (event) => {
  if (event.target.tagName === 'LI') {
    console.log(`${event.target.textContent} 클릭됨`)
  }
})

참고 자료

『모던 자바스크립트 Deep Dive』, 이웅모 저, 위키북스