✍️ 오프라인 에서도 동작 가능한 서비스를 만들기 위해 PWA를 사용한 적이 있다. 3년 전만 해도 자료 찾는 것에 애먹었던 기억이 있는데, 현재는 자동으로 코드를 만들어주는 사이트도 나왔다.😮 유용한 사이트와 함께 정리해 보았다.
검색엔진을 통해 찾을 수 있음.
기기의 홈 화면에서 사용할 수 있음.
➡️ manifest 설정 필요
간단하게 URL을 전송해 공유할 수 있음.
오프라인이나 불안한 네트워크 연결에서도 동작함.
➡️ 서비스 워커로 캐시 저장
브라우저의 기본 기능 사용 가능
새 컨텐츠가 생길때마다 푸시알림 가능
🚫 Safari 는 불가.
모든 기기의 화면이나 브라우저에 사용 할 수 있음.
보안 용이
➡️ https 사용 함.
PWA를 적용할 웹 사이트를 https로 연결 한다.
➕ root에 파일 업로드 할 권한 설정 ex) https://사이트주소/mango.txt
manifest 추가
<link>
로 연결한다.<link rel="manifest" href="/manifest.json" />
manifest.json
{
"name": "앱 이름",
"short_name": "앱 이름",
"icons": [
{
"src": "/images/icons/icon-128x128.png",
"sizes": "128x128",
"type": "image/png"
},
{
"src": "/images/icons/icon-144x144.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "/images/icons/icon-152x152.png",
"sizes": "152x152",
"type": "image/png"
},
{
"src": "/images/icons/icon-192x192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any maskable"
},
{
"src": "/images/icons/icon-256x256.png",
"sizes": "256x256",
"type": "image/png"
},
{
"src": "/images/icons/icon-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"start_url": "/",
"display": "standalone",
"background_color": "#121212",
"theme_color": "#f1718c"
}
각 key값 별 속성
name : 설치 페이지, 웹 스토어, 앱 관리 페이지 등에 표시되는 이름.
short_name: 앱 설치 했을 때 런처에 보이는 이름
icons: 앱 설치 시 보이는 아이콘 - 디바이스 별 필요한 크기로 자동으로 가져 감.
icon 이미지 생성 시 유용한 사이트
start_url: 앱 실행시 표시되는 주소
display: 앱이 표시되는 모드
background_color: 앱이 로딩되는 동안 나타나는 배경 색상
theme_color: 툴바, 상단바 색상
(ios일 경우) 메타태그 추가
<link rel="apple-touch-icon" href="/images/icons/icon-152x152.png" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="apple-mobile-web-app-title" content="앱 이름" />
서비스 워커 추가
<script>
로 service-worker.js를 추가 해 준다.// 0. 캐시 이름
const CACHE_NAME = "cache-v1";
// 0.캐싱할 파일 - 사이트 동작에 필요한 리소스들을 입력
const FILES_TO_CACHE = [
"/mango.css"
"/mango.js"
"/mango.jpg"
"/index.html"
"/error.html", // error일 때 보여줄 페이지
"/favicon.ico"
];
// 1. 상술한 파일 캐싱 - 사이트 동작에 필요한 리소스들을 캐시에 추가.
self.addEventListener("install", (event) => {
event.waitUntil(
caches.open(CACHE_NAME).then((cache) => cache.addAll(FILES_TO_CACHE))
);
});
//2. 요청된 리소스를 캐시에서 찾아 보내줌.
// 네트워크에도 요청하여 응답(리소스)을 받은 뒤 캐시에 추가 한다 - 리소스 업데이트
// 네트워크 요청시에도 응답(리소스)이 없으면 error 페이지를 보여준다.
const putInCache = async (request, response) => {
const cache = await caches.open("v1");
await cache.put(request, response);
};
const cacheFirst = async (request) => {
//2-1. 네트워크에서 요청된 리소스를 캐시에서 찾아 보내줌.
const responseFromCache = await caches.match(request);
if (responseFromCache) {
return responseFromCache;
}
//2-2. 네트워크에도 요청하여 응답(리소스)을 받은 뒤 캐시에 추가 한다 - 리소스 업데이트
try {
const responseFromNetwork = await fetch(request);
//응답은 1번 만 읽을 수 있으므로 clone()으로 복사 해서 캐시에 저장한다.
putInCache(request, responseFromNetwork.clone());
return responseFromNetwork;
} catch (error) {
//2-3. 네트워크 요청시에도 응답(리소스)이 없으면 error 페이지를 보여준다.
const fallbackResponse = await caches.match("/error.html");
if (fallbackResponse) {
return fallbackResponse;
}
}
};
self.addEventListener("fetch", (event) => {
event.respondWith(
cacheFirst(event.request)
);
});
상단의 입력 창에 웹사이트 주소를 입력 하면 다음 단계로 넘어감.
옵션 선택 만으로도 코드를 생성해 줌.
표시되는 점수를 통해 PWA로 적합한지 알 수 있음.