Mainline Menswear triển khai PWA và nhận thấy tỷ lệ chuyển đổi tăng 55%

Mainline là nhà bán lẻ quần áo trực tuyến, cung cấp các thương hiệu thiết kế lớn nhất trong lĩnh vực thời trang. Công ty có trụ sở tại Vương quốc Anh giao phó cho đội ngũ chuyên gia nội bộ của mình kết hợp một cách có chiến lược với các đối tác chủ chốt để mang đến trải nghiệm mua sắm suôn sẻ cho tất cả mọi người. Với sự hiện diện tại hơn 100 quốc gia thông qua 7 trang web được thiết kế tuỳ chỉnh theo lãnh thổ và một ứng dụng, Mainline sẽ tiếp tục đảm bảo các sản phẩm thương mại điện tử có sức cạnh tranh với các đối thủ cạnh tranh.

Khó khăn

Mục tiêu của Mainline Menswear là bổ sung các tính năng tiến bộ cho trang web hiện tại được tối ưu hoá cho thiết bị di động, nhằm tuân thủ tầm nhìn "ưu tiên thiết bị di động" của họ, tập trung vào thiết kế và chức năng thân thiện với thiết bị di động, chú trọng đến thị trường điện thoại thông minh đang phát triển.

Giải pháp

Mục tiêu là xây dựng và ra mắt một PWA bổ sung cho phiên bản gốc thân thiện với thiết bị di động của trang web Mainline Menswear, sau đó so sánh số liệu thống kê với ứng dụng kết hợp dành cho thiết bị di động hiện có trên Android và iOS.

Sau khi ra mắt và đang được một nhóm nhỏ người dùng Mainline Menswear sử dụng, họ có thể xác định sự khác biệt về các số liệu thống kê chính giữa PWA, ứng dụng và Web.

Phương pháp mà Mainline sử dụng khi chuyển đổi trang web sang PWA là đảm bảo rằng khung mà họ chọn cho trang web (Nuxt.js, sử dụng Vue.js) sẽ phù hợp với tương lai và cho phép họ tận dụng công nghệ web di chuyển nhanh.

Kết quả

139%

Số trang mỗi phiên trong PWA nhiều hơn so với trên web.

161%

Thời lượng phiên dài hơn trong PWA so với trên web.

10%

Tỷ lệ thoát trong PWA thấp hơn so với trên web

12,5%

Giá trị trung bình của đơn đặt hàng trong PWA cao hơn so với trên web

55%

Tỷ lệ chuyển đổi trong PWA cao hơn so với trên web.

243%

Doanh thu trên mỗi phiên trong PWA cao hơn so với trên web.

Tìm hiểu chuyên sâu về kỹ thuật

Mainline Menswear đang sử dụng khung Nuxt.js để nhóm và hiển thị trang web của họ, đây là một ứng dụng trang đơn (SPA).

Tạo tệp trình chạy dịch vụ

Để tạo trình chạy dịch vụ, Mainline Menswear đã thêm cấu hình thông qua phương thức triển khai tuỳ chỉnh của mô-đun Workbox nuxt/pwa.

Lý do họ tách mô-đun nuxt/pwa là để cho phép nhóm thêm nhiều phần tuỳ chỉnh hơn vào tệp trình chạy dịch vụ mà họ không thể thực hiện hoặc gặp vấn đề khi sử dụng phiên bản chuẩn. Một trong những cách tối ưu hoá đó là xoay quanh chức năng ngoại tuyến của trang web, chẳng hạn như phân phát trang ngoại tuyến mặc định và thu thập số liệu phân tích khi ngoại tuyến.

Phân tích thành phần của tệp kê khai ứng dụng web

Nhóm đã tạo một tệp kê khai có các biểu tượng cho nhiều kích thước biểu tượng ứng dụng di động và thông tin chi tiết khác về ứng dụng web như name, descriptiontheme_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"
}

Sau khi cài đặt, ứng dụng web có thể chạy từ màn hình chính mà không cần trình duyệt can thiệp. Bạn có thể thực hiện việc này bằng cách thêm tham số display vào tệp kê khai của ứng dụng web:

{
  "display": "standalone"
}

Cuối cùng nhưng không kém phần quan trọng, công ty này hiện có thể dễ dàng theo dõi số lượng người dùng đang truy cập vào ứng dụng web của họ từ màn hình chính bằng cách chỉ cần thêm tham số utm_source trong trường start_url của tệp kê khai:

{
  "start_url": "/?utm_source=pwa"
}

Lưu vào bộ nhớ đệm trong thời gian chạy để điều hướng nhanh hơn

Việc lưu vào bộ nhớ đệm cho ứng dụng web là điều cần thiết để tối ưu hoá tốc độ trang và mang lại trải nghiệm tốt hơn cho người dùng cũ.

Để lưu vào bộ nhớ đệm trên web, có khá nhiều phương pháp khác nhau. Nhóm này đang sử dụng kết hợp bộ nhớ đệm HTTPAPI Bộ nhớ đệm để lưu các tài sản vào bộ nhớ đệm ở phía máy khách.

API bộ nhớ đệm cho phép Mainline Menswear kiểm soát tốt hơn các nội dung đã lưu vào bộ nhớ đệm, cho phép họ áp dụng các chiến lược phức tạp cho từng loại tệp. Mặc dù mọi thứ nghe có vẻ phức tạp, khó thiết lập và bảo trì, nhưng Workbox lại giúp bạn dễ dàng khai báo các chiến lược phức tạp như vậy và giảm bớt công sức bảo trì.

Lưu CSS và JS vào bộ nhớ đệm

Đối với các tệp CSS và JS, nhóm đã chọn lưu các tệp này vào bộ nhớ đệm và phân phát chúng qua bộ nhớ đệm bằng cách sử dụng chiến lược Hộp công việc StaleWhileRevalidate. Chiến lược này cho phép họ phân phát nhanh tất cả các tệp CSS và JS của Nuxt, nhờ đó làm tăng đáng kể hiệu suất của trang web. Đồng thời, các tệp đang được cập nhật trong nền lên phiên bản mới nhất cho lần truy cập tiếp theo:

/* sw.js */
workbox.routing.registerRoute(
  /\/_nuxt\/.*(?:js|css)$/,
  new workbox.strategies.StaleWhileRevalidate({
    cacheName: 'css_js',
  }),
  'GET',
);

Lưu phông chữ của Google vào bộ nhớ đệm

Chiến lược lưu Google Fonts vào bộ nhớ đệm phụ thuộc vào 2 loại tệp:

  • Biểu định kiểu chứa nội dung khai báo @font-face.
  • Các tệp phông chữ cơ bản (được yêu cầu trong biểu định kiểu nêu trên).
// 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',
);

Lưu hình ảnh vào bộ nhớ đệm

Đối với hình ảnh, Mainline Menswear quyết định sử dụng hai chiến lược. Chiến lược đầu tiên áp dụng cho tất cả hình ảnh đến từ CDN của họ, thường là hình ảnh sản phẩm. Các trang của họ chứa nhiều hình ảnh, vì vậy, người dùng ý thức được việc không chiếm quá nhiều bộ nhớ trên thiết bị của người dùng. Vì vậy, thông qua Workbox, họ đã thêm một chiến lược lưu hình ảnh vào bộ nhớ đệm chỉ đến từ CDN với tối đa 60 hình ảnh bằng cách sử dụng ExpirationPlugin.

Hình ảnh thứ 61 (mới nhất) được yêu cầu sẽ thay thế hình ảnh đầu tiên (cũ nhất) để không quá 60 hình ảnh sản phẩm được lưu vào bộ nhớ đệm tại bất kỳ thời điểm nào.

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,
      }),
    ],
  }),
);

Chiến lược hình ảnh thứ hai xử lý các hình ảnh còn lại mà nguồn gốc yêu cầu. Những hình ảnh này có xu hướng rất ít và nhỏ trên toàn bộ nguồn gốc, nhưng để đảm bảo an toàn, số lượng hình ảnh được lưu vào bộ nhớ đệm cũng giới hạn ở 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,
      }),
    ],
  }),
);

Cung cấp chức năng ngoại tuyến

Trang ngoại tuyến được lưu trước vào bộ nhớ đệm ngay sau khi trình chạy dịch vụ được cài đặt và kích hoạt. Các thư viện này thực hiện việc này bằng cách tạo một danh sách tất cả các phần phụ thuộc ngoại tuyến: tệp HTML ngoại tuyến và biểu tượng SVG ngoại tuyến.

const OFFLINE_HTML = '/offline/offline.html';
const PRECACHE = [
  { url: OFFLINE_HTML, revision: '70f044fda3e9647a98f084763ae2c32a' },
  { url: '/offline/offline.svg', revision: 'efe016c546d7ba9f20aefc0afa9fc74a' },
];

Sau đó, danh sách bộ nhớ đệm được đưa vào Workbox giúp xử lý toàn bộ phần việc nặng nhọc là thêm URL vào bộ nhớ đệm, kiểm tra xem có bản sửa đổi không khớp hay không, cập nhật và phân phát các tệp lưu vào bộ nhớ đệm trước bằng chiến lược CacheFirst.

workbox.precaching.precacheAndRoute(PRECACHE);

Xử lý hoạt động chỉ đường khi không có mạng

Sau khi trình chạy dịch vụ kích hoạt và trang ngoại tuyến được lưu trước vào bộ nhớ đệm, trình chạy này sẽ được dùng để phản hồi yêu cầu điều hướng ngoại tuyến của người dùng. Mặc dù ứng dụng web của Mainline Menswear là một SPA, nhưng trang ngoại tuyến chỉ hiển thị sau khi trang tải lại, người dùng đóng và mở lại thẻ trình duyệt hoặc khi ứng dụng web chạy từ màn hình chính trong khi không có kết nối mạng.

Để đạt được điều này, Mainline Menswear đã cung cấp phương án dự phòng cho các yêu cầu NavigationRoute không thành công thông qua trang ngoại tuyến được lưu trước vào bộ nhớ đệm:

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);

Bản minh hoạ

Ví dụ về trang ngoại tuyến như trên www.mainlinemenswear.co.uk.

Báo cáo lượt cài đặt thành công

Ngoài tính năng theo dõi lượt khởi chạy màn hình chính (với "start_url": "/?utm_source=pwa" trong tệp kê khai ứng dụng web), ứng dụng web cũng báo cáo các lượt cài đặt ứng dụng thành công bằng cách theo dõi sự kiện appinstalled vào window:

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

Việc thêm các chức năng của PWA vào trang web sẽ giúp nâng cao trải nghiệm mua sắm của khách hàng hơn nữa và sẽ nhanh hơn trong việc tiếp thị so với ứng dụng [dành riêng cho nền tảng].

Andy Hoyle, Trưởng bộ phận phát triển

Kết luận

Để tìm hiểu thêm về các ứng dụng web tiến bộ và cách tạo các ứng dụng đó, hãy chuyển đến phần Ứng dụng web tiến bộ trên web.dev.

Để đọc thêm các nghiên cứu điển hình về Ứng dụng web tiến bộ, hãy duyệt qua phần nghiên cứu điển hình.