
تاريخ آخر تعديل: 30-04-2019
ما الذي يجعل تطبيق الويب تطبيق الويب التقدّميًا؟
تقدم تطبيقات الويب التقدّمية تجربة تثبيت تشبه تثبيت التطبيقات على أجهزة كمبيوتر سطح المكتب والأجهزة الجوّالة، ويتم إنشاؤها وتقديمها مباشرةً على الإنترنت. إنها تطبيقات ويب سريعة وموثوقة. والأهم من ذلك، أنها تطبيقات الويب التي تعمل في أي متصفح. إذا كنت بصدد إنشاء تطبيق ويب اليوم، يعني ذلك أنك على المسار الصحيح لإنشاء تطبيق ويب تقدّمي.
سريع وموثوق به
ويجب أن تكون كل تجربة ويب سريعة، وينطبق ذلك بالأخص على تطبيقات الويب التقدّمية. تشير كلمة "سريع" إلى الوقت المستغرق للحصول على محتوى مفيد على الشاشة وتوفير تجربة تفاعلية.
ويجب أن يكون الأمر سريعًا بشكل موثوق. من الصعب التركيز على الأداء الموثوق به بشكل كافٍ، فكّر في هذا الأمر على النحو التالي: الاستخدام الأول للتطبيق الأصلي محبط. فهو محاط بمتجر تطبيقات وتنزيل ضخم، ولكن بعد الوصول إلى النقطة التي يتم فيها تثبيت التطبيق، يتم تخفيض التكلفة المسبقة عند بدء تشغيل جميع التطبيقات، ولا يتأخر تنفيذ أي من هذه الخطوات. يتم تقديم كل طلب التقدّم بأسرع ما يمكن، بدون أي تباين. يجب أن يوفّر تطبيق الويب التقدّمي هذا الأداء الموثوق الذي يتوقعه المستخدمون من أي تجربة مثبَّتة.
قابل للتثبيت
يمكن تشغيل تطبيقات الويب التقدّمية في علامة تبويب متصفّح، ولكن يمكن تثبيتها أيضًا. إنّ وضع إشارة على الموقع الإلكتروني يؤدي فقط إلى إضافة اختصار، إلا أنّ تطبيق الويب التقدّمي (PWA) مثبّت ويبدو مشابهًا لجميع التطبيقات الأخرى المثبّتة. يتم تشغيله من المكان نفسه الذي تُطلق فيه التطبيقات الأخرى. ويمكنك التحكّم في تجربة الإطلاق، بما في ذلك شاشة البدء والرموز المخصّصة وغيرها. ويتم تشغيله كتطبيق، في نافذة تطبيق بدون شريط عناوين أو واجهة مستخدم أخرى في المتصفح. مثل كل التطبيقات المثبتة الأخرى، إنه تطبيق عالي المستوى في مبدِّل المهام.
تذكر، أنه من المهم أن يكون تطبيق الويب التقدّمي القابل للتثبيت سريعًا وموثوقًا. يتوقع المستخدمون الذين يثبتون تطبيق الويب التقدّمي (PWA) أن تعمل تطبيقاتهم، بغض النظر عن نوع اتصال الشبكة الذي يستخدمونه. وتمثل هذه التوقعات المتوقّعة التي يجب أن يستوفيها كل تطبيق مثبَّت.
التطبيقات المتوافقة مع الأجهزة الجوّالة وأجهزة AMP
باستخدام تقنيات التصميم السريع الاستجابة، تعمل تطبيقات الويب التقدّمية (PWA) على الأجهزة الجوّالة وأجهزة كمبيوتر سطح المكتب باستخدام قاعدة رموز واحدة بين المنصّات. إذا كنت تريد كتابة تطبيق محلي، ننصحك بإلقاء نظرة على المزايا التي يقدمها تطبيق الويب التقدّمي (PWA).
العناصر التي سيتم إنشاؤها
في هذا الدرس التطبيقي حول الترميز، ستنشئ تطبيق ويب للطقس باستخدام تقنيات تطبيق الويب التقدّمي (PWA). سيعمل تطبيقك على:
- استخدِم التصميم السريع الاستجابة لكي تعمل على أجهزة كمبيوتر سطح المكتب أو الأجهزة الجوّالة.
- استخدِم مشغّل الخدمات لتخزين موارد التطبيق مؤقتًا (HTML وCSS وJavaScript والصور) اللازمة لتشغيل بيانات الطقس وتخزينها في وقت التشغيل لتحسين الأداء.
- أن تكون قابلة للتثبيت، باستخدام بيان تطبيق الويب وحدث
beforeinstallpromptلإشعار المستخدم بأنه قابل للتثبيت.

ما ستتعرّف عليه
- كيفية إنشاء بيان تطبيق الويب وإضافته
- كيفية توفير تجربة بسيطة بلا اتصال بالإنترنت
- كيفية توفير تجربة كاملة بلا إنترنت
- كيفية إتاحة تثبيت تطبيقك
يركّز هذا الدرس التطبيقي على تطبيقات الويب التقدّمية. يتم معقل المفاهيم وقوالب الرموز غير ذات الصلة وتوفيرها لك لنسخها ولصقها.
المتطلبات اللازمة
- إصدار حديث من Chrome (74 أو أحدث). تعمل تطبيقات الويب التقدّمية (PWA) في جميع المتصفّحات، ولكننا سنستخدم بعض ميزات Chrome DevTools لفهم ما يحدث على مستوى المتصفّح بشكل أفضل واستخدامه لاختبار تجربة التثبيت.
- احرص على معرفة لغة HTML وCSS وJavaScript وChrome DevTools.
الحصول على مفتاح لواجهة برمجة التطبيقات Dark Sky API
ترِد بيانات الطقس من Dark Sky API. لتتمكّن من استخدامه، عليك طلب مفتاح واجهة برمجة تطبيقات. وهو سهل الاستخدام ومجاني للمشاريع غير التجارية.
التسجيل لمفتاح واجهة برمجة التطبيقات
التحقُّق من عمل مفتاح واجهة برمجة التطبيقات بشكل صحيح
لاختبار عمل مفتاح واجهة برمجة التطبيقات بشكل صحيح، يمكنك إرسال طلب HTTP إلى DarkSky API. يُرجى تعديل عنوان URL أدناه لاستبدال DARKSKY_API_KEY بمفتاح واجهة برمجة التطبيقات. إذا كان كل شيء يعمل بشكل صحيح، من المفترض أن ترى أحدث توقعات الطقس لمدينة نيويورك.
https://api.darksky.net/forecast/DARKSKY_API_KEY/40.7720232,-73.9732319
الحصول على الرمز
لقد وضعنا كل ما تحتاج إليه لهذا المشروع في شبكة Git. للبدء، ستحتاج إلى الحصول على الرمز وفتحه في بيئة مطوّري البرامج المفضّلة لديك. بالنسبة إلى هذا الدرس التطبيقي حول الترميز، ننصحك باستخدام Glitch.
ننصح بشدة باستخدام: Glitch لاستيراد استيراد repo
ويُعدّ استخدام Glitch هو الطريقة المُقترَحة للعمل من خلال هذا الدرس التطبيقي حول الترميز.
- افتح علامة تبويب متصفِّح جديدة، وانتقِل إلى https://glitch.com.
- إذا لم يكن لديك حساب، ستحتاج إلى الاشتراك.
- انقر على مشروع جديد، ثم نسخ من Git Repo.
- استنسِخ https://github.com/googlecodelabs/your-first-pwapp.git وانقر على "حسنًا".
- بعد تحميل ملف repo، عدِّل ملف
.envوعدِّله باستخدام واجهة برمجة تطبيقات DarkSky. - انقر على الزر عرض ثم اختر في نافذة جديدة للاطلاع على تطبيق الويب التقدّمي (PWA) بشكل عملي.
طريقة بديلة: تنزيل الرمز &؛ العمل محليًا
إذا أردت تنزيل الرمز والعمل محليًا، يجب أن يتوفّر لديك إصدار حديث من Node.js وأن يكون إعداد محرر الرمز جاهزًا للاستخدام.
- فك ضغط ملف zip الذي تم تنزيله.
- شغِّل
npm installلتثبيت التبعيات المطلوبة لتشغيل الخادم. - تعديل
server.jsوضبط مفتاح DarkSky API. - شغِّل
node server.jsلبدء الخادم على المنفذ 8000. - افتح علامة تبويب المتصفّح للوصول إلى http://localhost:8000
ما هي نقطة البداية لدينا؟
نقطة البداية هي تطبيق أساسي للطقس مصمَّم لهذا الدرس التطبيقي حول الترميز. تم تبسيط الرمز لعرض المفاهيم في هذا الدرس التطبيقي حول الترميز، ولا يتضمن سوى عدد قليل من معالجة الأخطاء. إذا اخترت إعادة استخدام أي رمز من رموز هذا التطبيق في أحد تطبيقات الإنتاج، تأكّد من معالجة أي أخطاء واختبار الرمز بالكامل.
بعض الأمور التي يمكنك تجربتها...
- إضافة مدينة جديدة باستخدام الزر الأزرق + في أسفل يسار الصفحة.
- إعادة تحميل البيانات باستخدام زر إعادة التحميل في أعلى يسار الصفحة.
- احذف إحدى المدن باستخدام علامة x في أعلى يسار كل بطاقة مدينة.
- باستخدام شريط أدوات تبديل الجهاز في Chrome DevTools، يمكنك الاطّلاع على آلية عمله على أجهزة كمبيوتر سطح المكتب والأجهزة الجوّالة.
- باستخدام لوحة الشبكة ضِمن "أدوات مطوري البرامج في Chrome"، يمكنك الاطّلاع على ما يحدث بلا اتصال بالإنترنت.
- باستخدام لوحة الشبكة في Chrome DevTools، اطّلِع على ما يحدث عند ضبط الشبكة على "شبكة الجيل الثالث" البطيئة.
- إضافة تأخير إلى خادم التوقعات من خلال تغيير قيمة
FORECAST_DELAYفيserver.js
تدقيق من خلال Lighthouse
أداة Lighthouse هي أداة سهلة الاستخدام لتحسين جودة مواقعك الإلكترونية وصفحاتك. تُجري خدمة Lighthouse عمليات تدقيق للأداء وتسهيل الاستخدام وتطبيقات الويب التقدّمية وغير ذلك الكثير. يتضمّن كل تدقيق مستندًا مرجعيًا يوضّح سبب أهمية التدقيق وكيفية حلّ المشاكل.

سنستخدم Lighthouse لتدقيق تطبيق "الطقس" والتحقّق من التغييرات التي أجريناها.
لنبدأ تشغيل Lighthouse
- افتح مشروعك في علامة تبويب جديدة.
- افتح أدوات مطوري البرامج في Chrome وانتقِل إلى لوحة عمليات التدقيق. اترك جميع أنواع التدقيق مفعّلة.
- انقر على تنفيذ عمليات التدقيق. بعد مرور بعض الوقت، توفّر لك خدمة Lighthouse تقريرًا على الصفحة.
تدقيق تطبيق الويب التقدّمي
سنركّز على نتائج تدقيق تطبيق الويب التقدّمي.

وهناك الكثير من اللون الأحمر الذي يجب التركيز عليه:
- ❗FAILED: الصفحة الحالية لا تستجيب باستخدام 200 عند عدم الاتصال بالإنترنت.
- ❗FAILED: لا يستجيب
start_urlباستخدام 200 عند عدم الاتصال بالإنترنت. - ❗Failed: لا يسجّل مشغّل خدمات يتحكّم في الصفحة و
start_url.. - ❗FAILED: لا يستوفي بيان تطبيق الويب متطلبات التثبيت.
- ❗FAILED: لم يتم ضبطه لشاشة بداية مخصصة.
- ❗Failed: لم يتم ضبط لون مظهر شريط العناوين.
لنبدأ معالجة بعض هذه المشاكل.
بنهاية هذا القسم، سيجتاز تطبيق الطقس عمليات التدقيق التالية:
- لا يستوفي بيان تطبيق الويب متطلبات التثبيت.
- لم يتم الضبط لشاشة بداية مخصّصة.
- لم يتم ضبط لون مظهر شريط العناوين.
إنشاء بيان تطبيق الويب
بيان تطبيق الويب هو ملف JSON بسيط يمنحك مطوّر البرامج إمكانية التحكّم في كيفية ظهور تطبيقك للمستخدم.
باستخدام بيان تطبيق الويب، يمكن لتطبيق الويب:
- أخبر المتصفّح الذي تريد أن يفتحه تطبيقك في نافذة مستقلة (
display). - تحديد الصفحة التي يتم فتحها عند تشغيل التطبيق لأول مرة (
start_url). - حدِّد الشكل الذي يجب أن يظهر به التطبيق في شريط التطبيقات أو مشغّل التطبيقات (
short_nameوicons). - يمكنك إنشاء شاشة بداية (
name،icons،colors). - اطلب من المتصفّح فتح النافذة في الوضع الأفقي أو في الوضع العمودي (
orientation). - والمزيد من الميزات.
أنشئ ملفًا باسم public/manifest.json في مشروعك. انسخ المحتوى التالي والصقه:
public/manifest.json
{
"name": "Weather",
"short_name": "Weather",
"icons": [{
"src": "/images/icons/icon-128x128.png",
"sizes": "128x128",
"type": "image/png"
}, {
"src": "/images/icons/icon-144x144.png",
"sizes": "144x144",
"type": "image/png"
}, {
"src": "/images/icons/icon-152x152.png",
"sizes": "152x152",
"type": "image/png"
}, {
"src": "/images/icons/icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
}, {
"src": "/images/icons/icon-256x256.png",
"sizes": "256x256",
"type": "image/png"
}, {
"src": "/images/icons/icon-512x512.png",
"sizes": "512x512",
"type": "image/png"
}],
"start_url": "/index.html",
"display": "standalone",
"background_color": "#3E4EB8",
"theme_color": "#2F3BA2"
}
يدعم البيان مجموعة من الرموز المخصصة لأحجام الشاشات المختلفة. في هذا الدرس التطبيقي حول الترميز، أدرجنا بعض الأنواع الأخرى لدمج نظام التشغيل iOS.
إضافة رابط إلى بيان تطبيق الويب
بعد ذلك، نحتاج إلى إعلام المتصفح بشأن ملف البيان من خلال إضافة <link rel="manifest"... إلى كل صفحة في تطبيقنا. أضف السطر التالي إلى العنصر <head> في ملف index.html.
public/index.html
<!-- CODELAB: Add link rel manifest -->
<link rel="manifest" href="/manifest.json">
قناة DevTools تحويلة
توفِّر"أدوات مطوري البرامج"طريقة سريعة وسهلة للتحقُّق من ملف manifest.json. افتح لوحة ملف البيان في لوحة التطبيق. إذا أضفت معلومات البيان بشكل صحيح، ستتمكن من الاطلاع على تحليلها وعرضها بتنسيق متوافق مع البشر على هذا الجزء.

إضافة علامات وصفية وعلامات لـ iOS
لا يدعم Safari على نظام التشغيل iOS بيان البيان (حتى الآن)، لذلك ستحتاج إلى إضافة علامات meta التقليدية إلى <head> من ملف index.html:
public/index.html
<!-- CODELAB: Add iOS meta tags and icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="Weather PWA">
<link rel="apple-touch-icon" href="/images/icons/icon-152x152.png">
مكافأة: إصلاحات Lighthouse السهلة
وتوضّح عملية تدقيق Lighthouse بعض الأمور الأخرى التي يسهل إصلاحها، لذلك سنهرب من هذه المشاكل أثناء توفّرها.
تحديد الوصف التعريفي
أثناء التدقيق في عملية تحسين محركات البحث، لاحظ فريق Lighthouse أنّ "المستند" لا يتضمّن وصفًا تعريفيًا. يمكن عرض الأوصاف في نتائج "بحث Google". يمكن أن تؤدي الأوصاف الفريدة والعالية الجودة إلى ملاءمة نتائجك لمستخدمي البحث وزيادة عدد زيارات البحث.
لإضافة وصف، أضِف العلامة meta التالية إلى <head> للمستند:
public/index.html
<!-- CODELAB: Add description here -->
<meta name="description" content="A sample weather app">
ضبط لون مظهر شريط العناوين
في تدقيق تطبيق الويب التقدّمي (PWA)، لاحظت أداة Lighthouse التطبيق الخاص بنا &;لا تضبط لونًا لمظهر شريط العناوين. إنّ تخصيص شريط عناوين المتصفّح بما يتناسب مع ألوان علامتك التجارية يوفّر تجربة متكاملة.
لضبط لون المظهر على الجوّال، أضِف علامة meta التالية إلى <head> للمستند:
public/index.html
<!-- CODELAB: Add meta theme-color -->
<meta name="theme-color" content="#2F3BA2" />
التحقّق من التغييرات باستخدام Lighthouse
شغِّل Lighthouse مرة أخرى (بالنقر على علامة + في أعلى يمين لوحة "عمليات التدقيق") والتحقُّق من التغييرات.
تدقيق تحسين محركات البحث
- › تم اجتياز الاختبار: يحتوي المستند على وصف تعريفي.
تدقيق تطبيق الويب التقدّمي
- ❗FAILED: الصفحة الحالية لا تستجيب باستخدام 200 عند عدم الاتصال بالإنترنت.
- ❗FAILED: لا يستجيب
start_urlباستخدام 200 عند عدم الاتصال بالإنترنت. - ❗Failed: لا يسجّل مشغّل خدمات يتحكّم في الصفحة و
start_url.. - 🎁 تم الاجتياز: استيفاء بيان تطبيق الويب متطلبات التثبيت.
- ○ تم اجتياز الاختبار: تم ضبطها للعمل في شاشة بداية مخصّصة.
- › تم الاجتياز: يتم ضبط لون شريط العناوين.
يتوقع المستخدمون أنّ التطبيقات المثبَّتة ستحصل دائمًا على تجربة أساسية في حال عدم اتصالهم بالإنترنت. ولهذا السبب، لا غنى عن تطبيقات الويب القابلة للتثبيت عدم عرض ألعاب الديناصورات بلا إنترنت على متصفّح Chrome. وتتراوح التجربة بلا اتصال بالإنترنت من صفحة بسيطة بلا اتصال بالإنترنت إلى تجربة للقراءة فقط من خلال البيانات المخزَّنة مؤقتًا سابقًا، إلى تجربة تعمل بلا اتصال بالإنترنت وتتزامن تلقائيًا عند استعادة اتصال الشبكة.
في هذا القسم، سنضيف صفحة بسيطة غير متصلة بالإنترنت إلى تطبيق الطقس التابع لنا. إذا حاول المستخدم تحميل التطبيق أثناء عدم الاتصال بالإنترنت، سيعرض الصفحة الخاصة بنا بدلاً من الصفحة العادية غير المتصلة بالإنترنت التي يعرضها المتصفّح. بنهاية هذا القسم، سيجتاز تطبيق الطقس عمليات التدقيق التالية:
- الصفحة الحالية لا تستجيب باستخدام رمز 200 عند عدم الاتصال بالإنترنت.
start_urlلا يستجيب مع ظهور 200 عندما تكون غير متصل.- عدم تسجيل مشغّل الخدمات الذي يتحكّم في الصفحة و
start_url.
في القسم التالي، سنستبدل صفحة "التشغيل بلا إنترنت" المخصّصة بتجربة كاملة بلا اتصال بالإنترنت. سيساهم ذلك في تحسين التجربة التي تتم بلا اتصال بالإنترنت، ولكن الأهم من ذلك هو أنّ هذه التجربة ستعمل بشكل أفضل على تحسين أدائنا، لأن معظم مواد العرض (HTML وCSS وJavaScript) سيتم تخزينها وتقديمها محليًا، ما يلغي الشبكة كتأثير محتمل.
موظفو الخدمة للإنقاذ
إذا لم تكن على دراية بعاملي الخدمة، يمكنك الحصول على فهم أساسي للمهام التي يمكنهم تنفيذها، وكيفية عمل مراحل نشاطهم، والمزيد من خلال قراءة مقدمة عن عاملي الخدمة.
يجب اعتبار الميزات المقدمة من خلال العاملين في الخدمة تحسينًا تدريجيًا، ولا تتم إضافتها إلا إذا كانت تدعم المتصفح. على سبيل المثال، باستخدام عاملي الخدمة، يمكنك تخزين صدف التطبيق مؤقتًا وبيانات تطبيقك، حتى تكون متاحة حتى عندما لا تكون الشبكة متاحة. عندما لا يكون مشغّلو الخدمات متاحين، لا يتم طلب الرمز بلا اتصال بالإنترنت، ويحصل المستخدم على تجربة أساسية. أعباء قليلة لاستخدام ميزة "اكتشاف الميزات" لتوفير التحسينات التدريجية، ولن تتوقف في المتصفحات القديمة التي لا تدعم هذه الميزة.
تسجيل مشغّل الخدمات
الخطوة الأولى هي تسجيل مشغّل الخدمات. أضِف الرمز التالي إلى ملف index.html:
public/index.html
// CODELAB: Register service worker.
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/service-worker.js')
.then((reg) => {
console.log('Service worker registered.', reg);
});
});
}
يتحقَّق هذا الرمز لمعرفة ما إذا كانت واجهة برمجة تطبيقات مشغّل الخدمة متاحة، وإذا كان متاحًا، يتم تسجيل مشغّل الخدمات في /service-worker.js بعد تحميل الصفحة.
ملاحظة: يتم تقديم مشغّل الخدمات من الدليل الجذري، وليس من الدليل /scripts/. هذه هي أسهل طريقة لضبط scope مشغّل الخدمات. يحدد scope لعامل الخدمة الملفات التي يتحكم فيها مشغّل الخدمات، بمعنى آخر، من المسار الذي سيعترض مشغّل الخدمات الطلبات عليه. scope التلقائي هو موقع ملف مشغّل الخدمات، ويمتد إلى جميع الأدلة أدناه. لذلك، إذا كان service-worker.js في الدليل الجذري، سيتحكّم مشغّل الخدمات في الطلبات الواردة من جميع صفحات الويب في هذا النطاق.
التخزين المؤقت للصفحة بلا اتصال بالإنترنت
عليك أولاً إخبار مشغّل الخدمات بالبيانات التي يجب تخزينها في ذاكرة التخزين المؤقت. لقد أنشأنا صفحة بلا اتصال بسيطة (public/offline.html) سيتم عرضها في أي وقت لا يتوفر فيه اتصال بالشبكة.
في service-worker.js، أضِف '/offline.html', إلى المصفوفة FILES_TO_CACHE، وستظهر النتيجة النهائية على النحو التالي:
public/service-work.js
// CODELAB: Add list of files to cache here.
const FILES_TO_CACHE = [
'/offline.html',
];
بعد ذلك، علينا إضافة الرمز التالي إلى الحدث install لنطلب من مشغّل الخدمات الاحتفاظ بنسخة مؤقتة من الصفحة المتوفّرة بلا إنترنت:
public/service-work.js
// CODELAB: Precache static resources here.
evt.waitUntil(
caches.open(CACHE_NAME).then((cache) => {
console.log('[ServiceWorker] Pre-caching offline page');
return cache.addAll(FILES_TO_CACHE);
})
);
يتم الآن فتح ذاكرة التخزين المؤقت باستخدام caches.open() من خلال حدث install وتوفير اسم لذاكرة التخزين المؤقت. يتيح لنا تقديم اسم ذاكرة التخزين المؤقت إنشاء نُسخ من الملفات أو فصل البيانات عن الموارد المخزنة مؤقتًا حتى نتمكن بسهولة من تحديث أحدها بدون التأثير في الأخرى.
وبعد فتح ذاكرة التخزين المؤقت، يمكننا استدعاء خدمة cache.addAll()، التي تأخذ قائمة بعناوين URL، وتجلبها من الخادم وتضيف الاستجابة إلى ذاكرة التخزين المؤقت. وتجدر الإشارة إلى أن cache.addAll() سيتعذّر تنفيذها إذا تعذّر تنفيذ أي من الطلبات الفردية. وهذا يعني أنّه في حال نجاح خطوة التثبيت، ستكون ذاكرة التخزين المؤقت في حالة متناسقة. ولكن إذا تعذّر لسبب ما، سيحاول مرة أخرى تلقائيًا عند تشغيل مشغّل الخدمات في المرة القادمة.
قناة DevTools تحويلة
لنلقِ نظرة على كيفية استخدام أدوات مطوّري البرامج لفهم عاملي الخدمة وتصحيح أخطائهم. قبل إعادة تحميل الصفحة، افتح مجموعة DevTools وانتقِل إلى اللوحة عاملو الخدمة في لوحة التطبيق. ومن المفترض أن يظهر الرقم بالشكل التالي:

وعند ظهور صفحة فارغة على هذا النحو، يعني ذلك أنّ الصفحة المفتوحة حاليًا لا تتضمّن أي عاملي خدمة مسجّلين.
والآن، أعِد تحميل صفحتك. يجب أن تظهر لوحة "عمّال الخدمة" الآن على النحو التالي:

عندما تشاهد معلومات كهذه، يعني ذلك أنّ الصفحة تتضمّن مشغّل خدمات قيد التشغيل.
بجوار تصنيف الحالة، هناك رقم (34251 في هذه الحالة). راقب هذا الرقم بينما تعمل مع موظفي الخدمة. إنها طريقة سهلة لمعرفة ما إذا تم تحديث مشغّل الخدمات أم لا.
تنظيف الصفحات القديمة بلا اتصال بالإنترنت
سنستخدم حدث activate لإزالة أي بيانات قديمة من ذاكرة التخزين المؤقت. ويضمن هذا الرمز تحديث مشغّل الخدمات لذاكرة التخزين المؤقت كلما طرأ تغيير على أي من ملفات هيكل التطبيق. ولإجراء ذلك، يجب زيادة المتغيّر CACHE_NAME في أعلى ملف مشغّل الخدمات.
أضِف الرمز التالي إلى حدث activate:
public/service-work.js
// CODELAB: Remove previous cached data from disk.
evt.waitUntil(
caches.keys().then((keyList) => {
return Promise.all(keyList.map((key) => {
if (key !== CACHE_NAME) {
console.log('[ServiceWorker] Removing old cache', key);
return caches.delete(key);
}
}));
})
);
قناة DevTools تحويلة
بعد فتح لوحة "عمال الخدمة"، أعِد تحميل الصفحة. سترى مشغّل الخدمات الجديد مثبتًا وزيادة رقم الحالة.

يتحكّم مشغّل الخدمات المعدَّل على الفور في حال انتهاء حدث install بـ self.skipWaiting()، وينتهي حدث activate بـ self.clients.claim(). وبدونها، سيستمر مشغّل الخدمات القديم في التحكّم في الصفحة طالما كانت هناك علامة تبويب مفتوحة في الصفحة.
معالجة طلبات الشبكة التي تعذّر تنفيذها
أخيرًا، علينا معالجة أحداث fetch. سنستخدم استراتيجية تعود الشبكة إلى ذاكرة التخزين المؤقت. يحاول مشغّل الخدمات جلب المورد من الشبكة أولاً. إذا أخفق ذلك، يعرض مشغّل الخدمات الصفحة بلا اتصال بالإنترنت من ذاكرة التخزين المؤقت.

public/service-work.js
// CODELAB: Add fetch event handler here.
if (evt.request.mode !== 'navigate') {
// Not a page navigation, bail.
return;
}
evt.respondWith(
fetch(evt.request)
.catch(() => {
return caches.open(CACHE_NAME)
.then((cache) => {
return cache.match('offline.html');
});
})
);
ويحتاج معالج fetch فقط إلى التعامل مع عمليات التنقل خلال الصفحات، لذا يمكن التخلص من الطلبات الأخرى من المعالج والتعامل معها بشكل طبيعي من خلال المتصفِّح. ولكن إذا كان الطلب .mode هو navigate، استخدِم fetch لمحاولة الحصول على العنصر من الشبكة. إذا تعذَّر، سيعالج المعالج catch ذاكرة التخزين المؤقت مع caches.open(CACHE_NAME) ويستخدم cache.match('offline.html') للحصول على الصفحة المخزَّنة مؤقتًا بلا اتصال بالإنترنت. بعد ذلك، يتم إرسال النتيجة إلى المتصفِّح باستخدام evt.respondWith().
قناة DevTools تحويلة
لنتأكّد من أنّ كل شيء يعمل على النحو المتوقّع. بعد فتح لوحة عمال الخدمة، أعِد تحميل الصفحة. سترى مشغّل الخدمات الجديد مثبتًا وزيادة رقم الحالة.
كما يمكننا أيضًا التحقق لمعرفة ما تم تخزينه مؤقتًا في ملف تعريف الارتباط. انتقِل إلى لوحة مساحة التخزين المؤقت على لوحة التطبيق في "أدوات مطوّري البرامج". النقر بزر الماوس الأيمن على تخزين ذاكرة التخزين المؤقت واختيار إعادة تحميل ذاكرات التخزين المؤقت وتوسيع القسم من المفترض أن يظهر اسم ذاكرة التخزين المؤقت الثابتة مُدرجًا في الجانب الأيمن. انقر على اسم ذاكرة التخزين المؤقت لمشاهدة جميع الملفات المخزنة مؤقتًا.

والآن، لنختبر وضع عدم الاتصال بالإنترنت. ارجع إلى الجزء Service Workers في لوحة التطبيق من أدوات مطوري البرامج وحدد مربع الاختيار بلا اتصال بالإنترنت. وبعد التحقّق منها، من المفترض أن يظهر رمز تحذير أصفر اللون بجانب علامة تبويب لوحة الشبكة. يشير هذا الرمز إلى أنك غير متصل بالإنترنت.

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

- بلا اتصال بالإنترنت - عند وضع علامة في المربع، يحاكي تجربة بلا اتصال بالإنترنت ويمنع أي طلبات من الانتقال إلى الشبكة.
- تحديث عند إعادة التحميل - عند وضع علامة في هذا المربع، سيحصل على أحدث مشغّل خدمات لتثبيته وتفعيله فورًا.
- تجاوز الشبكة - عند وضع علامة على هذا الخيار، تتجاوز الطلبات مشغّل الخدمات ويتم إرسالها مباشرةً إلى الشبكة.
بداية جديدة
في بعض الحالات، قد تجد نفسك تُحمِّل بيانات مخزَّنة مؤقتًا أو لا يتم تعديل ما تتوقّعه. لمحو جميع البيانات المحفوظة (localStorage وبيانات مفهرسة عن البيانات والملفات المخزَّنة مؤقتًا) وإزالة أي عاملي خدمة، استخدِم اللوحة محو مساحة التخزين في لوحة التطبيق. ويمكنك بدلاً من ذلك العمل في نافذة التصفح المتخفي.

نصائح أخرى:
- بعد إلغاء تسجيل مشغّل الخدمات، قد يظل مُدرجًا حتى يتم إغلاق نافذة المتصفّح التي تحتوي عليه.
- في حال فتح نوافذ متعددة لتطبيقك، لن يعمل مشغّل خدمات جديد حتى تتم إعادة تحميل جميع النوافذ وتحديثها إلى أحدث مشغّل خدمات.
- لا يؤدي إلغاء تسجيل مشغّل الخدمات إلى محو ذاكرة التخزين المؤقت.
- في حال وجود مشغّل خدمات وتسجيل مشغّل خدمات جديد، لن يتحكّم مشغّل الخدمات الجديد حتى تتم إعادة تحميل الصفحة، ما لم يتم التحكّم الفوري.
التحقّق من التغييرات باستخدام Lighthouse
شغِّل Lighthouse مرة أخرى وتحقّق من التغييرات. لا تنسَ إزالة العلامة من مربّع الاختيار "بلا اتصال بالإنترنت" قبل إثبات صحة التغييرات.
تدقيق تحسين محركات البحث
- › تم اجتياز الاختبار: يحتوي المستند على وصف تعريفي.
تدقيق تطبيق الويب التقدّمي
- ○ تم الاجتياز: ستستجيب الصفحة الحالية برقم 200 عندما تكون غير متصل بالإنترنت.
- › تم اجتياز الاختبار:
start_urlيستجيب باستخدام 200 في حال عدم الاتصال بالإنترنت. - › تم بنجاح: تسجيل مشغّل خدمات يتحكم في الصفحة و
start_url. - 🎁 تم الاجتياز: استيفاء بيان تطبيق الويب متطلبات التثبيت.
- ○ تم اجتياز الاختبار: تم ضبطها للعمل في شاشة بداية مخصّصة.
- › تم الاجتياز: يتم ضبط لون شريط العناوين.
يُرجى تخصيص بعض الوقت لوضع هاتفك على "وضع الطيران"، ومحاولة تشغيل بعض تطبيقاتك المفضّلة. في جميع الحالات تقريبًا، تقدم تجربة قوية بلا اتصال بالإنترنت. يتوقع المستخدمون الحصول على تجربة قوية من تطبيقاتهم. ويجب ألا يختلف الويب عن ذلك. يجب تصميم تطبيقات الويب التقدّمية بحيث لا تكون متصلاً بالإنترنت كسيناريو أساسي.
دورة حياة مشغّل الخدمات
تُعدّ دورة حياة عامل الخدمة هي الجزء الأكثر تعقيدًا. إذا لم تكن تعرف الإجراءات التي تحاول تنفيذها وفوائدها، يمكنك الشعور بأنها تكافح. ولكن بعد معرفة آلية العمل، يمكنك تقديم تحديثات سلسة وغير مزعجة للمستخدمين، وذلك من خلال دمج أفضل ما على الويب والأنماط الأصلية.
install حدث
الحدث الأول الذي يحصل عليه مشغّل الخدمات هو install. يتم تشغيله فور التنفيذ، ويتم استدعاؤه مرة واحدة فقط لكل عامل خدمة. في حال تغيير النص البرمجي لعامل الخدمة، يعتبره المتصفّح مشغّل خدمات مختلفًا، وسيحصل على الحدث install الخاص.

يُستخدم حدث install عادةً لتخزين كل ما تحتاج إليه لتشغيل تطبيقك في ذاكرة التخزين المؤقت.
activate حدث
وسيتلقّى مشغّل الخدمات حدث activate في كل مرة يبدأ فيها تشغيله. يتمثل الغرض الرئيسي من حدث activate في ضبط سلوك مشغّل الخدمات وتنظيف أي موارد متبقية من عمليات التشغيل السابقة (مثل ذاكرات التخزين المؤقت القديمة) وتجهيز مشغّل الخدمات لمعالجة طلبات الشبكة (على سبيل المثال، حدث fetch الموضّح أدناه).
fetch حدث
يتيح حدث الجلب لعامل الخدمة اعتراض أي طلبات على الشبكة والتعامل مع الطلبات. ويمكن أن ينتقل إلى الشبكة للحصول على المورد، ويمكنه سحبه من ذاكرة التخزين المؤقت الخاصة به، أو إنشاء رد مخصص، أو أي عدد من الخيارات المختلفة. ويمكنك الاطّلاع على كتاب الطبخ بلا إنترنت لمعرفة الاستراتيجيات المختلفة التي يمكنك استخدامها.
تحديث مشغّل الخدمات
يتحقّق المتصفِّح لمعرفة ما إذا كان هناك إصدار جديد من مشغّل الخدمات عند كل تحميل للصفحة. وفي حال العثور على إصدار جديد، يتم تنزيل الإصدار الجديد وتثبيته في الخلفية، ولكن لم يتم تفعيله. يظل الإصدار الجديد من مشغّل الخدمات في حالة انتظار إلى أن تنقضي أي صفحات مفتوحة تستخدم مشغّل الخدمات القديم. بعد إغلاق جميع النوافذ التي تستخدم عامل الخدمة القديم، يتم تفعيل مشغّل الخدمات الجديد ويمكنه التحكّم في استخدامه. يُرجى الاطّلاع على القسم تحديث عامل الخدمة في مستند "دورة حياة عامل الخدمة" للحصول على مزيد من التفاصيل.
اختيار استراتيجية التخزين المؤقت المناسبة
يعتمد اختيار استراتيجية التخزين المؤقت المناسبة على نوع المورد الذي تحاول تخزينه في ذاكرة التخزين المؤقت والطريقة التي قد تحتاج إليها للوصول إليها لاحقًا. بالنسبة إلى تطبيق الطقس، سنقسِّم الموارد التي نحتاج إليها لتخزينها مؤقتًا إلى فئتين: الموارد التي نريد تخزينها مؤقتًا، والبيانات التي سيتم تخزينها مؤقتًا في وقت التشغيل.
التخزين المؤقت للموارد الثابتة
إنّ تخزين مواردك هو مفهوم مشابه لما يحدث عندما يثبّت المستخدم تطبيقًا متوافقًا مع أجهزة سطح المكتب أو الأجهزة الجوّالة. ويتم تثبيت الموارد الرئيسية اللازمة لتشغيل التطبيق أو تخزينها مؤقتًا على الجهاز بحيث يمكن تحميلها لاحقًا سواء كان الاتصال بالشبكة متوفرًا أم لا.
بالنسبة إلى تطبيقنا، سنخزّن مؤقتًا جميع مواردنا الثابتة عند تثبيت مشغّل الخدمات لدينا، وبذلك يتم تخزين كل ما نحتاج إليه لتشغيل تطبيقنا على جهاز المستخدم. لضمان تحميل تطبيقنا بسرعة البرق، سنستخدم استراتيجية ذاكرة التخزين المؤقت أولاً؛ فبدلاً من الانتقال إلى الشبكة للحصول على الموارد، يتم سحبها من ذاكرة التخزين المؤقت المحلية؛ وإذا لم يكن ذلك متاحًا، سنحاول الحصول عليها من الشبكة.

يؤدي السحب من ذاكرة التخزين المؤقت المحلية إلى إزالة أي تنوع في الشبكة. وبغض النظر عن نوع الشبكة التي يتصل بها المستخدم (WiFi أو 5G أو 3G أو حتى 2G)، تتوفر الموارد الرئيسية التي نحتاج إلى تشغيلها في الحال تقريبًا.
التخزين المؤقت لبيانات التطبيق
وتُعدّ استراتيجية sall-when-reverify خيارًا مثاليًا لأنواع معيّنة من البيانات وتعمل بشكل جيد مع تطبيقنا، حيث يتم عرضها على الشاشة في أسرع وقت ممكن ثم تعديلها بعد عرض الشبكة لأحدث البيانات. وعند إعادة التحقّق من الصحة القديمة، علينا تنفيذ طلبَين غير متزامنَين، أحدهما مخصّص لذاكرة التخزين المؤقت والآخر للشبكة.

وفي ظل الظروف العادية، سيتم عرض البيانات المخزنة مؤقتًا على الفور تقريبًا لتزويد التطبيق بالبيانات الحديثة التي يمكنه استخدامها. وبعد ذلك، عند رجوع طلب الشبكة، سيتم تحديث التطبيق باستخدام أحدث البيانات من الشبكة.
بالنسبة إلى تطبيقنا، يوفّر ذلك تجربة أفضل من الشبكة، والانتباه إلى استراتيجية ذاكرة التخزين المؤقت لأن المستخدم لا يضطر إلى الانتظار حتى تنتهي مهلة طلب الشبكة لرؤية شيء على الشاشة. قد تظهر لهم البيانات القديمة في البداية، ولكن بعد إرجاع طلب الشبكة، يتم تحديث التطبيق بأحدث البيانات.
تحديث منطق التطبيق
كما ذكرنا سابقًا، يحتاج التطبيق إلى طرح طلبين غير متزامنين، أحدهما لذاكرة التخزين المؤقت والآخر للشبكة. يستخدم التطبيق العنصر caches المتوفّر في window للوصول إلى ذاكرة التخزين المؤقت واسترداد أحدث البيانات. وهذا مثال ممتاز لتحسين تدريجي، حيث قد لا يكون الكائن caches متاحًا في جميع المتصفحات، وإذا لم يكن متاحًا، من المفترض أن يظل طلب الشبكة يعمل.
عليك تحديث الدالة getForecastFromCache()، للتحقّق مما إذا كان الكائن caches متاحًا في العنصر window العام، وإذا كان متاحًا، يمكنك طلب البيانات من ذاكرة التخزين المؤقت.
public/scripts/app.js
// CODELAB: Add code to get weather forecast from the caches object.
if (!('caches' in window)) {
return null;
}
const url = `${window.location.origin}/forecast/${coords}`;
return caches.match(url)
.then((response) => {
if (response) {
return response.json();
}
return null;
})
.catch((err) => {
console.error('Error getting data from cache', err);
return null;
});
بعد ذلك، علينا تعديل updateData() بحيث يتم إجراء مكالمتين، واحدة إلى getForecastFromNetwork() للحصول على التوقعات من الشبكة، والأخرى إلى getForecastFromCache() للحصول على أحدث التوقعات المخزّنة مؤقتًا:
public/scripts/app.js
// CODELAB: Add code to call getForecastFromCache.
getForecastFromCache(location.geo)
.then((forecast) => {
renderForecast(card, forecast);
});
ينشئ تطبيق الطقس الآن طلبين غير متزامنين للبيانات، أحدهما من ذاكرة التخزين المؤقت والآخر من خلال fetch. إذا كانت هناك بيانات في ذاكرة التخزين المؤقت، سيتم عرضها وعرضها بسرعة كبيرة (عشرات المللي ثانية). وبعد تلقّي استجابة من fetch، سيتم تعديل البطاقة باستخدام أحدث البيانات مباشرةً من واجهة برمجة تطبيقات الطقس.
لاحِظ كيف ينتهي طلب ذاكرة التخزين المؤقت وطلب fetch باستدعاء تحديث بطاقة التوقعات. كيف يعرف التطبيق ما إذا كان يعرض أحدث البيانات؟ تتم معالجة هذا الأمر في الرمز التالي من renderForecast():
public/scripts/app.js
// If the data on the element is newer, skip the update.
if (lastUpdated >= data.currently.time) {
return;
}
في كل مرة يتم فيها تحديث بطاقة، يخزّن التطبيق الطابع الزمني للبيانات على سمة مخفية في البطاقة. يتوقّف التطبيق فقط إذا كان الطابع الزمني المتوفّر على البطاقة أحدث من البيانات التي تم تمريرها إلى الدالة.
تخزين موارد التطبيق مؤقتًا
في مشغّل الخدمات، أضِف DATA_CACHE_NAME حتى نتمكّن من فصل بيانات التطبيقات عن هيكل التطبيق. وعند تحديث هيكل التطبيق وإزالة النسخ المخبأة القديمة، تظل بياناتنا كما هي، جاهزة للتحميل بسرعة فائقة. تجدر الإشارة إلى أنه في حال تغيير تنسيق البيانات في المستقبل، ستحتاج إلى طريقة للتعامل مع ذلك وضمان بقاء هيكل التطبيق ومحتواه متزامنين.
public/service-work.js
// CODELAB: Update cache names any time any of the cached files change.
const CACHE_NAME = 'static-cache-v2';
const DATA_CACHE_NAME = 'data-cache-v1';
لا تنسَ تحديث CACHE_NAME أيضًا، وسنغيّر جميع مواردنا الثابتة أيضًا.
لكي يعمل تطبيقنا بلا اتصال بالإنترنت، نحتاج إلى تخزين مؤقت لجميع الموارد التي يحتاجها بشكل مؤقت. سيساعد ذلك أيضًا في تحسين أدائنا. بدلاً من الاضطرار إلى الحصول على جميع الموارد من الشبكة، سيتمكن التطبيق من تحميلها جميعًا من ذاكرة التخزين المؤقت المحلية، مما يلغي أي عدم استقرار في الشبكة.
تعديل مصفوفة FILES_TO_CACHE من خلال قائمة الملفات:
public/service-work.js
// CODELAB: Add list of files to cache here.
const FILES_TO_CACHE = [
'/',
'/index.html',
'/scripts/app.js',
'/scripts/install.js',
'/scripts/luxon-1.11.4.js',
'/styles/inline.css',
'/images/add.svg',
'/images/clear-day.svg',
'/images/clear-night.svg',
'/images/cloudy.svg',
'/images/fog.svg',
'/images/hail.svg',
'/images/install.svg',
'/images/partly-cloudy-day.svg',
'/images/partly-cloudy-night.svg',
'/images/rain.svg',
'/images/refresh.svg',
'/images/sleet.svg',
'/images/snow.svg',
'/images/thunderstorm.svg',
'/images/tornado.svg',
'/images/wind.svg',
];
ولأننا نُنشئ قائمة الملفات يدويًا في ذاكرة التخزين المؤقت، نعدّل CACHE_NAME في كل مرة نعدّل فيها ملفًا. لقد أزلنا offline.html من قائمة الملفات المخزّنة مؤقتًا لأنّ تطبيقنا يحتوي الآن على جميع الموارد اللازمة للعمل بلا اتصال بالإنترنت، ولن يعرض الصفحة بلا اتصال بالإنترنت مرة أخرى مطلقًا.
تعديل معالج حدث التفعيل
لضمان ألا يؤدي حدث activate إلى حذف بياناتنا عن طريق الخطأ، في حدث activate على service-worker.js، استبدِل if (key !== CACHE_NAME) { بما يلي:
public/service-work.js
if (key !== CACHE_NAME && key !== DATA_CACHE_NAME) {
تعديل معالج حدث الجلب
نحتاج إلى تعديل مشغّل الخدمات لاعتراض الطلبات على واجهة برمجة تطبيقات الطقس وتخزين ردوده في ذاكرة التخزين المؤقت، حتى نتمكن من الوصول إليها بسهولة لاحقًا. بالنسبة إلى الاستراتيجية القديمة أثناء إعادة التحقق، نتوقع أن تكون استجابة الشبكة هي "مصدر الحقيقة"'؛ وتزويدنا دائمًا بأحدث المعلومات. إذا لم تتمكن الشبكة من تنفيذ ذلك، فهي ليست صالحة لأننا استردنا بالفعل أحدث البيانات المخزنة مؤقتًا في تطبيقنا.
عدِّل معالج أحداث fetch لمعالجة الطلبات الواردة إلى واجهة برمجة التطبيقات للبيانات بشكل منفصل عن الطلبات الأخرى.
public/service-work.js
// CODELAB: Add fetch event handler here.
if (evt.request.url.includes('/forecast/')) {
console.log('[Service Worker] Fetch (data)', evt.request.url);
evt.respondWith(
caches.open(DATA_CACHE_NAME).then((cache) => {
return fetch(evt.request)
.then((response) => {
// If the response was good, clone it and store it in the cache.
if (response.status === 200) {
cache.put(evt.request.url, response.clone());
}
return response;
}).catch((err) => {
// Network request failed, try to get it from the cache.
return cache.match(evt.request);
});
}));
return;
}
evt.respondWith(
caches.open(CACHE_NAME).then((cache) => {
return cache.match(evt.request)
.then((response) => {
return response || fetch(evt.request);
});
})
);
يعترض الرمز الطلب ويتحقق مما إذا كان ذلك متوقعًا للطقس. وفي هذه الحالة، استخدِم fetch لتقديم الطلب. بعد إرجاع الرد، افتح ذاكرة التخزين المؤقت واستنساخ الاستجابة واحفظها في ذاكرة التخزين المؤقت وارجع الرد إلى مقدم الطلب الأصلي.
ونحن بحاجة إلى إزالة عملية التحقق من evt.request.mode !== 'navigate' لأننا نريد أن يعالج مشغّل الخدمات جميع الطلبات (بما في ذلك الصور والنصوص البرمجية وملفات CSS وغير ذلك)، وليس فقط عناصر التنقل. إذا تركنا هذا التحقق، سيتم عرض HTML فقط من ذاكرة التخزين المؤقت لعامل الخدمة. سيتم طلب كل الخدمات الأخرى من الشبكة.
جرّب بنفسك
من المفترض أن يعمل التطبيق بلا اتصال بالإنترنت تمامًا الآن. حدّث الصفحة للتأكد من تثبيت آخر مشغّل خدمات لديك. وبعد ذلك، احفظ بضع مدن واضغط على زر إعادة التحميل في التطبيق للحصول على بيانات الطقس الطازجة.
بعد ذلك، انتقِل إلى لوحة التخزين في ذاكرة التخزين المؤقت ضمن لوحة Application ضِمن "أدوات مطوري البرامج". وسِّع القسم، ومن المفترض أن ترى اسم ذاكرة التخزين المؤقت الثابتة وذاكرة التخزين المؤقت للبيانات مُدرَجة على الجانب الأيمن. يجب أن يؤدي فتح ذاكرة التخزين المؤقت للبيانات إلى عرض البيانات المخزنة لكل مدينة.

بدِّل إلى جزء عمال الخدمة وضَع علامة في مربّع الاختيار بلا اتصال بالإنترنت. يُرجى محاولة إعادة تحميل الصفحة ثم الانتقال إلى وضع عدم الاتصال وإعادة تحميل الصفحة.
إذا كنت تستخدم شبكة سريعة وتريد معرفة كيف يتم تحديث بيانات توقعات الطقس عندما يكون الاتصال بطيئًا، اضبط الخاصية FORECAST_DELAY في server.js على 5000. سيتم تأجيل جميع الطلبات إلى واجهة برمجة التطبيقات للتوقعات بمقدار 5000 مللي ثانية.
التحقّق من التغييرات باستخدام Lighthouse
من المفيد أيضًا تشغيل Lighthouse مرة أخرى.
تدقيق تحسين محركات البحث
- › تم اجتياز الاختبار: يحتوي المستند على وصف تعريفي.
تدقيق تطبيق الويب التقدّمي
- ○ تم الاجتياز: ستستجيب الصفحة الحالية برقم 200 عندما تكون غير متصل بالإنترنت.
- › تم اجتياز الاختبار:
start_urlيستجيب باستخدام 200 في حال عدم الاتصال بالإنترنت. - › تم بنجاح: تسجيل مشغّل خدمات يتحكم في الصفحة و
start_url. - 🎁 تم الاجتياز: استيفاء بيان تطبيق الويب متطلبات التثبيت.
- ○ تم اجتياز الاختبار: تم ضبطها للعمل في شاشة بداية مخصّصة.
- › تم الاجتياز: يتم ضبط لون شريط العناوين.
عند تثبيت تطبيق ويب تقدّمي، سيبدو سلوكه مثل جميع التطبيقات الأخرى المثبّتة. يتم تشغيله من المكان نفسه الذي تُطلق فيه التطبيقات الأخرى. ويتم تشغيله في أحد التطبيقات بدون شريط عناوين أو واجهة مستخدم متصفح أخرى. وكما هو الحال مع جميع التطبيقات المثبتة الأخرى، إنه تطبيق عالي المستوى في مبدِّل المهام.

في Chrome، يمكن تثبيت تطبيق ويب تقدّمي من خلال قائمة السياقات المكوّنة من ثلاث نقاط، أو يمكنك تقديم زر أو مكوّن واجهة مستخدم آخر للمستخدم يطلب منه تثبيت تطبيقك.
التدقيق باستخدام Lighthouse
لكي يتمكّن المستخدم من تثبيت تطبيق الويب التقدّمي، يجب أن يستوفي التطبيق معايير معيّنة. أسهل طريقة للتحقق هي استخدام أداة Lighthouse والتأكد من أنها تستوفي المعايير القابلة للتثبيت.

إذا كنت قد درست هذا الدرس التطبيقي حول الترميز، يجب أن يستوفي تطبيق الويب التقدّمي (PWA) هذه المعايير.
إضافة install.js إلى index.html
أولاً، لنضيف install.js إلى ملف index.html.
public/index.html
<!-- CODELAB: Add the install script here -->
<script src="/scripts/install.js"></script>
الاستماع إلى حدث beforeinstallprompt
في حال استيفاء معايير الإضافة إلى الشاشة الرئيسية، سيُطلق Chrome حدث beforeinstallprompt يمكنك استخدامه للإشارة إلى أنه يمكن تثبيت تطبيقك '؛ ثمّ يُطلب من المستخدم تثبيته. أضِف الرمز أدناه للاستماع إلى حدث beforeinstallprompt:
public/scripts/install.js
// CODELAB: Add event listener for beforeinstallprompt event
window.addEventListener('beforeinstallprompt', saveBeforeInstallPromptEvent);
زر حفظ الحدث وإظهار التثبيت
في دالة saveBeforeInstallPromptEvent، سنحفظ مرجعًا لحدث beforeinstallprompt حتى نتمكن من استدعاء prompt() في وقت لاحق وتحديث واجهة المستخدم لعرض زر التثبيت.
public/scripts/install.js
// CODELAB: Add code to save event & show the install button.
deferredInstallPrompt = evt;
installButton.removeAttribute('hidden');
عرض رسالة المطالبة وإخفاء الزر
عندما ينقر المستخدم على زر التثبيت، نحتاج إلى الاتصال بـ .prompt() في الحدث beforeinstallprompt المحفوظ. نحتاج أيضًا إلى إخفاء زر التثبيت، نظرًا لأنه يمكن استدعاء .prompt() مرة واحدة فقط في كل حدث محفوظ.
public/scripts/install.js
// CODELAB: Add code show install prompt & hide the install button.
deferredInstallPrompt.prompt();
// Hide the install button, it can't be called twice.
evt.srcElement.setAttribute('hidden', true);
سيؤدي الاتصال بالرقم .prompt() إلى ظهور مربّع حوار مشروط للمستخدم يطلب منه إضافة تطبيقك إلى الشاشة الرئيسية.
تسجيل النتائج
ويمكنك التحقّق لمعرفة كيفية استجابة المستخدم إلى مربّع حوار التثبيت من خلال الاستماع إلى الوعد الذي قدّمته خاصية userChoice للحدث beforeinstallprompt المحفوظ. ويعرض الوعد عنصرًا بعنصر outcome بعد عرض رسالة المطالبة والرد عليه.
public/scripts/install.js
// CODELAB: Log user response to prompt.
deferredInstallPrompt.userChoice
.then((choice) => {
if (choice.outcome === 'accepted') {
console.log('User accepted the A2HS prompt', choice);
} else {
console.log('User dismissed the A2HS prompt', choice);
}
deferredInstallPrompt = null;
});
تعليق واحد حول userChoice: المواصفات تحدّده باعتباره موقعًا، وليست وظيفة على النحو المتوقع.
تسجيل جميع أحداث التثبيت
بالإضافة إلى أي واجهة مستخدم تضيفها لتثبيت تطبيقك، يمكن للمستخدمين أيضًا تثبيت تطبيق الويب التقدّمي (PWA) الخاص بك من خلال طرق أخرى، على سبيل المثال قائمة Chrome على شكل ثلاث نقاط. لتتبُّع هذه الأحداث، يمكنك الاستماع إلى الحدث المثبّت عليه التطبيق.
public/scripts/install.js
// CODELAB: Add event listener for appinstalled event
window.addEventListener('appinstalled', logAppInstalled);
ثم سنحتاج إلى تحديث الدالة logAppInstalled. بالنسبة إلى هذا الدرس التطبيقي حول الترميز، سنستخدم console.log فقط، ولكن من المحتمل أن تحتاج إلى تسجيل هذا الحدث كحدث باستخدام برنامج تحليل البيانات في تطبيق الإنتاج.
public/scripts/install.js
// CODELAB: Add code to log the event
console.log('Weather App was installed.', evt);
تحديث مشغّل الخدمات
لا تنسَ تحديث CACHE_NAME في ملف service-worker.js لأنك أجريت تغييرات على الملفات المحفوظة في ذاكرة التخزين المؤقت. تفعيل مربّع الاختيار تجاوز الشبكة في اللوحة عاملو الخدمة بلوحة التطبيق في "أدوات مطوّري البرامج" قيد التطوير، ولكن لن يساعد في الواقع.
جرّب بنفسك
لنتعرّف على كيفية سير خطوات التثبيت. للحفاظ على أمانك، استخدم الزر محو بيانات الموقع الإلكتروني في لوحة التطبيق في "أدوات مطوري البرامج" لمحو كل شيء والتأكّد من أننا نبدأ من جديد. إذا سبق لك تثبيت التطبيق، تأكّد من إلغاء تثبيته، وإلا لن يظهر رمز التثبيت مرة أخرى.
التحقّق من ظهور زر التثبيت
أولاً، لنتحقق من ظهور رمز التثبيت بشكل صحيح. احرص على تجربة هذه الميزة على كل من الكمبيوتر المكتبي والجهاز الجوال.
- افتح عنوان URL في علامة تبويب جديدة في Chrome.
- افتح قائمة النقاط الثلاث في Chrome' (بجانب شريط العناوين).
▢ تحقَّق من الاطّلاع على &&سوق؛ تثبيت حالة الطقس..." في القائمة. - أعِد تحميل بيانات الطقس باستخدام زر إعادة التحميل في أعلى يسار الشاشة لضمان استيفاء إرشادات تفاعل المستخدم.
▢ يُرجى التحقّق من ظهور رمز التثبيت في عنوان التطبيق.
التحقُّق من عمل زر التثبيت
بعد ذلك، دعنا نتأكد من أن كل شيء يتم تثبيته بشكل صحيح ويتم تنشيط الأحداث بشكل صحيح. ويمكنك تنفيذ ذلك على أجهزة كمبيوتر سطح المكتب أو الأجهزة الجوّالة. إذا كنت تريد اختبار هذا على الجهاز الجوّال، احرص على استخدام "تصحيح الأخطاء عن بُعد" حتى تتمكن من رؤية ما تم تسجيله في وحدة التحكم.
- افتح Chrome، وفي علامة تبويب جديدة في المتصفّح، انتقِل إلى تطبيق PWA في تطبيق "الطقس".
- افتح مجموعة DevTools وبدِّل إلى لوحة وحدة التحكّم.
- انقر على زر التثبيت في أعلى يسار الشاشة.
▢ تحقّق من اختفاء زر التثبيت
▢ تحقّق من عرض مربع حوار التثبيت المشروط. - انقر على "إلغاء".
▢ إثبات الملكية &عرض:أغلق المستخدم رسالة A2HS" في مخرج وحدة التحكّم.
▢ يظهر الزر "تثبيت" مرة أخرى. - انقر على زر التثبيت مرة أخرى، ثم انقر على زر التثبيت في مربع الحوار المشروط.
▢ إثبات الملكية "؛وافق المستخدم على رسالة المطالبة A2HS" المعروضة في مخرجات وحدة التحكم.
▢ إثبات الملكية "؛تم تثبيت تطبيق الطقس"؛ في وحدة التحكم.
▢ تحقق من إضافة تطبيق الطقس إلى المكان الذي تظهر فيه عادةً. - شغِّل تطبيق الويب التقدّمي (PWA)
▢ تحقَّق من أن التطبيق يفتح كتطبيق مستقل، إما في نافذة تطبيق على جهاز كمبيوتر سطح المكتب أو في وضع ملء الشاشة على الأجهزة الجوّالة.
.
التحقُّق من عمل تثبيت نظام التشغيل iOS بشكل صحيح
لنتحقق أيضًا من السلوك على نظام التشغيل iOS. إذا كان لديك جهاز iOS، يمكنك استخدامه، أو إذا كان جهازك يعمل بنظام التشغيل Mac، جرِّب محاكي iOS المتاح مع Xcode.
- افتح متصفح Safari وفي علامة تبويب جديدة بالمتصفّح، انتقِل إلى تطبيق الويب التقدمي (PWA) في تطبيق "الطقس".
- انقر على الزر مشاركة
. - انتقِل لليسار وانقر على زر إضافة إلى الشاشة الرئيسية.
▢ تحقّق من صحة العنوان وعنوان URL والرمز. - انقر على إضافة.
▢ تحقّق من إضافة رمز التطبيق إلى الشاشة الرئيسية. - شغّل تطبيق الويب التقدّمي (PWA) من الشاشة الرئيسية.
▢ يُرجى التحقُّق من تشغيل التطبيق في وضع ملء الشاشة.
ملاحظة إضافية: رصد ما إذا كان تطبيقك قيد التشغيل من الشاشة الرئيسية
يتيح لك الاستعلام عن وسائط display-mode تطبيق الأنماط بناءً على كيفية إطلاق التطبيق أو تحديد كيفية إطلاقه باستخدام JavaScript.
@media all and (display-mode: standalone) {
body {
background-color: yellow;
}
}
ويمكنك أيضًا الاطّلاع على الاستعلام عن الوسائط display-mode في JavaScript لمعرفة ما إذا كنت تعمل بشكل مستقل.
مكافأة: إلغاء تثبيت تطبيق الويب التقدّمي (PWA)
تجدر الإشارة إلى أنّ beforeinstallevent لن يتم تنشيطه إذا كان التطبيق مثبتًا من قبل، لذا قد تحتاج أثناء التثبيت إلى إلغاء تثبيت التطبيق عدة مرات للتأكّد من عمل كل شيء على النحو المتوقّع.
Android
على نظام التشغيل Android، يتم إلغاء تثبيت تطبيقات الويب التقدّمية (PWA) بالطريقة نفسها التي يتم بها إلغاء تثبيت التطبيقات الأخرى المثبّتة.
- افتح درج التطبيقات.
- مرِّر للأسفل للعثور على رمز الطقس.
- اسحب رمز التطبيق إلى أعلى الشاشة.
- اختَر إلغاء التثبيت.
نظام التشغيل Chrome
على نظام التشغيل Chrome، يتم إلغاء تثبيت تطبيقات الويب التقدّمية (PWA) بسهولة من خلال مربّع البحث في مشغّل التطبيقات.
- افتح مشغِّل التطبيقات.
- اكتب "الطقس" في مربّع البحث، من المفترض أن يظهر تطبيق الويب التقدّمي (PWA) في النتائج.
- انقر بزر الماوس الأيمن على {0}تطبيق الويب التقدّمي (PWA) لتطبيق الطقس.
- انقر على إزالة من Chrome...
نظاما التشغيل macOS وWindows
على نظامي التشغيل Mac وWindows، قد يتم إلغاء تثبيت تطبيقات الويب التقدّمية (PWA) من خلال Chrome:
- في علامة تبويب متصفِّح جديدة، افتح chrome://apps.
- انقر بزر الماوس الأيمن على {0}تطبيق الويب التقدّمي (PWA) لتطبيق الطقس.
- انقر على إزالة من Chrome...
يمكنك أيضًا فتح تطبيق الويب التقدّمي (PWA) المُثبّت والنقر على قائمة السياقات المكوّنة من ثلاث نقاط في أعلى يسار الشاشة واختيار &إلغاء تثبيت;إلغاء تثبيت تطبيق الويب التقدّمي (PWA)....
تهانينا، لقد أنشأت بنجاح أول تطبيق ويب تقدّمي
لقد أضفت بيان تطبيق الويب لتفعيله وتمت إضافة مشغّل خدمات لضمان أن يكون تطبيق الويب التقدّمي (PWA) سريعًا وموثوقًا به دائمًا. لقد تعلّمت كيفية استخدام أدوات مطوري البرامج لتدقيق تطبيق معيّن وكيفية الاستفادة منه في تحسين تجربة المستخدم.
أصبحت تعرف الآن الخطوات الرئيسية المطلوبة لتحويل أي تطبيق ويب إلى تطبيق ويب تقدّمي.
الخطوات التالية
يمكنك الاطّلاع على بعض الدروس التطبيقية حول الترميز...