الميزات الجديدة في توجيه Angular NgOptimizedImage

قلعة أليكس
قلعة أليكس

قبل أكثر من عام بقليل، أطلق فريق Chrome Aurora توجيه Angular NgOptimizedImage. يركّز هذا التوجيه بشكل أساسي على تحسين الأداء، وفقًا لمقاييس مؤشرات أداء الويب الأساسية. وهي تجمع تحسينات الصور الشائعة وأفضل الممارسات في واجهة برمجة تطبيقات موجّهة للمستخدمين وليست أكثر تعقيدًا من عنصر <img> العادي.

في عام 2023، أدخلنا ميزات جديدة على التوجيه. توضح هذه المشاركة أهم هذه الميزات الجديدة، مع التركيز على سبب اختيارنا تحديد أولويات كل ميزة، وكيف يمكن أن تساعد في تحسين أداء تطبيقات Angular.

الميزات الجديدة

ومع مرور الوقت، تحسّنت ميزة NgOptimizedImage بدرجة كبيرة، بما في ذلك الميزات الجديدة التالية.

وضع التعبئة

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

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

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

يستخدم وضع التعبئة NgOptimizedImage كبديل أفضل أداء لخاصية css background-image. وضع صورة داخل <div> أو عنصر آخر كان من الممكن أن يكون له نمط background-image، ثم تفعيل وضع التعبئة، كما هو موضّح في مثال الرمز السابق. يمكنك استخدام سمتَي object-fit وobject-position في CSS في <div> للتحكّم في كيفية وضع الصورة في الخلفية.

// Height and width are required
<img ngSrc="example.com" height="300" width="400">

// Unless you use fill mode!
<div style="width: 100vw; height: 50em; position: relative">
  <img ngSrc="example.com" fill>
</div>

إنشاء Srcset

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

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

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

لقد أدرجنا واجهة برمجة تطبيقات مبسّطة لإعداد السمة sizes، حيث يتم استخدام هذه الواجهة لضمان حصول كل صورة على النوع الصحيح من السمة srcset. في حال عدم تضمين السمة sizes، هذا يعني أنّه من المفترض أن تكون الصورة ذات حجم ثابت، ومن المفترض أن تتوفّر لها سمة srcset تعتمد على الكثافة، على النحو التالي:

<img src="www.example.com/image.png" srcset="www.example.com/image.png?w=400 1x, www.example.com/image.png?w=800 2x" >

ويضمن هذا النوع من srcset عرض الصور بحجم يأخذ في الاعتبار كثافة وحدات البكسل لجهاز المستخدم.

من ناحية أخرى، في حال تضمين السمة sizes، سينشئ NgOptimizedImage مجموعة srcset متجاوبة تتضمّن نقاط توقف للعديد من أحجام الأجهزة والصور الشائعة، وذلك باستخدام القائمة التلقائية لنقاط الإيقاف التالية:

[16, 32, 48, 64, 96, 128, 256, 384, 640, 750, 828, 1080, 1200, 1920, 2048, 3840]

إنشاء الاتصال المُسبَق

لتحسين سرعة LCP، من المهم تقليل الوقت الذي يقضيه المستخدمون في تنزيل صورة LCP. في القسم السابق، اطّلعتم على كيفية مساعدة srcset من خلال نقل ملفات الصور الأصغر حجمًا، إلا أنّ بدء عملية النقل في أقرب وقت ممكن من أهم التحسينات. ويمكنك إجراء ذلك باستخدام علامات link rel="preconnect" لبدء الربط بنطاق الصورة بشكل سريع.

منذ البداية، حذّر فريق NgOptimizedImage في حال تعذّر الاتصال المسبق بنطاق صورة LCP، ولكن التحذير ليس الحل المثالي، بل ننصحك بحل المشكلة فقط. وهذا بالضبط ما تفعله شركة NgOptimizedImage الآن مع إنشاء الاتصال المسبق الآلي.

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

دعم محسَّن لعمليات التحميل المخصّصة

تعتبر بنية برنامج التحميل من العناصر الرئيسية في NgOptimizedImage، وهي بنية تتيح للتوجيه إنشاء عناوين URL تلقائيًا تم تصميمها خصيصًا لشبكة عرض المحتوى (CDN) لصورة التطبيق. يتمّ تضمين مجموعة من التحميلات المدمجة لشبكات توصيل المحتوى (CDN) المستخدَمة على نطاق واسع. ونتيح أيضًا استخدام برامج التحميل المخصصة التي تتيح لك دمج NgOptimizedImage مع أي حل تقريبًا لاستضافة الصور.

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

يوضّح المثال التالي كيف يمكن لبرنامج تحميل مخصّص بسيط استخدام واجهة برمجة التطبيقات loaderParams للاختيار من بين نطاقَين بديلَين للصور:

const myCustomLoader = (config: ImageLoaderConfig) => {
  if (config.loaderParams?.alternateDomain) {
    return `https://alternate.domain.com/images/${config.src}`
  }
  return `https://primary.domain.com/images/${config.src}`;
};

يتوفر مثال على برنامج تحميل مخصص أكثر تعقيدًا في وثائق Angular.

إرشادات موسّعة حول أداء الصور

حتى الآن، كان كل تنبيه بخصوص أداء الصور الذي أضفناه إلى Angular جزءًا من توجيه NgOptimizedImage. وإذا كنت لا تستخدِم التوجيه في التطبيق، لن تحصل على أي إرشادات بشأن مشاكل أداء الصور.

في Angular 17، نعمل على توسيع نطاق إرشادات أداء الصور لتشمل جميع تطبيقات Angular. والآن، في حال رصدنا أنماطًا للصور نُدرك أنها أخطاء تؤثر سلبًا في الأداء، مثل التحميل الكسول لصورة LCP أو تنزيل ملف كبير جدًا بالنسبة إلى الصفحة، سنُعلمك بذلك حتى في حال عدم استخدامك NgOptimizedImage.

يُعد أداء الصور مهمًا لجميع التطبيقات، ويسعدنا مواصلة وضع قيود حماية للمساعدة في منع الأخطاء الشائعة في تطبيقات Angular.

التطلّع إلى المستقبل

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

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