Graphy | PWA

Kyu-hyun Lee
6 min readJun 10, 2023

--

PWA(Progressive Web App)

PWA Logo
PWA LOGO

PWA는 웹과 네이티브 앱의 장점을 결합한 기술로, 웹 애플리케이션에 네이티브 앱과 유사한 경험을 제공합니다.

PWA의 핵심 기능 중 하나는 오프라인 작동입니다. 이를 통해 사용자가 인터넷 연결이 불안정하거나 끊긴 환경에서도 애플리케이션을 계속 사용할 수 있습니다. 또한, 홈 화면에 앱을 추가하는 기능을 통해 사용자가 애플리케이션을 쉽게 접근하고 다시 방문할 수 있게 만듭니다. 이 외에도 푸시 알림을 통해 사용자 참여를 증가시키고, 웹 애플리케이션 업데이트를 사용자가 별도로 수행할 필요 없이 자동으로 적용하는 등의 이점이 있습니다.

이런 PWA의 특징들은 사용자 경험을 향상시키고, 웹 애플리케이션의 가용성을 높이며, 사용자 참여를 증대시키는데 큰 도움이 됩니다. 따라서 이번 프로젝트에서는 이러한 이점을 활용하기 위해 PWA를 적용하게 되었습니다.

웹앱으로 추가된 모습

PWA를 구축하기위한 핵심 기술

Manifest.json

Manifest.json은 웹 앱 매니페스트로 웹 앱을 디바이스의 홈 화면에 추가 할 수 있게 해주고 오프라인 상황에서 어떻게 할 지 등 그에 따른 설정을 할 수 있게 해줍니다.

Manifest.json에는 이름, 작성자, 아이콘, 버전, 설명, 필요한 모든 리소스 목록 등을 설정 할 수 있습니다.

밑은 Manifest.json의 예시입니다.

{
"icons": [
{
"src": "src/assets/image/icon/192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any"
},
{
"src": "src/assets/image/icon/512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
],
"display_override": ["window-controls-overlay"],
"protocol_handlers": [],
"name": "프로젝트 이름",
"short_name": "이름",
"start_url": "http://localhost:3000",
"id": "/",
"display": "standalone",
"description": "설명",
"lang": "Korean",
"dir": "auto",
"theme_color": "#00000",
"background_color": "#000000",
"orientation": "any",
"screenshots": [],
"shortcuts": [
{
"name": "shortcuts으로 설정할 링크 이름",
"url": "/url",
"description": "설명",
"icons": []
}
],
"related_applications": []
}

ServiceWorker

Service Worker는 브라우저의 thread를 이용하는 Web Worker의 일종으로 Client의 Browser에 등록되어 Background로 동작하는 javascript 파일 입니다.

Service Worker는 브라우저에서 서버로 가는 request, response를 가로채는 proxy 서버로 작동하기 때문에 네트워크 작업을 통해 주고 받는 컨텐츠들을 수정하고 저장하는 등을 해 웹 앱에 다양하고 유용한 기능을 구현 할 수 있습니다.

이를 통해 정적 데이터 캐싱, 동적 데이터 캐싱과 같은 일이 가능해지고 캐싱된 데이터를 통해 오프라인 서비스 지원이 가능해집니다.

또 Push API, Notification API등을 Service Worker에 등록 및 연계해서 사용 할 수 있어 웹 알람을 구현 할 수 있는 핵심 기술이라 할 수 있습니다.

다음은 작성한 serviceWorker 코드입니다.

const filesToCache = ['/', '/index.html'];
const CACHE_NAME = 'graphy';

첫 부분에서는 캐싱할 파일들의 경로를 배열로 정의하고, 캐시 이름을 설정합니다. 여기에서는 '/''/index.html' 두 파일을 캐시하고, 캐시 이름을 'graphy'로 정의하였습니다.

self.addEventListener('install', (event) => {
...
});

위의 코드는 Service Worker의 ‘install’ 이벤트에 대한 핸들러를 정의합니다. 이 이벤트는 Service Worker가 처음 설치될 때 발생하며, 보통 캐시에 필요한 asset들을 추가하는 데 사용됩니다.

event.waitUntil(
caches
.open(CACHE_NAME)
.then((cache) => {
return cache
.addAll(
filesToCache.map((file) => new Request(file, { cache: 'reload' })),
)
.catch((error) => {
console.error('Failed to add files to cache:', error);
});
})
.catch((error) => {
console.error('Failed to open cache:', error);
}),
);

‘install’ 이벤트 핸들러에서는 event.waitUntil() 함수를 사용하여 Promise가 resolve 될 때까지 설치 프로세스가 지연되도록 합니다. caches.open()을 통해 캐시를 열고, cache.addAll()을 사용하여 정의한 파일들을 캐시에 추가합니다.

self.addEventListener('fetch', function (event) {
...
});

다음으로 ‘fetch’ 이벤트에 대한 핸들러를 설정합니다. 이 이벤트는 클라이언트가 네트워크 요청을 할 때마다 발생합니다. 여기서는 GET 요청에 대해서만 캐싱 전략을 적용하며, 그 외의 요청에 대해서는 원래의 요청을 그대로 전달합니다.

‘fetch’ 이벤트 핸들러에서는 요청을 캐시에서 먼저 찾아보고, 존재하지 않을 경우에 네트워크를 통해 요청하도록 합니다. 이후 응답을 캐시에 저장하여 다음에 동일한 요청이 있을 경우 캐시에서 바로 가져올 수 있도록 합니다.

마치면서

PWA는 웹의 유연성과 네이티브 앱의 편의성을 결합하여 사용자에게 최적의 경험을 제공하고, 접근성을 높이며 사용자 참여를 촉진하는 효과적인 도구입니다. Manifest.json과 Service Worker를 이용하여 PWA의 핵심 기능을 구현할 수 있습니다. 여러분이 만드는 웹 애플리케이션에 PWA를 적용하고, 그 효과를 직접 체험해 보셨으면 합니다. 감사합니다.

--

--