讓 PWA 感覺像應用程式一樣

發布日期:2020 年 6 月 15 日

玩漸進式網頁應用程式流行語賓果時,可以放心地押注「PWA 只是網站」。Microsoft 的 PWA 說明文件也同意我們也這麼認為, PWA 提名者 Frances Berriman 和 Alex Russell 也是如此。 沒錯,PWA 只是網站,但功能遠遠不只如此。如果做法正確,PWA 的使用體驗會很像應用程式,而不是網站。

但「感覺像真正的應用程式」是什麼意思?

以 Apple Podcast 應用程式為例。 這項功能適用於電腦上的 macOS,以及行動裝置上的 iOS (和 iPadOS)。雖然 Podcasts 是媒體應用程式,但我用它來說明的核心概念也適用於其他類別的應用程式。

iPhone 和 MacBook 並排顯示,兩者都執行 Podcast 應用程式。
iPhone 和 macOS 上的 Apple Podcasts (來源)。

可離線執行

請回想你在手機或桌機上使用的平台專屬應用程式。最特別的是,這項功能隨時可用。在 Google 播客應用程式中,即使我處於離線狀態,也總有事可做或可看。即使沒有網路連線,應用程式仍會開啟。「熱門排行榜」部分不會顯示任何內容,而是顯示「目前無法連線」訊息和「重試」按鈕。

如果沒有網路連線,Podcast 應用程式會顯示「目前無法連線」訊息。

在網路上執行這項操作

播客應用程式採用所謂的應用程式殼層模型。顯示核心應用程式所需的所有靜態內容都會快取至本機, 包括裝飾圖片,例如左側選單圖示和核心播放器 UI 圖示。 系統只會在需要時載入動態內容,例如「熱門排行榜」資料,如果載入失敗,則會提供本機快取的回溯內容。 請參閱「應用程式 Shell 模式」一文,瞭解如何將這個架構模式套用至您的網路應用程式。

可離線觀看內容和播放媒體

離線時,我仍可在左側抽屜式選單中前往「已下載」部分,播放已下載的 Podcast 集數,這些集數會顯示所有中繼資料,包括圖片和說明。

Podcast 應用程式正在播放已下載的 Podcast 節目。
下載的 Podcast 節目集數即使沒有網路也能播放。

在網路上執行這項操作

先前下載的媒體內容可以從快取提供,例如使用 Workbox 程式庫的「提供快取音訊和影片」食譜。其他內容一律可儲存在快取或 IndexedDB 中。如需所有詳細資料,以及瞭解何時該使用哪種儲存技術,請參閱「網頁儲存空間」一文。如果資料需要永久儲存,以免記憶體空間不足時遭到清除,可以使用 Persistent Storage API

主動在背景下載

我回到線上後,當然可以透過 http 203 等查詢字串搜尋內容,決定訂閱搜尋結果 (即 HTTP 203 Podcast) 後,系統會立即下載該系列的最新一集,完全不需要詢問。

訂閱 Podcast 後,Podcast 應用程式會立即下載最新一集。
訂閱 Podcast 後,系統會立即下載最新一集。

在網路上執行這項操作

下載 Podcast 集數可能需要較長時間。Background Fetch API 可讓您將下載作業委派給瀏覽器,由瀏覽器在背景處理。

在 Android 上,瀏覽器甚至可以將這些下載作業委派給作業系統,因此瀏覽器不需要持續執行。下載完成後,應用程式的服務工作人員會喚醒,您可以決定如何處理回應。

與其他應用程式互動及共用

Podcast 應用程式可與其他應用程式自然整合。舉例來說,如果我喜歡某集節目,只要按一下滑鼠右鍵,就能將該集節目分享到裝置上的其他應用程式,例如「訊息」應用程式。此外,這項功能也會自然整合到系統剪貼簿。我可以對任何集數按一下滑鼠右鍵,然後複製連結。

在 Podcast 應用程式中,對 Podcast 集數叫用內容選單,並選取「分享集數」→「訊息」選項。
將 Podcast 節目集數分享到「訊息」應用程式。

在網路上執行這項操作

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

背景應用程式重新整理

在 Google 播客應用程式的設定中,我可以將應用程式設為自動下載新集數。這樣一來,我甚至不必多想,更新後的內容就會自動顯示。神奇。

Podcast 會設定為每小時重新整理動態消息,查看是否有新的 Podcast 集數。

在網路上執行這項操作

Periodic Background Sync API 可讓應用程式在背景定期重新整理內容,不必執行應用程式。也就是說,新內容會主動提供給使用者,方便他們隨時深入瞭解。

透過雲端同步處理的狀態

我的訂閱項目會同步到所有裝置。在無縫世界中,我不需要手動同步 Podcast 訂閱項目。同樣地,我也不必擔心行動裝置的記憶體會被我已在電腦上收聽的集數佔用。系統會保持播放狀態同步,並自動刪除已收聽的集數。

「進階」部分的 Google 播客應用程式設定選單,其中「在多部裝置間同步處理訂閱項目」選項已啟用。狀態會透過雲端同步處理。

在網路上執行這項操作

您可以將同步處理應用程式狀態資料的工作委派給 Background Sync API。同步作業本身不必立即執行,最終會執行即可,甚至可能在使用者再次關閉應用程式時執行。

硬體媒體鍵控制項

當我忙於使用其他應用程式 (例如在瀏覽器中閱讀新聞頁面) 時,仍可透過筆電上的媒體鍵控制「Podcast」應用程式。不必切換到應用程式,就能快轉或倒轉。

Apple MacBook Pro 巧控鍵盤,媒體鍵已加上註解。
媒體鍵可控制 Google 播客應用程式。

在網路上執行這項操作

媒體工作階段 API 支援媒體鍵。 這樣一來,使用者就能透過實體鍵盤或耳機上的硬體媒體鍵,甚至透過智慧手錶上的軟體媒體鍵控制網頁應用程式。此外,當使用者搜尋內容的重要部分時 (例如跳過片頭或章節界線),您可以使用震動模式

多工處理和應用程式捷徑

當然,我隨時可以從任何地方切換回 Podcast 應用程式。應用程式的圖示非常顯眼,我也可以將圖示放在桌面或應用程式 Dock 上,想聽播客時就能立即啟動。

macOS 工作切換器,可選擇多個應用程式圖示,其中一個是「Podcast」應用程式。
多工處理返回 Google 播客應用程式。

在網路上執行這項操作

電腦和行動裝置上的漸進式網頁應用程式都可以安裝到主畫面、開始功能表或應用程式 Dock。 安裝作業可根據主動提示進行,或由應用程式開發人員全權控管。 如需瞭解所有相關資訊,請參閱「如何讓網站可供安裝」一文。 執行多工時,PWA 會獨立於瀏覽器顯示。

內容選單中的快速動作

最常見的應用程式動作 (搜尋新內容和查看新集數) 可直接透過 Dock 中應用程式的快速選單執行。在「選項」選單中,我也可以決定在登入時開啟應用程式。

Podcast 應用程式圖示的內容選單,顯示「搜尋」和「檢查是否有新集數」選項。
只要點選應用程式圖示,即可立即使用快速操作。

在網路上執行這項操作

在 PWA 的 Web 應用程式資訊清單中指定應用程式圖示捷徑,即可註冊常見工作的快速路徑,使用者可直接從應用程式圖示存取這些路徑。在 macOS 等作業系統上,使用者也可以在應用程式圖示上按一下滑鼠右鍵,然後設定在登入時啟動應用程式。 我們正在研擬登入時執行的提案。

設為預設應用程式

其他 iOS 應用程式,甚至是網站或電子郵件,都可以運用 podcasts:// 網址架構與「Podcast」應用程式整合。如果我在瀏覽器中點選 podcasts://podcasts.apple.com/podcast/the-css-podcast/id1042283903 這類連結,系統會直接將我帶往 Google 播客應用程式,讓我決定是否要訂閱或收聽該 Podcast。

Chrome 瀏覽器顯示確認對話方塊,詢問使用者是否要開啟 Podcast 應用程式。
你可以直接從瀏覽器開啟 Google 播客應用程式。

在網路上執行這項操作

目前還無法處理完全自訂的網址配置,但我們正在進行提案,希望為 PWA 提供網址通訊協定處理常式registerProtocolHandler() 加上 web+ 結構前置字串是最佳替代方案。

整合本機檔案系統

你可能不會馬上想到,但「播客」應用程式自然會與本機檔案系統整合。我將 Podcast 集數下載到筆電後,系統會將集數儲存在 ~/Library/Group Containers/243LU875E5.groups.com.apple.podcasts/Library/Cache。與 ~/Documents 不同,一般使用者不應直接存取這個目錄。

「離線內容」部分會參照檔案以外的儲存機制。

macOS Finder 已導覽至 Podcasts 應用程式的系統目錄。
Podcast 集數會儲存在特殊的系統應用程式資料夾中。

在網路上執行這項操作

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

平台外觀和風格

iOS 應用程式 (例如「Podcast」) 還有一個更細微的功能,所有文字標籤都無法選取,且所有文字都會與機器的系統字型融為一體。此外,系統會採用我選擇的色彩主題 (例如深色模式)。

深色模式下的「播客」應用程式。
Podcast 應用程式支援淺色和深色模式。
淺色模式下的 Google 播客應用程式。
應用程式使用預設系統字型。

在網路上執行這項操作

只要使用 user-select CSS 屬性,並將值設為 none,即可防止 UI 元素遭到誤選。但請務必不要濫用這項屬性,導致應用程式內容無法選取。 這項屬性只應適用於按鈕文字等 UI 元素。 font-family CSS 屬性的 system-ui 值可讓您指定應用程式要使用的系統預設 UI 字型。 最後,應用程式可以尊重使用者的 prefers-color-scheme 選擇,並提供選用的深色模式切換按鈕來覆寫設定,藉此遵守使用者的色彩配置偏好設定。 另一個要決定的事項是,瀏覽器到達捲動區域的邊界時應執行的動作,例如實作自訂的「下拉重新整理」。您可以使用 overscroll-behavior CSS 屬性達成這項要求。

自訂標題列

查看「Podcast」應用程式視窗時,您會發現它沒有傳統的整合式標題列和工具列 (例如 Safari 瀏覽器視窗),而是自訂體驗,看起來像是固定在主要播放器視窗的側邊欄。

Safari 瀏覽器整合的圖塊列和工具列。
Safari 和「Podcast」的自訂標題列。

在網路上執行這項操作

標題列自訂功能僅適用於部分地區。您可以 (也應該) 指定網頁應用程式資訊清單的 displaytheme-color 屬性。這會決定應用程式視窗的外觀和風格,以及要顯示哪些預設瀏覽器控制項 (可能完全不顯示)。

流暢動畫

Podcast 應用程式中的動畫快速流暢,舉例來說,當我開啟右側的「集數說明」抽屜時,它會優雅地滑入畫面。從下載內容中移除一集後,其餘集數會向上浮動,並佔用刪除集數釋出的螢幕空間。

Podcast 應用程式,展開的「集數說明」抽屜。
開啟抽屜等應用程式內動畫時,速度很快。

在網路上執行這項操作

只要考量「動畫和效能」一文列出的多項最佳做法,網頁上就能呈現高效能動畫。使用 CSS 捲動捕捉功能,可大幅改善捲動動畫,例如分頁內容或媒體輪播中的動畫。 如要全面控管,可以使用 Web Animations API

在應用程式外顯示內容

iOS 版的「Podcast」應用程式可能會在實際應用程式以外的位置顯示內容,例如系統的「小工具」檢視畫面或 Siri 建議。

主動式行動號召會根據使用情況顯示,只要輕觸即可與應用程式互動,因此能大幅提升應用程式 (例如 Google 播客) 的重新參與率。

iOS 小工具檢視畫面會顯示 Google 播客應用程式建議的新集數。

在網路上執行這項操作

在應用程式中使用 Content Index API,告知瀏覽器 PWA 的哪些內容可離線使用。這樣一來,瀏覽器就能在主要應用程式以外顯示這類內容。只要在應用程式中將有趣的內容標記為適合朗讀音訊播放,並使用結構化標記,就能協助搜尋引擎和虛擬助理 (例如 Google 助理) 以理想的方式呈現你的內容。

螢幕鎖定媒體控制小工具

播放 Podcast 集數時,Podcast 應用程式會在鎖定畫面上顯示精美的控制項小工具,當中包含集數插圖、集數標題和 Podcast 名稱等中繼資料。

iOS 螢幕鎖定畫面上的媒體播放小工具,顯示含有豐富中繼資料的 Podcast 集數。
在螢幕鎖定畫面中控制應用程式播放的媒體。

在網路上執行這項操作

媒體工作階段 API 可讓您指定中繼資料,例如圖片、曲目標題等,然後顯示在螢幕鎖定畫面、智慧手錶或瀏覽器中的其他媒體小工具。

推播通知

網頁推播通知已成為網路上的惱人干擾 (不過通知提示現在安靜許多)。但如果使用得當,這些功能可以帶來許多價值。 舉例來說,iOS 上的「Podcast」應用程式可以選擇性地通知我訂閱的 Podcast 有新集數,或推薦新的 Podcast,以及提醒我應用程式有新功能。

iOS 播客應用程式的「通知」設定畫面,顯示已啟用「新集數」通知切換鈕。
應用程式可以傳送推播通知,告知使用者有新內容。

在網路上執行這項操作

Push API 可讓應用程式接收推播通知,以便在 PWA 發生重大事件時通知使用者。如要讓通知在未來特定時間觸發,且不需要網路連線,可以使用 Notification Triggers API

應用程式圖示標記

每當我訂閱的 Podcast 有新集數時,Podcast 主畫面圖示上就會顯示應用程式圖示徽章,再次鼓勵我以不打擾的方式重新使用應用程式。

iOS 設定畫面,顯示已啟用的「徽章」切換鈕。
應用程式可透過徽章,以不顯眼的方式通知使用者新內容。

在網路上執行這項操作

您可以使用 Badging API 設定應用程式圖示上的標記。 如果 PWA 有「未讀」項目,或需要以不顯眼的方式吸引使用者返回應用程式,這項功能就特別實用。

媒體播放的優先順序高於節約耗電量設定

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

macOS「節約耗電量」部分的偏好設定。
應用程式可以讓螢幕保持喚醒狀態。

在網路上執行這項操作

使用 Screen Wake Lock API 可防止螢幕關閉。在網頁上播放媒體時,系統會自動避免進入待機模式。

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

播客應用程式是 macOS 電腦版體驗的一部分,但 iOS 版必須從 App Store 安裝。只要快速搜尋 podcastpodcastsapple podcasts,應用程式就會立即顯示在 App Store 中。

在 iOS App Store 搜尋「podcast」,會顯示「Podcast」應用程式。
使用者已習慣在應用程式商店中尋找應用程式。

在網路上執行這項操作

雖然 Apple 不允許在 App Store 上架 PWA,但您可以在 Android 上提交以受信任的網頁活動包裝的 PWA。bubblewrap 指令碼可讓您輕鬆完成這項作業。這個指令碼也是 PWABuilder Android 應用程式匯出功能背後的技術,您無須使用指令列即可運用這項功能。

特徵摘要

這個表格會簡要列出所有功能,並提供實用資源清單,協助您在網路上實現這些功能。

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

結論

自 2015 年推出以來,PWA 已有長足進展。 在 Project Fugu 🐡 的背景下,跨公司 Chromium 團隊正努力填補最後的缺口。 只要遵循我們分享的部分建議,就能更接近應用程式的體驗,讓使用者忘記他們只是在瀏覽「網站」。歸根究底,只要感覺像是真正的應用程式,大多數使用者都不會在意應用程式的建構方式 (他們為什麼要在意?)。

特別銘謝

本文由 Kayce BasquesJoe MedleyJoshua BellDion AlmaerAde OshineyePete LePageSam ThorogoodReilly GrantJeffrey Yasskin 審查。