شركة Mainline للملابس الرجالية تستخدم PWA وتشهد زيادة في معدل الإحالات الناجحة بنسبة 55%

Mainline هو متجر تجزئة للملابس على الإنترنت يقدّم أكبر العلامات التجارية للمصمّمين في مجال الأزياء. تعتمد الشركة ومقرها المملكة المتحدة على فريقها من الخبراء الداخليين، الذين يعملون بشكل استراتيجي مع الشركاء الرئيسيين، لتوفير تجربة تسوّق سلسة للجميع. من خلال التواجد في السوق في أكثر من 100 بلد من خلال سبعة مواقع إلكترونية مخصّصة وتطبيق، ستواصل Mainline ضمان تنافسية عروض التجارة الإلكترونية.

التحدي

كان هدف Mainline Menswear هو إضافة ميزات تصاعدية تتماشى مع رؤية "الأجهزة الجوّالة أولاً" إلى الموقع الإلكتروني الحالي المحسّن للأجهزة الجوّالة، مع التركيز على التصميم والوظائف المتوافقة مع الأجهزة الجوّالة مع أخذ سوق الهواتف الذكية المتزايد في الاعتبار.

الحل

كان الهدف من ذلك هو إنشاء وإطلاق تطبيق ويب تقدّمي يكمل الإصدار الأصلي المتوافق مع الأجهزة الجوّالة من موقع Mainline Menswear الإلكتروني، ثم مقارنة الإحصاءات مع تطبيقه الهجين المتوافق مع الأجهزة الجوّالة، الذي يتوفّر حاليًا على Android وiOS.

بعد إطلاق التطبيق واستخدامه من قِبل شريحة صغيرة من مستخدمي Mainline Menswear، تمكّنت الشركة من تحديد الفرق في الإحصاءات الرئيسية بين التطبيق المتوافق مع الأجهزة الجوّالة والتطبيق والويب.

اتّبع فريق Mainline نهجًا يضمن أنّ الإطار الذي اختاروه لموقعهم الإلكتروني (Nuxt.js باستخدام Vue.js) سيكون مناسبًا للمستقبل ويتيح لهم الاستفادة من تكنولوجيا الويب سريعة التغيير.

النتائج

139%

عدد صفحات أكبر لكل جلسة في تطبيق الويب التقدّمي مقارنةً بالويب

161%

مدّة جلسات أطول في التطبيقات المتوافقة مع الأجهزة الجوّالة مقارنةً بالتطبيقات على الويب

زيادة بنسبة %10

انخفاض في معدّل الارتداد في تطبيق الويب التقدّمي مقارنةً بالموقع الإلكتروني

‫12.5%

متوسّط قيمة طلب شراء أعلى في تطبيق الويب التقدّمي مقارنةً بالويب

‎55%

معدّل إحالات ناجحة أعلى في التطبيق المتوافق مع الأجهزة الجوّالة مقارنةً بالموقع الإلكتروني

243%

تحقيق أرباح أعلى لكل جلسة في تطبيق الويب التقدّمي مقارنةً بالويب

نظرة تفصيلية على الجوانب الفنية

تستخدم شركة Mainline Menswear إطار عمل Nuxt.js لتجميع موقعها الإلكتروني وعرض محتواه، وهو تطبيق صفحة واحدة (SPA).

إنشاء ملف عامل خدمة

لإنشاء الخدمة العاملة، أضافت Mainline Menswear إعدادات من خلال تنفيذ مخصّص لوحدة nuxt/pwa Workbox.

تمّ إنشاء نسخة من وحدة nuxt/pwa للسماح للفريق بإضافة المزيد من التخصيصات إلىملف worker service الذي لم يتمكّنوا من إجراء ذلك أو واجهوا مشاكل عند استخدام الإصدار العادي. كان أحد هذه التحسينات على وظائف الموقع الإلكتروني بلا إنترنت، مثل عرض صفحة تلقائية بلا إنترنت وجمع الإحصاءات بلا إنترنت.

بنية بيان تطبيق الويب

أنشأ الفريق بيانًا يتضمّن رموزًا لأحجام مختلفة من رموز التطبيقات المتوافقة مع الأجهزة الجوّالة وتفاصيل أخرى لتطبيقات الويب، مثل 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"
}

أخيرًا، يمكن للشركة الآن تتبُّع عدد المستخدمين الذين يزورون تطبيق الويب الخاص بها من الشاشة الرئيسية بسهولة، وذلك عن طريق إلحاق مَعلمة utm_source في الحقل start_url منملف الманиفيست:

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

ميزة التخزين المؤقت أثناء التشغيل لتسهيل عملية التنقّل

إنّ ميزة التخزين المؤقت لتطبيقات الويب ضرورية لتحسين سرعة الصفحة وتوفير تجربة مستخدم أفضل للمستخدِمين المتكرّرين.

بالنسبة إلى التخزين المؤقت على الويب، هناك العديد من الطرق المختلفة. يستخدم الفريق مزيجًا من ذاكرة التخزين المؤقت لبروتوكول HTTP وCache API لتخزين مواد العرض مؤقتًا على جانب العميل.

تمنح واجهة برمجة التطبيقات Cache API شركة Mainline Menswear قدرة أكبر على التحكّم في مواد العرض المخزّنة مؤقتًا، ما يتيح لها تطبيق استراتيجيات معقّدة على كل نوع من أنواع الملفات. على الرغم من أنّ كل هذا يبدو معقّدًا ويصعب إعداده وصيرفته، توفّر Workbox طريقة سهلة لإعلان هذه الاستراتيجيات المعقّدة وتسهّل عملية الصيانة.

تخزين ملفّات CSS وJavaScript مؤقتًا

بالنسبة إلى ملفات CSS وJS، اختار الفريق تخزينها مؤقتًا وعرضها من خلال ذاكرة التخزين المؤقت باستخدام استراتيجية StaleWhileRevalidate Workbox. تتيح لهم هذه الاستراتيجية عرض جميع ملفات CSS وJS في Nuxt بسرعة، ما يؤدي إلى تحسين أداء موقعهم الإلكتروني بشكل كبير. في الوقت نفسه، يتم تحديث الملفات في الخلفية إلى أحدث إصدار للزيارة التالية:

/* 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) فقط مع الحد الأقصى لتحميل 60 صورة باستخدام العلامة ExpirationPlugin.

تستبدل الصورة 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,
      }),
    ],
  }),
);

توفير وظائف بلا إنترنت

يتم تخزين الصفحة بلا إنترنت مؤقتًا بعد تثبيت مشغّل الخدمة وتفعيله مباشرةً. ويتم ذلك من خلال إنشاء قائمة بجميع العناصر التي تعتمد عليها العناصر الأخرى بلا إنترنت: ملف HTML بلا إنترنت ورمز SVG بلا إنترنت.

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

بعد ذلك، يتمّ نقل قائمة التخزين المؤقت المُسبَق إلى Workbox التي تتولّى جميع الإجراءات المتعلّقة بإضافة عناوين ‎ URL إلى ذاكرة التخزين المؤقت والتحقّق من أيّ عدم تطابق في المراجع وتعديلها وعرض ملفّات ‎ التخزين المؤقت المُسبَق باستخدام استراتيجية CacheFirst.

workbox.precaching.precacheAndRoute(PRECACHE);

التعامل مع عمليات التنقّل بلا إنترنت

بعد تفعيل مشغّل الخدمة وتخزين الصفحة بلا إنترنت مؤقتًا، يتم استخدامه للردّ على طلبات التنقّل بلا إنترنت التي يقدّمها المستخدم. على الرغم من أنّ تطبيق الويب الخاص بـ Mainline Menswear هو تطبيق متعدّد الصفحات، لا تظهر صفحة الويب بلا إنترنت إلا بعد إعادة تحميل الصفحة أو إغلاق المستخدم لعلامة التبويب في المتصفّح وإعادة فتحها أو عند تشغيل تطبيق الويب من الشاشة الرئيسية بلا إنترنت.

لتحقيق ذلك، قدّمت 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);

عرض توضيحي

مثال على صفحة بلا إنترنت كما تظهر على www.mainlinemenswear.co.uk

الإبلاغ عن عمليات التثبيت الناجحة

بالإضافة إلى تتبُّع عمليات الإطلاق من الشاشة الرئيسية (باستخدام "start_url": "/?utm_source=pwa" في بيان تطبيق الويب)، يُبلغ تطبيق الويب أيضًا عن عمليات تثبيت التطبيق الناجحة من خلال الاستماع إلى حدث appinstalled على window:

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

ستؤدي إضافة إمكانات التطبيقات المتوافقة مع الأجهزة الجوّالة إلى موقعك الإلكتروني إلى تحسين تجربة التسوّق لدى عملائك، كما أنّ طرحها في السوق سيكون أسرع من طرح [تطبيق مخصّص لمنصّة معيّنة].

آندي هويل، رئيس قسم التطوير

الخاتمة

للاطّلاع على مزيد من المعلومات عن تطبيقات الويب التقدّمية وكيفية إنشائها، انتقِل إلى قسم "تطبيقات الويب التقدّمية" على web.dev.

للاطّلاع على المزيد من دراسات حالة تطبيقات الويب التقدّمية، انتقِل إلى قسم دراسات الحالة.