PWA離線應用
-
前端的日益發展,都離不開效能優化的手段,包括 CDN、CSS Sprite、檔案的合併壓縮、非同步載入、資源快取等等。更多的時候為了減少使用者量的請求,於是就有了PWA,秒開網站,離線訪問等等的炫酷裝B技能。
-
於是就迫不及待想拉開PWA神祕的面紗,使用到下面的:
- vuecli3.0
- register-service-worker
- 一臺不太卡的安卓(安卓版本不夠高,Chrome不能新增到桌面上)
-
先上圖:
vuecli3.0
- vuecli的最新版本vuecli3.1,通過 npm install -g vue@cli 來安裝
- vuecli3.0多了很多神奇方便的功能,作者應該想要簡化開發者的開發過程,有了炫酷的視覺化介面GUI,通過 vue ui 可在瀏覽器檢視、安裝、管理包等等
- vuecli3.0還整合了service worker、一些常用的語法檢測,自動化測試等等的工具
register-service-worker
-
使用過 create-react-app 的小夥伴肯定知道,react官方推薦的腳手架中預設佩帶有 register-service-worker的包,經過打包後,額外生成以下檔案:
-
`manifest.json: 可配置該應用在瀏覽器,桌面中的開啟方式,應用名字,應用執行動畫等等
-
service-worker.js: 可看到被壓縮打包好的service worker的安裝,啟用、解除安裝等等的功能與配置
-
asset-manifest.json: 離線下強制快取的檔案,使得APP可在離線下執行
-
有關service worker的詳細問題可通過以下連結檢視:
後端配置
- 離線快取需要後臺配合,通過有效的快取達到離線的效果,怎樣的快取才是有效的?就是強制快取啊!
- 強制快取與協商快取都為快取,主要有以下的不同:
- 協商快取:有快取,但是會主動請求伺服器後,伺服器不返回任何資源
- 強制快取:有快取,不會請求伺服器,使用本地或者記憶體或者service worker中的快取
- 先科普下快取的分佈圖:
- 在Chrome控制檯的 Network 中檢視頁面載入時所下載的資源,會發現有些資源會有cache from disk、cache from memory等等,還會有些資源直接顯示該資源的資原始檔大小,那麼這是怎麼回事呢?
- cache from disk: 這是強制快取,表示該資源從本地的快取檔案中拉取資源
- cache from memory:這是強制快取,表示該資源從記憶體中拉取資源
- 直接顯示資源大小:這是協商快取或者是不存在快取,每次都是從伺服器下載該資源
- 這裡就以express為例子,需要設定公用過濾器,為GET請求設定強制快取,時間為兩小時
//以下的Code設定了公用的響應頭中返回的強快取時間、CORS跨域等等app.all("*", function(req, res, next) {
if(req.path !== "/" &
&
!req.path.includes(".")) {
res.header("Access-Control-Allow-Origin", req.headers["origin"] || "*") res.header("Access-Control-Allow-Credentials", true) res.header("Access-Control-Allow-Headers", 'Content-Type,Content-Length, Authorization, authorization,\'Origin\',Accept,X-Requested-With') res.header("Access-Control-Allow-Methods", "POST,GET,PUT,DELETE,OPTIONS") res.header("Content-Type", "application/json;
charset=utf-8") if(req.method.toUpperCase() === "GET"){
res.header("Cache-Control","max-age=7200")
}
} next()
})複製程式碼
通過設定請求快取後,靜態資源都必須設定為強制快取,才能達到離線訪問的效果。
-
這次採坑中遇到神坑的問題,當伺服器設定了響應頭
res.header("Access-Control-Allow-Origin", req.headers["origin"] || "*")
後,如果同一個瀏覽器都是GET到該伺服器的請求,則會報錯,報錯中顯示跨域禁止,因為上面設定的強制快取的原因,瀏覽器會主動快取該GET請求,所以快取中的GET請求的響應頭中的Access-Control-Allow-Origin
(設定允許域名跨域)會顯示第一次發出GET請求的域名,而第二次同一個瀏覽器不同的域名去GET這個請求,則Access-Control-Allow-Origin
返回的是第一個請求的域名,所以會報錯。 -
最後通過打包後,第一次訪問SPA時,service worker會自動快取該SPA中所需要的資源,而AJAX請求的資料,則是被瀏覽器主動快取的,從而可以達到快取的效果,在安卓的高版本的chrome中,還可以將該SPA像APP一樣打包下載到桌面上,有自己的開機動畫等等。
-
在評論處感謝
王品洲
的提醒:(PC)Chrome不能新增到桌面上 :可以試試 F12->
Application->
Manifest ->
Add to homesreen