WPA-漸進式 web 應用
PWA 是什么
漸進式 Web 應用,提升 web app 瀏覽體驗,
manifest
應用程式清單
基本介紹:
-
web app manifest是 PWA 技術集合中的一部分 -
web app manifest可以讓網站安裝到設備的主螢屏,而不需要用戶通過應用商店下載 -
web app manifest,在一個 JSON 文本檔案中提供有關應用程式的資訊(名稱,作者,圖示和描述等等) -
傳統的 web app 入口
- 網站
- 書簽,收藏夾
- 直接搜索
-
Web app manifest:
- 可以添加到桌面,有唯一的圖示和名稱
- 有啟動時的界面,避免生硬的過渡
- 隱藏瀏覽器相關的 UI,比如地址欄等等
-
適用步驟:
- 在專案根目錄創建一個 manifest.json 檔案
- 在 index.html 引入 manifest.json 檔案
- 在 manifest.json 檔案中提供常見的配置
- 需要在 https 協議或者在 http://localhost 下訪問專案
<link rel="manifest" href="https://www.cnblogs.com/yevin/p/manifest.json" />
-
常見配置清單
- name:應用的指定名稱,安裝橫幅的文字,啟影片面的文字
- short_name:應用的短名稱,用于主螢屏顯示
- start_url:指定用戶從設備啟動應用程式時加載的 URL,可以是絕對路徑和相對路徑
- icons:用于指定可在各種環境中用作應用程式圖示的影像
- background_color:用戶啟動時的背景色
- theme_color:用于配置應用程式的主題顏色
- display:用于指定 web app 的顯示模式
- fullscreen:全屏顯示
- standalone
- minimal-ui
service worker
- 基本介紹
- 標準的 PWA 程式,包括 3 個部分
- https 服務器或者
http://localhost - manifest.json
- service worker
- https 服務器或者
- service worker 和 web worker
- web worker 的使用
- 創建:web worker
var worker = new Worker('work.js') - 在 web work 中進行復雜的計算
- 在 web work 計算結束,通過
self.postMessage(msg)給主執行緒發訊息 - 主執行緒通過
worker.onmessage=function(msg){}監聽訊息 - 主執行緒也可以用同樣的方式給 web worker 進行通訊
- 創建:web worker
- service worker 介紹
- 一旦 install 就會永遠存在,除非手動 unregister
- 用到的時候可以直接喚醒,不用的時候 自動睡眠
- 可以變成攔截代理請求和回傳,快取檔案,快取的檔案可以被網頁行程取到,包括網路離線狀態
- 離線內容開發者可控
- 必需在 HTTPS 環境下才能作業
- 異步實作,內部大都是 Promise 實作
- sevice worker 適用物件
- 在 window.onload 中注冊 service worker,防止與其他資源競爭
- navigator 物件中內置了 serviceWorker 屬性
- service worker 在老版本的瀏覽器中不支持,需要進行瀏覽器兼容
if('serviceWorker in navigator'){}
- 注冊 service worker
navigator.serviceWorker.register('./sw.js'),回傳一個 promise 物件
<script>
//需要在localhost 或者 HTTPS中才能使用
// 網頁加載完成時注冊
window.addEventListener("load", () => {
// 能力檢測
if ("serviceWorker" in navigator) {
navigator.serviceWorker.register("./sw.js").then((res) => {
console.log(res);
});
}
});
</script>
-
service worker 宣告周期
- install 事件會在 service worker 注冊成功時候觸發,主要用于快取資源
- activate 事件會在 service worker 激活的時候觸發,主要用于洗掉舊的資源
- fetch 事件會在發送請求的時候觸發,主要用于操作快取或者讀取網路資源
- 如果 sw.js 發生了改變,install 事件會重新觸發
- activate 事件會在 install 事件后觸發,但是如果現在已經存在 service worker,就會處于等待狀態直到 service worker 終止
- 可以通過
self.skipWaiting()方法跳過等待,回傳一個 promise 物件 - 可以通過
event.WautUntil()方法擴的引數是一個 promise 物件,會在 promise 結束后才會結束當前生命周期函式,防止瀏覽器在一步操作之前就停止了生命周期 - service worker 激活后,會在下一次重繪頁面的時候生效,可以通過
self.clients.claim()立即活的控制權
self.addEventListener("install", (event) => {
console.log("install", event);
});
self.addEventListener("activate", (event) => {
console.log("activate", event);
});
self.addEventListener("fetch", (event) => {
console.log("fetch", event);
});
self.addEventListener("install", (event) => {
console.log("install", event);
// skipWaiting 會讓serviceworker跳過等待,直接進入activate
//waitUntil 等待skipWaiting結束才進入到activate
event.waitUntil(self.skipWaiting());
});
self.addEventListener("activate", (event) => {
console.log("activate", event);
// 表示service worker激活后,立即活的控制權
event.waitUntil(self.clients.claim());
}); //fetch事件會在請求發送的時候觸發
self.addEventListener("fetch", (event) => {
console.log("fetch", event);
});
promise
- 基本適用
- Promise 是異步編程的一種解決方案,比傳統的解決方法,回呼函式和事件更強大
- Promise 可以以鏈式的方式來進行異步編程,解決了回呼地獄的問題
- Promise 常用的靜態方法
- Promise.resolve()回傳一個決議過帶著給定值的 Promise 物件,如果回傳值是一個 Promise 物件,則直接回傳這個 Promise 物件
- Promise.reject()靜態函式 Promise.reject()回傳一個被拒絕的 Promise 物件
- Promise.all() 回傳一個 Promise 實體,等所有 promise 物件都成功了,才成功
- Promise.race()競速,只要有一個 Promise 物件成功了或者失敗了,結果就是成功或者失敗了
async/await
- 基本適用
- ES2017(ES8)標準引入了 async 函式,使得異步操作變得更加方便
- async 用于修飾一個函式 async function fn(){},await 函式會回傳一個 promise 物件
- await 只能出現在 async 函式中,await 后面跟一個 promise 物件,用于獲取 promise 物件成功的結果,如果不是 promise 物件,直接回傳值
- await 會阻塞 async 函式的執行
- await 后面的 promise 如果沒有成功,那么會拋出例外需要用 try catch 語法
fetch api
在 service worker 如果想要發送請求,必需適用 fetch api
基本使用:
fetch("./manifest.json")
.then((res) => {
return res.json();
})
.then((data) => {
console.log(data);
});
cache storage
cacheStorage 介面表示 Cache 物件的儲存,配合 service worker 來實作資源的快取
- cache api 類似于資料庫的操作
- caches.open(cacheName).then(res=>{}),用于打開快取,回傳 一個匹配 cacheName 的 cache 物件的 Promise,類似于連接資料庫
- caches.key() 回傳一個 promise 物件,包括所有的快取 key
- caches.delete(key) 根據 key 洗掉對應的快取
- cache 物件常用方法:
- cache 介面為快取的 Request/Response 物件對提供存盤機制
- cache.put(req,res)把請求當成 key,并且把對應的回應存盤起來
- cache.add(url)根據 url 發起請求,并且吧回應結果儲存起來
- cache.addAll(urls) 抓取一個 url 陣列,并且把結果都儲存起來
- cache.match(req) 獲取 req 對應的 response
開啟快取:
<!-- index.html -->
<script>
// 網頁加載完成時注冊
window.addEventListener("load", async () => {
// 能力檢測
if ("serviceWorker" in navigator) {
try {
const registration = await navigator.serviceWorker.register("/sw.js");
console.log("注冊成功");
} catch (error) {
console.log("注冊成功", error);
}
}
});
</script>
//sw.js
// 主要用來快取內容
const CACHE_NAME = "cache_v1";
self.addEventListener("install", async (event) => {
// 開啟一個cache 得到一個cache物件
const cache = await caches.open(CACHE_NAME);
// 等待cache把所有的資源存盤
await cache.addAll(["/", "/img/icon.png", "/manifest.json", "/index.css"]);
// 會讓service worker跳過等待,直接進入activate
// 等待skipWaiting結束才進入到activate
await self.skipWaiting();
});
// 主要清除舊的快取
self.addEventListener("activate", async (event) => {
const keys = await caches.keys();
// 判斷key 洗掉舊的資源
keys.forEach((key) => {
if (key !== CACHE_NAME) {
caches.delete(key);
}
});
// 表示service worker激活后,立即活的控制權
await self.clients.claim();
});
// fetch事件 會在請求發送的時候觸發
// 判斷資源是否能夠請求成功,如果能請求成功,就回應成功的結果,如果斷網,請求失敗了,讀取cache快取即可
self.addEventListener("fetch", (event) => {
// console.log('fetch', event)
const req = event.request;
event.respondWith(networkFirst(req));
});
// 網路優先
async function networkFirst(req) {
try {
// 優先網路讀取最新的資源
const fresh = await fetch(req);
return fresh;
} catch (e) {
// 去快取中讀取
const cache = await caches.open(CACHE_NAME);
const cached = await cache.match(req);
return cached;
}
}
notification api
- 基本使用:
- Notification API 的通知介面用于向用戶配置和顯示桌面通知
- Notification.permission 可以獲取當前用戶的授權情況
- Default:默認,未授權
- Denied:拒絕的,拒絕無法再次授權
- Granted:授權的,可以彈窗提醒
- 通過
Notification.requestPermission()可以請求用戶的授權 - 通過
new Notification('title',{body:'',icon:''})可以顯示通知 - 在授權通過得情況下,可以在 service worker 中顯示通知
self.registration.showNotification('你好',{body:'msg'})
// 通知訊息
if (Notification.permission === "default") {
Notification.requestPermission();
}
if (navigator.onLine) {
new Notification("提示", {
body: "歡迎使用耶溫記賬本~,此應用為PWA應用支持離線使用~",
});
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/276595.html
標籤:JavaScript
