🌍 웹 기초 지식 완전 정리
"프레임워크는 몇 년마다 바뀌지만, 브라우저와 네트워크의 기본 원리는 변하지 않는다."
프론트엔드 면접에서는 프레임워크 지식만큼이나 웹의 근본 동작 원리를 자주 묻습니다. 이 글에서는 URL 입력부터 화면 렌더링까지의 전체 과정을 정리합니다.
📌 목차
1️⃣ 브라우저에 URL을 입력하면 일어나는 일
면접 단골 질문입니다. 전체 흐름을 단계별로 정리하면:
1. URL 파싱
2. DNS 조회 (도메인 → IP 주소)
3. TCP 연결 (3-way Handshake)
4. TLS 핸드셰이크 (HTTPS인 경우)
5. HTTP 요청 전송
6. 서버 응답 수신
7. HTML 파싱 → DOM 트리 생성
8. CSS 파싱 → CSSOM 트리 생성
9. DOM + CSSOM → Render Tree 생성
10. Layout (요소 위치/크기 계산)
11. Paint (화면에 실제로 그리기)
TCP 3-way Handshake
클라이언트 ──SYN──▶ 서버
클라이언트 ◀──SYN-ACK── 서버
클라이언트 ──ACK──▶ 서버
(연결 완료, 데이터 전송 시작)
💡 면접 포인트: 단순히 단계를 나열하는 것보다, "DNS 조회 결과는 캐싱되어 다음 요청부터는 생략될 수 있다"거나 "HTTPS는 TCP 연결 후 TLS 핸드셰이크가 추가로 필요해 초기 연결이 더 느리다" 같은 디테일을 곁들이면 좋습니다.
2️⃣ 렌더링 과정: Critical Rendering Path
브라우저가 HTML/CSS를 받아 화면에 그리기까지의 과정을 Critical Rendering Path라고 부릅니다.
HTML ──파싱──▶ DOM Tree
╲
╲──▶ Render Tree ──▶ Layout ──▶ Paint ──▶ Composite
╱
CSS ──파싱──▶ CSSOM Tree
왜 <script> 태그 위치가 중요한가?
<head>
<script src="app.js"></script> <!-- ❌ 파싱을 막음(Render Blocking) -->
</head>
<body>
...
<script src="app.js" defer></script> <!-- ✅ HTML 파싱을 막지 않고, 파싱 완료 후 실행 -->
</body>
속성동작
| 없음 | 스크립트를 만나는 즉시 다운로드+실행, HTML 파싱 중단 |
| async | 다운로드는 비동기, 완료되면 즉시 실행 (순서 보장 안 됨) |
| defer | 다운로드는 비동기, HTML 파싱 완료 후 순서대로 실행 |
3️⃣ 리플로우 vs 리페인트
Reflow (Layout)Repaint
| 발생 조건 | 요소의 크기, 위치가 변경될 때 | 색상, 배경 등 시각적 스타일만 변경될 때 |
| 비용 | 높음 (레이아웃 전체 재계산 가능) | 상대적으로 낮음 |
| 예시 | width, height, display 변경 | color, background-color 변경 |
// ❌ 나쁜 예: 매 반복마다 강제 Reflow 발생
for (let i = 0; i < 100; i++) {
element.style.width = element.offsetWidth + 1 + 'px'; // 읽기+쓰기 반복
}
// ✅ 좋은 예: 읽기와 쓰기를 분리
const width = element.offsetWidth;
element.style.width = width + 100 + 'px';
최적화 팁
- transform, opacity는 Compositor 단계에서만 처리되어 Reflow/Repaint 없이 애니메이션 가능 → GPU 가속 활용
- will-change: transform 힌트로 브라우저에 최적화 유도 가능 (남용은 오히려 메모리 낭비)
4️⃣ HTTP/HTTPS와 캐싱
HTTP 캐싱 헤더
Cache-Control: max-age=3600, public
ETag: "abc123"
[브라우저] [서버]
│ │
│──1차 요청──────────────────────▶│
│◀───응답 (ETag: abc123)──────────│
│ │
│──재요청 (If-None-Match: abc123)─▶│
│◀───304 Not Modified (본문 없음)──│ ← 캐시 재사용
캐시 전략 요약
헤더역할
| Cache-Control: max-age | 지정 시간 동안 재검증 없이 캐시 사용 |
| ETag | 리소스의 고유 해시값, 변경 여부 확인용 |
| Last-Modified | 마지막 수정 시각 기반 검증 |
HTTP/1.1 vs HTTP/2
HTTP/1.1HTTP/2
| 연결 방식 | 요청마다 별도 연결 필요 (또는 Keep-Alive) | 하나의 연결에서 다중 요청 처리 (Multiplexing) |
| Head-of-Line Blocking | 발생 | 완화 |
| 헤더 압축 | 없음 | HPACK 압축 |
5️⃣ CORS (Cross-Origin Resource Sharing)
브라우저의 Same-Origin Policy로 인해, 다른 출처(도메인/포트/프로토콜이 다른)의 리소스에 대한 요청은 기본적으로 차단됩니다. CORS는 서버가 "이 출처는 허용한다"고 명시적으로 알려주는 메커니즘입니다.
[프론트엔드: https://my-app.com]
│
│ fetch('https://api.other.com/data')
▼
[서버: https://api.other.com]
│
│ 응답 헤더: Access-Control-Allow-Origin: https://my-app.com
▼
브라우저가 헤더 확인 후 응답을 JS에 전달 (없으면 차단)
Simple Request vs Preflight Request
- Simple Request: GET, POST(특정 Content-Type)는 바로 요청
- Preflight Request: PUT, DELETE, 커스텀 헤더 사용 시 브라우저가 먼저 OPTIONS 요청으로 서버에 허용 여부를 확인
클라이언트 ──OPTIONS(preflight)──▶ 서버
클라이언트 ◀──허용 헤더 응답────── 서버
클라이언트 ──실제 요청(PUT)──────▶ 서버
💡 면접 포인트: CORS 에러는 서버가 해결해야 하는 문제입니다. 프론트엔드에서 아무리 코드를 바꿔도 서버가 Access-Control-Allow-Origin을 설정하지 않으면 해결되지 않는다는 점을 명확히 설명할 수 있어야 합니다.
6️⃣ 브라우저 저장소 비교
용량만료서버 전송용도
| Cookie | ~4KB | 설정 가능 | 매 요청마다 자동 전송 | 인증 토큰, 세션 |
| localStorage | ~5-10MB | 없음 (수동 삭제 전까지) | 안 됨 | 사용자 설정, 캐시 데이터 |
| sessionStorage | ~5-10MB | 탭 종료 시 | 안 됨 | 일시적 폼 데이터 |
| IndexedDB | 매우 큼 (수백MB+) | 없음 | 안 됨 | 대용량 구조화된 데이터 |
⚠️ 보안 팁: 인증 토큰을 localStorage에 저장하면 XSS 공격에 취약합니다(JS로 직접 접근 가능). 민감한 토큰은 httpOnly 쿠키에 저장하는 것이 더 안전합니다.
🔚 마무리
웹 기초 지식은 프레임워크가 아무리 바뀌어도 변하지 않는 가장 근본적인 자산입니다. "왜 이렇게 동작하는가"를 스스로 설명할 수 있을 때까지 원리를 파고드는 것이, 프레임워크 트렌드를 따라가는 것보다 장기적으로 더 큰 경쟁력이 됩니다.
'Frontend' 카테고리의 다른 글
| [Frontend] 디지털트윈 방역공조 모니터링 시스템(feat. R&D 과제) (0) | 2026.07.04 |
|---|---|
| [Frontend] 3D 재난 모니터링 플랫폼(feat. R&D 과제) (0) | 2026.07.04 |
| [Frontend] Framwork 정리 (0) | 2026.07.03 |
| [Frontend] 콜백 지옥에서 벗어나기 (0) | 2026.07.03 |
| [Frontend] React Hook - 함수 컴포넌트 이해하기 (0) | 2026.07.03 |