干貨 | 10分鐘玩轉PWA
- 2020-10-26 09:53:56
- 薛才杰 原創
- 1911
關于PWA
PWA(Progressive Web App), 即漸進式web應用。PWA本質上是web應用,目的是通過多項新技術,在安全、性能、體驗等方面給用戶原生應用的體驗。而且無需像原生應用那樣繁瑣的下載、安裝、升級等操作。
這里解釋下概念中的“漸進式”,意思是這個web應用還在不斷地進步中。因為目前而言,PWA還沒有成熟到一蹴而就的程度,想在安全、性能、體驗上達到原生應用的效果還是有很多的提升空間的。一方面是構建PWA的成本問題,另一方面是目前各大瀏覽器、安卓和IOS系統對于PWA的支持和兼容性還有待提高。
本文我將從網站緩存、http請求攔截、推送到主屏等功能,結合實例操作,一步步引領大家快速玩轉PWA技術。
Service Worker
Service Worker是PWA的核心技術,它能夠為web應用提供離線緩存功能,當然不僅如此,下面列舉了一些Service Worker的特性:
-
基于HTTPS 環境,這是構建PWA的硬性前提。( LAMP環境網站升級HTTPS解決方案 )
-
是一個獨立的 worker 線程,獨立于當前網頁進程,有自己獨立的 worker context
-
可攔截HTTP請求和響應,可緩存文件,緩存的文件可以在網絡離線狀態時取到
-
能向客戶端推送消息
-
不能直接操作 DOM
-
異步實現,內部大都是通過 Promise 實現
Service Worker生命周期
serviceworker的使用流程可以簡單總結為注冊--安裝--激活。
注冊
注冊其實就是告訴瀏覽器serviceworkerJS文件存放在什么位置,然后瀏覽器下載、解析、執行該文件,進而啟動安裝。這里我創建一個app.js文件,注冊代碼如下,將該文件在網站的head標簽里引入。
if ('serviceWorker' in navigator) {
window.addEventListener('load', function () {
navigator.serviceWorker.register('/sw.js')
.then(function (registration) {
// 注冊成功
console.log('ServiceWorker registration successful with scope: ', registration.scope);
})
.catch(function (err) {
// 注冊失敗:(
console.log('ServiceWorker registration failed: ', err);
});
});
}
安裝
當執行serviceworkerJS文件時,首先觸發的是install事件,進行安裝。安裝的過程就是將指定的一些靜態資源進行離線緩存。下面是我的sw.js文件中的安裝代碼:
var CACHE_VERSION = 'sw_v8';
var CACHE_FILES = [
'/js/jquery/min.js',
'/js/zui/min.js',
'/js/chanzhi.js',
];
self.addEventListener('install', function (event) {
event.waitUntil(
caches.open(CACHE_VERSION)
.then(cache => cache.addAll(CACHE_FILES)
));
});
激活
當安裝成功后,serviceworker就會激活,這時就會處理 activate 事件回調 (提供了更新緩存策略的機會)。并可以處理功能性的事件 fetch (請求)、sync (后臺同步)、push (推送)。
self.addEventListener('activate', function (event) {
event.waitUntil(
caches.keys().then(function(keys){
return Promise.all(keys.map(function(key, i){
if(key !== CACHE_VERSION){
return caches.delete(keys[i]);
}
}));
})
);
});
serviceworker的緩存功能
安裝時,serviceworker將我們指定的靜態資源進行緩存(即預緩存),你也許會問,如果是實時的動態內容怎么辦,我們不可能預先將所有的文件資源提前指定好,讓serviceworker緩存。這就要提到serviceworker的攔截HTTP請求響應的特性了。
serviceworker攔截http請求,首先去檢查請求的資源在緩存中是否存在,如果存在,則直接從緩存中調用,而且即便是無網絡情況下,serviceworker也能調用緩存中的資源。如果緩存中沒有請求的資源,則通過網絡去服務器上檢索,而且在找到并響應時,serviceworker會將其存入緩存中,以備下次再請求時直接從緩存中調用。
serviceworker緩存流程
serviceworker文件中fetch事件代碼如下:
self.addEventListener('fetch', function (event) { event.respondWith( caches.match(event.request).then(function(response){ if(response){ return response; } var requestToCache = event.request.clone(); return fetch(requestToCache).then( function(response){ if(!response || response.status !== 200){ return response; } var responseToCache = response.clone(); caches.open(CACHE_VERSION) .then(function(cache){ cache.put(requestToCache, responseToCache); }); return response; } ); }) ); });
在網站前臺通過瀏覽器開發者工具,我們可以看下從緩存中調用資源的效果:
我這里操作演示用的是谷歌瀏覽器,下面是各大瀏覽器對于serviceworker的支持情況:
serviceworker瀏覽器支持情況
添加到主屏
PWA支持將web應用在主屏桌面上添加一個快捷方式,以方便用戶快速訪問,同時提升web應用重復訪問的幾率。你也許會說,現在移動端上的瀏覽器功能列表里一般都提供了“添加到桌面”的功能呀,但是PWA與瀏覽器自帶的添加到桌面的實現方式不同。
PWA不需要用戶刻意去功能列表中使用這個功能按鈕,而是在用戶訪問web應用時,直接在界面中提示一個添加到主屏桌面的橫幅,從web應用角度而言,這其實就是主動與被動的區別。
PWA實現該功能非常簡單,只需要一個manifest.json文件,文件中用戶可以自定義應用的啟動頁面、 模板顏色、圖標等內容。下面是我的manifest.json文件設置,大家可作參考:
{ "short_name": " 蟬知 資源站", "name": "蟬知資源站", "icons": [ { "src": "chanzhiicon.png", "type": "image/png", "sizes": "48x48" }, { "src": "192.png", "type": "image/png", "sizes": "192x192" }, { "src": "512.png", "type": "image/png", "sizes": "512x512" }, { "src": "144.png", "type": "image/png", "sizes": "144x144" } ], "start_url": "/index.html", "display": "standalone", "background_color": "#2196F3", "orientation": "landscape", "theme_color": "#2196F3" }
需要提醒的是,目前移動端IOS系統的支持并不好,安卓手機上須使用57版本以上的谷歌瀏覽器可以支持該功能,下面是我在安卓手機上的操作演示:
添加到主屏
小結
PWA技術正被廣大企業及開發者們關注,雖然目前各設備的支持兼容有待提高,但這些都正在不斷的改善進步。我也相信在不久的將來,PWA技術會逐步廣泛普及,為廣大企業和用戶帶來便利。本文和大家一起分享了PWA的相關技術與實例操作,后面還會就消息推送、數據同步等功能做進一步探討交流。如果大家在學習PWA的過程中遇到其他問題,歡迎一起討論交流。