PWA的探索與應用

来源:https://www.cnblogs.com/qcloud1001/archive/2019/01/11/10256645.html
-Advertisement-
Play Games

本文由雲+社區發表 PWA(Progressive Web App)起源背景 傳統的Web網頁存在以下幾個問題: 進入一個頁面必須要記住它的url或者加入書簽,入口不便捷; 沒網路就沒響應,不具備離線能力; 不像APP一樣能進行消息推送。 Native app: 開發成本高 軟體上線需要審核 即使使 ...


本文由雲+社區發表

PWA(Progressive Web App)起源背景

傳統的Web網頁存在以下幾個問題:

  • 進入一個頁面必須要記住它的url或者加入書簽,入口不便捷;
  • 沒網路就沒響應,不具備離線能力;
  • 不像APP一樣能進行消息推送。

Native app:

  • 開發成本高
  • 軟體上線需要審核
  • 即使使用頻率不高,想使用一個app必須先下載安裝

PWA概念的提出

2016 年Google I/O 大會上提出一個 Next Web Generation 的概念。PWA是在傳統Web應用的基礎上,結合Manifest和service worker,完善Web應用的一些能力,比如:

  • 添加至主屏幕,點擊主屏幕圖標可以實現啟動動畫以及隱藏地址欄
  • 實現離線緩存功能,即使用戶手機沒有網路,依然可以使用一些離線功能
  • 消息推送

PWA技術點

Web App Manifest

Web App Manifest 技術實現了將PWA網頁應用 添加至桌面的功能,但該項技術目前仍處於實驗性階段,各瀏覽器支持度不高

imgimage.png

PWA 站點部署的 manifest.json文件滿足以下條件時會自動顯示橫幅:

- short\\_name (主屏幕顯示)
- name (安裝橫幅顯示)
- icons (必須包含一個 mime 類型為 image/png 的圖標聲明)
- start\\_url (應用啟動地址)
- display (必須為 standalone 或 fullscreen)
- 站點註冊 Service Worker。
- 站點支持 HTTPS 訪問。
- 同一瀏覽器中站點至少被訪問兩次,間隔至少為 5 分鐘。

Service Worker

​ PWA應用的離線體驗、定期的後臺同步以及推送通知等功能的實現依賴於Service Worker技術,下圖為目前SW技術的支持度。

img

SW具有以下特征:

  • 一個獨立的 worker 線程,獨立於當前網頁進程,有自己獨立的 worker context。
  • 一旦被 install,就永遠存在,除非被手動 unregister
  • 用到的時候可以直接喚醒,不用的時候自動睡眠
  • 離線內容開發者可控
  • 能向客戶端推送消息
  • 不能直接操作 DOM
  • 必須在 HTTPS 環境下才能工作
  • 非同步實現,內部大都是通過 Promise 實現

Service Worker生命周期

img

  • installing:這個狀態發生在 SW 註冊之後開始安裝,install 事件回調中執行skipWaiting()方法表示強制當前處在 waiting 狀態的 Service Worker 進入 activate 狀態。
  • installed:SW已經完成了安裝,等待其他的 SW 線程被關閉。
  • activating:在這個狀態下清除其他的worker 以及關聯緩存的舊緩存資源,等待新的 SW線程被激活。在 activate 事件回調中執行self.clients.claim()方法表示取得頁面的控制權, 這樣之後打開頁面都會使用版本更新的緩存。舊的 Service Worker 腳本不再控制著頁面,之後會被停止。
  • activated:在這個狀態可以處理功能性的事件 fetch (請求)、sync (後臺同步)、push (推送)。
  • 廢棄狀態 ( redundant ):這個狀態表示一個 Service Worker 的生命周期結束。

Service Worker 支持的事件

img

  • install:Service Worker 安裝成功後被觸發的事件, 在事件處理函數中可以添加需要緩存的文件
  • activate:當 Service Worker 安裝完成後併進入激活狀態,會觸發 activate 事件。通過監聽 activate 事件你可以做一些預處理,如對舊版本的更新、對無用緩存的清理等。
  • message:Service Worker 運行於獨立 context 中,無法直接訪問當前頁面主線程的 DOM 等信息,但是通過 postMessage API,可以實現他們之間的消息傳遞,這樣主線程就可以接受 Service Worker 的指令操作 DOM。
  • fetch :當瀏覽器在當前指定的 scope 下發起請求時,會觸發 fetch 事件,並得到傳有 response 參數的回調函數。fetch 事件特別重要,因為它能夠定義你的緩存策略。也就是說,你可以決定何時使用緩存數據,何時使用網路請求來的數據。
  • push:push 事件是為推送準備的。通過 PUSH API,當訂閱了推送服務後,可以使用推送方式喚醒 Service Worker 以響應來自系統消息傳遞服務的消息,即使用戶已經關閉了頁面。
  • sync:sync 事件由 background sync (後臺同步)發出。background sync 是 Google 配合 SW 推出的 API,用於為 Service Worker 提供一個可以實現註冊和監聽同步處理的方法。但它還不在 W3C Web API 標準中。在 Chrome 中這也只是一個實驗性功能,需要訪問 chrome://flags/#enable-experimental-web-platform-features ,開啟該功能,然後重啟生效。Sync 事件允許延遲網路任務,直到用戶連接上網路,它實現的功能通常被稱為後臺同步。這對於在離線模式下,確保用戶啟動的任何有網路依賴的任務,最終都將在網路再次可用時達到其預期目的,是非常有用的。

Service Worker 的工作原理

Service Worker是基於註冊、安裝、激活等步驟

註冊

if ('serviceWorker' in navigator) {
window.addEventListener('load', function () {
    navigator.serviceWorker.register('/jslearning/sw.js') // 預設作用域為jslearning下,也可以通過設置scope參數進行設置
        .then(function (registration) {
            // 註冊成功
            console.log('ServiceWorker registration successful with scope: ', registration.scope);
        })
        .catch(function (err) {
            // 註冊失敗:(
            console.log('ServiceWorker registration failed: ', err);
        });
});
}

安裝

this.addEventListener('install', function(event) {
  console.log('V1 installing…');
  //需要緩存的重要的高優先順序資源
  var vipUrlsToPrefetch = [
'./index.html'
  ];
  //次重要的資源
  var urlsToPrefetch = [
'./icon.png'
  ];
  event.waitUntil(
caches.open(OFFLINE_CACHE_NAME).then(function(cache) {
  //urlsToPrefetch非重要資源,即使有資源載入失敗也不影響Service Worker安裝
  cache.addAll(urlsToPrefetch);
  //vipUrlsToPrefetch中資源全部請求成功,Service Worker安裝事件才順利完成,可以進入激活事件
  return cache.addAll(vipUrlsToPrefetch);
})
  );      
});

激活

//Service Worker激活事件
this.addEventListener('activate', function(event) {
  //在激活事件中清除非當前版本的緩存避免用戶存儲空間急劇膨脹
  event.waitUntil(caches.keys().then(function(cacheNames) {
console.log('V1 activate');
return Promise.all(cacheNames.map(function(cacheName) {
    if (cacheName !== OFFLINE_CACHE_NAME) {
      if(cacheName.indexOf(OFFLINE_CACHE_PREFIX) != -1) {
        return caches.delete(cacheName);
      }
    }
}));
  }));
});

Service Worker更新

  • 如果線程的位元組與已有的SW線程位元組不同,瀏覽器則考慮更新SW線程。
  • 更新的SW線程與現有SW線程一起啟動,並獲取自己的 install 事件。
  • 如果新工作SW線程出現不正常狀態代碼(例如,404)、解析失敗,在執行中引發錯誤或在安裝期間被拒,則系統將捨棄新工作線程,但當前工作線程仍處於活動狀態。
  • 安裝成功後,更新的工作線程將 wait,直到現有工作線程式控制制0個客戶端。
  • self.skipWaiting() 可跳過等待情況,這意味著sw線程在安裝完後立即激活。

Service Worker緩存策略

​ Service Worker緩存策略大部分在fetch與install時間中定義,對於某些固定不變的靜態資源,可以在Service Worker初次安裝的install事件中將其緩存,但資源過大或者網路不佳都會造成資源並未全部下載成功而導致Service Worker安裝被中斷安裝失敗。SW主要有以下幾類緩存策略:

  • 不影響安裝的資源預緩存
  • 漸進式緩存
  • 僅使用緩存、僅使用網路
  • 緩存優先 、網路優先
// 漸進式緩存
var addToCache = function(req) {   
  return fetch(req.clone()).then(function(resp) {   
    var cacheResp = resp.clone();
    if (!resp.ok) {
      return resp;
    }
    caches.open(OFFLINE_CACHE_NAME).then(function(cache) {
      cache.put(req.clone(), cacheResp);
    });
    return resp;
  });
};
 
this.addEventListener('fetch', function(event)  {
  event.respondWith(
     caches.open(OFFLINE_CACHE_NAME).then(function(cache) {
          return cache.match(event.request);
      }).then(function(response) {
        if (response) {
            return response;
        } else {
            return addToCache(event.request);
        }
    })
  ); 
});

PWA應用可以通過開發者工具中的Application進行查看調試,如下圖所示:

img

PWA優缺點總結

優點

  • 可以將app的快捷方式放置到桌面上,全屏運行,與原生app無異
  • 能夠在網路差和斷網條件下
  • 推送消息的能力
  • 快速響應用戶指令

缺點

  • 支持率不高
  • Chrome在安卓移動端上的占有率很低
  • 依賴的GCM服務在國內無法使用
  • 微信小程式的競爭

PWA應用

  • Lavas 是一套基於 Vue 的 PWA 解決方案,能夠幫助開發者快速搭建 PWA 應用
  • 新浪微博
  • 餓了麽
  • Instagram
  • Twitter
  • Offline Wikipedia
  • Spotlight
  • ...

參考文獻

此文已由作者授權騰訊雲+社區在各渠道發佈

獲取更多新鮮技術乾貨,可以關註我們騰訊雲技術社區-雲加社區官方號及知乎機構號


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • MIUI12系統能有啥方法開啟root超級許可權?各位都清楚,Android機器有root超級許可權,如果手機開啟root相關許可權,可以實現更好的功能,舉例子,各位公司的營銷部門,使用某些營銷軟體都需要在root超級許可權下執行,如果手機無能獲的root的許可權,則沒辦法正常使用相關的功能。 MIUI12系 ...
  • 背景: 由於,項目需要,需要進行視頻通信,把a的畫面,轉給b。 運維部署: APP1:編碼攝像頭採集的數據,並且發送數據到服務端 APP2:從服務端,拉取數據,並且進行解碼顯示 服務端:接收APP1提交的數據,發送APP1提交數據到APP2 應用說明: APP1:camera = Camera.op ...
  • 1.CommonJS 中的 require/exports 和 ES6 中的 import/export 區別? 2.項目做過哪些性能優化? 3.js 非同步載入的方式? 4.get與post 通訊的區別? 5.為什麼虛擬 dom 會提高性能? ...
  • 1 function formatDateTime(date) { 2 var y = date.getFullYear(); 3 var m = date.getMonth() + 1; 4 m = m < 10 ? ('0' + m) : m; 5 var d = date.getDate();... ...
  • 固定導航欄 前言:很多網站都有這種網頁的效果:滑動瀏覽器右側的滾動條,導航欄會一直處於最上方 下麵我就來簡單實現以下這個功能 一.首先我們來寫一下html的結構: 二.我們來簡單寫一下樣式 這個結構可以說是簡單明瞭,由三部分組成 頂部 導航欄 還有主體部分 但是我們並不打算繼續寫下去 我們簡單的用樣 ...
  • ♥緩動動畫函數 · 之前我在博客上寫過勻速的動畫函數 :https://www.cnblogs.com/Lzxgg-xl/p/10227127.html · 與勻速的相比 有相同的地方 也有不同的地方 我在這裡就簡單的寫一遍 一. 首先還是一樣,因為它是個函數體我們要傳參 即 : 1.移動的元素 2 ...
  • datagrid 擴展單元格textarea editor by:授客 QQ:1033553122 測試環境 jquery-easyui-1.5.3 問題描述 如下,在沒有擴展的情況下,初始化如下 手動拖拽,拖拽時一邊往右側拖拽,結果如下,上圖那個拖拽圖標被隱藏了。停止拖拽後無法再次拖拽 解決方案 ...
  • HTML細化知識點總結 1.h1-h6標簽 都是標題標簽,定義一段話的標題,h1最大,依次遞減,h6最小 標題標簽的作用:讓文本加粗顯示 2. 段落標簽:p標簽 用來顯示一段文本(圖片),它會忽略源代碼中的排版 塊元素:獨占一行的元素,和相鄰的元素不能共用同一行,所有的塊元素都有align屬性,h1 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...