Service Worker API 알아보기

_sw_·2025년 2월 6일
0
post-thumbnail

최근 프로젝트에서 PWA 기능을 구현 하거나, MSW를 통해서 백엔드 데이터를 mocking한 경험들이 있었다.

두 가지 경험을 하면서 공통적으로 나왔던 용어가 있었는데 바로 Service Worker 다.

Service Worker라는 개념이 여러번 나오다보니 조금 더 알고 있으면 좋을 것 같아 정리하게 되었다.

먼저, 우리 어디서 봤더라..

먼저 MSW의 공식문서를 살펴 봤다. MSW의 철학에 대한 문서 중간에 아래 이미지에서 볼 수 있듯이, 브라우저 네트워크 수준에서 요청을 가로채기 위한 목적 때문에 Service Worker를 채택하여 사용한다.

다음은 PWA에 관한 MDN 문서인데, PWA에서는 캐싱을 활용해서 로딩 시간을 줄이기 위해 사용한다고 한다.

같은 도구를 활용했는데 서로 다른 목적을 가지고 있는 것을 알 수 있었고, 당연한 소리지만 Service Woker가 다양한 기능을 제공하는 것을 짐작할 수 있었다. ( 예리한 척. 🧐 )


Service Worker

Service Worker는 출처와 경로에 페이지를 제어하는 스크립트이며, 이벤트 기반의 워커로 JS 파일을 말한다.

연관된 웹 페이지/사이트를 통제해서 리소스 요청을 가로채 수신하여 수정할 수 있고, 다시 페이지로 돌려보낼 수 있습니다. 또한 서비스의 리소스를 세부적으로 캐싱할 수 있다.

그리고 브라우저와 별도의 Worker Context를 가지기 때문에 DOM에 접근할 수 없고, 웹/앱을 구동하는 JS 스레드와 다른 스레드에서 동작하기 때문에 웹/앱을 구동하는 JS 스레드 입장에서 연산을 가로막지 않는 (Non-blocking) 특징이 있다.

또한, 보안 상의 이유로 HTTPS에서만 동작한다. 네트워크를 가로채 수정한다는 점에서 중간자 공격에 취약할 수 있기 때문이다.

Service Worker 기본 흐름

  1. 서비스 워커 로드 ( Download )

    브라우저가 웹 페이지를 열면 리소스(HTML, JS, CSS)를 로드되는데, 이때 JS를 통해서 ServiceWorker 파일가 로드 됩니다. 브라우저가 새로고침 되었을때, 변경 여부를 다시 확인하는데, 파일이 변경되었다면 다시 Service Worker를 다운로드 한다.

  2. 설치(Install) / 캐싱 (Caching)

    다운로드 이후에 설치(Install) 이벤트가 발생한다. 이때 필요한 리소스를 캐싱한다. 해당 리소스들을 추후에 오프라인에서도 활용할 수 있다.

  3. 활성화 (Activate)

    설치가 완료된 이후 활성화(Activate) 이벤트가 발생하고, Service Worker가 활성화된다. 이때 오래된 캐시를 삭제하거나 앱 초기화 작업을 수행할 수 있다.

    이 시점 부터 Service Woker는 네트워크 요청을 가로챌 수 있다.

  4. 가로채기 (Fetch)

    페이지 요청을 가로채서 Service Worker의 fetch 이벤트를 통해서 요청을 핸들링할 수 있다(Proxy). 캐싱된 값을 전달하거나, 네트워크로 보내거나, 응답을 임의로 설정할 수 있다.

위 과정들은 아래 MDN에서 제공하는 이미지를 통해 더 쉽게 이해할 수 있다..!

궁금한 점

1. 캐싱되는 장소는 어디인가?

Service Worker가 설치되는 시점에 초기 리소스를 캐싱하게 된다. 이 캐싱 데이터가 실제 저장된 위치는 어디일까?

추측컨데 Service Worker는 앞서 웹/앱과 다른 스레드에서 실행된다고 했다. 그렇다면 스레드 메모리 구조에서 Stack에 저장되는 게 아닐까하는 생각이 들었다.

→ 땡 ❌. 바보 같게도 오프라인에서도 유지되어야 하는데 스레드의 스택에 저장되면 브라우저 내 지속성을 유지하기 어렵다…

캐싱된 리소스들은 브라우저 내에 cache storage에 저장된다.

이전 프로젝트에서 PWA를 찍먹 했을 때 코드를 활용해서 실제 리소스가 캐싱된 위치를 찾아가보았다.

    self.addEventListener('install', function () {
      self.waitUntil(
        caches.open('v1').then((cache) => {
          return cache.addAll(['/index.html']);
        }),
      );
    });

service worker가 install 될때 /index.html을 캐싱하도록 지정해주었고,
브라우저 개발자 도구에서 Application > Cache Strage 내에 지정한대로 캐싱이 이루어지고 있는 것을 확인할 수 있었다.

추가) Service Worker 확인하기

  • chrome://serviceworker-internals/ 접속

    로컬에 연결된 모든 서비스 워커를 확인할 수 있다.

  • 개발자 도구 활용
    브라우저의 개발자 도구에서 Application > Service workers 탭에서 현재 도메인에 설치된 Service Worker에 대한 정보를 확인할 수 있다.


2. JS Proxy API vs Service Worker

지금까지 알아봤던 Service Worker는 Proxy의 역할을 가지고 있다.
단순히 요청을 가로채서 원하는 값만 주는 것을 원하면 JS Proxy API와 같이 다른 방식도 있을 텐데 굳이 Service Worker를 사용한 이유에 대해서도 생각해 보았다.

우선 JS Proxy API는 객체 대한 작업을 가로채서 재정의 할 수 있게 해준다.
만약 JS Proxy API로 Mocking하는 API를 만든다면 아래와 같이 만들 수도 있다.
( Thanks to GPT… )

import axios from 'axios';
    
// Axios 인스턴스 생성
const apiClient = axios.create({
	baseURL: 'https://api.example.com',
    timeout: 5000,
});
    
// Proxy를 활용해 요청을 가로채기
const proxiedApiClient = new Proxy(apiClient, {
	get(target, propKey) {
	// propKey: 'get', 'post' 등 Axios의 HTTP 메서드
    
	// 원래 메서드 가져오기 (예: axios.get)
	const originalMethod = target[propKey];
    
	// 요청 가로채기
    return async (...args) => {
     	const [url] = args;
    
        // 특정 엔드포인트 모킹
        if (url.includes('/mock-endpoint')) {
          console.log('Mocking response for:', url);
          
          return Promise.resolve({
            data: { mock: 'This is mock data!' },
            status: 200,
          });
        }
    
        // 나머지는 실제 네트워크 요청
        return originalMethod.apply(target, args);
      };
    },
  });

단순히 코드와 API 모킹에 대한 봤을 때는 가능한 이야기지만 JS Proxy의 경우 단순히 코드 레벨에서 기존 메서드의 동작과 다르게 동작 시키는 것이었고, Service Worker를 사용한다면 실제 브라우저에서 보낸 네트워크 요청을 가로채서 API 모킹을 하게 된다.

Service Worer를 사용하는 것이 보다 백엔드 서버에 요청 / 응답을 보내는 실제 동작에 더 유사한 가로채기? 방식이기 때문에 내가 비교했던 Proxy보다 Service Worker를 활용하는 쪽이 더 적합한 방식이다.


끝내며…

PWA의 오프라인 환경에서의 앱 실행과 MSW의 Mocking 전략에 대해서 이해할 수 있었다. 결국 두 방식 모두 요청을 주고 받을 대상이 없는 상태에서 Service Worker를 통해서 마치 실제 앱이 네트워크를 통해 데이터를 요청/응답하는 것 처럼 보이게 하기 위해서 Service Worker를 활용하는 것이다.

이번에 Service Worker가 무엇인지, 어떤 흐름을 통해서 동작하는지를 보다 잘 알게 된 것 같다. 동시에 내 프로젝트에 만들어뒀던 service worker 파일이 얼마나 엉망인지도 알게 되었다… ㅎ…

해당 글과는 살짝 관계 없는 내용이지만,

매번 새로운 개념을 공부하면서 수동적으로 인터넷에 있는 글들을 받아들이지 않기 위해서, 내가 기존에 알고있는 개념을 비교해보거나, 왜?라는 질문을 달기 위해서 노력하려고 한다.

하지만 고민해서 낸 질문에 비해서 생각보다 어렵지 않게 질문에 대한 답을 찾는 것 같아서 뭔가 생각하는 방향이 잘못된건지, 억지로 질문을 짜내려고해서 그런건지, 문득 잘못 공부하고 있나? 하는 생각이 들었다.

다른 개발자 분들은 블로그나 GPT를 통한 정보를 어떻게 비판적으로 수용하는지 궁금해졌다.

Reference

https://developer.mozilla.org/ko/docs/Web/API/Service_Worker_API

https://fe-developers.kakaoent.com/2022/221208-service-worker/

profile
나도 잘하고 싶다..!

0개의 댓글

관련 채용 정보