في مؤتمر Google IO لعام 2018، قدّمنا مجموعة من الأدوات والمكتبات وأساليب التحسين التي تسهّل تحسين أداء الويب. في هذا الفيديو، نشرح هذه المفاهيم باستخدام تطبيق The Oodles Theater، ونتحدّث أيضًا عن تجاربنا مع التحميل التوقّعي ومبادرة Guess.js الجديدة.
لقد انشغلنا كثيرًا خلال العام الماضي بمحاولة معرفة كيفية جعل الويب أسرع وأكثر فعالية. وقد أدّى ذلك إلى توفير أدوات وأساليب ومكتبات جديدة نريد مشاركتها معك في هذه المقالة. في الجزء الأول، سنعرض لك بعض تقنيات التحسين التي استخدمناها عمليًا أثناء تطوير تطبيق The Oodles Theater. وفي الجزء الثاني، سنتحدث عن تجاربنا مع التحميل التوقعي ومبادرة Guess.js الجديدة.
الحاجة إلى الأداء
تزداد كثافة الإنترنت عامًا بعد عام. إذا ألقينا نظرة على حالة الويب، نلاحظ أنّ متوسط حجم الصفحة على الأجهزة الجوّالة يبلغ 1.5 ميغابايت تقريبًا، ومعظم هذا الحجم يرجع إلى JavaScript والصور.
يساهم الحجم المتزايد للمواقع الإلكترونية، إلى جانب عوامل أخرى، مثل وقت استجابة الشبكة أو قيود وحدة المعالجة المركزية أو أنماط حظر العرض أو الرموز البرمجية غير الضرورية التابعة لجهات خارجية، في تعقيد مشكلة الأداء.
يصنّف معظم المستخدمين السرعة في أعلى هرم احتياجات تجربة المستخدم. وهذا ليس مفاجئًا، لأنّه لا يمكنك إجراء الكثير من العمليات إلى أن ينتهي تحميل الصفحة. لا يمكنك استخلاص قيمة من الصفحة، ولا يمكنك الإعجاب بجمالها.
ندرك أنّ الأداء يهمّ المستخدمين، ولكن قد يبدو الأمر سرّيًا عند محاولة معرفة من أين تبدأ عملية التحسين. لحسن الحظ، تتوفّر أدوات يمكن أن تساعدك في ذلك.
Lighthouse: أساس سير عمل الأداء
Lighthouse هي جزء من "أدوات مطوّري البرامج في Chrome" تتيح لك تدقيق موقعك الإلكتروني وتقدّم لك تلميحات حول كيفية تحسينه.
أطلقنا مؤخرًا مجموعة من عمليات التدقيق الجديدة في الأداء التي تُعدّ مفيدة جدًا في سير عمل التطوير اليومي.
لنستكشف كيف يمكنك الاستفادة منها من خلال مثال عملي: تطبيق Oodles Theater هو تطبيق ويب تجريبي صغير يتيح لك تجربة بعض رسومات Google التفاعلية المفضّلة لدينا ولعب بعض الألعاب.
أردنا التأكّد من أنّ التطبيق يعمل بأعلى أداء ممكن أثناء إنشائه. كانت نقطة البداية في عملية التحسين هي تقرير Lighthouse.
كان الأداء الأولي لتطبيقنا كما هو موضّح في تقرير Lighthouse سيئًا للغاية. وعند استخدام شبكة الجيل الثالث للإنترنت، كان على المستخدم الانتظار لمدة 15 ثانية حتى يظهر أول محتوى مفيد، أو حتى يصبح التطبيق تفاعليًا. أشارت أداة Lighthouse إلى الكثير من المشاكل في موقعنا الإلكتروني، وعكست النتيجة الإجمالية للأداء البالغة 23 ذلك تمامًا.
كان وزن الصفحة حوالي 3.4 ميغابايت، وكان علينا بشدة تقليل حجمها.
بدأنا أول تحدٍّ للأداء: العثور على عناصر يمكننا إزالتها بسهولة بدون التأثير في التجربة الإجمالية.
فرص تحسين الأداء
إزالة المراجع غير الضرورية
هناك بعض العناصر الواضحة التي يمكن إزالتها بأمان، مثل المسافات البيضاء والتعليقات.
تُبرز Lighthouse هذه الفرصة في تدقيق CSS وJavaScript غير المصغّر. استخدمنا webpack في عملية الإنشاء، لذا استخدمنا Uglify JS plugin للحصول على تصغير.
تعتبر عملية التصغير مهمة شائعة، لذا من المفترض أن تتمكّن من العثور على حلّ جاهز لأي عملية إنشاء تستخدمها.
من عمليات التدقيق المفيدة الأخرى في هذا المجال تفعيل ضغط النص. لا داعي لإرسال ملفات غير مضغوطة، ومعظم شبكات توصيل المحتوى (CDN) تتيح ذلك تلقائيًا في الوقت الحالي.
كنا نستخدم Firebase Hosting لاستضافة الرمز، وتتيح Firebase ضغط الملفات باستخدام gzip تلقائيًا، لذا حصلنا على هذه الميزة مجانًا من خلال استضافة الرمز على شبكة توصيل محتوى (CDN) معقولة.
على الرغم من أنّ gzip هي طريقة شائعة جدًا للضغط، إلا أنّ آليات أخرى، مثل Zopfli وBrotli، أصبحت رائجة أيضًا. تتوافق معظم المتصفحات مع Brotli، ويمكنك استخدام ملف ثنائي لضغط مواد العرض مسبقًا قبل إرسالها إلى الخادم.
استخدام سياسات ذاكرة التخزين المؤقت الفعّالة
كانت خطوتنا التالية هي التأكّد من عدم إرسال الموارد مرتين إذا لم يكن ذلك ضروريًا.
ساعدتنا عملية التدقيق Inefficient cache policy في Lighthouse على ملاحظة أنّه يمكننا تحسين استراتيجيات التخزين المؤقت لتحقيق ذلك بالضبط. من خلال ضبط عنوان انتهاء الصلاحية max-age في الخادم، تأكّدنا من أنّه عند تكرار الزيارة، يمكن للمستخدم إعادة استخدام الموارد التي سبق له تنزيلها.
يُفضَّل أن تهدف إلى تخزين أكبر عدد ممكن من الموارد بشكل آمن لأطول فترة زمنية ممكنة، وأن تقدّم رموز التحقّق من الصحة لإعادة التحقّق من صحة الموارد التي تم تعديلها بكفاءة.
إزالة الرموز غير المستخدَمة
حتى الآن، أزلنا الأجزاء الواضحة من التنزيل غير الضروري، ولكن ماذا عن الأجزاء الأقل وضوحًا؟ على سبيل المثال، الرموز غير المستخدَمة.
في بعض الأحيان، نضمّن في تطبيقاتنا رمزًا برمجيًا غير ضروري. يحدث ذلك خاصةً إذا كنت تعمل على تطبيقك لفترة زمنية أطول، أو إذا تغيّر فريقك أو العناصر التابعة لك، وفي بعض الأحيان يتم ترك مكتبة غير مستخدَمة. وهذا ما حدث لنا بالضبط.
في البداية، كنا نستخدم مكتبة Material Components لإنشاء نموذج أولي لتطبيقنا بسرعة. ومع مرور الوقت، انتقلنا إلى مظهر وملمس أكثر تخصيصًا، ونسينا تمامًا تلك المكتبة. لحسن الحظ، ساعدتنا عملية التحقّق من تغطية الرمز البرمجي في إعادة اكتشافه في الحزمة.
يمكنك الاطّلاع على إحصاءات تغطية الرمز البرمجي في "أدوات مطوّلي البرامج"، وذلك لكلّ من وقت التشغيل ووقت التحميل لتطبيقك. يمكنك رؤية الخطَّين الأحمرَين الكبيرَين في لقطة الشاشة أدناه، إذ كان أكثر من %95 من CSS غير مستخدَم، بالإضافة إلى مجموعة كبيرة من JavaScript.
رصدت Lighthouse أيضًا هذه المشكلة في عملية التدقيق في قواعد CSS غير المستخدَمة. وقد أظهرت توفيرًا محتملاً يزيد عن 400 كيلوبايت. لذا، عدنا إلى الرمز البرمجي وأزلنا جزءَي JavaScript وCSS من تلك المكتبة.
وقد أدّى ذلك إلى تقليل حجم حزمة CSS بمقدار 20 مرة، وهو أمر جيد جدًا بالنسبة إلى عملية دمج صغيرة تتألف من سطرَين.
بالطبع، أدّى ذلك إلى تحسين نتيجة الأداء، كما تحسّن وقت التفاعل بشكل كبير.
ومع ذلك، لا يكفي التحقّق من المقاييس والنتائج وحدها عند إجراء تغييرات من هذا النوع. إنّ إزالة الرموز البرمجية الفعلية لا تخلو أبدًا من المخاطر، لذا عليك دائمًا الانتباه إلى أي تراجع محتمل.
لم يتم استخدام الرمز في %95 من الحالات، ولا يزال هناك% 5 من الحالات. يبدو أنّ أحد مكوّناتنا كان لا يزال يستخدم الأنماط من تلك المكتبة، وهي الأسهم الصغيرة في شريط تمرير رسومات الشعار المبتكرة. ولكن بما أنّها كانت صغيرة جدًا، كان بإمكاننا ببساطة إعادة دمج هذه الأنماط يدويًا في الأزرار.
لذلك، إذا أزلت رمزًا، عليك التأكّد من توفّر سير عمل مناسب للاختبار يساعدك في الحماية من أي مشاكل محتملة في العرض.
تجنُّب أحجام الحمولة الكبيرة على الشبكة
ندرك أنّ الموارد الكبيرة يمكن أن تؤدي إلى بطء تحميل صفحات الويب. ويمكن أن تتسبّب في تكبّد المستخدمين تكاليف إضافية، كما يمكن أن يكون لها تأثير كبير على خطط البيانات، لذا من المهم جدًا الانتباه إلى ذلك.
تمكّنت أداة Lighthouse من رصد مشكلة في بعض حمولات الشبكة باستخدام تدقيق حمولات الشبكة الضخمة.
لاحظنا هنا أنّنا نرسل أكثر من 3 ميغابايت من الرموز البرمجية، وهو حجم كبير جدًا، خاصةً على الأجهزة الجوّالة.
في أعلى هذه القائمة، أشار Lighthouse إلى أنّ لدينا حزمة JavaScript خاصة بمورّد تبلغ سعتها 2 ميغابايت من الرمز غير المضغوط. هذه أيضًا مشكلة يسلّط عليها webpack الضوء.
وكما يقول المثل: أسرع طلب هو الطلب الذي لم يتم تقديمه.
من المفترض أن تقيس قيمة كلّ عنصر من العناصر التي تقدّمها للمستخدمين، وتقيس أداء هذه العناصر، وتحدّد ما إذا كان من المفيد تضمينها في التجربة الأولية. ويرجع ذلك إلى أنّه يمكن في بعض الأحيان تأجيل تحميل مواد العرض هذه أو تحميلها بشكل غير متزامن أو معالجتها أثناء وقت عدم النشاط.
في حالتنا، وبما أنّنا نتعامل مع الكثير من حِزم JavaScript، كان من حسن حظنا أنّ منتدى JavaScript يوفّر مجموعة كبيرة من أدوات التدقيق في حِزم JavaScript.
بدأنا باستخدام أداة webpack bundle analyzer التي أظهرت لنا أنّنا نضمّن تبعية باسم unicode تبلغ سعتها 1.6 ميغابايت من JavaScript المحلَّل، وهو حجم كبير جدًا.
بعد ذلك، انتقلنا إلى المحرّر واستخدمنا Import Cost Plugin for Visual code وتمكّنا من تصوّر تكلفة كل وحدة نمطية كنا نستوردها. وقد سمح لنا ذلك باكتشاف المكوّن الذي كان يتضمّن رمزًا يشير إلى هذه الوحدة.
بعد ذلك، انتقلنا إلى أداة أخرى، وهي BundlePhobia. هذه أداة تتيح لك إدخال اسم أي حزمة NPM والاطّلاع على حجمها المقدَّر بعد تصغيرها وضغطها باستخدام gzip. لقد عثرنا على بديل جيد لوحدة slug التي كنا نستخدمها، ويبلغ حجمها 2.2 كيلوبايت فقط، لذا استبدلناها.
وقد كان لذلك تأثير كبير على أدائنا. وبين هذا التغيير واكتشاف فرص أخرى لتقليل حجم حزمة JavaScript، وفّرنا 2.1 ميغابايت من الرموز البرمجية.
لقد شهدنا تحسّنًا بنسبة% 65 بشكل عام، وذلك بعد أخذ حجم هذه الحِزم المضغوطة والمصغّرة في الاعتبار. ووجدنا أنّ هذه العملية تستحق العناء.
لذا، بشكل عام، حاوِل التخلّص من عمليات التنزيل غير الضرورية في مواقعك الإلكترونية وتطبيقاتك. يمكن أن يؤدي إعداد قائمة بمواد العرض وقياس تأثيرها في الأداء إلى إحداث فرق كبير، لذا احرص على مراجعة مواد العرض بانتظام.
تقليل وقت بدء تشغيل JavaScript باستخدام تقسيم الرموز
على الرغم من أنّ أحجام البيانات الكبيرة على الشبكة يمكن أن تؤثر بشكل كبير في تطبيقنا، هناك عامل آخر يمكن أن يكون له تأثير كبير جدًا، وهو JavaScript.
JavaScript هو مادة العرض الأغلى تكلفة. على الأجهزة الجوّالة، إذا كنت ترسل حِزمًا كبيرة من JavaScript، قد يؤدي ذلك إلى تأخير الوقت الذي يمكن فيه للمستخدمين التفاعل مع عناصر واجهة المستخدم. وهذا يعني أنّه يمكنهم النقر على واجهة المستخدم بدون حدوث أي شيء ذي مغزى. لذلك، من المهم أن نفهم سبب ارتفاع تكلفة JavaScript.
هذه هي الطريقة التي يعالج بها المتصفّح لغة JavaScript.
أولاً، علينا تنزيل هذا النص البرمجي، ولدينا محرك JavaScript يحتاج بعد ذلك إلى تحليل هذا الرمز البرمجي وتجميعه وتنفيذه.
لا تستغرق هذه المراحل الكثير من الوقت على جهاز متطوّر مثل الكمبيوتر المكتبي أو المحمول، أو حتى الهاتف المتطوّر. ولكن على هاتف جوّال متوسط، يمكن أن تستغرق هذه العملية وقتًا أطول يتراوح بين خمسة أضعاف وعشرة أضعاف. وهذا ما يؤخّر التفاعل، لذا من المهم أن نحاول تقليل هذا الوقت.
لمساعدتك في رصد هذه المشاكل في تطبيقك، أضفنا تدقيقًا جديدًا لوقت بدء تشغيل JavaScript إلى Lighthouse.
وفي حالة تطبيق Oodle، أخبرنا أنّ الوقت الذي استغرقه بدء تشغيل JavaScript هو 1.8 ثانية. كانت المشكلة تكمن في أنّنا كنا نستورد بشكل ثابت جميع مساراتنا ومكوّناتنا إلى حزمة JavaScript واحدة ضخمة.
إحدى الطرق لتجنُّب ذلك هي استخدام تقسيم الرموز.
تقسيم الرموز هو فكرة مفادها أنّه بدلاً من تقديم كمية كبيرة من JavaScript للمستخدمين، ماذا لو قدّمت لهم شريحة واحدة فقط في كل مرة يحتاجون إليها؟
يمكن تطبيق تقسيم الرمز على مستوى المسار أو على مستوى المكوّن. تعمل هذه الميزة بشكل رائع مع React وReact Loadable وVue.js وAngular وPolymer وPreact والعديد من المكتبات الأخرى.
لقد أدرجنا تقسيم الرمز البرمجي في تطبيقنا، وانتقلنا من عمليات الاستيراد الثابتة إلى عمليات الاستيراد الديناميكية، ما أتاح لنا تحميل الرمز البرمجي بشكل غير متزامن عند الحاجة إليه.
وقد أدّى ذلك إلى تقليل حجم الحِزم، بالإضافة إلى تقليل وقت بدء تشغيل JavaScript. وقد تمكّنّا من خفضها إلى 0.78 ثانية، ما جعل التطبيق أسرع بنسبة% 56.
بشكل عام، إذا كنت بصدد إنشاء تجربة تتضمّن الكثير من JavaScript، احرص على إرسال الرمز البرمجي الذي يحتاجه المستخدم فقط.
يمكنك الاستفادة من مفاهيم مثل تقسيم الرموز، واستكشاف أفكار مثل إزالة الرموز غير المستخدَمة، والاطّلاع على مستودع webpack-libs-optimizations للحصول على بعض الأفكار حول كيفية تقليل حجم المكتبة إذا كنت تستخدم webpack.
تحسين الصور
في تطبيق Oodle، نستخدم الكثير من الصور. مع ذلك، لم يكن أداء الموقع الإلكتروني جيدًا وفقًا لأداة Lighthouse. في الواقع، لم ننجح في جميع عمليات التدقيق الثلاث المتعلقة بالصور.
لقد نسينا تحسين صورنا، ولم نكن نحدّد حجمها بشكل صحيح، وكان بإمكاننا أيضًا تحقيق بعض التحسينات من خلال استخدام تنسيقات صور أخرى.
بدأنا بتحسين صورنا.
بالنسبة إلى جولة التحسين لمرة واحدة، يمكنك استخدام أدوات مرئية مثل ImageOptim أو XNConvert.
هناك طريقة أكثر آلية وهي إضافة خطوة لتحسين الصور إلى عملية الإنشاء، وذلك باستخدام مكتبات مثل imagemin.
بهذه الطريقة، ستضمن تحسين الصور التي تتم إضافتها في المستقبل تلقائيًا. توفّر بعض شبكات توصيل المحتوى، مثل Akamai أو الحلول التابعة لجهات خارجية مثل Cloudinary أو Fastly أو Uploadcare، حلولاً شاملة لتحسين الصور، لذا يمكنك أيضًا استضافة صورك على هذه الخدمات.
إذا كنت لا تريد استخدام هذه الخدمات بسبب التكلفة أو مشاكل وقت الاستجابة، يمكنك الاستعانة بمشاريع مثل Thumbor أو Imageflow التي توفّر بدائل مستضافة ذاتيًا.
تم الإبلاغ عن أنّ ملف PNG الخاص بالخلفية كبير الحجم في Webpack، وهذا صحيح. وبعد ضبط حجمه بشكل صحيح ليتناسب مع إطار العرض وتشغيله من خلال ImageOptim، انخفض حجمه إلى 100 كيلوبايت، وهو حجم مقبول.
وقد سمح لنا تكرار هذه العملية لعدة صور على موقعنا الإلكتروني بتقليل حجم الصفحة الإجمالي بشكل كبير.
استخدام التنسيق المناسب للمحتوى المتحرّك
يمكن أن تكون صور GIF باهظة الثمن. من المثير للدهشة أنّ تنسيق GIF لم يكن مخصّصًا في الأساس كمنصة للصور المتحركة. لذلك، يتيح لك التبديل إلى تنسيق فيديو أكثر ملاءمة توفيرًا كبيرًا في حجم الملف.
في تطبيق Oodle، كنا نستخدم صورة GIF كتسلسل تقديمي على الصفحة الرئيسية. وفقًا لأداة Lighthouse، يمكننا توفير أكثر من 7 ميغابايت من خلال التبديل إلى تنسيق فيديو أكثر فعالية. كان حجم المقطع الصوتي يبلغ حوالي 7.3 ميغابايت، وهو حجم كبير جدًا بالنسبة إلى أي موقع إلكتروني معقول، لذا حوّلناه إلى عنصر فيديو يتضمّن ملفَي مصدر، أحدهما mp4 والآخر WebM لتوفير توافق أوسع مع المتصفحات.
استخدمنا أداة FFmpeg لتحويل صورة GIF المتحركة إلى ملف mp4. يوفّر لك تنسيق WebM توفيرًا أكبر في المساحة، ويمكن أن تنفّذ واجهة برمجة التطبيقات ImageOptim API عملية التحويل هذه نيابةً عنك.
ffmpeg -i animation.gif -b:v 0 -crf 40 -vf scale=600:-1 video.mp4
تمكّنا من توفير أكثر من% 80 من الوزن الإجمالي بفضل عملية التحويل هذه. وقد أدّى ذلك إلى خفض حجم الملف إلى حوالي 1 ميغابايت.
ومع ذلك، يمثّل حجم 1 ميغابايت حجمًا كبيرًا من الموارد التي يتم إرسالها عبر الشبكة، خاصةً بالنسبة إلى المستخدمين الذين لديهم نطاق ترددي محدود. لحسن الحظ، تمكّنا من استخدام Effective Type API لإدراك أنّهم يستخدمون نطاقًا تردديًا بطيئًا، وبالتالي قدّمنا لهم صورة JPEG أصغر بكثير.
تستخدِم هذه الواجهة قيم وقت الاستجابة الفعّال ووقت التعطّل لتقدير نوع الشبكة التي يستخدمها المستخدم. تعرض هذه السمة ببساطة سلسلة، مثل slow 2G أو 2G أو 3G أو 4G. وبناءً على هذه القيمة، إذا كان المستخدم يستخدم شبكة أقل من 4G، يمكننا استبدال عنصر الفيديو بالصورة.
if (navigator.connection.effectiveType) { ... }
صحيح أنّ ذلك يؤثر قليلاً في التجربة، ولكن على الأقل يصبح الموقع الإلكتروني قابلاً للاستخدام على اتصال بطيء.
تحميل الصور خارج الشاشة بأسلوب "التحميل الكسول"
غالبًا ما يتم تحميل الصور في العروض الدوّارة أو أشرطة التمرير أو الصفحات الطويلة جدًا، حتى إذا لم يتمكّن المستخدم من رؤيتها على الصفحة مباشرةً.
ستشير أداة Lighthouse إلى هذا السلوك في تدقيق الصور خارج الشاشة، ويمكنك أيضًا الاطّلاع عليه بنفسك في لوحة الشبكة في DevTools. إذا لاحظت ورود الكثير من الصور بينما لا يظهر سوى عدد قليل منها على الصفحة، يعني ذلك أنّه يمكنك استخدام التحميل الكسول بدلاً من ذلك.
لا تتوافق ميزة "التحميل الكسول" مع المتصفّح بشكلٍ تلقائي، لذا علينا استخدام 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 هي تجنُّب إجراء رحلات متعدّدة مكلفة إلى أي مصدر.
في حالة تطبيق Oodle، نستخدم في الواقع "خطوط Google" بشكل كبير. عندما تضيف ورقة أنماط من Google Fonts إلى صفحتك، سيتم الربط بنطاقَين فرعيَين. وتشير أداة Lighthouse إلى أنّه إذا تمكّنا من تسريع عملية إنشاء هذا الاتصال، يمكننا توفير ما يصل إلى 300 ملي ثانية من وقت الاتصال الأوّلي.
من خلال الاستفادة من ميزة "الربط المُسبَق" في rel، يمكننا إخفاء وقت استجابة الاتصال هذا بشكل فعّال.
يمكن أن يكون لهذا الإجراء تأثير كبير، خاصةً مع خدمات مثل Google Fonts التي تتم فيها استضافة CSS الخاص بنوع الخط على googleapis.com، واستضافة موارد الخط على Gstatic. لذلك طبّقنا هذا التحسين وتمكّنا من تقليل وقت الاستجابة ببضع مئات من الملّي ثانية.
النصيحة التالية التي تقدّمها أداة Lighthouse هي التحميل المُسبَق للطلبات الرئيسية.
<link rel=preload> هي أداة فعّالة جدًا، فهي تُعلم المتصفح بأنّه يجب توفير مورد كجزء من عملية التنقّل الحالية، وتحاول أن تجعل المتصفح يجلب هذا المورد في أسرع وقت ممكن.
يخبرنا Lighthouse الآن أنّه يجب الانتقال إلى تحميل موارد خطوط الويب الرئيسية مسبقًا، لأنّنا نحمّل خطَّي ويب.
يبدو التحميل المُسبَق لخط ويب على النحو التالي: عند تحديد rel=preload، يمكنك إدخال as مع نوع الخط، ثم تحديد نوع الخط الذي تحاول تحميله، مثل woff2.
يمكن أن يكون تأثير ذلك على صفحتك كبيرًا جدًا.
في العادة، وبدون استخدام link rel preload، إذا كانت خطوط الويب مهمة لصفحتك، على المتصفح أولاً جلب HTML، ثم تحليل CSS، وبعد ذلك بكثير، سيتم جلب خطوط الويب.
باستخدام link rel preload، يمكن للمتصفّح البدء في جلب خطوط الويب هذه في وقت مبكر جدًا بمجرد أن يحلّل رمز HTML. في حالة تطبيقنا، تمكّنا من تقليل الوقت المستغرَق في عرض النص باستخدام خطوط الويب بمقدار ثانية واحدة.
إذا كنت ستجرّب التحميل المُسبَق للخطوط باستخدام Google Fonts، هناك مشكلة واحدة يجب الانتباه إليها.
إنّ عناوين URL الخاصة بـ Google Font التي نحدّدها في وجوه الخطوط في أوراق الأنماط يتم تعديلها بانتظام من قِبل فريق الخطوط. يمكن أن تنتهي صلاحية عناوين URL هذه أو يتم تعديلها بشكل منتظم، لذا ننصحك باستضافة خطوط الويب بنفسك إذا كنت تريد التحكّم بشكل كامل في تجربة تحميل الخطوط. وهذا أمر رائع لأنّه يتيح لك الوصول إلى ميزات مثل link rel preload.
في حالتنا، وجدنا أنّ الأداة Google Web Fonts Helper مفيدة جدًا في مساعدتنا على إيقاف بعض خطوط الويب هذه وإعدادها محليًا، لذا ننصحك بتجربة هذه الأداة.
سواء كنت تستخدم خطوط الويب كجزء من الموارد المهمة أو كنت تستخدم JavaScript، حاوِل مساعدة المتصفّح في عرض الموارد المهمة في أسرع وقت ممكن.
ميزة تجريبية: تلميحات الأولوية
لدينا مفاجأة مميزة لك اليوم. بالإضافة إلى ميزات مثل تلميحات الموارد والتحميل المُسبَق، نعمل على تطوير ميزة تجريبية جديدة تمامًا للمتصفح أطلقنا عليها اسم تلميحات الأولوية.
هذه ميزة جديدة تتيح لك الإشارة إلى المتصفّح بمدى أهمية أحد الموارد، وتعرض سمة جديدة باسم importance تتضمّن القيم low أو high أو auto.
يتيح لنا ذلك نقل أولوية الموارد الأقل أهمية، مثل الأنماط غير المهمة أو الصور أو طلبات البيانات من واجهة برمجة التطبيقات Fetch، إلى مستوى أقل لتقليل التنازع. يمكننا أيضًا زيادة أولوية العناصر الأكثر أهمية، مثل صور الجزء الرئيسي.
في حالة تطبيق Oodle، أدّى ذلك إلى توفير مكان عملي يمكننا تحسينه.
قبل أن نضيف ميزة التحميل الكسول إلى صورنا، كان المتصفّح يتبع الخطوات التالية: كان لدينا لوحة عرض دوّارة للصور تحتوي على جميع رسومات الشعار المبتكرة، وكان المتصفّح يجلب جميع الصور في بداية اللوحة بأولوية عالية. وللأسف، كانت الصور في منتصف لوحة العرض الدوّارة هي الأكثر أهمية للمستخدم. لذلك، حدّدنا مستوى أهمية منخفضًا جدًا لصور الخلفية، ومستوى أهمية مرتفعًا جدًا لصور المقدمة، وقد أدّى ذلك إلى تحسين الأداء بمقدار ثانيتَين على شبكة الجيل الثالث البطيئة، كما ساعدنا في سرعة جلب هذه الصور وعرضها. لذا، كانت تجربة إيجابية لطيفة.
نأمل أن نتيح هذه الميزة في قناة Canary خلال بضعة أسابيع، لذا ترقَّبوا إطلاقها.
وضع استراتيجية لتحميل خطوط الويب
يُعدّ أسلوب الخط أساسيًا للتصميم الجيد، وإذا كنت تستخدم خطوط الويب، من الأفضل ألا تحظر عرض النص، ومن المؤكّد أنّك لا تريد عرض نص غير مرئي.
نبرز هذه المشكلة الآن في Lighthouse من خلال عملية التدقيق تجنُّب النص غير المرئي أثناء تحميل خطوط الويب.
إذا كنت تحمّل خطوط الويب باستخدام كتلة font-face، فإنّك تتيح للمتصفّح تحديد الإجراء الذي يجب اتّخاذه إذا استغرق جلب خط الويب وقتًا طويلاً. ستنتظر بعض المتصفحات مدة تصل إلى ثلاث ثوانٍ قبل الرجوع إلى خط النظام، وستستبدله في النهاية بالخط بعد تنزيله.
نحن نحاول تجنُّب هذا النص غير المرئي، لذا في هذه الحالة، لم نكن لنتمكّن من رؤية رسومات الشعار المبتكرة الكلاسيكية لهذا الأسبوع إذا استغرق تحميل خط الويب وقتًا طويلاً. لحسن الحظ، تتيح لك ميزة جديدة باسم
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');
}
تساعدك ميزة "عرض الخط" في تحديد طريقة عرض خطوط الويب أو طريقة الرجوع إليها استنادًا إلى المدة التي تستغرقها عملية التبديل.
في هذه الحالة، نستخدم font display swap. تمنح عملية التبديل وجه الخط فترة حظر تبلغ صفر ثانية، وفترة تبديل غير محدودة. وهذا يعني أنّ المتصفّح سيرسم النص على الفور تقريبًا باستخدام خط احتياطي إذا استغرق تحميل الخط بعض الوقت. وسيتم استبدالها عندما يصبح خط الوجه متاحًا.
في حالة تطبيقنا، كان هذا الإجراء مفيدًا لأنّه سمح لنا بعرض بعض النصوص المهمة في وقت مبكر جدًا، ثم الانتقال إلى خط الويب بعد أن يصبح جاهزًا.
بشكل عام، إذا كنت تستخدم خطوط الويب، كما يفعل جزء كبير من الويب، عليك وضع استراتيجية جيدة لتحميل خطوط الويب.
تتوفّر العديد من ميزات منصة الويب التي يمكنك استخدامها لتحسين تجربة تحميل الخطوط، ولكن ننصحك أيضًا بالاطّلاع على مستودع Web Font Recipes الخاص بـ "زاك ليذرمان"، لأنّه مفيد جدًا.
تقليل النصوص البرمجية التي تمنع عرض الإعلانات
هناك أجزاء أخرى من تطبيقنا يمكننا عرضها في وقت أبكر من سلسلة التنزيل لتوفير تجربة مستخدم أساسية على الأقل في وقت أبكر قليلاً.
في شريط المخطط الزمني في Lighthouse، يمكنك أن ترى أنّه خلال الثواني القليلة الأولى التي يتم فيها تحميل جميع الموارد، لا يمكن للمستخدم رؤية أي محتوى.
يؤدي تنزيل أوراق الأنماط الخارجية ومعالجتها إلى منع عملية العرض من إحراز أي تقدّم.
يمكننا محاولة تحسين مسار العرض الحرج من خلال عرض بعض الأنماط قبل غيرها.
إذا استخرجنا الأنماط المسؤولة عن هذا العرض الأولي وضمّناها في HTML، سيتمكّن المتصفّح من عرضها على الفور بدون انتظار وصول أوراق الأنماط الخارجية.
في حالتنا، استخدمنا وحدة NPM تُسمّى Critical لتضمين المحتوى المهم في ملف index.html أثناء خطوة الإنشاء.
على الرغم من أنّ هذه الوحدة النمطية قدّمت لنا الكثير من المساعدة، كان من الصعب بعض الشيء أن تعمل بسلاسة على مستوى مسارات مختلفة.
إذا لم تكن حريصًا أو كان تصميم موقعك الإلكتروني معقّدًا للغاية، قد يكون من الصعب جدًا تقديم هذا النوع من الأنماط إذا لم تخطّط لتصميم واجهة تطبيق منذ البداية.
لهذا السبب من المهم جدًا مراعاة الأداء في المراحل المبكرة. إذا لم تصمّم تطبيقك مع مراعاة الأداء منذ البداية، هناك احتمال كبير أن تواجه مشاكل عند محاولة تحسين الأداء لاحقًا.
في النهاية، أثمرت المخاطرة التي اتّخذناها، وتمكّنا من إنجاح هذه العملية، وبدأ التطبيق في عرض المحتوى في وقت أبكر بكثير، ما أدّى إلى تحسين كبير في سرعة عرض أوّل محتوى مفيد على الصفحة.
النتيجة
كانت هذه قائمة طويلة بعمليات تحسين الأداء التي أجريناها على موقعنا الإلكتروني. لنلقِ نظرة على النتيجة. في ما يلي طريقة تحميل تطبيقنا على جهاز جوّال متوسط المستوى على شبكة الجيل الثالث، قبل عملية التحسين وبعدها.
ارتفعت نتيجة الأداء في Lighthouse من 23 إلى 91. هذا تقدّم جيد جدًا من حيث السرعة. وقد تم إجراء كل هذه التغييرات استنادًا إلى تقرير Lighthouse الذي نراجعه ونتبعه باستمرار. إذا أردت الاطّلاع على كيفية تنفيذنا لجميع التحسينات من الناحية الفنية، يمكنك مراجعة مستودعنا، وخاصةً طلبات الدمج التي تمّت الموافقة عليها.
الأداء التوقّعي: تجارب المستخدمين المستندة إلى البيانات
نحن نؤمن بأنّ تعلُّم الآلة يمثّل فرصة رائعة للمستقبل في العديد من المجالات. إحدى الأفكار التي نأمل أن تشجّع على إجراء المزيد من التجارب في المستقبل هي أنّ البيانات الحقيقية يمكن أن ترشدنا حقًا إلى تجارب المستخدمين التي نصمّمها.
في الوقت الحالي، نتّخذ الكثير من القرارات العشوائية بشأن ما قد يريده المستخدم أو يحتاج إليه، وبالتالي بشأن ما يستحق أن يتم جلبه مسبقًا أو تحميله مسبقًا أو تخزينه مؤقتًا مسبقًا. وإذا كان تخميننا صحيحًا، يمكننا تحديد أولويات كمية صغيرة من الموارد، ولكن من الصعب جدًا توسيع نطاق ذلك ليشمل الموقع الإلكتروني بأكمله.
في الواقع، تتوفّر لدينا بيانات تساعدنا في تحسين أداء الإعلانات بشكل أفضل اليوم. باستخدام Google Analytics Reporting API، يمكننا إلقاء نظرة على الصفحة التالية الأعلى ترتيبًا ونسب الخروج لأي عنوان URL على موقعنا الإلكتروني، وبالتالي استخلاص استنتاجات بشأن الموارد التي يجب أن نعطيها الأولوية.
وإذا جمعنا ذلك مع نموذج احتمالية جيد، سنتجنّب إهدار بيانات المستخدم من خلال إجراء عملية جلب مسبق مفرطة للمحتوى. يمكننا الاستفادة من بيانات "إحصاءات Google" هذه واستخدام تعلُّم الآلة ونماذج مثل سلاسل ماركوف أو الشبكة العصبية من أجل تنفيذ هذه النماذج.
لتسهيل هذه التجارب، يسعدنا الإعلان عن مبادرة جديدة أطلقنا عليها اسم Guess.js.
Guess.js هو مشروع يركّز على تجارب المستخدم المستندة إلى البيانات على الويب. نأمل أن يشجّعك ذلك على استكشاف طرق استخدام البيانات لتحسين أداء الويب وتجاوز ذلك. وجميعها مفتوحة المصدر ومتوفّرة على GitHub اليوم. تم إنشاء هذه الميزة بالتعاون مع منكو غيتشيف وكايل ماثيوز من Gatsby وكيتي هيمبينيوس وعدد من الأشخاص الآخرين من منتدى المصادر المفتوحة.
يمكنك الاطّلاع على Guess.js وإخبارنا برأيك.
ملخّص
تساعد النتائج والمقاييس في تحسين سرعة الويب، ولكنّها مجرد وسائل، وليست الأهداف نفسها.
لقد واجهنا جميعًا مشاكل في تحميل الصفحات أثناء التنقّل، ولكن لدينا الآن فرصة لتقديم تجارب أكثر متعة للمستخدمين يتم تحميلها بسرعة كبيرة.
تحسين الأداء هو رحلة. يمكن أن تؤدي الكثير من التغييرات الصغيرة إلى تحقيق مكاسب كبيرة. باستخدام أدوات التحسين المناسبة ومتابعة تقارير Lighthouse، يمكنك تقديم تجربة أفضل وأكثر شمولاً للمستخدمين.
نتوجّه بالشكر إلى: Ward Peeters وMinko Gechev وKyle Mathews وKatie Hempenius وDom Farolino وYoav Weiss وSusie Lu وYusuke Utsunomiya وTom Ankers وLighthouse وGoogle Doodles.