"일꾼이 일을 잘하려면 먼저 도구를 갈고 닦아야 한다." - 공자, 『논어』.
첫 장 > 프로그램 작성 > 프런트엔드에서 서비스 워커를 사용하여 로딩 시간을 최적화한 방법

프런트엔드에서 서비스 워커를 사용하여 로딩 시간을 최적화한 방법

2024년 11월 18일에 게시됨
검색:342

아래 gif처럼 웹사이트 로딩이 너무 오래 걸리는 상황이 있었나요?

How I optimized loading time using service workers in frontend

? 서비스 워커에 대해 들어보셨나요?

이 게시물에서는 서비스 워커가 무엇인지, 어떻게 작동하는지 ⚙️, 웹 애플리케이션 성능을 향상하기 위해 이를 어떻게 사용했는지에 대해 알아봅니다.


서비스 워커란 무엇입니까? ?

서비스 워커는 웹페이지와 별도로 실행되는 백그라운드 스크립트이며 다음을 수행할 수 있습니다.

  • 캐시 자산 ?️
  • 네트워크 요청을 차단하시겠습니까?
  • 오프라인 기능 제공 ?

서비스 근로자의 주요 특성:

  1. 백그라운드에서 실행: 서비스 워커는 페이지의 수명 주기에 묶여 있지 않습니다. 즉, 페이지가 닫혀도 계속 실행될 수 있습니다.
  2. 이벤트 중심: 서비스 워커는 네트워크 요청(이벤트 가져오기)과 같은 특정 이벤트를 수신합니다.
  3. DOM 액세스 없음: 다른 웹 워커와 달리 서비스 워커는 DOM에 직접 액세스할 수 없습니다. 백그라운드에서 작동하여 리소스와 네트워크 트래픽을 관리합니다.

다음은 서비스 워커 스크립트의 간단한 예입니다.

if ('serviceWorker' in navigator) {
  window.addEventListener('load', function() {
    navigator.serviceWorker.register('/service-worker.js').then(function(registration) {
      console.log('Service Worker registered with scope:', registration.scope);
    }).catch(function(error) {
      console.error('Service Worker registration failed:', error);
    });
  });
}

? 이 스니펫에서는 페이지가 로드될 때 서비스 워커(service-worker.js)가 등록됩니다. 등록이 성공하면 서비스 워커의 범위가 기록됩니다. 그렇지 않으면 오류가 기록됩니다.


내 과제: Unity WebGL 게임을 웹 페이지에 통합

저는 Unity WebGL 게임을 .NET Razor 웹사이트에 통합하고 있었습니다. 게임은 게임을 로드하는 데 중요한 JavaScript 파일과 함께 대용량 ".wasm" 및 ".data" 파일로 구성되었습니다. 하지만 처음 페이지를 로드할 때 20초 이상이 걸렸습니다! ? 이는 주로 ".wasm" 및 ".data" 파일의 크기 때문이었습니다.


해결책: 서비스 워커를 사용한 캐싱

로딩 시간을 줄이기 위해 필요한 모든 게임 자산을 캐시하는 "ServiceWorker.js" 파일을 만들었습니다. 파일 내용은 다음과 같습니다.

const cacheName = "$Project_name";
const contentToCache = [
    "Build/Game.loader.js",
    "Build/Game.framework.js",
    "Build/Game.data",
    "Build/Game.wasm",
    "TemplateData/game_style.css"
];

self.addEventListener('install', function (e) {
    console.log('[Service Worker] Install');

    e.waitUntil((async function () {
        try {
            const cache = await caches.open(cacheName);
            console.log('[Service Worker] Caching all: app shell and content');
            for (const resource of contentToCache) {
                try {
                    await cache.add(resource);
                } catch (error) {
                    console.error(`[Service Worker] Failed to cache: ${resource}`, error);
                }
            }
        } catch (error) {
            console.error('[Service Worker] Failed to open cache', error);
        }
    })());
});

self.addEventListener('fetch', function (e) {
     e.respondWith((async function () {
        try {
            const response = await caches.match(e.request);
            console.log(`[Service Worker] Fetching resource: ${e.request.url}`);
            if (response) return response;

            const fetchResponse = await fetch(e.request);
            const cache = await caches.open(cacheName);
            console.log(`[Service Worker] Caching new resource: ${e.request.url}`);
            await cache.put(e.request, fetchResponse.clone());
            return fetchResponse;
        } catch (error) {
            console.error(`[Service Worker] Error fetching resource: ${e.request.url}`, error);
            throw error;
        }
    })());
});

이 코드의 기능은 무엇인가요?

이 서비스 워커 스크립트는 다음 작업을 수행합니다.

  • 설치 단계에서 ".wasm", ".data" 및 JS 파일을 포함하여 게임 실행에 필요한 필수 파일을 캐시합니다.
  • 가능한 경우 캐시된 리소스를 제공하기 위해 가져오기 요청을 가로챕니다. 리소스가 캐시에 없으면 네트워크에서 리소스를 가져와서 캐시한 후 응답을 반환합니다.

결과: 상당한 성능 향상

이러한 자산을 캐싱함으로써 로딩 시간이 20초에서 3초 미만으로 단축되었습니다. 다음에 사용자가 페이지를 방문하면 자산이 이미 로컬에 저장되어 있어 경험 속도가 대폭 향상됩니다.

⚠️ 조심하세요! 캐싱 문제

이 접근 방식은 성능 향상에 놀라운 효과가 있지만 오래된 캐시 파일이라는 또 다른 문제가 발생했습니다. 우리는 Unity 게임을 적극적으로 개발하고 새 버전을 출시하고 있기 때문에 새 버전이 배포될 때마다 캐시된 파일을 지워야 했습니다.

이 문제를 해결하기 위해 저는 새 게임 빌드를 게시할 때마다 자동으로 이전 서비스 워커 등록을 취소하고 캐시를 지우는 파이프라인 스크립트를 만들었습니다. 이를 통해 사용자는 캐시된 이전 버전에 얽매이지 않고 항상 최신 자산을 로드할 수 있습니다.


결론

웹 애플리케이션에 서비스 워커를 구현하면 특히 Unity WebGL 게임과 같은 대규모 자산을 처리할 때 성능이 크게 향상될 수 있습니다. 그러나 오래된 파일을 제공하지 않으려면 캐싱을 신중하게 처리하는 것이 중요합니다.

로드 시간을 최적화하는 유사한 경험이 있습니까? 서비스 워커나 다른 기술을 사용했나요? 아래 댓글로 여러분의 생각과 통찰력을 공유해 주세요! ?

오늘 새로운 것을 배웠기를 바랍니다! ✌️

릴리스 선언문 이 기사는 https://dev.to/perisicnikola37/how-i-optimized-loading-time-using-service-workers-in-frontend-2lk9?1에서 복제됩니다. 침해가 있는 경우에는 Study_golang@163으로 문의해 주세요. .com에서 삭제하세요
최신 튜토리얼 더>

부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.

Copyright© 2022 湘ICP备2022001581号-3