1.什麼是pwa?
PWA是指可以在任何浏覽器上執行的支援網際網路的應用程式,它是由伺服器端腳本(PHP和ASP)和用戶端腳本(JavaScript和HTML)組成的。
一個 PWA 應用首先是一個網頁, 可以通過 Web 技術編寫出一個網頁應用. 随後添加上 App Manifest 和 Service Worker 來實作 PWA 的安裝和離線等功能。解決了哪些問題?可以添加至主螢幕,點選主螢幕圖示可以實作啟動動畫以及隐藏位址欄實作離線緩存功能,即使使用者手機沒有網絡,依然可以使用一些離線功能-實作了消息推送。
2.PWA的原理是什麼,它是如何開始工作的
第一步:使用HTTPS
第二步:建立一個應用程式清單(Manifest)
第三步:建立一個 Service Worker
第四步:建立可用的離線頁面
3.PWA示例
我們先建立一個關于 PWA 的項目檔案夾,
進入檔案夾下我們準備一張 120x120的圖檔一張,作為我們的應用程式圖示。
建立一個 index.html 檔案
建立一個 main.css 檔案
建立一個 manifest.json 檔案
建立一個 sw.js 檔案
index.html
<!DOCTYPE html>
<html >
<head>
<meta charset="UTF-8">
<title>Hello PWA</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<link rel="stylesheet" href="main.css" target="_blank" rel="external nofollow" >
<link rel="manifest" href="manifest.json" target="_blank" rel="external nofollow" >
</head>
<body>
<h3>Hello PWA</h3>
</body>
<script>
// 檢測浏覽器是否支援SW
if(navigator.serviceWorker != null){
navigator.serviceWorker.register('sw.js')
.then(function(registartion){
console.log('支援sw:',registartion.scope)
})
}
</script>
</html>
main.css
h3{
color: #f00;
}
manifest.json
short_name: “ " 使用者主螢幕上的應用名字
display : “standalone" 設定啟動樣式,讓您的網絡應用隐藏浏覽器的 URL 位址欄
start_url : “/“ 設定啟動網址,如果不提供的話,預設是使用目前頁面
theme_color : “ “ 用來告知浏覽器用什麼顔色來為位址欄等 UI 元素着色
background_color: “ ” 設定啟動頁面的背景顔色
icons:”” 就是添加到主螢幕之後的圖示
{
"name": "一個PWA示例",
"short_name": "PWA示例",
"start_url": "/index.html",
"display": "standalone",
"background_color": "#fff",
"theme_color": "#3eaf7c",
"icons": [
{
"src": "/youhun.jpg",
"sizes": "120x120",
"type": "image/png"
}
],
}
sw.js
看網上很多人都安裝的hs和ngrok去調試,
在這裡為了照顧新手我是直接引用的sw處理靜态緩存,
首先定義需要緩存的路徑,以及需要緩存的靜态檔案的清單。
借助 SW 注冊完成安裝 SW 時,抓取資源寫入緩存中。
使用了一個方法那就是 self.skipWaiting( ) ,為了在頁面更新的過程當中,新的 SW 腳本能夠立刻激活和生效。
importScripts("https://storage.googleapis.com/workbox-cdn/releases/3.1.0/workbox-sw.js");
var cacheStorageKey = 'minimal-pwa-1'
var cacheList=[
'/',
'index.html',
'main.css',
'youhun.jpg'
]
self.addEventListener('install',e =>{
e.waitUntil(
caches.open(cacheStorageKey)
.then(cache => cache.addAll(cacheList))
.then(() => self.skipWaiting())
)
})
處理動态緩存,我們監聽 fetch 事件,在 caches 中去 match 事件的 request ,
如果 response 不為空的話就傳回 response ,最後傳回 fetch 請求,
在 fetch 事件中我們可以手動生成 response 傳回給頁面。更新靜态資源,
緩存的資源會跟随着版本的更新會過期的,是以會根據緩存的字元串名稱清除舊緩存。
在新安裝的 SW 中通過調用 self.clients.claim( ) 取得頁面的控制權,
這樣之後打開頁面都會使用版本更新的緩存。
舊的 SW 腳本不在控制着頁面之後會被停止,也就是會進入 Redundant 期。
self.addEventListener('fetch',function(e){
e.respondWith(
caches.match(e.request).then(function(response){
if(response != null){
return response
}
return fetch(e.request.url)
})
)
})
self.addEventListener('activate',function(e){
e.waitUntil(
//擷取所有cache名稱
caches.keys().then(cacheNames => {
return Promise.all(
// 擷取所有不同于目前版本名稱cache下的内容
cacheNames.filter(cacheNames => {
return cacheNames !== cacheStorageKey
}).map(cacheNames => {
return caches.delete(cacheNames)
})
)
}).then(() => {
return self.clients.claim()
})
)
})
部署
我們可以把目前pwa目錄的所有内容都扔進伺服器中,或者coding Pages和gitHub Pages也是可以的,
當然,記得開啟https。
在上變介紹過SW的權利比較大,為了安全性,我們使用https協定來通路。
試着通路一下,我們這裡用的coding Pages并且綁定了自己的域名
打開 chrom 的調試工具,打開 application ,點選 service workers 之後我們會發現 sw.js 腳本已經存到了 SW 中 。
我們打開 Network 重新整理頁面一下,看看,我們的頁面資源來自 SW 而不是其他的地方,
在 Console 中也列印出了我們在 index.html 中判斷的語句,浏覽器支援就會列印出這一句話。
通過存放到 Cache Storage 中,我們下次通路的時候如果是弱網或者斷網的情況下,
就可以不走網絡請求,而直接就能将本地緩存的内容展示給使用者,優化使用者的弱網及斷網體驗。
這個時候肯定會有同學在想,如果内容更新了,那麼頁面展示的内容是新内容呢還是舊内容呢?
下面我們操作一下,打開 index.html 檔案,我們在 body 中添加一個 p 标簽 ,然後回到頁面重新整理。
我們看到,頁面上的内容并沒有顯示出我剛剛添加的那個 p 标簽。這說明了,
我們拿到的資料還是從 Cache Storage 中擷取到的,
Cache Storage中的内容并沒有更新,強制重新整理也不行哦,
那麼我們怎麼才能讓我剛剛添加 的那個 p 标簽顯示出來呢。我們打開 sw.js 腳本檔案,我們修改一下 cacheStorageKey。
總結
PWA的核心目标并不是想取代App,就像電子書的出現并沒有取代紙書一樣,它真正想做的相信還是不斷改善使用者體驗,将網絡與應用的長處結合起來。
盡管PWA身後是Web的标準與規範,在使用體驗上也更接近原生App,但有時問題核心并不隻取決于技術與體驗,而更多在對開發者的互惠上,無論是PWA
,小程式,還是快應用,哪個可以讓開發者和商家更快更便捷地搭建自己的服務并推廣出去進而形成商業閉環才是最重要的。
當然,PWA作為開源協作的典範,以及開放的Web特性,人們還是願意看到它完善的那一天。
隻是在那一天來之前,國内局面還是要靠BAT這些更懂商業而不是情懷的公司所掌控