讓 PWA 感覺像應用程式一樣

讓漸進式網頁應用程式看起來不像是網站,而是「真實」的應用程式

暢玩 Progressive Web App 上的 Buzz Word bingo 時,「PWA 將僅為網站」,是很好的挑戰。Microsoft 的 PWA 說明文件提醒、我們會在這個網站上介紹,甚至 PWA 提名者也在「法國貝里曼」和 Alex Russell 上寫出這類文章。可以,PWA 其實只是網站,但用途遠不止於此。如果做得好,PWA 將不像網站,而是「真實」的應用程式。 PWA 的運作原理為何?

為了回答這個問題,我會以 Apple Podcast 應用程式為例。 這項功能適用於電腦版 macOS,以及適用於 iOS 行動裝置和 iPad OS 的裝置。 雖然 Podcast 是媒體應用程式,但我在其中說明的核心概念也適用於其他應用程式類別。

iPhone 和 MacBook 並排執行,兩台都執行網播應用程式。
iPhone 和 macOS 上的 Apple Podcast (來源)。

可離線執行

往後當您回想手機或桌上型電腦上的平台專屬應用程式時,最主要的特色就是:您永遠不可能有任何事情。即使我處於離線狀態,Podcast 應用程式仍會持續提供任何內容。沒有網路連線時,應用程式仍會正常開啟。「熱門排行榜」部分不會顯示任何內容,而是會改回顯示「目前無法連線」訊息,以及「重試」按鈕。這或許不是最令人愉快的體驗,但我有點東西。

沒有網路連線時,Podcast 應用程式顯示「目前無法連線」資訊訊息。
Podcast 應用程式沒有網路連線。
如何在網頁上進行

Podcast 應用程式遵循所謂的應用程式殼層模型。顯示核心應用程式所需的靜態內容都會在本機快取,包括左側選單圖示和核心玩家 UI 圖示等裝飾性圖片。只有隨選載入熱門排行榜資料這類動態內容。如果載入失敗,可在本機快取備用內容。 請參閱 App Shell 模型,瞭解如何將此架構模型套用至網頁應用程式。

提供離線內容與可播放媒體內容

在離線狀態下,我仍可透過左側導覽匣前往「已下載」部分,盡情觀看已下載的 Podcast 節目,隨時都可以播放,並會顯示所有中繼資料 (例如圖片和說明)。

Podcast 應用程式,顯示已下載的 Podcast 節目。
即使沒有網路連線,也能播放已下載的 Podcast 節目。
如何在網頁上進行

先前下載的媒體內容可以從快取中提供,例如使用 Workbox 程式庫中的提供快取音訊和影片方案。其他內容隨時可儲存在快取或 IndexedDB 中。如需更多詳細資訊,以及使用特定儲存技術,請參閱網路儲存空間一文。如果有應永久儲存的資料,且在可用記憶體量降低時資料遭到清除的風險,您可以使用 Persistent Storage API

主動下載背景

重新連上網路後,我一定會使用 http 203 這類查詢搜尋內容。當我決定訂閱搜尋結果,HTTP 203 Podcast 就會立即下載系列的最新一集節目,不會問我任何問題。

訂閱後,Podcast 應用程式會立即下載 Podcast 的最新集數。
訂閱 Podcast 後,系統會立即下載最新集數。
如何在網頁上進行

如果下載 Podcast 單集節目,這項作業可能需要較長時間才能完成。背景擷取 API 可讓您將下載作業委派給瀏覽器,由瀏覽器在背景中完成下載作業。在 Android 上,瀏覽器甚至可以進一步將下載作業委派給作業系統,因此瀏覽器不需要持續執行。下載完成後,應用程式的服務工作處理程序就會喚醒,您可以決定如何處理回應。

與其他應用程式分享及互動

「播客」應用程式能自然地與其他應用程式整合。舉例來說,在喜歡的節目上按一下滑鼠右鍵後,我可以將內容分享到裝置上的其他應用程式 (例如「訊息」應用程式),同時也能和系統剪貼簿自然整合。我可以在任一集節目上按一下滑鼠右鍵,然後複製頁面連結。

針對 Podcast 單集節目,已選取「分享單集節目 → 訊息」選項,系統叫用 Podcast 應用程式的內容選單。
將 Podcast 節目分享到「訊息」應用程式。
如何在網頁上進行

Web Share APIWeb Share Target API 可讓應用程式與裝置上的其他應用程式分享及接收文字、檔案和連結。雖然目前網頁應用程式尚無法在作業系統內建的右鍵選單中新增選單項目,但仍可透過許多方式連結或連線至裝置上的其他應用程式。 使用 Async Clipboard API,即可透過程式輔助方式在系統剪貼簿中讀取及寫入文字和圖片資料 (PNG 圖片)。在 Android 中,您可以使用 Contact Picker API,從裝置的聯絡人管理員中選取項目。如果您同時提供平台專屬應用程式和 PWA,可以使用 Get Installed Related Apps API 檢查是否已安裝特定平台的應用程式。在這種情況下,就不必鼓勵使用者安裝 PWA 或接受網路推播通知。

背景應用程式重新整理

在 Podcast 應用程式的設定中,我可以調整應用程式,讓應用程式自動下載新的集數。這表示我什麼都不用考慮,更新內容永遠不會出現。魔法。

在「一般」部分中,Podcast 應用程式的設定選單,「重新整理 Podcast」選項已設為「每小時」。
設為每小時檢查新 Podcast 節目的 Podcast。
如何在網頁上進行

Periodic Background Sync API 可讓應用程式定期在背景重新整理內容,不需要應用程式執行。也就是說,系統會主動提供新內容,讓使用者知道何時想要探索新內容。

狀態已透過雲端同步處理

同時,我的訂閱內容也會同步到我擁有的所有裝置上。在流暢的環境中,我不必擔心手動同步 Podcast 訂閱項目。同樣地,我也不需要擔心,已在電腦上收聽的劇集會佔用行動裝置的記憶體。播放狀態會保持同步,並自動刪除已收聽的節目。

Podcast 應用程式的設定選單,位於「進階」部分中,且已啟用「同步多部裝置的訂閱項目」選項。
系統會透過雲端同步處理狀態。
如何在網頁上進行

同步處理應用程式狀態資料是一項可以委派給 Background Sync API 的工作。同步處理作業本身不一定要立即進行,最終甚至即便使用者再次關閉應用程式亦然。

硬體媒體按鍵控制項

比如說,當我在其他忙著使用其他應用程式時,比如用 Chrome 瀏覽器閱讀新聞頁面時,還是可以使用筆電上的媒體鍵來控制 Podcast 應用程式。 您不需要切換應用程式即可快轉或倒轉。

Apple MacBook Pro 魔術鍵盤,具有附註解的媒體鍵。
您可以使用媒體鍵控制 Podcast 應用程式 (來源)。
如何在網頁上進行

Media Session API 支援媒體金鑰。這麼一來,使用者就能使用實體鍵盤或耳機上的硬體媒體鍵,甚至透過智慧手錶上的軟體媒體鍵控制網頁應用程式。為了讓搜尋作業順利進行,還有一個方法是在使用者搜尋內容的大部分內容時傳送震動模式,例如傳遞片頭或章節界線。

多工處理和應用程式捷徑

當然,我也可以隨時隨地使用 Podcast 應用程式進行多工處理。應用程式有清楚辨別的圖示,這個圖示也可以放在桌面或應用程式的座架上,以便在滿意時立即啟動。

macOS 工作切換器,有許多應用程式圖示可供選擇,其中一個是播客應用程式。
返回 Podcast 應用程式,同時執行多項工作。
如何在網頁上進行

電腦版和行動版的漸進式網頁應用程式可安裝在主畫面、開始選單或應用程式座架上。 系統會透過主動提示或完全由應用程式開發人員控管安裝作業。「需要安裝哪些項目需要哪些條件?」一文已涵蓋所有須知事項。 多工處理時,PWA 不會與瀏覽器不同。

內容選單中的快速操作

最常用的應用程式動作「搜尋」會顯示新內容,以及「檢查新集數」,這兩者位於 Dock 的應用程式內容選單中。透過「選項」選單,我也可以決定是否要在登入時開啟應用程式。

顯示「搜尋」和「查看新集數」選項的 Podcast 應用程式圖示內容選單。
直接透過應用程式圖示使用快速操作功能。
如何在網頁上進行

在 PWA 的網頁應用程式資訊清單中指定應用程式圖示捷徑,即可註冊快速路徑,讓使用者可透過應用程式圖示直接存取常見工作。在 macOS 等作業系統上,使用者也可以在應用程式圖示上按一下滑鼠右鍵,然後將應用程式設為在登入時啟動。我們正在編輯「在登入時執行」提案。

設為預設應用程式

其他 iOS 應用程式,甚至網站或電子郵件都可以使用 podcasts:// 網址配置,與播客應用程式整合。如果我在瀏覽器中點選類似「podcasts://podcasts.apple.com/podcast/the-css-podcast/id1042283903的連結,就會直接開啟播客應用程式,並可決定要訂閱或收聽該 Podcast。

Chrome 瀏覽器顯示確認對話方塊,詢問使用者是否想要開啟播客應用程式。
你可以直接在瀏覽器中開啟 Podcast 應用程式。
如何在網頁上進行

目前仍無法處理完整自訂網址配置,不過我們仍在努力改善 PWA 網址通訊協定處理的提案。目前最佳替代方案是採用 web+ 配置前置字串的 registerProtocolHandler()

本機檔案系統整合

你也許不會馬上想到這一點,但「播客」應用程式自然能與本機檔案系統完美整合。下載 Podcast 單集節目後,該集節目會儲存在我的筆電上,儲存在 ~/Library/Group Containers/243LU875E5.groups.com.apple.podcasts/Library/Cache 中。與 ~/Documents 不同,這個目錄當然並非開放一般使用者直接存取,但確實存在。「離線內容」一節會參照檔案以外的其他儲存機制。

macOS Finder 會前往 Podcast 應用程式的系統目錄。
Podcast 節目會儲存在特殊的系統應用程式資料夾中。
如何在網頁上進行

File System Access API 可讓開發人員存取裝置的本機檔案系統。您可以直接使用,也可以透過 browser-fs-access 支援程式庫以公開透明的方式為不支援 API 的瀏覽器提供備用選項。基於安全考量,系統目錄無法存取網路。

平台外觀和風格

對 Podcast 等 iOS 應用程式而言,沒有什麼巧思可自行辨識:所有文字標籤都無法選取,且所有文字都會與電腦的系統字型融為一體。此外,我也尊重我選擇的系統色彩主題 (深色模式)。

Podcast 應用程式採用深色模式。
Podcast 應用程式支援淺色和深色模式。
採用淺色模式的 Podcast 應用程式。
應用程式使用預設的系統字型。
如何在網頁上進行

使用 user-select CSS 屬性搭配 none 的值,即可避免 UI 元素意外選取。不過,請勿濫用這個屬性,讓使用者無法選取應用程式內容。 這個項目僅適用於按鈕文字等 UI 元素。font-family CSS 屬性的 system-ui 值可讓您指定應用程式要使用的預設 UI 字型。最後,您的應用程式可以遵循使用者的 prefers-color-scheme 選擇,並視情況採用深色模式切換來覆寫色彩配置偏好設定。您還可以決定瀏覽器在到達捲動區域的邊界時,應執行的操作,例如實作自訂提取並重新整理overscroll-behavior CSS 屬性或許就能辦到。

自訂標題列

查看「播客」應用程式視窗時,您會發現並未提供傳統的整合式標題列和工具列 (例如 Safari 瀏覽器視窗),而是在主要播放器視窗的側欄中,顯示具有側欄的自訂功能。

Safari 瀏覽器的整合資訊方塊列和工具列。
Podcast 應用程式的自訂分割標題列。
自訂 Safari 和 Podcast 的標題列。
如何在網頁上進行

目前尚未支援標題列自訂功能。不過,您可以 (也應該) 指定網頁應用程式資訊清單的 displaytheme-color 屬性,決定應用程式視窗的外觀和風格,並決定哪些預設瀏覽器控制項可能完全不顯示。

Snappy 動畫

Podcast 中的應用程式內動畫會流暢、順暢。舉例來說,開啟右側的「劇集筆記」導覽匣時,畫面會流暢地滑入。當我將某集從下載內容中移除時,剩餘的集數會浮動,並消耗原本刪除的劇集釋出的螢幕空間。

已展開「劇集附註」導覽匣的 Podcast 應用程式。
應用程式內動畫 (例如開啟導覽匣時) 會很流暢。
如何在網頁上進行

事實上,只要考量了動畫與效能文章中所述的幾項最佳做法,就可以在網路上放送成效良好的動畫。使用 CSS Scroll Snap 功能可大幅改善捲動動畫 (一般在分頁內容或媒體輪轉介面中的情況)。如要取得完整的控制項,請使用 Web Animation API

內容在應用程式外顯示

iOS 版 Podcast 應用程式可以將內容顯示在非實際應用程式以外的位置,例如系統的小工具檢視畫面或 Siri 建議。採用主動式的行動號召訊息,使用者只需輕觸一下互動,就能大幅提升 Podcast 等應用程式的再參與率。

顯示 Podcast 應用程式推薦新一集 Podcast 的 iOS 小工具檢視畫面。
應用程式內容會顯示在 Google 播客主應用程式以外的地方。
如何在網頁上進行

Content Index API 可讓應用程式告知瀏覽器哪些 PWA 內容可供離線使用。如此一來,瀏覽器就能在主要應用程式之外顯示這項內容。只要標記應用程式中有趣的內容適合播放可朗讀的音訊,並使用結構化標記,整體來說,您就能協助搜尋引擎和虛擬助理 (例如 Google 助理) 以理想的光源呈現您的產品/服務。

螢幕鎖定畫面媒體控制小工具

當 Podcast 單集播放時,播客應用程式會在螢幕鎖定畫面中顯示精美的控制小工具,並提供劇集圖片、單集節目名稱和 Podcast 名稱等中繼資料。

iOS 媒體播放小工具鎖定畫面,顯示內含多媒體中繼資料的 Podcast 單集節目。
你可以透過螢幕鎖定畫面控制應用程式中播放的媒體。
如何在網頁上進行

Media Session API 可讓您指定圖片、曲目標題等中繼資料,這些中繼資料會顯示在螢幕鎖定畫面、智慧手錶或其他媒體小工具中。

推播通知

推播通知已經成為網頁版的討喜 (雖然現在通知提示其實較為安靜)。但只要妥善運用,就能創造極大價值。 舉例來說,iOS 播客應用程式可選擇在有新的 Podcast 節目時傳送通知給我,或推薦新集數,以及通知我有新的應用程式功能。

iOS 播客應用程式位於「通知」設定畫面中,顯示「新集數」通知切換鈕已啟用。
應用程式可以傳送推播通知,向使用者通知新內容。
如何在網頁上進行

Push API 可讓應用程式接收推播通知,以便通知使用者有關 PWA 的重要事件。 對於應於未來已知時間觸發且不需要網路連線的通知,您可以使用 Notification Triggers API

應用程式圖示徽章

每當我訂閱的 Podcast 有新集數時,Podcast 主畫面圖示都會顯示應用程式圖示徽章,再次鼓勵我以不干擾的方式再次與應用程式互動。

顯示已啟用「徽章」切換鈕的 iOS 設定畫面。
徽章是一種巧妙的方式,可讓應用程式向使用者傳達新內容。
如何在網頁上進行

您可以使用 Badging API 設定應用程式圖示標記。如果您的 PWA 有一些「未讀取」項目的概念,或是您需要以不突兀的方式將使用者的注意力吸引回應用程式,這項功能就特別實用。

媒體播放的優先順序高於省電模式設定

Podcast 媒體播放時,螢幕可能會關閉,但系統不會進入待機模式。 應用程式還可以選擇讓螢幕保持喚醒狀態,例如顯示歌詞或字幕。

macOS 的「偏好設定」。
應用程式可以保持螢幕喚醒。
如何在網頁上進行

「Screen Wake Lock API」功能可防止螢幕關閉。 在網路上播放媒體會自動阻止系統進入待機模式。

透過應用程式商店探索應用程式

雖然 Podcast 應用程式是 macOS 電腦版的一部分,但在 iOS 上則必須從 App Store 安裝。 快速搜尋「podcast」、「podcasts」或「apple podcasts」後,應用程式就會立即在 App Store 中曝光。

在 iOS App Store 中搜尋「Podcast」時,系統會顯示 Podcast 應用程式。
使用者學會如何在應用程式商店中發掘應用程式。
如何在網頁上進行

雖然 Apple 不允許在 App Store 上架 PWA,但您可以在 Android 上提交 PWA 並納入「受信任網路活動」中bubblewrap 指令碼讓這項作業變得輕而易舉。此外,這個指令碼也是 PWABuilder Android 應用程式匯出功能的內部技術,您不必輕觸指令列就能使用這些功能。

特徵摘要

下表簡要介紹所有功能,並提供實用資源清單,協助使用者在網路上瞭解這些功能。

功能 在網路上達成這項作業的實用資源
可離線執行
可離線使用內容與媒體播放功能
主動下載背景
分享至其他應用程式及進行互動
背景應用程式重新整理
狀態在雲端中同步處理
硬體媒體按鍵控制項
多工處理和應用程式捷徑
內容選單中的快速動作
設為預設應用程式
本機檔案系統整合
平台外觀和風格
自訂標題列
Snappy 動畫
在應用程式外顯示的內容
螢幕鎖定畫面媒體控制小工具
推播通知
應用程式圖示徽章
媒體播放功能的優先順序高於節能模式設定
透過應用程式商店探索應用程式

結論

自 2015 年推出以來,PWA 已有長足進步。就 Project Fugu 🐡? 的情況來看,跨公司 Chromium 團隊正在設法彌補最後剩餘的缺口。 即使只參考本文中的部分建議,您可以進一步拉近與應用程式般的感受,並讓使用者忘記自己處理的是「僅限網站」,因為老實說,大多數人都不在意應用程式的建構方式 (以及為什麼要這麼做),只要看起來像真實的應用程式一樣。

特別銘謝

本文由 Kayce BasquesJoe MedleyJoshua BellDion AlmaerAde OshineyePete LePageSam ThorogoodSam ThorogoodReilly Jeffy{/15.