تحسين أداء الويب - إصدار Google I/O 2018

في معرض Google IO لعام 2018، قدّمنا ملخصًا عن الأدوات والمكتبات وأساليب التحسين التي تسهّل عملية تحسين أداء الويب. هنا نشرحهم باستخدام تطبيق The Oodles Trail، كما نتحدث عن تجاربنا في التحميل التنبؤي ومبادرة Guess.js الجديدة.

Addy Osmani
Addy Osmani
Ewa Gasperowicz

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

الحاجة إلى الأداء

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

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

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

هرم تسلسل هرمي لتجربة المستخدم
الشكل 1. ما مدى أهمية السرعة للمستخدمين؟ (Speed Matters, الجزء 3)

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

أداة Lighthouse: أساس سير عمل الأداء

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

وأطلقنا مؤخرًا مجموعة من عمليات تدقيق الأداء الجديدة المفيدة حقًا في سير عمل التطوير اليومي.

عمليات تدقيق Lighthouse الجديدة
الشكل 2: عمليات تدقيق Lighthouse الجديدة

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

أثناء إنشاء التطبيق، أردنا التأكد من أنّه كان يحقّق أفضل أداء ممكن. كانت نقطة البداية للتحسين هي تقرير Lighthouse.

تقرير Lighthouse عن تطبيق Oodles
الشكل 3. تقرير Lighthouse عن تطبيق Oodles

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

يُقدّر حجم الصفحة بحوالي 3.4 ميغابايت، لأنّنا بحاجة ماسة إلى تخفيف بعض الدهون.

أدى ذلك إلى إطلاق أول تحدي للأداء، وهو البحث عن الأشياء التي يمكننا إزالتها بسهولة دون التأثير على التجربة الكلية.

فرص تحسين الأداء

إزالة الموارد غير الضرورية

هناك بعض الأشياء الواضحة التي يمكن إزالتها بأمان: المسافة البيضاء والتعليقات.

المكاسب من التخلص من البيانات
الشكل 4. تصغير وضغط لغة JavaScript وCSS

تُبرز أداة Lighthouse هذه الفرصة في تدقيق CSS وJavaScript غير المصغر. كنّا نستخدم حزمة الويب في عملية التصميم، لذا استخدمنا ببساطة المكوّن الإضافي Uglify JS لإجراء عملية التخلص من البيانات.

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

هناك عملية تدقيق أخرى مفيدة في هذه المساحة هي تفعيل ضغط النص. لا يوجد سبب لإرسال ملفات غير مضغوطة، وتتيح معظم شبكات توصيل المحتوى (CDN) استخدام هذا المحتوى بدون أي تكلفة في الوقت الحالي.

كنّا نستخدم استضافة Firebase لاستضافة الرموز البرمجية الخاصة بنا، ويتيح Firebase استخدام gzipping تلقائيًا، لذلك بفضل استضافة الرموز البرمجية لدينا على شبكة توصيل محتوى (CDN) معقولة، حصلنا على ذلك مجانًا.

يُعد gzip طريقة شائعة جدًا للضغط، ولكن هناك آليات أخرى مثل Zopfli وButli تحقق رواجًا كبيرًا أيضًا. تتمتع Brotli بدعم في معظم المتصفحات، ويمكنك استخدام برنامج ثنائي لضغط مواد العرض مسبقًا قبل إرسالها إلى الخادم.

استخدام سياسات ذاكرة التخزين المؤقت الفعالة

كانت خطوتنا التالية هي التأكّد من عدم إرسال الموارد مرّتين إذا كانت غير ضرورية.

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

من الناحية المثالية، يجب أن تهدف إلى تخزين أكبر عدد ممكن من الموارد بشكل آمن لأطول فترة زمنية ممكنة، وتوفير رموز مميزة للتحقق من الصحة بفعالية للموارد التي تم تحديثها.

إزالة الرموز غير المستخدَمة

حتى الآن أزلنا الأجزاء الواضحة من التنزيل غير الضروري، ولكن ماذا عن الأجزاء الأقل وضوحًا؟ على سبيل المثال، الرموز غير المستخدَمة.

تغطية الرمز في "أدوات مطوري البرامج"
الشكل 5. التحقّق من تغطية الرمز

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

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

يمكنك التحقّق من إحصاءات تغطية الرموز البرمجية في "أدوات مطوري البرامج"، سواء من حيث وقت التشغيل أو وقت تحميل التطبيق. يمكنك رؤية الشريطَين الأحمرَين الكبيرَين في لقطة الشاشة السفلية، إذ إنّ أكثر من %95 من صفحات CSS لم يتم استخدامها بالإضافة إلى مجموعة كبيرة من JavaScript.

رصدت أداة Lighthouse أيضًا هذه المشكلة في تدقيق قواعد CSS غير المستخدَمة. فقد أظهرت توفيرًا محتملاً لأكثر من 400 كيلوبايت. لذا عدنا إلى تعليماتنا البرمجية وأزلنا جزء كل من JavaScript وCSS من تلك المكتبة.

إذا تم إسقاط محوّل MVC، ستنخفض الأنماط إلى 10 كيلوبايت
الشكل 6. فإذا أغفلنا محول MVC، ستنخفض أنماطنا إلى 10 كيلوبايت!

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

ولا شكّ في أنّ ذلك أدى إلى ارتفاع نتيجة أدائنا، كما أدّى أيضًا إلى تحسُّن أداء وقت التفاعل.

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

لم يتم استخدام رموزنا البرمجية في 95%، ولا تزال هذه النسبة هي 5% في مكان ما. على ما يبدو أن أحد مكوناتنا كان لا يزال يستخدم الأنماط من تلك المكتبة - الأسهم الصغيرة في شريط تمرير رسومات الشعار المبتكرة. نظرًا لأنها كانت صغيرة جدًا، على الرغم من ذلك، يمكننا فقط الانتقال ودمج هذه الأنماط يدويًا في الأزرار.

تعطّلت الأزرار بسبب عدم توفّر مكتبة.
الشكل 7. كان أحد المكوّنات لا يزال يستخدم المكتبة التي تمت إزالتها.

لذلك إذا قمت بإزالة التعليمات البرمجية، فتأكد من وجود سير عمل اختبار مناسب لمساعدتك في الحماية من أي انحدارات مرئية محتملة.

تجنُّب الأحمال الضخمة للشبكة

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

رصدت أداة Lighthouse مشكلة في بعض حمولات البيانات في الشبكة باستخدام عملية تدقيق حمولة الشبكة غير المشروعة.

اكتشاف حمولات ضخمة للشبكة
الشكل 8. رصد الأحمال الضخمة للشبكة

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

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

كما يقول المثل: أسرع طلب هو الذي لم يتم تقديمه.

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

في هذه الحالة، كنا نتعامل مع الكثير من حِزم JavaScript، لذا كنا محظوظين لأنّ منتدى JavaScript لديه مجموعة غنية من أدوات تدقيق حزمة JavaScript.

تدقيق حزمة JavaScript
الشكل 9. تدقيق حزمة JavaScript

لقد بدأنا باستخدام أداة تحليل حزمة Webpack، التي أخبرتنا أننا كنا ندرج تبعية تسمى unicode والتي كانت تمثل 1.6 ميغابايت من JavaScript تم تحليلها، وبالتالي كثيرًا جدًا.

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

بعد ذلك، عمِلنا على استخدام أداة أخرى، وهي BundlePhobia. تتيح لك هذه الأداة إدخال اسم أي حزمة من حزم NPM والاطّلاع على الحجم المقدَّر لحزمة NPM. وجدنا بديلاً رائعًا لوحدة البَزَّاق التي كنا نستخدمها والتي كان وزنها 2.2 كيلوبايت فقط، لذا قمنا بتبديله.

كان لذلك تأثير كبير في أدائنا. بين هذا التغيير واكتشاف فرص أخرى لخفض حجم حزمة JavaScript، وفرنا 2.1 ميغابايت من الرموز البرمجية.

لقد شهدنا تحسينات بنسبة 65% بشكل عام، بعد أن قمت بضغط حجم هذه الحزم وتصغيرها. ووجدنا أن هذا الأمر يستحق حقًا القيام به كعملية.

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

تقليل وقت تشغيل JavaScript من خلال تقسيم الرمز

على الرغم من أن أحمال الشبكة الكبيرة يمكن أن يكون لها تأثير كبير على تطبيقنا، هناك شيء آخر يمكن أن يكون له تأثير كبير حقًا، وهو JavaScript.

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

وهذه هي الطريقة التي يعالج بها المتصفح JavaScript.

معالجة JavaScript
الشكل 10. معالجة JavaScript

علينا أولاً تنزيل هذا النص البرمجي، لدينا محرك JavaScript يحتاج بعد ذلك إلى تحليل الرمز البرمجي وتجميعه وتنفيذه.

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

ولمساعدتك في اكتشاف هذه المشاكل في تطبيقك، قدّمنا تدقيقًا جديدًا لوقت تشغيل JavaScript في Lighthouse.

وقت تشغيل JavaScript
الشكل 11. تدقيق في وقت تشغيل JavaScript

وفي حالة تطبيق Oodle، أخبرَنا أنّ لدينا 1.8 ثانية من الوقت نقضيه في تشغيل JavaScript. وما كان يحدث هو أننا كنا نستورد بشكل ثابت في جميع مساراتنا ومكوناتنا إلى حزمة JavaScript واحدة متجانسة.

ويتمثّل أحد الأساليب للتغلب على ذلك في تقسيم الرموز البرمجية.

تقسيم التعليمة البرمجية مثل البيتزا

تقسيم الرمز هو فكرة بدلاً من منح المستخدمين قيمة JavaScript كاملة، ماذا لو أعطيتهم شريحة واحدة فقط في كل مرة حسب الحاجة؟

ويمكن تطبيق تقسيم الرمز على مستوى المسار أو مستوى المكوِّن. وهي تعمل بشكلٍ رائع مع React وReact Loadable وVue.js وAngular وPolymer وPreact ومكتبات أخرى متعددة.

لقد دمجنا عملية تقسيم الرموز إلى تطبيقنا، وتحوّلنا من عمليات الاستيراد الثابتة إلى عمليات الاستيراد الديناميكية، ما أتاح لنا إمكانية التحميل الكسول للرموز بشكل غير متزامن حسب الحاجة.

تقسيم الرمز باستخدام عمليات الاستيراد الديناميكية
الشكل 13. تقسيم الرمز باستخدام عمليات الاستيراد الديناميكية

وكان ذلك بسبب تقليص حجم الحِزم، بالإضافة إلى تقليل وقت تشغيل JavaScript. وانخفضت مدته إلى 0.78 ثانية، ما جعل التطبيق أسرع بنسبة 56%.

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

يمكنك الاستفادة من مفاهيم مثل تقسيم الرموز البرمجية، واستكشاف أفكار مثل اهتزاز الشجرة، ومراجعة مستودع webpack-libs-Optimizations للاطّلاع على بعض الأفكار حول كيفية تقليل حجم المكتبة في حال استخدام حزمة الويب.

تحسين الصور

نكتة عن أداء تحميل الصورة

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

لقد نسينا تحسين صورنا ولم نكن نحدد حجمها بشكل صحيح، وكان بإمكاننا أيضًا تحقيق بعض الربح من استخدام تنسيقات صور أخرى.

عمليات تدقيق الصور
الشكل 14. عمليات تدقيق الصور باستخدام أداة Lighthouse

بدأنا في تحسين الصور.

لإجراء جولة تحسين لمرة واحدة، يمكنك استخدام أدوات مرئية مثل ImageOptim أو XNConvert.

تعتمد الطريقة الآلية بشكل أكبر على إضافة خطوة لتحسين الصور إلى عملية التصميم باستخدام مكتبات مثل imagemin.

بهذه الطريقة، تتأكّد من تحسين الصور التي تتم إضافتها في المستقبل تلقائيًا. تقدّم لك بعض شبكات توصيل المحتوى (CDN)، على سبيل المثال Akamai أو حلول تابعة لجهات خارجية، مثل Cloudinary أو Fastly أو Uploadcare حلولاً شاملة لتحسين الصور، ما يتيح لك استضافة صورك بسهولة على تلك الخدمات.

إذا كنت لا تريد إجراء ذلك بسبب التكلفة أو المشاكل المتعلقة بوقت الاستجابة، تقدّم مشاريع مثل Thumbor أو Imageflow بدائل تتم استضافتها ذاتيًا.

قبل التحسين وبعده
الشكل 15. قبل التحسين وبعده

تم وضع علامة على خلفية PNG في حزمة الويب على أنها كبيرة الحجم، وهذا أمر صحيح. وبعد تغيير حجمها بشكل صحيح إلى إطار العرض وتشغيله من خلال ImageOptim، انخفضنا إلى 100 كيلوبايت، وهو أمر مقبول.

وسمح لنا تكرار ذلك لصور متعددة على موقعنا بخفض الوزن الإجمالي للصفحة بشكل كبير.

استخدام التنسيق المناسب لمحتوى الصور المتحركة

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

في تطبيق Oodle، كنا نستخدم ملف GIF كتسلسل مقدمة على الصفحة الرئيسية. وفقًا لـ Lighthouse، يمكننا توفير أكثر من 7 ميغابايت من خلال التبديل إلى تنسيق فيديو أكثر كفاءة. وكان ترجيح المقطع يبلغ حوالي 7.3 ميغابايت، وهو ما يجعله كبيرًا جدًا بالنسبة إلى أي موقع إلكتروني معقول، لذا حوّلناه إلى عنصر فيديو يتضمّن ملفَّي مصدر، وهما mp4 وWebM لتوفير إمكانية استخدام أوسع للمتصفح.

استبدال ملفات GIF المتحركة بالفيديو
الشكل 16. استبدال ملفات GIF المتحركة بفيديو

استخدمنا أداة FFmpeg لتحويل ملف GIF للصور المتحركة إلى ملف mp4. يوفر لك تنسيق WebM مبالغ أكبر في التوفير، حيث يمكن لواجهة برمجة التطبيقات Imageoptim API إجراء هذا التحويل نيابةً عنك.

ffmpeg -i animation.gif -b:v 0 -crf 40 -vf scale=600:-1 video.mp4

وقد تمكّنا من توفير ما يزيد عن 80% من وزننا الإجمالي بفضل هذه الإحالة الناجحة. وقد جعلنا ذلك نحو 1 ميغابايت.

ومع ذلك، يُعد 1 ميغابايت موردًا كبيرًا لدفع السلك لأسفل، خاصةً بالنسبة إلى المستخدم الذي يستخدم معدل نقل بيانات محدود. لحسن الحظ، يمكننا استخدام Activate Type API لندرك أنّ معدل نقل البيانات بطيء، ومنحهم صورة JPEG أصغر بكثير بدلاً من ذلك.

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

if (navigator.connection.effectiveType) { ... }

يؤدي هذا الإجراء إلى إزالة الموقع الإلكتروني قليلاً من التجربة، ولكن على الأقل يكون الموقع قابلاً للاستخدام على اتصال بطيء.

تحميل الصور خارج الشاشة باستخدام طريقة "التحميل الكسول"

غالبًا ما تُحمّل العروض الدوارة أو أشرطة التمرير أو الصفحات الطويلة جدًا الصور، على الرغم من أن المستخدم لا يمكنها رؤيتها على الصفحة على الفور.

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

لا يمكن بعد استخدام طريقة "التحميل الكسول" في المتصفّح، لذلك علينا استخدام JavaScript لإضافة هذه الإمكانية. استخدمنا مكتبة Lazysizes لإضافة طريقة التحميل الكسول إلى أغاني Oodle المقتبسة.

<!-- Import library -->
import lazysizes from 'lazysizes'  <!-- or -->
<script src="lazysizes.min.js"></script>

<!-- Use it -->

<img data-src="image.jpg" class="lazyload"/>
<img class="lazyload"
    data-sizes="auto"
    data-src="image2.jpg"
    data-srcset="image1.jpg 300w,
    image2.jpg 600w,
    image3.jpg 900w"/>

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

بعد هذا التغيير، يتم جلب الصور عند الطلب. لمزيد من التفاصيل عن هذا الموضوع، اطّلِع على images.guide، وهو مرجع شامل وسهل الاستخدام.

مساعدة المتصفِّح في تقديم الموارد المهمة مبكرًا

ليس لكل بايت يتم شحنه عبر السلك إلى المتصفح نفس الدرجة من الأهمية، ويعرف المتصفح ذلك. وتحتوي الكثير من المتصفحات على إشارات إرشادية لتحديد ما الذي يجب جلبه أولاً. لذلك، قد يجلبون أحيانًا ملفات CSS قبل الصور أو النصوص البرمجية.

والأمر الذي قد يكون مفيدًا، بصفتنا مؤلفي الصفحة، هو إعلام المتصفح بما هو مهم بالنسبة إلينا حقًا. ولحسن الحظ، أضاف مورّدو المتصفحات على مدار العامين الماضيين عددًا من الميزات لمساعدتنا في ذلك، مثل تلميحات حول الموارد مثل link rel=preconnect أو preload أو prefetch.

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

لنرَ كيف توجّهنا أداة Lighthouse إلى استخدام بعض هذه الميزات بشكل فعّال.

إنّ أول ما تخبرنا به أداة Lighthouse هو تجنُّب رحلات ذهاب وعودة متعددة مكلفة إلى أي مكان.

تجنَّب رحلات ذهاب وعودة متعددة ومكلفة إلى أي مصدر.
الشكل 17. تجنُّب رحلات ذهاب وعودة متعددة ومكلّفة إلى أي مصدر

في حالة تطبيق Oodle، نحن في الواقع نستخدم Google Fonts بشكل كبير. وعندما تضع ورقة أنماط من Google Font في صفحتك، سيتم ربط ما يصل إلى نطاقين فرعيين. وما تخبرنا به Lighthouse هو أنه إذا تمكنا من تحمُّل هذا الاتصال، فيمكننا توفير ما يصل إلى 300 مللي ثانية في وقت الاتصال الأولي.

وبالاستفادة من رابط rel Connect بشكل مسبق، يمكننا إخفاء وقت استجابة الاتصال هذا بفعالية.

قد يكون لذلك تأثير كبير خاصةً في برامج مثل Google Fonts حيث تتم استضافة CSS لواجهة الخط على googleapis.com وتتم استضافة موارد الخطوط على Gstatic. لذلك طبقنا هذا التحسين وقللنا بضع مئات من المللي ثانية.

إنّ الاقتراح التالي الذي تقترحه أداة Lighthouse هو أننا نحمّل الطلبات الرئيسية مسبقًا.

التحميل المُسبَق للطلبات الرئيسية
الشكل 18. التحميل المُسبَق للطلبات الرئيسية

إنّ <link rel=preload> فعّالة للغاية، إذ تُعلِم المتصفح بأنّ هناك موردًا مطلوبًا كجزء من عملية التنقّل الحالية، وتحاول جعل المتصفِّح يجلبه في أقرب وقت ممكن.

تخبرنا أداة Lighthouse الآن بأنّنا يجب أن نحمّل موارد خطوط الويب الرئيسية وذلك مسبقًا، لأنّنا سنحمّل الخطين على الويب.

يشبه التحميل المُسبق في خط ويب ما يلي: تحديد rel=preload، وإرسال as إلى نوع الخط، ثم تحديد نوع الخط الذي تحاول التحميل به، مثل woff2.

ويكون التأثير الذي قد يحدثه ذلك في صفحتك واضحًا جدًا.

تأثير التحميل المُسبق للموارد
الشكل 19. تأثير التحميل المُسبق للموارد

وفي العادة، بدون استخدام التحميل المسبق لرابط rel، وإذا كانت خطوط الويب ضرورية لصفحتك، يجب أن يجلب المتصفّح أولاً تنسيق HTML، وأن يحلّل CSS، ثمّ ينتقل أخيرًا إلى خط الويب ويجلب خطوط الويب الخاصة بك.

باستخدام التحميل المسبق لرابط rel، فبمجرد تحليل المتصفح لـ HTML، يمكن أن يبدأ بالفعل في جلب خطوط الويب هذه في وقت مبكر جدًا. في حالة تطبيقنا، كان هذا قادرًا على توفير ثانية من الوقت الذي نستغرقه لعرض النص باستخدام خطوط الويب الخاصة بنا.

إذا كنت ستجرب التحميل المسبق للخطوط باستخدام Google Fonts، فهناك مشكلة واحدة،

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

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

سواء كنت تستخدم خطوط الويب كجزء من مواردك المهمة، أو تستخدم JavaScript، حاول مساعدة المتصفح في تقديم مواردك المهمة في أقرب وقت ممكن.

ميزة تجريبية: تلميحات ذات الأولوية

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

ضبط الأولوية للمحتوى المرئي في البداية
الشكل 20. تلميحات حسب الأولوية

هذه ميزة جديدة تتيح لك أن توضِّح للمتصفح مدى أهمية الموارد. فهي تعرض سمة جديدة - الأهمية - ذات قيم منخفضة أو عالية أو تلقائية.

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

في حالة تطبيق Oodle، أدى هذا في الواقع إلى مكان عملي واحد يمكننا تحسينه.

ضبط الأولوية للمحتوى المرئي في البداية
الشكل 21. تحديد أولوية المحتوى المرئي في البداية

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

نأمل أن نطرح هذه الميزة في إصدار Canary في غضون أسابيع قليلة، لذا ترقَّب ذلك.

اتّباع استراتيجية لتحميل الخطوط على الويب

يعتبر أسلوب الخط أمرًا أساسيًا للتصميم الجيد، وإذا كنت تستخدم خطوط الويب، فأنت لا تريد بشكل مثالي حظر عرض النص، وبالتأكيد لا تريد إظهار نص غير مرئي.

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

تجنُّب النص غير المرئي أثناء تحميل خطوط الويب
الشكل 22. تجنُّب النص غير المرئي أثناء تحميل خطوط الويب

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

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

    @font-face {
      font-family: 'Montserrat';
      font-style: normal;
      font-display: swap;
      font-weight: 400;
      src: local('Montserrat Regular'), local('Montserrat-Regular'),
          /* Chrome 26+, Opera 23+, Firefox 39+ */
          url('montserrat-v12-latin-regular.woff2') format('woff2'),
            /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
          url('montserrat-v12-latin-regular.woff') format('woff');
    }

يساعدك عرض الخطوط في تحديد كيفية عرض خطوط الويب أو كيفية عرضها احتياطيًا بناءً على المدة التي يستغرقها التبديل.

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

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

نتيجة عرض الخط
الشكل 23. نتيجة عرض الخط

بشكل عام، إذا كنت تستخدم خطوط الويب، كنسبة كبيرة من مواقع الويب، اعتمد استراتيجية جيدة لتحميل الخطوط على الويب.

هناك الكثير من ميزات النظام الأساسي للويب التي يمكنك استخدامها لتحسين تجربة التحميل للخطوط، ولكن يمكنك أيضًا الاطّلاع على Web Font Recipes من Zach Leatherman، لأنها رائعة حقًا.

تقليل النصوص البرمجية التي تحظر العرض

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

ضمن شريط المخطط الزمني لأداة Lighthouse، يمكنك أن ترى أنّه خلال هذه الثواني القليلة الأولى عندما يتم تحميل جميع الموارد، لن يتمكن المستخدم من رؤية أي محتوى.

تقليل فرصة حظر عرض أوراق الأنماط
الشكل 24. تقليل فرصة حظر عرض أوراق الأنماط

يمنع تنزيل أوراق الأنماط الخارجية ومعالجتها عملية العرض من إحراز أي تقدم.

يمكننا محاولة تحسين مسار العرض الحرج من خلال تقديم بعض الأنماط في وقت أبكر من السابق.

إذا استخرجنا الأنماط المسؤولة عن هذا العرض الأولي وتم تضمينها في HTML الخاص بنا، سيكون بإمكان المتصفح عرضها على الفور بدون انتظار وصول أوراق الأنماط الخارجية.

في هذه الحالة، استخدمنا وحدة من NPM تسمى الحرجة لتضمين المحتوى المهم في index.html أثناء خطوة الإنشاء.

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

وإذا لم تكن حريصًا أو إذا كانت بنية موقعك الإلكتروني معقدة للغاية، قد يكون من الصعب حقًا تقديم هذا النوع من الأنماط إذا لم تكن تخطط لبنية هيكل التطبيق من البداية.

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

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

النتيجة

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

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

الأداء التوقّعي - تجارب المستخدمين المستندة إلى البيانات

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

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

لدينا حاليًا بيانات تتيح لنا الاستفادة بشكل أفضل من عمليات التحسين التي نُجريها. باستخدام Google Analytics Reporting API، يمكننا إلقاء نظرة على الصفحة التالية في أعلى الصفحة والخروج من النسب المئوية لأي عنوان URL على موقعنا الإلكتروني، وبالتالي التوصّل إلى استنتاجات حول الموارد التي يجب أن تكون الأولوية لها.

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

التجميع المستند إلى البيانات لتطبيقات الويب
الشكل 25. التجميع المستند إلى البيانات لتطبيقات الويب

لتسهيل هذه التجارب، يسرّنا الإعلان عن مبادرة جديدة أطلقنا عليها اسم Guess.js.

Guess.js
الشكل 26. Guess.js

Guess.js هو مشروع يركز على تجارب المستخدمين المستندة إلى البيانات على الويب. ونأمل أن تكون هذه المعلومات ملهمة لاستكشاف استخدام البيانات لتحسين أداء الويب وتجاوز ذلك. إنها كلها مفتوحة المصدر ومتاحة على GitHub اليوم. تم إنشاء هذا بالتعاون مع منتدى البرامج المفتوحة المصدر بواسطة مينكو غيشيف، وكيل ماثيوز من غاتسبي، وكاتي هيمبينيوس، وعدد من الآخرين.

تحقق من Guess.js، وأخبرنا برأيك.

ملخّص

تُعدّ النتائج والمقاييس مفيدة في تحسين سرعة الويب، ولكنها مجرد وسيلة، وليست الأهداف في حد ذاتها.

لقد عانينا جميعًا من بطء في تحميل الصفحات أثناء التنقل، ولكن لدينا الآن فرصة لمنح المستخدمين تجارب أكثر إمتاعًا يتم تحميلها بسرعة كبيرة.

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

نتوجّه بالشكر الخاص إلى كل من "وارد بيترز" و"مينكو غيشيف" و"كايل ماثيوز" و"كاتي هيمبينيوس" و"دوم فارولينو" و"يواف وايس" و"سوزي لو" و"يوسوكي أوتسونوميا" و"توم أنكرز" و"منارة" و"رسومات الشعار المبتكرة من Google".