從 Native App 看 Web 的離線困境#

把 Web App 與 Native App 放到沒有網路的環境下對照,差異會非常明顯。多數網站如果沒有特別處理,斷線時會直接顯示 network error,使用者除了重新整理什麼也做不了。Native App 多半就算離線也能開啟畫面,至少能看到上次瀏覽的內容、保留基本的操作介面。

Application Shell(App Shell)就是讓 Web 也能逼近這種體驗的設計。

App Shell 的概念是:把 UI 中相對固定的「殼」(例如 navbar、footer、版面骨幹)與必須動態抓取的 Dynamic Content 分開。殼的部分會在第一次造訪後存進 Service Worker 的快取裡,之後再次開啟頁面就可以立刻顯示,即使在離線狀態也能呈現。

如果用 Native App 來類比,App Shell 就像是裝在使用者手機裡、被 App Store 或 Google Play 下載過的核心程式碼,沒有網路時依然能撐起 UI 骨架;剩下的內容則由網路動態填上。

App Shell 應具備的特性#

設計 App Shell 時,可以用以下三個目標來檢視:

  • 快速載入。
  • 將動態資料抽離。
  • 從快取載入靜態資源。

切分時要拿捏分寸:

  • App Shell 越簡單越好。
  • 但仍要包含足夠有意義的頁面內容,不能空到讓人覺得「什麼都沒看到」。
  • 為了使用者體驗,可以加入 placeholder、skeleton 等暫時佔位元件。

想像離線時打開頁面:什麼東西該被看到?這通常就是 App Shell 應該包進去的內容。

一個直觀的例子#

以 Google 推薦的離線版維基百科為例,模擬 offline 狀態時,畫面仍然會呈現上方的搜尋欄與下方的灰色內容區,這部分就是 App Shell。中間的條目內容、清單則屬於 Dynamic Content,會透過 API 動態填入。

對於 Dynamic Content,也可以選擇性地放進快取,讓使用者在離線時還能瀏覽之前載入過的資料;不過這時就要考慮新鮮度問題,盡量在恢復連線時讓使用者拿到最新版本。

對網頁效能的影響#

採用 App Shell 後,第一次造訪會稍微慢一點,因為需要:

  • 在瀏覽器註冊 Service Worker。
  • 把屬於 Shell 的靜態資源放進 Service Worker 的 Cache。

第一次完成這些動作後,後續的造訪就能立即從 Cache 顯示 Shell 元件,因此會有比較好的 First Meaningful Paint,再透過 Ajax 把動態資料補上。

這種架構同時提升了「感知效能」:雖然使用者還是要等動態資料才能完整操作頁面,但因為先看到了部分畫面,等待的痛苦會降低許多。

Google 曾在 3G 網路環境下做過實驗,量測 App Shell 對載入時間的改善效果,數字差距相當明顯。

適合採用的情境#

App Shell 最能發揮價值的場景,是頁面同時包含大量動態內容與相對固定的版面結構。常見情境包含:

  • 內容平台、社群應用:navbar、側邊選單固定,動態列表頻繁更新。
  • 後台管理介面:版面骨幹相同,內容由 API 帶入。

如果網站本身規模很小、或內容多半是靜態的,採用 App Shell 反而失去意義,整個網站打包後直接放進 Service Worker 的快取就好。

不支援 Service Workers 的瀏覽器怎麼辦#

像比較舊或比較輕量的瀏覽器(例如 KaiOS)目前還不支援 Service Worker。這時就得回頭依靠 HTTP 快取(HTTP Caching):透過設定 Cache-Control 等 Header,仍然能讓這些瀏覽器享有一定程度的快取效益。

換句話說,Service Worker Cache 與 HTTP Cache 並不是互斥關係,而是要互相搭配;前者撐起離線優先(Offline First)的體驗,後者作為瀏覽器層級的保底。

本章重點#

  • Application Shell 的核心概念是把固定的 UI 殼與 Dynamic Content 分開,前者預先快取以提供瞬時顯示與離線能力。
  • App Shell 是達成離線優先(Offline First)的具體手法,背後仰賴 Service Worker 的快取機制。
  • 第一次載入會略微變慢(要註冊 Service Worker、預存靜態資源),但後續造訪可大幅改善 First Meaningful Paint 與感知效能。
  • App Shell 適合擁有大量動態內容、版面結構穩定的網站;純靜態小網站直接整包快取即可。
  • 對不支援 Service Worker 的瀏覽器,仍應透過 HTTP 快取(HTTP Caching)的設定提供基本的效能保障。

原文出處#