브라우저는 이제 단순한 문서 뷰어가 아닙니다.
Web API의 발전 덕분에 우리는 웹에서도 네이티브 앱 못지않은 강력한 기능을 구현할 수 있게 되었죠.
실무에서 가장 빈번하게 쓰이고 중요한 Web API들을 5가지 핵심 카테고리로 정리해 보았습니다.
1. 백그라운드 & 오프라인 (Background & Offline)
사용자가 탭을 닫아도, 혹은 인터넷이 끊겨도 작동하는 '앱다운 웹'을 만드는 핵심 기술입니다.
🛠️ Service Workers (서비스 워커)
서비스 워커는 브라우저와 네트워크 사이의 '프록시 서버' 역할을 합니다.
- 핵심: 네트워크 요청을 가로채 캐시된 응답을 보냄 (오프라인 지원).
- 실무 팁: 서비스 워커 내부에서는 DOM에 직접 접근할 수 없습니다. 대신
postMessage를 통해 메인 스레드와 통신해야 합니다. - 전략:
Stale-while-revalidate나Cache-First같은 캐싱 전략을 적재적소에 사용하는 것이 실력의 차이를 만듭니다.
🤝 Shared Worker (공유 워커)
여러 탭이 하나의 '공용 비서'를 공유하는 개념입니다.
- 장점: 중복된 WebSocket 연결을 하나로 합쳐 리소스를 절약할 수 있습니다. 탭이 10개 열려도 서버와의 연결은 단 하나로 관리 가능하죠.
2. 브라우저 데이터 저장소 비교
데이터의 성격에 따라 올바른 저장소를 선택하는 것이 성능과 보안의 시작입니다.
| 구분 | Web Storage (Local/Session) | IndexedDB |
|---|---|---|
| 데이터 타입 | String만 가능 (객체는 JSON 변환 필수) | 객체, 파일, Blob 등 모든 타입 |
| 용량 | 작음 (약 5MB ~ 10MB) | 매우 큼 (디스크 용량에 비례) |
| 작동 방식 | 동기(Blocking) | 비동기(Non-blocking) |
| 검색/정렬 | 불가 (직접 구현해야 함) | 인덱스를 이용한 빠른 검색 가능 |
👨💻 개발자 노트: localStorage는 동기적으로 작동하므로, 너무 큰 데이터를 다루면 메인 스레드가 멈출 수 있습니다. 복잡한 오프라인 앱을 빌드한다면 무조건 IndexedDB를 고려하세요.
3. 애니메이션 & 렌더링 최적화
60fps의 부드러운 UX를 위해 브라우저의 렌더링 루프와 소통하는 방법입니다.
🏃 requestAnimationFrame (rAF)
setTimeout과 달리 **브라우저의 리프레시 레이트(주사율)**에 맞춰 실행됩니다.
- 최적화: 탭이 백그라운드에 있으면 자동으로 멈춰 배터리와 리소스를 절약합니다. 애니메이션 구현 시 선택이 아닌 필수입니다.
👁️ Intersection Observer API
요소가 화면에 보이는지 감시합니다.
- 활용: 이미지 지연 로딩(Lazy Loading), 무한 스크롤(Infinite Scroll).
- 장점:
scroll이벤트 리스너처럼 매 프레임마다 계산하지 않아 성능상 매우 유리합니다.
4. 네트워크 & 라우팅 제어
📡 Fetch API vs Axios
현대 웹에서는 Fetch API가 표준이지만, 실무에서는 여전히 Axios를 선호하기도 합니다.
- Fetch의 단점:
404,500에러에서도catch로 가지 않고ok: false를 반환하므로 별도의 에러 핸들링 로직이 필요합니다. - Fetch의 장점: 별도의 라이브러리 설치가 필요 없고, 서비스 워커의
fetch이벤트와 완벽히 호환됩니다.
📍 History API
SPA(Single Page Application) 라우팅의 심장입니다. pushState를 사용하면 새로고침 없이 URL만 바꾸고, 브라우저 뒤로가기 기능을 완벽히 지원할 수 있습니다.
5. 하드웨어 및 OS 통합
웹이 장치와 직접 소통하며 네이티브 앱의 경계를 허뭅니다.
- MediaDevices: 화상 회의, QR 스캐너 구현의 필수.
- Geolocation: 사용자의 현재 위치를 기반으로 한 로컬 서비스 구현.
- Notifications: 서비스 워커와 결합하여 웹 푸시 알림 구현. (사용자 재방문 유도에 치명적으로 중요!)
🏁 마무리하며
이 모든 API를 관통하는 가장 중요한 원칙은 **'점진적 향상 기법(Progressive Enhancement)'**입니다.
모든 사용자가 최신 브라우저를 쓰지는 않습니다.
특정 기능을 쓰기 전에 반드시 지원 여부를 체크하는 방어적인 코드를 작성하는 습관을 가져야 겠습니다.
// 권장되는 체크 방식
if ('serviceWorker' in navigator) {
// 로직 실행
}