PWA

PWA詳解及實踐探索

PWA 不是一項具體的技術,他是應用了一系列技術進行使用體驗優化後的Web APP,具備與Native App 一致的用戶體驗,可以添加主屏圖標、離線可用、接收離線通知等。css

什麼是PWA

PWA 全稱Progressive Web Apps(漸進式Web應用程序),旨在使用現有的web技術提供用戶更優的使用體驗。 PWA 具備三個主要的特性html

  • 可靠  一方面是指 PWA 的安全性,PWA 只能運行在 HTTPS 上;另外一方面是指在網絡不穩定或者沒網狀況下,PWA 依然能夠訪問。
  • 快速  快速響應用戶的交互行爲,而且具備平滑流暢的動畫、加載速度、渲染速度和渲染性能等。
  • 用戶粘性  經過添加到桌面以及離線消息推送,能帶來用戶的第二次訪問,而且依靠良好的用戶體驗吸引用戶再次訪問。 PWA背後不是一種新的技術,而是集合當前多種web技術的一種集合。分別利用各自的功能來完成漸進式的總體需求

下面是幾個demojava

http://boscdn.bpc.baidu.com/assets/Screenrecorder-2018-03-20-21-54-22-56-2a6d5ac3.mp4 http://boscdn.bpc.baidu.com/assets/Screenrecorder-2018-03-21-17-27-31-297-a4d9412e.mp4 https://pwa.rocksgit

Web App Manifest

Web App Manifest 是支持站點在主屏上建立圖標的技術方案,而且定製 PWA 的啓動畫面的圖標和顏色等,以下圖:github

就是一個外鏈的 json 文件,經過 link 來引入:<link rel=「manifest」 href=「/assets/manifest.json」>,文件的具體內容如圖,Web App Manifest 的標準裏還有不少其餘的字段能夠去 W3C 的標準裏查找 當 Web 添加到桌面後,會出現的 icon 和 name。name 就是用來定義桌面上顯示的名字,不過,若是你的名字取的太長,大於 icon 的寬度,可能會形成顯示上的問題。因此,這裏還有另一個 short_name 用來當寬度不夠時,顯示的精簡版字體。web

icons: {Array.<ImageObject>} 應用圖標列表編程

其中 ImageObject 的屬性值包括:json

  • src: {string} 圖標 url
  • type {string=} 圖標的 mime 類型,非必填項,該字段可以讓瀏覽器快速忽略掉不支持的圖標類型
  • sizes {string} 圖標尺寸,格式爲widthxheight,寬高數值以 css 的 px 爲單位。若是須要填寫多個尺寸,則使用空格進行間隔,如"48x48 96x96 128x128「

Display跨域

定義 web 在打開時使用哪一種預覽模式。這裏主要有 4 種:數組

  • fullscreen:全屏。全部可用的區域均可以被排列,目前該特性還未被徹底支持。
  • standalone:當作一個獨立應用。該模式是忽略掉瀏覽器自己的一些導航欄。不過,它能夠進行下拉刷新。
  • minimal-ui:該模式的外觀和 standalone 差很少,不過它會提供用來控制 navigator 的最小 UI。不支持
  • browser:使用默認瀏覽器模式。

就是一個外鏈的 json 文件,經過 link 來引入:<link rel=「manifest」 href=「/assets/manifest.json」>,文件的具體內容如圖,Web App Manifest 的標準裏還有不少其餘的字段能夠去 W3C 的標準裏查找

當 Web 添加到桌面後,會出現的 icon 和 name。name 就是用來定義桌面上顯示的名字,不過,若是你的名字取的太長,大於 icon 的寬度,可能會形成顯示上的問題。因此,這裏還有另一個 short_name 用來當寬度不夠時,顯示的精簡版字體。

Service Worker

Web Worker這個 API 的惟一目的就是解放主線程,Web Worker 是脫離在主線程以外的,將一些複雜的耗時的活交給它幹,完成後經過 postMessage 方法告訴主線程,而主線程經過 onMessage 方法獲得 Web Worker 的結果反饋。

  • Service Worker 在 Web Worker 的基礎上加上了持久離線緩存能力
  • 一旦被 install,就永遠存在,除非被手動 unregister
  • 用到的時候能夠直接喚醒,不用的時候自動睡眠
  • 可編程攔截代理請求和返回,緩存文件,緩存的文件能夠被網頁進程取到(包括網絡離線狀態)
  • 離線內容開發者可控
  • 能向客戶端推送消息

基於瀏覽器中的 javaScript 單線程的現實逐漸不能知足現代web需求的現狀,例如耗時的計算,用戶的交互顯然會受影響。- 爲了將這些耗時操做從主線程中解放出來,早期W3C新增了一個Web Worker 的 API,能夠脫離主線程單獨執行,而且能夠與主線程交互。

  • 不過Web Worker是臨時性的依賴於建立頁面 ,不能知足咱們持久化的需求。
  • 衝着這個目標,下面就比較容易解決了,搞個能持久存在的就好了。
  • 在Web Worker的基礎上,W3C新增了service worker來知足咱們持久化的需求。
  • 其生命週期與頁面無關,關聯頁面未關閉時,它也能夠退出,沒有關聯頁面時,它也能夠啓動功能

Service Worker 的緩存機制是依賴 Cache API 實現的

Chrome搞了個Service Worker出來,給了Web一個能夠跑在後臺的線程,它能夠搭配很是靠譜的Cache API作緩存、能夠攔截全部HTTP請求並使用Fetch API進行response,一個很是完備的Proxy就這麼誕生了。

Service Worker 的工做原理是基於註冊、安裝、激活等步驟在瀏覽器 js 主線程中獨立分擔緩存任務的

要安裝 Service Worker, 咱們須要經過在 js 主線程(常規的頁面裏的 js )註冊 Service Worker 來啓動安裝,這個過程將會通知瀏覽器咱們的 Service Worker 線程的 javaScript 文件在什麼地方呆着。

這段代碼首先是要判斷 Service Worker API 的可用狀況,支持的話我們才繼續談實現,不然免談了。

若是支持的話,在頁面 onload 的時候註冊位於 /sw.js 的 Service Worker 每次頁面加載成功後,就會調用 register() 方法,瀏覽器將會判斷 Service Worker 線程是否已註冊並作出相應的處理。

register 方法的 scope 參數是可選的,用於指定你想讓 Service Worker 控制的內容的子目錄。本 demo 中服務工做線程文件位於根網域, 這意味着服務工做線程的做用域將是整個來源。

Service Worker 線程將接收 scope 指定網域目錄上全部事項的 fetch 事件,若是咱們的 Service Worker 的 javaScript 文件在 /a/b/sw.js, 不傳 scope 值的狀況下, scope 的值就是 /a/b

install 事件咱們會綁定在 Service Worker 文件中,在 Service Worker 安裝成功後,install 事件被觸發。

install 事件通常是被用來填充你的瀏覽器的離線緩存能力。爲了達成這個目的,咱們使用了 Service Worker 新的標誌性的存儲 cache API — 一個 Service Worker 上的全局對象,它使咱們能夠存儲網絡響應發來的資源,而且根據它們的請求來生成key。這個 API 和瀏覽器的標準的緩存工做原理很類似,可是是隻對應你的站點的域的。它會一直持久存在,直到你告訴它再也不存儲,你擁有所有的控制權。localStorage 的用法和 Service Worker cache 的用法很類似,可是因爲 localStorage 是同步的用法

ExtendableEvent.waitUntil() 方法——這會確保 Service Worker 不會在 waitUntil() 裏面的代碼執行完畢以前安裝完成 使用了 caches.open() 方法來建立了一個叫作 v1 的新的緩存,將會是咱們的站點資源緩存的第一個版本。它返回了一個建立緩存的 promise,當它 resolved 的時候,咱們接着會調用在建立的緩存實例(Cache API)上的一個方法 addAll(),這個方法的參數是一個由一組相對於 origin 的 URL 組成的數組,這些 URL 就是你想緩存的資源的列表。

在 activate 事件發生時,經過執行 self.clients.claim() 方法,更新全部客戶端上的 Service

Service Worker 的特殊之處除了由瀏覽器觸發更新以外,還應用了特殊的緩存策略: 若是該文件已 24 小時沒有更新,當 Update 觸發時會強制更新。這意味着最壞狀況下 Service Worker 會天天更新一次。

每次任何被 Service Worker 控制的資源被請求到時,都會觸發 fetch 事件,這些資源包括了指定的 scope 內的 html 文檔,和這些 html 文檔內引用的其餘任何資源(好比 index.html 發起了一個跨域的請求來嵌入一個圖片,這個也會經過 Service Worker)

廢棄狀態 ( redundant ):這個狀態表示一個 Service Worker 的生命週期結束 進入廢棄 (redundant) 狀態的緣由可能爲這幾種: 安裝 (install) 失敗 激活 (activating) 失敗 新版本的 Service Worker 替換了它併成爲激活狀態

Push Notification( 消息通知 )

  • Push 和 Notification 是兩個不一樣的功能,涉及到兩個 API 。
  • Notification 是瀏覽器發出的通知消息。須要用戶的贊成:Notification.requestPermission();
  • Push 和 Notification 的關係,Push:服務器端將更新的信息傳遞給 SW ,Notification: SW 將更新的信息推送給用戶。

Notification 也不是一開始就具有的,這也須要用戶的贊成才行:模擬像 APP 推送,可以打開 APP 這種行爲,在 SW 中監聽 notificationclick 便可

Web Push

首先要生成 pair keys,接着經過客戶端訂閱,而後才能發送其中的 key 是咱們以前用 web-push 生成的。咱們經過 subscribe() 會自動獲得本次訂閱獨一無二的描述,固然,咱們以前須要檢查一下訂閱狀態,若是已經訂閱了,就不必重複訂閱了

後臺也須要存儲該次訂閱的信息。後臺的話,發送 push 給前臺。以後,咱們在 sw.js 中的 push 事件中作相關處理便可,不過,你能不能成功仍是要看運氣的。由於,咱們一直活在牆中,若是你使用 Chrome 的話。它的 message server 你是連不上的。 因此,關於 push 還須要等國內的瀏覽器跟上才行。

PWA 的兼容性

PWA 在 2017 年初,僅僅 Chrome 和 Firefox 支持 PWA,通過一年的發展,國內主流瀏覽器都已經支持 PWA,iOS 在 新發布的11.3 版本中也支持了 PWA。

基於 Vue.js 的 PWA 解決方案

Lavas:https://github.com/lavas-project/lavas

開發桌面端應用

Nw.js: https://nwjs.io/ Electron: https://electron.org.cn/doc/index.html

相關文章
相關標籤/搜索