Mainline هو متجر تجزئة للملابس على الإنترنت يقدّم أكبر العلامات التجارية للمصمّمين في مجال الأزياء. تعتمد الشركة ومقرها المملكة المتحدة على فريقها من الخبراء الداخليين، الذين يعملون بشكل استراتيجي مع الشركاء الرئيسيين، لتوفير تجربة تسوّق سلسة للجميع. من خلال التواجد في السوق في أكثر من 100 بلد من خلال سبعة مواقع إلكترونية مخصّصة وتطبيق، ستواصل Mainline ضمان تنافسية عروض التجارة الإلكترونية.
التحدي
كان هدف Mainline Menswear هو إضافة ميزات تصاعدية تتماشى مع رؤية "الأجهزة الجوّالة أولاً" إلى الموقع الإلكتروني الحالي المحسّن للأجهزة الجوّالة، مع التركيز على التصميم والوظائف المتوافقة مع الأجهزة الجوّالة مع أخذ سوق الهواتف الذكية المتزايدة في الاعتبار.
الحل
وكان الهدف هو إنشاء وإطلاق تطبيق ويب تقدّمي (PWA) يكمّل الإصدار الأصلي المتوافق مع الأجهزة الجوّالة من موقع Mainline الإلكتروني للملابس الرجالية، ثم مقارنة الإحصاءات بتطبيقها المختلط للأجهزة الجوّالة، المتاح حاليًا على نظامَي التشغيل Android وiOS.
بعد إطلاق التطبيق واستخدامه من قِبل قسم صغير من مستخدمي Mainline Menswear، تمكّنوا من تحديد الفرق في الإحصاءات الرئيسية بين التطبيق المتوافق مع الأجهزة الجوّالة والتطبيق والويب.
اتّبع فريق Mainline نهجًا يضمن أنّ الإطار الذي اختاروه لموقعهم الإلكتروني (Nuxt.js باستخدام Vue.js) سيكون مناسبًا للمستقبل ويتيح لهم الاستفادة من تكنولوجيا الويب سريعة التغيير.
النتائج
139%
عدد صفحات أكبر لكل جلسة في تطبيق الويب التقدّمي مقارنةً بالويب
زيادة بنسبة %161
مُدد جلسات أطول في تطبيق الويب التقدّمي مقارنةً بالويب
زيادة بنسبة %10
انخفاض في معدّل الارتداد في تطبيق الويب التقدّمي مقارنةً بالموقع الإلكتروني
12.5%
متوسّط قيمة طلب شراء أعلى في التطبيق المتوافق مع الأجهزة الجوّالة على الويب مقارنةً بالتطبيق على الويب
55%
معدّل إحالات ناجحة أعلى في تطبيق الويب التقدّمي (PWA) مقارنةً بالويب
243%
أرباح أعلى لكل جلسة في تطبيق الويب التقدّمي (PWA) مقارنةً بالويب
نظرة تفصيلية على الجوانب الفنية
تستخدم Mainline Womenswear إطار عمل 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 للرجال للملابس استخدام استراتيجيتَين. تنطبق الاستراتيجية الأولى
على جميع الصور الواردة من شبكة توصيل المحتوى (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 التي تتولّى جميع الإجراءات المتعلّقة بإضافة عناوين "أزرار الربط بصفحات في التطبيق" إلى ذاكرة التخزين المؤقت، والتحقّق من أيّ عدم تطابق في المراجعات، وتعديل وعرض "الملفات المخزّنة مسبقًا" باستخدام استراتيجية 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);
عرض توضيحي
الإبلاغ عن عمليات التثبيت الناجحة
بالإضافة إلى تتبُّع عمليات الإطلاق من الشاشة الرئيسية (باستخدام "start_url": "/?utm_source=pwa"
في بيان
تطبيق الويب)، يُبلغ تطبيق الويب أيضًا عن عمليات تثبيت التطبيق الناجحة من خلال الاستماع إلى حدث
appinstalled
على window
:
window.addEventListener('appinstalled', (evt) => {
ga('send', 'event', 'Install', 'Success');
});
ستؤدي إضافة إمكانات التطبيقات المتوافقة مع الأجهزة الجوّالة إلى موقعك الإلكتروني إلى تحسين تجربة التسوّق لدى عملائك، كما أنّها ستُطرح في السوق بشكل أسرع من [تطبيق مخصّص لمنصّة معيّنة].
أندي هويل، رئيس قسم التطوير
الخاتمة
للاطّلاع على مزيد من المعلومات حول تطبيقات الويب التقدّمية وكيفية إنشائها، انتقِل إلى قسم "تطبيقات الويب التقدّمية" على web.dev.
للاطّلاع على المزيد من دراسات حالة تطبيقات الويب التقدّمية، انتقِل إلى قسم دراسات الحالة.