mitmitwiki
PWA 적용 도전ㄱㅣ...!
kohi ☕
2023. 4. 2. 01:08
PWA는 HTML, CSS, JS와 같은 웹 기술과 네이티브 앱의 장점을 결합한 것이다. 네이티브 앱을 개발하고 유지보수하는 것은 시간이나 비용이 상당히 소요되지만, PWA는 훨씬 더 빠르게 개발할 수 있고 푸시 알림이나 오프라인 지원과 같은 네이티브 앱의 특징들도 전부 제공할 수 있다.
PWA의 세 가지 구성 요소
- HTTPS: PWA는 신뢰할 수 있는 연결 상태에서만 동작하기 때문에, 보안 연결을 통해서 서비스를 제공해야 한다.
- 이번 프로젝트에서는 로컬 환경에서 시도했기 때문에 해당사항 X
- servise worker: 서비스 워커는 백그라운드에서 실행되는 스크립트이다. 네트워크와 관련된 요청의 처리를 돕는다.
- manifest: JSON 파일 형식이며 PWA가 표시되고 기능하는 방식에 대한 정보를 포함한다.
적용 과정
1. PWA용 Maskable 아이콘 제작
2. manifest.json 추가
{
"name": "HeyTossMe",
"short_name": "HeyTossMe",
"icons": [
{
"src": "/icons/maskable_icon_x48.png",
"sizes": "48x48",
"type": "image/png"
},
{
"src": "/icons/maskable_icon_x72.png",
"sizes": "72x72",
"type": "image/png"
},
{
"src": "/icons/maskable_icon_x96.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "/icons/maskable_icon_x128.png",
"sizes": "128x128",
"type": "image/png"
},
{
"src": "/icons/maskable_icon_x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/icons/maskable_icon_x192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any maskable"
},
{
"src": "/icons/maskable_icon_x384.png",
"sizes": "384x384",
"type": "image/png"
},
{
"src": "/icons/maskable_icon_x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"start_url": "/",
"display": "standalone",
"background_color": "#FFFFFF",
"theme_color": "#ec7357"
}
- name: 설치 페이지, 웹 스토어, 앱 관리 페이지 등에서 표시되는 이름
- short_name: 앱을 설치했을 때 런처에서 보이는 이름
- icons: ㅈㄱㄴ
- start_url: 앱을 실행하면 표시되는 주소
- display
- browser: 일반적인 브라우저
- standalone: 주소창이 사라진 형태
- minimal-ui: standalone에서 뒤로 가기, 새로 고침 등의 키가 추가된 형태
- fullscreen: 전체 화면으로 앱 표시
- background_color: 앱이 로딩되는 동안 배경에 표시되는 색
- theme_color: 툴바, 상단바 색상
3. root html에 manifest 추가
<link rel="manifest" href="/manifest.json" />
여기까지 문제 없으면 Application > manifest 이르케 됨 ▼
4. offline.html 추가
<!DOCTYPE html>
<html>
<head>
<title>Not Connected</title>
<link
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/css/all.min.css"
rel="stylesheet"
/>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<style>
body {
width: 100%;
min-height: 100vh;
display: relative;
margin: 0;
padding: 0;
}
.wrapper {
position: absolute;
top: 50%;
left: 50%;
align-items: center;
justify-content: center;
-webkit-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
-o-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
text-align: center;
}
h1 {
color: #ec7357;
font-weight: bold;
font-size: 50px;
letter-spacing: 5px;
line-height: 1rem;
text-shadow: 0 0 3px #ec7357;
}
h4 {
color: #ec7357;
font-weight: 300;
font-size: 16px;
}
.button {
display: block;
margin: 20px 0 0;
padding: 15px 30px;
letter-spacing: 5px;
border-radius: 0.4rem;
text-decoration: none;
background-color: #ec7357;
box-shadow: inset 0.2rem 0.2rem 1rem #ff7d5e, inset -0.2rem -0.2rem 1rem #bd5d46;
color: white;
}
</style>
</head>
<body>
<!-- This file lives in public/404.html -->
<div class="wrapper">
<h1>OFFLINE</h1>
<h4>Please check your internet connection</h4>
<a href="https://github.com/hey-tossme" class="button">github</a>
<a
href="https://www.notion.so/trustmitt/0224991ff0d945879625f77d6a99218b"
class="button"
>notion</a
>
</div>
</body>
</html>
5. service-worker.js 추가
const CACHE_NAME = "cache-v1";
const FILES_TO_CACHE = ["/offline.html", "/public/icons/favicon.ico"];
self.addEventListener("install", (event) => {
event.waitUntil(caches.open(CACHE_NAME).then((cache) => cache.addAll(FILES_TO_CACHE)));
});
self.addEventListener("activate", (event) => {
event.waitUntil(
caches.keys().then((keyList) =>
Promise.all(
keyList.map((key) => {
if (CACHE_NAME !== key) return caches.delete(key);
})
)
)
);
});
self.addEventListener("fetch", (event) => {
if ("navigate" !== event.request.mode) return;
event.respondWith(
fetch(event.request).catch(() =>
caches.open(CACHE_NAME).then((cache) => cache.match("/offline.html"))
)
);
});
6. 해당 코드 작성 후 root html 파일에 스크립트 태그 추가
<script>
if ("serviceWorker" in navigator) {
window.addEventListener("load", () => {
navigator.serviceWorker.register("/service-worker.js");
});
}
</script>
여기까지 완료하면 일어나는 일
성능 점수 눈치껏 못본 척해라
오프라인일 때 offline.html
이 놈 자식을 열어보면은
간지가 폭발하는 웹 애플리케이션이 낙타나고
바탕화면에 바로가기도 생김
레퍼런스
너무 많이 참고했어요 감사합니다