طريقة أفضل لتحديث تطبيقات الويب

Dan Murphy
Dan Murphy
Dibyajyoti Pal
Dibyajyoti Pal

تاريخ النشر: 21 يناير 2026

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

الطريقة السابقة (قبل الإصدار 114 من Chrome)

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

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

باستخدام هذا الأسلوب، كان على المطوّرين التعامل مع تعقيدات عند تنفيذ تغييرات حساسة للأمان، مثل تعديل اسم التطبيق أو رمزه، وهو ما يُعرف غالبًا باسم تغييرات هوية التطبيق. وبما أنّ تطبيقات الويب لا تتضمّن جهة مركزية مثل Google Play لمراجعة التحديثات، يجب عرض هذه التعديلات بوضوح للمستخدمين لتأكيدها. ومع ذلك، ظلّ تحديد الوقت الأنسب لإرسال إشعار إلى المستخدمين بشأن هذه التغييرات يمثّل تحديًا.

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

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

تنبيه يعرض التغيير في الرمز ورسالة تحذير للمستخدم تتضمّن أزرارًا للموافقة على التغيير أو إلغاء تثبيت التطبيق
الكمبيوتر المكتبي (الإصدار 91 من Chrome والإصدارات الأحدث غير المتوفرة بعد)
تنبيه على الجهاز الجوّال يعرض التغيير في الرمز ورسالة تحذّر المستخدم مع أزرار للموافقة على التغيير أو إلغاء تثبيت التطبيق
Android (الإصدار الحالي)

القيود والأهداف المتعلّقة بالتغييرات على تحديثات تطبيقات الويب

استرشدنا بالأهداف التالية عند تطوير عملية التحديث الجديدة:

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

ما هي التغييرات التي أجريناها في الإصدار 144 من Chrome؟

أصبحت التعديلات على الاسم والرمز اختيارية

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

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

القائمة التي تعرض الخيار "مراجعة تحديث التطبيق"

يؤدي النقر على مراجعة تحديث التطبيق إلى عرض مربّع الحوار المعدَّل. يتغيّر العنوان استنادًا إلى العناصر التي يتم تعديلها.

مربع الحوار على الكمبيوتر المكتبي الذي يطلب من المستخدم مراجعة التعديلات التي تم إجراؤها على الرمز والاسم

لا يتم تنزيل الرموز إذا لم يتضمّن حقل الرموز أي تغييرات

تُعد الرموز الآن بدون تغيير إذا ظل حقل icons في البيان كما هو في آخر إصدار تم تطبيقه. بموجب هذه المنطق الجديد، يتجنّب Chrome تنزيل الرموز للمقارنة المرئية، ويتعامل مع عناوين URL الخاصة بالرموز على أنّها Cache-Control:immutable. لتفعيل عملية تعديل الرمز، على المطوّرين الآن تعديل إما البيانات الوصفية أو عنوان URL الخاص بالرمز.

إزالة الحدّ الأقصى لعدد التعديلات

بما أنّ Chrome لم يعُد ينزّل الرموز في كل مرة يصادف فيها بيانًا لتطبيق مثبَّت، تم إلغاء القيد السابق الذي كان يقتصر على إجراء عمليات التحقّق من التحديث مرة واحدة في اليوم. يمكن للمطوّرين الآن الاعتماد على التحديث الذي يتم على الفور لجميع الأعضاء غير الحساسين للأمان.

التعامل مع الاختلافات البسيطة في الرموز على جميع الأنظمة الأساسية

لتحسين تجربة المستخدم، يطبّق Chrome الآن تلقائيًا تحديثات الرموز التي تظهر فرقًا أقل من% 10 في مقارنة البكسل بالبكسل. يضمن ذلك عدم ظهور مربّع حوار تحديث مربك للمستخدم بسبب الاختلافات الطفيفة، مثل تلك الناتجة عن إعادة الترميز في شبكة توصيل المحتوى (CDN).

يتم تقييد هذا الإذن مرة واحدة في اليوم لمنع إساءة الاستخدام المحتملة. إذا حدثت تغييرات أخرى خلال تلك الفترة، سيتم التعامل مع الرمز على أنّه تعديل عادي وسيُطلب من المستخدم تأكيد التغيير.

مثال على تعديل الرمز والاسم

{
  "name": "Example App",
  "short_name": "App",
  "id": "https://www.example-app.com/",
  "start_url": "https://www.example-app.com/index.html",
  "scope": "https://www.example-app.com/",
  "icons": [
    {
      "src": "https://www.example-app.com/img/app.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "any"
    }
  ],

  ... other attributes omitted ...
}

يضمن تغيير عنوان URL الخاص بالرمز أن يرى المستخدم مربع حوار تحديث لتغيير الرمز.

{
  "name": "Example App",
  "short_name": "App",
  "id": "https://www.example-app.com/",
  "start_url": "https://www.example-app.com/index.html",
  "scope": "https://www.example-app.com/",
  "icons": [
    {
      "src": "https://www.example-app.com/img/app-NEW-URL.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "any"
    }
  ],

  ... other attributes omitted ...
}