PWA는 Progressive Web Application의 약자로 웹과 네이티브 앱의 기능 모두의 이점을 갖도록 수 많은 현대 웹 기술을 활용하여 개발된 웹 앱입니다.
PWA의 역사는 현대 웹 기술의 발전과 함께 시작되었다. 2015년, 구글은 Progressive Web Apps라는 개념을 처음으로 소개하였다. 이는 사용자가 웹 애플리케이션을 네이티브 앱처럼 경험할 수 있도록 만들기 위한 노력의 일환이다. PWA의 개념은 웹의 장점을 최대한 활용하면서도 오프라인에서의 사용성과 빠른 로딩 속도, 그리고 푸시 알림과 같은 기능을 결합하여 사용자 경험을 향상시키는 것을 목표로 한다. PWA의 역사는 이러한 기술이 탄생한 이후 여러 웹 표준과 기술이 결합되면서 발전해왔다. 2016년에는 PWA를 구현하기 위한 서비스 워커와 웹 앱 매니페스트가 공식적으로 W3C의 추천 표준으로 채택되었다. 이로 인해 개발자들은 PWA를 보다 쉽게 구현할 수 있게 되었다. 이후 수많은 기업들이 PWA 기술을 적용하여 웹 애플리케이션을 개발하였고, 사용자들은 이러한 애플리케이션을 통해 더욱 향상된 경험을 누릴 수 있게 되었다. 특히, 2018년에는 여러 유명한 웹사이트와 애플리케이션이 PWA로 전환되면서 그 가능성이 더욱 주목받았다. 현재 PWA는 다양한 플랫폼에서 지원되며, 개발자와 사용자 모두에게 긍정적인 영향을 미치는 기술로 자리 잡았다.
웹과 네이티브 앱의 기능 모두의 이점을 모두 가질 수 있기 떄문입니다.
웹의 이점 :
네이티브 앱의 이점:
PWA 라우트를 시도하고 네이티브 앱 보다 더 향상된 웹 사이트 경험을 선택하여 측정 가능한 의미있는 이득을 본 회사들의 성공 스토리가 많습니다.
앱이 위의 요구 사항을 만족하여 다음 기능들이 구현되었을 때 PWA라고 볼 수 있습니다.
(Lighthouse로 자신의 웹앱이 PWA를 만족하는 지 확인할 수 있었지만, 이제 못함…ㅠ)
설치 이벤트를 처리하는 코드
self.addEventListener("install", event => { // 요청 처리 코드 });
활성화 이벤트를 처리하는 코드
self.addEventListener("activate", event => { // 요청 처리 코드 });
fetch 이벤트를 처리하는 코드
```jsx
self.addEventListener(fetch", event => { // 요청 처리 코드 });
```
요청을 가로채고 캐시된 자원을 제공하기 위한 fetch 이벤트를 설정한다. 이 과정에서 와 같은 코드를 사용하여 네트워크 요청을 처리할 수 있다.
push 이벤트를 처리하는 코드
self.addEventListener("push", function (e) {
if (!e.data || !e.data.json()) {
console.error("Push event does not contain valid JSON data.");
return;
}
const resultData = e.data.json().notification;
const resultURL = e.data.json().data.click_action;
if (!resultData || !resultData.title || !resultData.body) {
const notificationTitle = "Notification data is incomplete.";
const notificationOptions = {
body: "Notification data is incomplete.",
};
self.registration.showNotification(notificationTitle, notificationOptions);
return;
}
const notificationTitle = resultData.title;
const notificationOptions = {
body: resultData.body.split("\\n").join("\n"),
icon: resultData.image,
tag: resultData.tag,
data: { click_action: resultURL },
};
self.registration.showNotification(notificationTitle, notificationOptions);
});
웹푸시 클릭 이벤트를 처리하는 코드
self.addEventListener("notificationclick", function (event) {
const resultURL =
event.notification.data && event.notification.data.click_action;
if (!resultURL) {
const notificationTitle = "URL is missing.";
const notificationOptions = {
body: "Notification click action URL is missing.",
};
self.registration.showNotification(notificationTitle, notificationOptions);
return;
}
event.waitUntil(
clients
.matchAll({ type: "window", includeUncontrolled: true })
.then(function (clientList) {
for (var i = 0; i < clientList.length; i++) {
var client = clientList[i];
if (client.url === resultURL && "focus" in client) {
return client.focus();
}
}
if (clients.openWindow) {
return clients.openWindow(resultURL);
}
})
);
event.notification.close();
});
if (‘serviceWorker’ in navigator) {
navigator.serviceWorker.register(‘/service-worker.js’);
}
만약 다른 serviceWorker(FCM)를 설치하고 싶다면 register내의 serviceWorker.js파일을 바꾸면 된다.if (‘serviceWorker’ in navigator) {
navigator.serviceWorker.register("./firebase-messaging-sw.js";
}
<!DOCTYPE html>
<html lang="en">
<head>
...
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#ffffff" />
<meta
name="description"
content="아주대학교 공지사항 및 이벤트 알림을 받아보세요!"
/>
<meta content="아주대학교 이벤트 알림 웹앱" property="og:title" />
<meta content="팀 이쿠죠" property="og:description" />
...
</html>
manifest.json
이라는 이름으로 프로젝트의 루트 디렉토리에 위치한다. 다음은 간단한 매니페스트 파일의 예시이다: {
"name": "Witt Web App", // 긴제목
"short_name": "Witt", // 긴 제목이 표시될 자리가 없을 때 표시되는 짧은 제목
"description": "카페, 이벤트의 중심이 되다", // 설치시 아래에 나오는 설명
"icons": [
{
"src": "/icons/icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/icons/icon-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff", // 앱실행시 로고와 함께 뜨는 로딩 화면의 배경색 설정
"theme_color": "#000000" // 앱 상단 바 색깔 설정
}
이 파일은 PWA가 어떻게 작동하는지를 정의하는 중요한 정보를 담고 있다. 매니페스트 파일은 HTML 문서의 “ 섹션에 링크를 통해 추가해야 한다. 예를 들어, 다음과 같이 추가할 수 있다: 이 설정을 통해 브라우저는 해당 매니페스트 파일을 인식하고, 사용자가 웹 애플리케이션을 설치할 수 있도록 안내한다. 또한, 매니페스트의 속성들은 사용자가 홈 화면에 추가한 애플리케이션이 어떻게 표시될지를 결정하므로, 디자인에 대한 신중한 고려가 필요하다. PWA의 매니페스트 구성은 웹 애플리케이션의 성공에 중요한 요소로 작용하며, 이를 통해 사용자는 보다 나은 경험을 할 수 있다.create-react-app
로 설정create-react-app
으로 생성된 프로젝트는 기본적으로 PWA를 지원하며, 서비스 워커를 쉽게 설정할 수 있습니다.create-react-app
설치 (생성된 프로젝트가 없는 경우)bash
코드 복사
npx create-react-app my-pwa-app
serviceWorker
활성화create-react-app
프로젝트는 src/service-worker.js
파일을 포함하고 있습니다. 이를 활성화하려면 src/index.js
파일에서 serviceWorkerRegistration
을 등록해야 합니다.serviceWorkerRegistration.js
가져오기:
javascript
코드 복사
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import * as serviceWorkerRegistration from "./serviceWorkerRegistration";
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("root")
);
// 서비스 워커 등록
serviceWorkerRegistration.register();
src/serviceWorkerRegistration.js
는 이미 create-react-app
에 포함되어 있습니다.
manifest.json
설정public/manifest.json
에서 다음과 같은 PWA 속성을 설정합니다:
json
코드 복사
{
"short_name": "ReactPWA",
"name": "My React Progressive Web App",
"icons": [
{
"src": "icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icon-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
Note: 아이콘 이미지를 public 폴더에 추가해야 합니다.
next-pwa
라이브러리 설치
Next.js 앱을 PWA로 전환하기 위한 플러그인 설치
npm install next-pwa
yarn add next-pwa
next.config.js
설정
next-pwa
를 설정하려면 next.config.js
에서 구성
const withPWA = require('next-pwa')({
dest: 'public', // 서비스 워커 파일을 public 폴더에 생성
register: true, // 앱 로드 시 서비스 워커 등록
skipWaiting: true, // 새로운 서비스 워커 설치 시 기존 워커를 대기하지 않고 바로 활성화
});
module.exports = withPWA({
reactStrictMode: true,
// 추가 Next.js 설정이 여기에 포함될 수 있음
});
manifest.json
생성
manifest.json
은 PWA의 메타정보를 정의하는 파일입니다. 프로젝트의 public
폴더에 생성합니다.
public/manifest.json
:
{
"name": "My Next.js PWA",
"short_name": "NextPWA",
"description": "This is a Progressive Web App built with Next.js.",
"icons": [
{
"src": "/icons/icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/icons/icon-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#000000"
}
아이콘 추가
PWA에서 사용할 앱 아이콘을 public/icons
폴더에 저장합니다. 일반적으로 192x192 및 512x512 크기의 PNG 이미지를 포함해야 합니다.
서비스 워커 테스트
개발 모드에서는 서비스 워커가 작동하지 않습니다. 프로덕션 빌드 후 테스트해야 합니다.
npm run build
npm start
아주대학교 파란학기 프로젝트
웹시스템설계 기말프로젝트
PWA 이점을 나타내는 많은 사례 연구 사이트 : PWA Stats
PWA를 온라인에서 생성 사이트 : PWABuilder
Service worker와 푸시에 관련된 정보 : Service Worker Cookbook