Mainline Menswear 導入 PWA,結果轉換率提升 55%

Mainline 是一家線上服飾零售商,販售全球知名的設計師品牌名稱。這間英國公司委託內部專家團隊與關鍵合作夥伴緊密合作,為所有人提供順暢的購物體驗。透過七個自訂地域網站和應用程式,在 100 多個國家/地區的市場曝光,Mainline 將繼續確保提供電子商務服務,讓競爭更加激烈。

挑戰

Mainline Menswear 的目標是透過符合其「行動優先」願景的漸進式功能,來補強目前針對行動裝置最佳化的網站,並將重點放在適合行動裝置的設計和功能,以及日益成長的智慧型手機市場。

解決方法

我們的目標是建構並啟動可搭配使用原始行動裝置友善版本的 Mainline Menswear 網站,然後將統計資料與目前適用於 Android 和 iOS 的混合型行動應用程式進行比較。

當 Mainline Menswear 使用者啟動應用程式並開始使用後,他們就能確定 PWA、應用程式和網頁的主要統計資料差異。

Mainline 方法在將網站轉換為 PWA 時採用的方法,是確保他們為網站選擇的架構 (透過 Vue.js 使用 Nuxt.js) 符合未來趨勢,並能利用快速移動的網路技術。

結果

139%

與網頁相比,PWA 的單次工作階段頁數更多。

161%

與網頁相比,PWA 中的工作階段持續時間較長。

10%

PWA 的跳出率降幅 (與網頁相比)

12.5%

PWA 的平均訂單價值升幅 (與網站相比)

55%

PWA 的轉換率升幅 (與網站相比)。

243%

PWA 的單次工作階段收益升幅 (與網站相比)。

深入探討技術

Mainline Menswear 使用了 Nuxt.js 架構來封裝並轉譯自家網站,也就是單頁應用程式 (SPA)。

產生 Service Worker 檔案

為了產生 Service Worker,Mainline Menswear 會透過 nuxt/pwa Workbox 模組的自訂實作新增設定。

之所以為 nuxt/pwa 模組建立分支,是為了讓團隊為 Service Worker 檔案新增更多自訂項目,而這些自訂項目在使用 Standard 版本時不可行,或發生問題。這類最佳化措施之一與網站的「離線功能」有關,例如放送預設離線網頁及在離線時收集分析資料。

網頁應用程式資訊清單剖析

該團隊產生了資訊清單,其中包含不同的行動應用程式圖示大小,以及其他網頁應用程式詳細資料 (例如 namedescriptiontheme_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 Fonts 的快取策略取決於兩種檔案類型:

  • 包含 @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 新增一項策略,使用 ExpirationPlugin 快取僅從 CDN 取得的圖片最多包含 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);

處理離線瀏覽

Service Worker 啟用並預先快取離線網頁後,就會使用到使用者回應的離線導航要求。雖然 Mainline Menswear 的網頁應用程式是 SPA,但離線頁面只會在重新載入頁面、使用者關閉並重新開啟瀏覽器分頁,或是從離線狀態下從主畫面啟動網頁應用程式時才會顯示。

為此,Minline 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);

操作示範

造訪 www.mainlinemenswear.co.uk 上的離線網頁範例。

回報安裝成功

除了主畫面啟動追蹤 (在網頁應用程式資訊清單中使用 "start_url": "/?utm_source=pwa") 以外,網頁應用程式也會監聽 window 上的 appinstalled 事件,藉此回報應用程式安裝成功:

window.addEventListener('appinstalled', (evt) => {
  ga('send', 'event', 'Install', 'Success');
});

在網站中新增 PWA 功能,可進一步改善消費者的購物體驗,且比 [平台專屬] 應用程式更快上市。

開發部門主管 Andy Hoyle

結論

如要進一步瞭解漸進式網頁應用程式及其建構方式,請前往 web.dev,參閱漸進式網頁應用程式專區

如需更多漸進式網頁應用程式個案研究,請前往個案研究一節