PWA介紹及快速上手搭建一個PWA應用

PWA初次體驗

​ 前言:本示例不用安裝任何東西

部分資源來自網絡資源及PWA官網,不要把PWA想象的太複雜,跟着示例走一下,你行的。javascript

PWA介紹

一個新的前端技術,PWA( 全稱:Progressive Web App )也就是說這是個漸進式的網頁應用程序。css

官網:https://developers.google.com... html

是 Google 在 2015 年提出,2016年6月才推廣的項目。是結合了一系列現代Web技術的組合,在網頁應用中實現和原生應用相近的用戶體驗。前端

官網上給出 PWA 的宣傳是 : Reliable ( 可靠的 )、Fast( 快速的 )、Engaging( 可參與的 )java

Reliable :當用戶從手機主屏幕啓動時,不用考慮網絡的狀態是如何,均可以馬上加載出 PWA。git

Fast:這一點應該都很熟悉了吧,站在用戶的角度來考慮,若是一個網頁加載速度有點長的話,那麼咱們會放棄瀏覽該網站,因此 PWA 在這一點上作的很好,他的加載速度是很快的。web

Engaging : PWA 能夠添加在用戶的主屏幕上,不用從應用商店進行下載,他們經過網絡應用程序 Manifest file 提供相似於 APP 的使用體驗( 在 Android 上能夠設置全屏顯示哦,因爲 Safari 支持度的問題,因此在 IOS 上並不能夠 ),而且還能進行 」推送通知」 。npm

PWA關鍵技術

  • Service Worker (能夠理解爲服務工廠)
  • Manifest (應用清單)
  • Push Notification(推送通知)

Service Worker

如下用SW來表示json

SW 是什麼呢?這個是離線緩存文件。咱們 PWA 技術使用的就是它!SW 是瀏覽器在後臺獨立於網頁運行的腳本,它打開了通向不須要網頁或用戶交互的功能的大門,由於使用了它,纔會有的那個 Reliable 特性吧,SW 做用於 瀏覽器於服務器之間,至關於一個代理服務器。後端

瀏覽器支持

順便帶一句:目前只能在 HTTPS 環境下才能使用SW,由於SW 的權利比較大,可以直接截取和返回用戶的請求,因此要考慮一下安全性問題。

事件機制

功能(仍是比較逆天的)

  • 後臺數據的同步
  • 從其餘域獲取資源請求
  • 接受計算密集型數據的更新,多頁面共享該數據
  • 客戶端編譯與依賴管理
  • 後端服務的hook機制
  • 根據URL模式,自定義模板
  • 性能優化
  • 消息推送
  • 定時默認更新
  • 地理圍欄

生命週期

  • Parsed ( 解析成功 ): 首次註冊 SW 時,瀏覽器解決腳本並得到入口點,若是解析成功,就能夠訪問到 SW 註冊對象,在這一點中咱們須要在 HTML 頁面中添加一個判斷,判斷該瀏覽器是否支持 SW 。
  • Installing ( 正在安裝 ):SW 腳本解析完成以後,瀏覽器會嘗試進行安裝,installing 中 install 事件被執行,若是其中有 event.waitUntil ( ) 方法,則 installing 事件會一直等到該方法中的 Promise 完成以後纔會成功,若是 Promise 被拒絕,則安裝失敗,SW會進入 Redundant( 廢棄 )狀態。
  • Installed / Waiting (安裝成功/等待中):若是安裝成功,SW 將會進入這個狀態。
  • Activating ( 正在激活 ):處於 waiting 狀態的 SW 發生如下狀況,將會進入 activating 狀態中:

    當前已無激活狀態的 worker 、 SW腳本中的 self.skipWaiting()方法被調用 ( ps: self 是 SW 中做用於全局的對象,這個方法根據英文翻譯過來也能明白什麼意思啦,跳過等待狀態 )、用戶已關閉 SW 做用域下的全部頁面,從而釋放了當前處於激活狀態的 worker、超出指定時間,從而釋放當前處於激活狀態的 worker

  • Activated ( 激活成功 ):該狀態,其成功接收了 document 全面控制的激活態 worker 。
  • Redundant ( 廢棄 ):這個狀態的出現時有緣由的,若是 installing 事件失敗或者 activating 事件失敗或者新的 SW 替換其成爲激活態 worker 。installing 事件失敗和 activating 事件失敗的信息咱們能夠在 Chrome 瀏覽器的 DevTools 中查看

一個很不錯的全面介紹sw的教程:https://www.villainhr.com/page/2017/01/08/Service%20Worker%20%E5%85%A8%E9%9D%A2%E8%BF%9B%E9%98%B6

Manifest

Web App Manifest 是一個 W3C 規範,它定義了一個基於 JSON 的 List 。Manifest 在 PWA 中的做用有:

​ 可以將你瀏覽的網頁添加到你的手機屏幕上

​ 在 Android 上可以全屏啓動,不顯示地址欄 ( 因爲 Iphone 手機的瀏覽器是 Safari ,因此不支持哦)

​ 控制屏幕 橫屏 / 豎屏 展現

​ 定義啓動畫面

​ 能夠設置你的應用啓動是從主屏幕啓動仍是從 URL 啓動

​ 能夠設置你添加屏幕上的應用程序圖標、名字、圖標大小

Push Notification

Push 和 Notification 是兩個不一樣的功能,涉及到兩個 API 。

​ Notification 是瀏覽器發出的通知消息。

​ Push 和 Notification 的關係,Push:服務器端將更新的信息傳遞給 SW ,Notification: SW 將更新的信息推送給用戶。

PWA示例

準備

咱們先建立一個關於 PWA 的項目文件夾,

進入文件夾下咱們準備一張 120x120的圖片一張,做爲咱們的應用程序圖標。

建立一個 index.html 文件

建立一個 main.css 文件

建立一個 manifest.json 文件

建立一個 sw.js 文件

index.html

<!DOCTYPE html>
<html lang="en">
<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">
  <link rel="manifest" href="manifest.json">
</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 中判斷的語句,瀏覽器支持就會打印出這一句話。

接下來咱們斷網操做,在 Application 中給 Offline 打上對勾就行啦。而後刷新頁面,咱們仍然能看到以前的頁面,緣由就是咱們在上圖看到,他的資源是從 SW 上得到到的。當咱們第一次打開這個頁面的時候,Resopnse 對象被存到了 Cache Storage ( 定義在 SW 規範中 ,相關資料請同窗們自行查詢啦 )中,咱們看下圖:

經過存放到 Cache Storage 中,咱們下次訪問的時候若是是弱網或者斷網的狀況下,就能夠不走網絡請求,而直接就能將本地緩存的內容展現給用戶,優化用戶的弱網及斷網體驗。

這個時候確定會有同窗在想,若是內容更新了,那麼頁面展現的內容是新內容呢仍是舊內容呢?下面咱們操做一下,打開 index.html 文件,咱們在 body 中添加一個 p 標籤 ,而後回到頁面刷新。

咱們看到,頁面上的內容並無顯示出我剛剛添加的那個 p 標籤。這說明了,咱們拿到的數據仍是從 Cache Storage 中獲取到的,Cache Storage中的內容並無更新,強制刷新也不行哦,那麼咱們怎麼才能讓我剛剛添加的那個 p 標籤顯示出來呢。

咱們打開 sw.js 腳本文件,咱們修改一下 cacheStorageKey。

修改後,咱們再次打開該網址,強制刷新下或者關掉瀏覽器從新打開。

頁面中出現了剛剛添加的P標籤,咱們再看一下 Cache Storage 中的緩存名字,已經被修改。

總結

若是是使用coding或者gitHub提供的pages服務,則須要注意最好綁定下獨立域名。若是不綁定則注意下文件請求路徑便可。

研究PWA門檻不低,部署的服務器要求HTTPS,ServiceWorker涉及API衆多,須要單獨學習,另外npm中也已經有這個包了https://www.npmjs.com/package... ,玩玩能夠,真正部署到項目生產環境可能坑不少,但有坑填坑,不折騰還叫前端麼。

相關文章
相關標籤/搜索