PWA的價值與成立要件

Progressive Web Apps 的價值、應用限制、成立要件。

PWA簡介

PWA 的全名為 Progressive Web Apps ,有以下特徵:

  • 其應用程式可以由 JS、HTML 與 CSS 來組成。

  • 可以被『安裝』到 mobile 系統上。

  • 可以『離線(offline caching)』使用。

  • 可以使用網頁推播通知。

  • PWA 的核心為service workermanifest.json

  • 必需在 HTTPS 環境下才可成立。

白話PWA

PWA用白話來說就是『fake native app』,偽原生APP。構想讓 web app 可以像 native app 一樣的在手機(iOS,Android)上執行。於當初 iPhone 剛出現時 iPhone App 太少,賈伯斯(Steve Jobs)公開提出用來快速積累 iPhone App 讓市場接受 iPhone 來賺大錢。然而 PWA 是在 Google 手上才變得成熟。

PWA - 簡介與使用情境
關於iOS上的PWA應用,你需要知道些什麼?

PWA 歷史

其實早在 2007 年,Steve Jobs 就提出想要把 Web App 包裝成 Native App 的構想,不過後來 Apple 的策略是推出 SDK 讓大家寫 iOS App,再推出 App Store:App 上得去,錢進得來,Apple 發大財。Google 則是一直到 2015 年才隆重推出 PWA 的概念,簡單來說就是讓大家只要維護一套程式碼,就可以在各式各樣的裝置有相似的體驗。爾後 PWA 慢慢發展,近年來 Microsoft 開始攜手和 Google 一起推廣 PWA,Microsoft 開源的 PWA Builder 加入了 Google 制訂的 Web Shorcuts 等協定;在今(2020)年,Amazon 的雲端遊戲串流平臺也使用 PWA 的方式來避開 Apple 訂定的 App Store 規則 [2],畢竟你怎麼可能讓 Apple 審查每一款雲端遊戲才上架?Google 更是直接打造了一款 Chrome OS,系統打開就只有瀏覽器,你可以使用網際網路上幾十億個網站的功能,更可以把其中一些有 PWA 的網站「安裝」在 Chrome OS 的啟動列裡。

為什麼你會需要 PWA 應用程式,原生不好嗎?

PWA 的價值、應用限制、成立要件

PWA 的價值有

  1. 不需要透過 stroe 就可以安裝到手機上。(不用付上架費)

  2. 有部份 native app 的能力。(看開放狀況)

  3. 可用現成的 web application 直接改裝。

  4. offline caching。(這其實不重要尤其是與金錢相關的操作)

iOS 系統上 PWA 應用可以幹什麼?(看開放狀況)

  • 地理定位

  • 傳感器(磁強計、加速度計、陀螺儀)

  • 相機

  • 音頻輸出

  • 語音合成(僅連接耳機)

  • Apple Pay

  • WebAssembly、WebRTC、WebGL 等實驗特性

PWA 應用在安卓上可以做些什麼?(看開放狀況)

  • 在安卓上,你可以存儲超過50 Mb 的東西

  • 如果你不使用該應用,安卓不會刪除它的文件,但是在手機存儲不夠時會刪除。同時,如果用戶安裝或使用頻繁,PWA 應用可以請求永久存儲

  • 為 BLE 設備接入藍牙

  • 通過 Web 共享訪問本地共享對話框

  • 語音識別

  • 後臺同步和網頁推送通知

  • 通過 Web App Banner 邀請用戶安裝 PWA 應用

  • 你可以在一定程度上自定義想要的啟動畫面和方向

  • 使用 WebAPK 和 Chrome,用戶只能安裝同個 PWA 應用的一個實例

  • 使用 WebAPK 和 Chrome,PWA 應用顯示在設置界面中,你還可以看到數據的使用情況;在 iOS 系統中,這些都體現在 Safari 中

  • 使用 WebAPK 和 Chrome,PWA 應用管理著 URL 的用途,如果你得到一個指向 PWA 應用的 URL,它將會在 standalone 模式下打開,而不是在瀏覽器的窗口中

PWA 的應用限制

  1. 不管如何 PWA 就是 web app 的一種特化,仍會受到 web app 本身暨有的限制。

PWA 的成立要件

因為PWA俱有部份native app的能力,所以在安全性上有基本上的要求:

  1. Installable web apps

    • HTTPS

    • A web manifest

    • A service worker with a functional fetch handler

  2. Server workers

    • Requires HTTPS

    • Registered on page load

    • A script that browser runs in the background separate from your web app.

    • Acts a a network proxy, allowing you to control how requests are handled.

manifest.json 的作用:install

它提供了應用程式相關的資訊(像是名稱、作者、圖示、描述)。 manifest 的功用是將 Web 應用程式『安裝』到設備的主畫面,為使用者提供更快速的訪問和更豐富的體驗。

manifest.json是做什麼用的?
manifest.json

serviceWorker.js 的作用:offline caching

Service Worker 是非常強大的 offline caching,讓使用者可以重複使用 cache,即時顯示畫面在網站或應用程式裡,提供優異的效能。

Service Worker 解決了 WEB 用戶無法離線瀏覽的問題,當網站處於離線狀態,沒有辦法利用網路得到更多資料之前,仍然可以提供基本體驗,讓網站更像 Native App、可以提供像是定期更新、推播通知等功能。

Service Workers 不能直接操作 DOM,但是可以通過 postMessage,把消息傳送給頁面,讓頁面去操作 DOM。

Service Worker,在瀏覽器的背景默默地執行,不需要透過網頁的操作觸發,Service Worker 有著自己的生命週期,為了使用 Service Worker,你的網站必須使用 Javascript 進行註冊,並且必須在 localhost 或 HTTPS 的環境底下,才能運行。

Serving files from the cache

以下是數種 offline caching 模式

  • cache only

  • network only

  • cache falling back to network

  • network falling back to cache

  • cache then network

There are a few approaches we don't cover here. See Jake Archibald's Offline Cookbook for a full list.

Service Work 簡介
Caching Files with Service Worker
The Offline Cookbook

實作要點紀錄

在經驗上,只要有HTTPS就可以使用PWA的能力。 serviceWorker.js不實作也沒關系,照樣也是PWA。 然而manifest.json在行動狀置上就有差異了,有manifest.json才能『安裝』(偽裝)成 native app。

下面是 manifest.json 實作紀錄:

wwwroot/manifest.json
{
  "name": "Your PWA full name",
  "version": "0.1.0.0",
  "short_name": "short_name",
  "start_url": "./",
  "display": "standalone",
  "background_color": "#fafafa",
  "theme_color": "#C54DAA",
  "icons": [
    {
      "src": "image/icon-512.png",
      "type": "image/png",
      "sizes": "512x512"
    },
    {
      "src": "image/icon-192.png",
      "type": "image/png",
      "sizes": "192x192"
    }
  ]
}

必要的網站資源 for manifest.json

在主網頁導入 manifest.json 。以 Blazor App 為例的話,就是 _Host.cshtml_Layout.cshtml,在 <head> 區段進行宣示:

_Layout.cshtml
@using Microsoft.AspNetCore.Components.Web
@namespace YourPWAProject.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

<!DOCTYPE html>
<html lang="zh-hant">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>YourPWAProject</title>
  <base href="~/" />
  <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" rel="stylesheet" />
  <link href="_content/MudBlazor/MudBlazor.min.css" rel="stylesheet" />
  <link href="css/site.css" rel="stylesheet" />
  <link href="YourPWAProject.styles.css" rel="stylesheet" />
  <!-- manifest.json 相關:BEGIN -->
  <link href="manifest.json" rel="manifest" />
  <link rel="apple-touch-icon" sizes="512x512" href="icon-512.png" />
  <link rel="apple-touch-icon" sizes="192x192" href="icon-192.png" />
  <!-- manifest.json 相關:END -->
  <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
</head>
<body>
  @RenderBody()
  ...省略...
</body>
</html>

Last updated