如何让你的网站支持PWA?
![如何让你的网站支持PWA?](https://picture.richarvin.com/202403/202403190014.webp)
一、什么是PWA?
渐进式 Web 应用(Progressive Web App,PWA)是一个使用 web 平台技术构建的应用程序,但它提供的用户体验就像一个特定平台的应用程序。它能像网站一样,通过一个代码库在多个平台和设备上运行。它也像一个特定平台的应用程序一样,可以安装在设备上,可以离线和在后台运行,并且可以与设备和其他已安装的应用程序集成。优点是增加了用户的粘性,省去了用户记忆域名的繁琐过程,在Google的大力支持下,对你网站排名SEO的优化也有很大的帮助。
虽然有以上的优点,但是很多人仍会把PWA与传统书签搞混,误以为PWA就是一个书签。那么两者到底有什么区别呢:
![](https://picture.richarvin.com/202310/xnip2023-10-29_02-27-31.png)
二、如何安装PWA?
为你的网站创建一个PWA,我们至少需要以下功能:
- 网站必须支持HTTPS协议
- manifest.json(清单文件)、配置文件中所要的logo图片
- Service Worker(sw.js脚本)
1、创建 manifest.json(清单文件)
{
"name": "HackerWeb",
"short_name": "HackerWeb",
"start_url": "https://www.example.com",
"display": "standalone",
"background_color": "#212121",
"theme_color": "#FF0000",
"description": "A simply readable Hacker News app.",
"dir": "ltr",
"lang": "en-US",
"icons": [
{
"src": "path/maskable48.png",
"sizes": "48x48",
"type": "image/png"
},
{
"src": "path/maskable72.png",
"sizes": "72x72",
"type": "image/png"
},
{
"src": "path/maskable96.png",
"sizes": "96x96",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "path/maskable144.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "path/maskable168.png",
"sizes": "168x168",
"type": "image/png"
},
{
"src": "path/maskable192.png",
"sizes": "192x192",
"type": "image/png"
}
],
"screenshots": [
{
"src": "path/screenshot-desktop.png",
"type": "image/png",
"form_factor": "wide",
"sizes": "2398x1636"
},
{
"src": "path/screenshot-mobile.png",
"type": "image/png",
"sizes": "708x1300"
}
]
}
配置文件必须要的参数:
基于 Chromium 的浏览器,包括 Google Chrome、Samsung Internet 和 Microsoft Edge,要求清单包含以下成员:
- name :表示web应用的名称的字符串,因为它通常被显示给用户(例如,在其它应用程序的列表中,或者作为图标的标签)
- icons :指定了一个对象数组,这些对象表示可以作为不同上下文的应用程序图标的图像文件。icons数组必须包含一个具有purpose属性的对象,并且该purpose属性的值必须包含maskable。
PWA可遮盖图标(maskable)编辑器 - start_url :当用户从设备的应用菜单或主屏幕轻敲web应用的图标时所展示的页面
- display :显示模式。显示模式会更改向用户显示的浏览器UI的大小,范围可以从browser(显示完整的浏览器窗口时)到fullscreen(全屏显示应用程序时)
- "dir": "ltr" 表示文本方向为从左到右 (left-to-right),这是指示浏览器渲染文本的方向。在大多数语言中,如英语、法语、西班牙语等,文本都是从左到右排列的,所以可以使用 "ltr" 来指定文本方向。如果你的应用需要支持从右到左的语言(如阿拉伯语、希伯来语等),你可以将 "dir" 设置为 "rtl",表示文本方向是从右到左。
manifest.json文件一定要存放到你网站的根目录下。
2、配置Service worker(sw.js)
service worker脚本与网页分开运行。通过使用service worker,我们能够为自己的web应用程序创建离线体验。该sw.js文件也要存放到你网站的根目录下。下面是一个官方sw.js代码模版:
const addResourcesToCache = async (resources) => {
// 打开缓存
const cache = await caches.open('v1');
// 将资源添加到缓存中
await cache.addAll(resources);
};
const putInCache = async (request, response) => {
// 打开缓存
const cache = await caches.open('v1');
// 将请求和响应放入缓存
await cache.put(request, response);
};
const cacheFirst = async ({ request, preloadResponsePromise, fallbackUrl }) => {
// 首先尝试从缓存中获取资源
const responseFromCache = await caches.match(request);
if (responseFromCache) {
return responseFromCache;
}
// 接下来尝试使用预加载的响应(如果有的话)
const preloadResponse = await preloadResponsePromise;
if (preloadResponse) {
console.info('使用预加载响应', preloadResponse);
putInCache(request, preloadResponse.clone());
return preloadResponse;
}
// 接下来尝试从网络获取资源
try {
const responseFromNetwork = await fetch(request);
// 响应只能使用一次
// 我们需要保存副本以将一个副本放入缓存
// 并提供第二个副本
putInCache(request, responseFromNetwork.clone());
return responseFromNetwork;
} catch (error) {
const fallbackResponse = await caches.match(fallbackUrl);
if (fallbackResponse) {
return fallbackResponse;
}
// 即使连备用响应也不可用,
// 我们必须始终返回一个 Response 对象
return new Response('网络错误发生', {
status: 408,
headers: { 'Content-Type': 'text/plain' },
});
}
};
const enableNavigationPreload = async () => {
if (self.registration.navigationPreload) {
// 启用导航预加载
await self.registration.navigationPreload.enable();
}
};
// 当服务工作者被激活时执行
self.addEventListener('activate', (event) => {
event.waitUntil(enableNavigationPreload());
});
// 当服务工作者被安装时执行
self.addEventListener('install', (event) => {
event.waitUntil(
addResourcesToCache([
'/sw-test/',
'/sw-test/index.html',
'/sw-test/style.css',
'/sw-test/app.js',
'/sw-test/image-list.js',
'/sw-test/star-wars-logo.jpg',
'/sw-test/gallery/bountyHunters.jpg',
'/sw-test/gallery/myLittleVader.jpg',
'/sw-test/gallery/snowTroopers.jpg',
])
);
});
// 当发出网络请求时执行
self.addEventListener('fetch', (event) => {
event.respondWith(
cacheFirst({
request: event.request,
preloadResponsePromise: event.preloadResponse,
fallbackUrl: '/sw-test/gallery/myLittleVader.jpg',
})
);
});
上述代码是一个使用 Service Worker 的缓存策略示例。它首先尝试从缓存中获取资源,如果不在缓存中,它会检查是否有预加载的响应,然后再尝试从网络获取资源。如果出现网络错误,它会回退到备用响应。在代码中,还有一些用于管理缓存的函数和事件监听器。sw.js被激活时会启用导航预加载。一旦被安装,它会将一组资源添加到缓存中,这些资源在后续的网络请求中可以用于缓存。
所以最重要的是要根据你自己网站的需求,配置相应的缓存策略,通俗的说就是你想让自己站点的哪些静态资源(图片、JS、CSS等不会经常改动的文件)缓存下来,而不需要每次用户访问的时候同样的资源还需要请求服务器,即便断网,用户仍然能够访问曾经打开加载过的资源页面,这样既加快了自己站点的打开速度,一定程度上也缓解了服务器的压力。
3、HTML文件中引入manifest.json以及注册
在HTML的<head>标签中引入manifest.json文件:
<!doctype html>
<html lang="en">
<head>
<link rel="manifest" href="manifest.json" />
<!-- ... -->
</head>
<body></body>
</html>
在HTML的</body>标签之前引入注册的js代码(直接无脑复制粘帖即可):
const registerServiceWorker = async () => {
if ("serviceWorker" in navigator) {
try {
const registration = await navigator.serviceWorker.register("/sw.js", {
scope: "/",
});
if (registration.installing) {
console.log("Service worker installing");
} else if (registration.waiting) {
console.log("Service worker installed");
} else if (registration.active) {
console.log("Service worker active");
}
} catch (error) {
console.error(`Registration failed with ${error}`);
}
}
};
registerServiceWorker();
浏览器开发者工具的应用选项则会显示当前网站PWA的配置信息:清单、Service workers、存储,这里在调试PWA功能的时候会非常有用:
![](https://picture.richarvin.com/202311/wx20231124-125236-2x.png)
三、安装和卸载 PWA Web 应用
安装 PWA
安装PWA 的用户界面因设备和操作系统的组合而异。在 iOS 的 Safari 上,用户界面“添加到主屏幕”会安装 PWA。其他浏览器,包括 Android 上的 Chrome,在浏览器设置菜单中包含应用程序安装命令。在桌面上的 Chrome 和 Edge 中,当用户导航到页面时,如果页面是 PWA,并且浏览器当前未安装该 PWA,URL 地址栏中将显示一个安装图标:
![URL 地址栏中的 PWA 安装提示](https://developer.mozilla.org/zh-CN/docs/Web/Progressive_web_apps/Guides/Installing/pwa-install.png)
当用户选择该图标时,浏览器会显示一个提示,询问是否要安装 PWA,如果用户接受,PWA 将被安装。
![PWA 安装确认提示](https://developer.mozilla.org/zh-CN/docs/Web/Progressive_web_apps/Guides/Installing/installconfirm.jpg)
一旦安装,PWA 将像操作系统上的其他应用程序一样运行。例如,在 macOS 上,图标将显示在 Dock 中,并具有与其他应用程序相同的图标选项:
![PWA 在 MacOS 上的 Dock 中的图标](https://developer.mozilla.org/zh-CN/docs/Web/Progressive_web_apps/Guides/Installing/dock.jpg)
在大多数桌面浏览器上,安装提示位于 URL 栏中。在移动设备上,安装提示通常位于浏览器选项菜单中。无论是哪种浏览器还是操作系统,都需要确认安装。
![在 Android 上安装 PWA 的示例,包括确认、主屏幕图标和离线体验](https://developer.mozilla.org/zh-CN/docs/Web/Progressive_web_apps/Guides/Installing/android_pwa.jpg)
一旦安装,PWA 的行为就像其他已安装的应用程序一样:单击应用程序图标即可打开 PWA,即使用户处于离线状态也可以打开。
所有现代桌面和移动设备都支持安装。PWA 是否可以由浏览器在操作系统上安装取决于浏览器/操作系统的组合。大多数浏览器直接或在安装扩展程序后支持在所有操作系统(如 Chrome OS、MacOS、Windows、Android、Linux 等)上安装 PWA。
卸载PWA
在大多数移动操作系统上,卸载 PWA 的方法与卸载其他应用程序相同。在某些移动操作系统上,PWA 显示在管理从应用商店下载的应用程序的同一控制面板中,可以在那里卸载它们。
在 iOS 上,从 Safari 安装的 PWA 在“应用库”屏幕上列出并可搜索,但不会在“设置”下的其他已安装应用程序中列出。在 iOS 上,长按图标会显示删除书签的用户界面;从主屏幕删除图标会删除 PWA。
在某些桌面操作系统上,可以直接在已打开的 PWA 中卸载 PWA。要卸载,打开 PWA。在打开的应用程序的右上角,有一个图标,必须展开以查看更多工具。根据用于安装 PWA 的浏览器,要么有一个卸载 PWA 的链接,要么有一个打开浏览器设置页面的链接,其中包含一个卸载链接。如果有的话,可以单击下拉菜单中的卸载选项,或在浏览器选项卡中导航到应用程序设置,并点击卸载。
![MS Edge 中的应用程序设置,包含卸载链接](https://developer.mozilla.org/zh-CN/docs/Web/Progressive_web_apps/Guides/Installing/remove.jpg)
在 Edge 中,从打开的下拉菜单中选择应用设置,会打开 MS Edge 浏览器的 edge://apps
标签页。在那里,我们会看到已安装应用程序的列表,每个应用程序都有各种选项,包括“🗑️ 卸载”。确认卸载操作。就这么简单!
在 Edge 中,已安装的 PWA 会列在一个列表中,可以通过在 Edge 浏览器中访问 edge://apps
来管理它们。在 Chrome 中,Google 应用和已安装的 PWA 的列表可以通过在 Chrome 浏览器中访问 chrome://apps
来查看和管理。