Mainline 是一家線上服飾零售商,販售時尚界知名的設計師品牌。這家位於英國的公司委託其內部專家團隊,並與重要合作夥伴建立策略聯盟,為所有人提供順暢的購物體驗。透過七個自訂的區域網站和應用程式,Mainline 在 100 多個國家/地區都有市場,因此將持續確保電子商務產品能與競爭對手一較高下。
挑戰
Mainline Menswear 的目標是透過漸進式功能,為現有的行動裝置最佳化網站增色,並堅持「行動裝置優先」的理念,以行動裝置友善的設計和功能為重點,並考量智慧型手機市場的成長趨勢。
解決方案
目標是建構並推出 PWA,以補足 Mainline Menswear 網站的原始行動裝置版,然後將統計資料與目前在 Android 和 iOS 上推出的混合型行動應用程式進行比較。
應用程式推出後,Mainline Menswear 的部分使用者開始使用,他們可以判斷 PWA、應用程式和網頁之間的主要統計資料差異。
Mainline 將網站轉換為漸進式網頁應用程式時,採用的方法是確保他們為網站選用的架構 (Nuxt.js,使用 Vue.js) 能與時俱進,並讓他們充分利用快速變化的網路技術。
結果
139%
在 PWA 中,單次工作階段的頁面數量多於網頁。
161%
PWA 與網頁的工作階段持續時間比較。
10%
PWA 的跳出率低於網站
12.5%
PWA 的平均訂單價值高於網站
55%
PWA 的轉換率高於網站。
243%
PWA 的單次工作階段收益高於網站。
深入探討技術
Mainline Menswear 使用 Nuxt.js 架構來整合及轉譯網站,也就是單頁應用程式 (SPA)。
產生服務工作者檔案
為了產生服務工作站,Mainline Menswear 透過 nuxt/pwa
Workbox 模組的自訂實作新增設定。
他們分支 nuxt/pwa
模組的原因,是為了讓團隊能夠在服務工作者檔案中新增更多自訂項目,而這項操作在使用標準版本時無法執行,或會發生問題。其中一個最佳化項目是針對網站的離線功能,例如在離線時放送預設離線網頁,以及收集相關數據。
網頁應用程式資訊清單的解剖
團隊產生包含不同行動應用程式圖示大小和其他網頁應用程式詳細資料 (例如 name
、description
和 theme_color
) 的資訊清單:
{
"name": "Mainline Menswear",
"short_name": "MMW",
"description": "Shop mens designer clothes with Mainline Menswear. Famous brands including Hugo Boss, Adidas, and Emporio Armani.",
"icons": [
{
"src": "/_nuxt/icons/icon_512.c2336e.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#107cbb"
}
安裝完成後,您可以從主畫面啟動網頁應用程式,而不會受到瀏覽器干擾。如要這麼做,請在網路應用程式資訊清單檔案中新增 display
參數:
{
"display": "standalone"
}
最後,公司現在只要在資訊清單的 start_url
欄位中附加 utm_source
參數,就能輕鬆追蹤從主畫面造訪其網頁應用程式的使用者人數:
{
"start_url": "/?utm_source=pwa"
}
執行階段快取功能,加快導覽速度
您必須為網頁應用程式快取,才能改善網頁速度,並為回訪使用者提供更優質的使用者體驗。
針對網路快取,有許多不同的做法。團隊會同時使用 HTTP 快取和 Cache API,在用戶端快取資產。
Cache API 可讓 Mainline Menswear 更精細地控管快取的素材資源,讓他們為每種檔案類型套用複雜的策略。雖然這一切聽起來複雜且難以設定及維護,但 Workbox 提供簡單的方式,讓您宣告這類複雜的策略,並減輕維護的負擔。
快取 CSS 和 JS
對於 CSS 和 JS 檔案,團隊選擇將其快取,並透過 StaleWhileRevalidate
Workbox 策略提供快取內容。這項策略可讓他們快速提供所有 Nuxt CSS 和 JS 檔案,大幅提升網站效能。同時,系統會在背景將檔案更新為最新版本,以便在下次造訪時使用:
/* sw.js */
workbox.routing.registerRoute(
/\/_nuxt\/.*(?:js|css)$/,
new workbox.strategies.StaleWhileRevalidate({
cacheName: 'css_js',
}),
'GET',
);
快取 Google 字型
快取 Google 字體的策略取決於兩種檔案類型:
- 包含
@font-face
宣告的樣式表。 - 底層字型檔案 (在上述樣式表內要求)。
// Cache the Google Fonts stylesheets with a stale-while-revalidate strategy.
workbox.routing.registerRoute(
/https:\/\/fonts\.googleapis\.com\/*/,
new workbox.strategies.StaleWhileRevalidate({
cacheName: 'google_fonts_stylesheets',
}),
'GET',
);
// Cache the underlying font files with a cache-first strategy for 1 year.
workbox.routing.registerRoute(
/https:\/\/fonts\.gstatic\.com\/*/,
new workbox.strategies.CacheFirst({
cacheName: 'google_fonts_webfonts',
plugins: [
new workbox.cacheableResponse.CacheableResponsePlugin({
statuses: [0, 200],
}),
new workbox.expiration.ExpirationPlugin({
maxAgeSeconds: 60 * 60 * 24 * 365, // 1 year
maxEntries: 30,
}),
],
}),
'GET',
);
快取圖片
在圖片方面,Mainline Menswear 決定採用兩種策略。第一個策略適用於來自 CDN 的所有圖片,通常是產品圖片。他們的網頁圖片很多,因此會注意不要占用太多使用者的裝置儲存空間。因此,他們透過 Workbox 新增了只快取來自 CDN 的圖片策略,並使用 ExpirationPlugin
最多快取 60 張圖片。
系統會將要求的第 61 張 (最新) 圖片取代第 1 張 (最舊) 圖片,因此在任何時間點都不會快取超過 60 張產品圖片。
workbox.routing.registerRoute(
({ url, request }) =>
url.origin === 'https://mainline-menswear-res.cloudinary.com' &&
request.destination === 'image',
new workbox.strategies.StaleWhileRevalidate({
cacheName: 'product_images',
plugins: [
new workbox.expiration.ExpirationPlugin({
// Only cache 60 images.
maxEntries: 60,
purgeOnQuotaError: true,
}),
],
}),
);
第二種圖片策略會處理來源要求的其他圖片。這些圖片在整個來源中通常數量很少且很小,但為了安全起見,這些快取圖片的數量也設有 60 張的上限。
workbox.routing.registerRoute(
/\.(?:png|gif|jpg|jpeg|svg|webp)$/,
new workbox.strategies.StaleWhileRevalidate({
cacheName: 'images',
plugins: [
new workbox.expiration.ExpirationPlugin({
// Only cache 60 images.
maxEntries: 60,
purgeOnQuotaError: true,
}),
],
}),
);
提供離線功能
在 Service Worker 安裝及啟用後,系統會預先快取離線頁面。方法是建立所有離線依附元件的清單:離線 HTML 檔案和離線 SVG 圖示。
const OFFLINE_HTML = '/offline/offline.html';
const PRECACHE = [
{ url: OFFLINE_HTML, revision: '70f044fda3e9647a98f084763ae2c32a' },
{ url: '/offline/offline.svg', revision: 'efe016c546d7ba9f20aefc0afa9fc74a' },
];
接著,預先快取清單會饋送至 Workbox,後者會負責處理所有繁重的工作,包括將網址新增至快取,檢查是否有任何修訂版本不相符的情況,以及使用 CacheFirst
策略更新及放送預先快取的檔案。
workbox.precaching.precacheAndRoute(PRECACHE);
處理離線導覽
服務工作者啟用且離線網頁預先快取後,系統就會用來回應使用者的離線瀏覽要求。雖然 Mainline Menswear 的網路應用程式是 SPA,但只有在網頁重新載入、使用者關閉並重新開啟瀏覽器分頁,或是在離線時從主畫面啟動網路應用程式時,才會顯示離線網頁。
為達成這項目標,Mainline Menswear 使用預先快取的離線網頁,為失敗的 NavigationRoute
要求提供備用方案:
const htmlHandler = new workbox.strategies.NetworkOnly();
const navigationRoute = new workbox.routing.NavigationRoute(({ event }) => {
const request = event.request;
// A NavigationRoute matches navigation requests in the browser, i.e. requests for HTML
return htmlHandler.handle({ event, request }).catch(() => caches.match(OFFLINE_HTML, {
ignoreSearch: true
}));
});
workbox.routing.registerRoute(navigationRoute);
示範
回報安裝成功
除了主畫面啟動追蹤 (在網頁應用程式資訊清單中使用 "start_url": "/?utm_source=pwa"
) 之外,網頁應用程式也會透過監聽 window
上的 appinstalled
事件,回報成功安裝的應用程式:
window.addEventListener('appinstalled', (evt) => {
ga('send', 'event', 'Install', 'Success');
});
在網站中加入 PWA 功能,可進一步提升消費者的購物體驗,且相較於 [平台專屬] 應用程式,可更快上市。
開發總監 Andy Hoyle
結論
如要進一步瞭解漸進式網頁應用程式及其建構方式,請前往 web.dev 的漸進式網頁應用程式專區。
如要進一步瞭解更多漸進式網頁應用程式個案研究,請瀏覽個案研究專區。