قائمة مراجعة الأداء للواجهة الأمامية 2021 (PDF ، صفحات Apple ، MS Word)
نشرت: 2022-03-10تم دعم هذا الدليل من قبل أصدقائنا في LogRocket ، وهي خدمة تجمع بين مراقبة أداء الواجهة الأمامية وإعادة تشغيل الجلسة وتحليلات المنتج لمساعدتك في بناء تجارب أفضل للعملاء. LogRocket يتتبع المقاييس الرئيسية ، بما في ذلك. اكتمل DOM ، الوقت حتى البايت الأول ، تأخير الإدخال الأول ، استخدام وحدة المعالجة المركزية للعميل والذاكرة. احصل على نسخة تجريبية مجانية من LogRocket اليوم.
أداء الويب هو وحش مخادع ، أليس كذلك؟ كيف نعرف حقًا موقفنا من حيث الأداء ، وما هي بالضبط اختناقات الأداء لدينا؟ هل هو برنامج JavaScript مكلف ، أم بطء تسليم خط ويب ، أم صور ثقيلة ، أم عرض بطيء؟ هل قمنا بالتحسين بدرجة كافية باستخدام اهتزاز الشجرة ، ورفع النطاق ، وتقسيم الشفرة ، وجميع أنماط التحميل الفاخرة باستخدام مراقب التقاطع ، والترطيب التدريجي ، وتلميحات العملاء ، و HTTP / 3 ، وعمال الخدمة ، و- يا عمال الحافة؟ والأهم من ذلك ، من أين نبدأ في تحسين الأداء وكيف نؤسس ثقافة الأداء على المدى الطويل؟
في الماضي ، كان الأداء غالبًا مجرد فكرة لاحقة . غالبًا ما يتم تأجيله حتى نهاية المشروع ، فسيتم اختصاره في التصغير والتسلسل وتحسين الأصول وربما بعض التعديلات الدقيقة على ملف config
الخادم. إذا نظرنا إلى الوراء الآن ، يبدو أن الأمور قد تغيرت بشكل كبير.
الأداء ليس مجرد مصدر قلق تقني: إنه يؤثر على كل شيء بدءًا من إمكانية الوصول إلى سهولة الاستخدام وحتى تحسين محرك البحث ، وعند إدخاله في سير العمل ، يجب أن تكون قرارات التصميم مدعومة بآثارها على الأداء. يجب قياس الأداء ومراقبته وصقله باستمرار ، ويشكل التعقيد المتزايد للويب تحديات جديدة تجعل من الصعب تتبع المقاييس ، لأن البيانات ستختلف بشكل كبير اعتمادًا على الجهاز والمتصفح والبروتوكول ونوع الشبكة ووقت الاستجابة ( تلعب شبكات CDN و ISPs وذاكرة التخزين المؤقت والوكلاء والجدران النارية وموازن التحميل والخوادم دورًا في الأداء).
لذا ، إذا أنشأنا نظرة عامة على جميع الأشياء التي يجب أن نضعها في الاعتبار عند تحسين الأداء - من بداية المشروع حتى الإصدار النهائي للموقع - فكيف سيبدو ذلك؟ ستجد أدناه قائمة مراجعة أداء أمامية (نأمل أن تكون غير متحيزة وموضوعية) لعام 2021 - نظرة عامة محدثة على المشكلات التي قد تحتاج إلى أخذها في الاعتبار لضمان أن أوقات استجابتك سريعة ، وتفاعل المستخدم سلسًا ومواقعك ليست كذلك استنزاف النطاق الترددي للمستخدم.
جدول المحتويات
- كل ذلك في صفحات منفصلة
- الاستعداد: التخطيط والقياسات
ثقافة الأداء ، حيوية الويب الأساسية ، ملفات تعريف الأداء ، أجهزة CrUX ، Lighthouse ، FID ، TTI ، CLS ، الأجهزة. - تحديد أهداف واقعية
ميزانيات الأداء ، أهداف الأداء ، إطار عمل السكك الحديدية ، موازنات 170 كيلو بايت / 30 كيلو بايت. - تعريف البيئة
اختيار إطار العمل ، تكلفة الأداء الأساسية ، Webpack ، التبعيات ، CDN ، بنية الواجهة الأمامية ، CSR ، SSR ، CSR + SSR ، التقديم الثابت ، العرض المسبق ، نمط PRPL. - تحسينات الأصول
Brotli ، AVIF ، WebP ، الصور المستجيبة ، AV1 ، تحميل الوسائط التكيفية ، ضغط الفيديو ، خطوط الويب ، خطوط Google. - بناء التحسينات
وحدات جافا سكريبت ، نمط الوحدة النمطية / الوحدة النمطية ، اهتزاز الشجرة ، تقسيم الكود ، رفع النطاق ، حزمة الويب ، الخدمة التفاضلية ، عامل الويب ، WebAssembly ، حزم JavaScript ، React ، SPA ، الترطيب الجزئي ، الاستيراد عند التفاعل ، الأطراف الثالثة ، ذاكرة التخزين المؤقت. - تحسينات التسليم
التحميل الكسول ، مراقب التقاطع ، التأجيل وفك التشفير ، CSS الحرجة ، التدفق ، تلميحات الموارد ، تحولات التخطيط ، عامل الخدمة. - الشبكات ، HTTP / 2 ، HTTP / 3
تدبيس OCSP ، شهادات EV / DV ، التغليف ، IPv6 ، QUIC ، HTTP / 3. - الاختبار والمراقبة
تدقيق سير العمل ، المتصفحات الوكيلة ، صفحة 404 ، مطالبات الموافقة على ملف تعريف الارتباط لـ GDPR ، تشخيصات الأداء CSS ، إمكانية الوصول. - انتصارات سريعة
- قم بتنزيل قائمة التحقق (PDF ، Apple Pages ، MS Word)
- فعلينا العودة!
(يمكنك أيضًا تنزيل قائمة التحقق بتنسيق PDF (166 كيلوبايت) أو تنزيل ملف Apple Pages القابل للتحرير (275 كيلوبايت) أو ملف .docx (151 كيلوبايت). أتمنى لك التحسين السعيد ، الجميع!)
الاستعداد: التخطيط والقياسات
تعد عمليات التحسين الجزئي رائعة للحفاظ على الأداء في المسار الصحيح ، ولكن من الأهمية بمكان وضع أهداف محددة بوضوح في الاعتبار - أهداف قابلة للقياس من شأنها التأثير على أي قرارات يتم اتخاذها خلال العملية. هناك نوعان من النماذج المختلفة ، والنماذج التي تمت مناقشتها أدناه لها رأي كبير - فقط تأكد من تحديد أولوياتك في وقت مبكر.
- ترسيخ ثقافة الأداء.
في العديد من المؤسسات ، يعرف مطورو الواجهة الأمامية بالضبط المشكلات الأساسية الشائعة وما هي الاستراتيجيات التي يجب استخدامها لإصلاحها. ومع ذلك ، طالما أنه لا يوجد تأييد مؤكد لثقافة الأداء ، فإن كل قرار سيتحول إلى ساحة معركة بين الأقسام ، مما يؤدي إلى تقسيم المنظمة إلى صوامع. أنت بحاجة إلى موافقة أصحاب المصلحة التجاريين ، وللحصول عليها ، تحتاج إلى إنشاء دراسة حالة ، أو إثبات مفهوم حول مدى السرعة - خاصةً أساسيات الويب الأساسية التي سنقوم بتغطيتها بالتفصيل لاحقًا - فوائد المقاييس ومؤشرات الأداء الرئيسية ( مؤشرات الأداء الرئيسية ) التي يهتمون بها.على سبيل المثال ، لجعل الأداء ملموسًا بشكل أكبر ، يمكنك الكشف عن تأثير أداء الإيرادات من خلال إظهار الارتباط بين معدل التحويل ووقت تحميل التطبيق ، بالإضافة إلى عرض الأداء. أو معدل زحف روبوت البحث (ملف PDF ، الصفحات 27-50).
بدون محاذاة قوية بين المطورين / التصميم وفرق العمل / التسويق ، لن يستمر الأداء على المدى الطويل. دراسة الشكاوى الشائعة الواردة في خدمة العملاء وفريق المبيعات ، ودراسة التحليلات لمعدلات الارتداد المرتفعة وانخفاض التحويل. اكتشف كيف يمكن أن يساعد تحسين الأداء في تخفيف بعض هذه المشكلات الشائعة. اضبط الحجة اعتمادًا على مجموعة أصحاب المصلحة الذين تتحدث إليهم.
قم بإجراء تجارب الأداء وقياس النتائج - سواء على الهاتف المحمول أو على سطح المكتب (على سبيل المثال ، باستخدام Google Analytics). سيساعدك على بناء دراسة حالة مصممة خصيصًا للشركة باستخدام بيانات حقيقية. علاوة على ذلك ، فإن استخدام البيانات من دراسات الحالة والتجارب المنشورة على WPO Stats سيساعد على زيادة حساسية الأعمال حول سبب أهمية الأداء ، وتأثيره على تجربة المستخدم ومقاييس الأعمال. ومع ذلك ، فإن القول بأن الأداء مهم وحده لا يكفي - فأنت بحاجة أيضًا إلى إنشاء بعض الأهداف القابلة للقياس والتتبع ومراقبتها بمرور الوقت.
كيفية الوصول الى هناك؟ في حديثها عن بناء الأداء على المدى الطويل ، تشارك أليسون ماكنايت دراسة حالة شاملة عن كيفية مساعدتها في تأسيس ثقافة الأداء في Etsy (الشرائح). في الآونة الأخيرة ، تحدث تامي إيفيرتس عن عادات فرق الأداء عالية الفعالية في كل من المؤسسات الصغيرة والكبيرة.
أثناء إجراء هذه المحادثات في المؤسسات ، من المهم أن تضع في اعتبارك أنه تمامًا مثل UX عبارة عن مجموعة من الخبرات ، فإن أداء الويب هو توزيع. كما لاحظت كارولينا سزكور ، "توقع أن يكون رقم واحد قادرًا على توفير تصنيف يطمح إليه هو افتراض خاطئ". ومن ثم يجب أن تكون أهداف الأداء دقيقة وقابلة للتتبع وملموسة.


- الهدف: أن تكون أسرع بنسبة 20٪ على الأقل من أسرع منافس لك.
وفقًا للبحث النفسي ، إذا كنت تريد أن يشعر المستخدمون أن موقع الويب الخاص بك أسرع من موقع منافسيك ، فيجب أن تكون أسرع بنسبة 20٪ على الأقل . ادرس منافسيك الرئيسيين ، واجمع مقاييس حول كيفية أدائهم على الأجهزة المحمولة وسطح المكتب وحدد عتبات من شأنها أن تساعدك على التفوق عليهم. للحصول على نتائج وأهداف دقيقة ، تأكد أولاً من الحصول على صورة شاملة لتجربة المستخدمين من خلال دراسة تحليلاتك. يمكنك بعد ذلك محاكاة تجربة الشريحة المئوية التسعين للاختبار.للحصول على انطباع أول جيد عن أداء منافسيك ، يمكنك استخدام تقرير Chrome UX ( CrUX ، مجموعة بيانات RUM جاهزة ، مقدمة فيديو بواسطة Ilya Grigorik ودليل مفصل بواسطة Rick Viscomi) ، أو Treo ، أداة مراقبة RUM التي مدعوم من Chrome UX Report. يتم جمع البيانات من مستخدمي متصفح Chrome ، لذا ستكون التقارير خاصة بـ Chrome ، لكنها ستمنحك توزيعًا شاملاً إلى حد ما للأداء ، والأهم من ذلك نتائج Core Web Vitals ، عبر مجموعة واسعة من الزوار. لاحظ أنه يتم إصدار مجموعات بيانات CrUX الجديدة في الثلاثاء الثاني من كل شهر .
بدلاً من ذلك ، يمكنك أيضًا استخدام:
- أداة مقارنة تقرير Chrome UX من Addy Osmani ،
- بطاقة قياس أداء السرعة (توفر أيضًا مقدرًا لتأثير الإيرادات) ،
- مقارنة اختبار تجربة المستخدم الحقيقي أو
- SiteSpeed CI (بناءً على الاختبارات التركيبية).
ملاحظة : إذا كنت تستخدم Page Speed Insights أو Page Speed Insights API (لا ، لم يتم إهمالها!) ، يمكنك الحصول على بيانات أداء CrUX لصفحات معينة بدلاً من التجميعات فقط. يمكن أن تكون هذه البيانات أكثر فائدة في تحديد أهداف الأداء لمواد مثل "الصفحة المقصودة" أو "قائمة المنتجات". وإذا كنت تستخدم CI لاختبار الميزانيات ، فأنت بحاجة إلى التأكد من أن بيئتك المختبرة تطابق CrUX إذا استخدمت CrUX لتحديد الهدف ( شكرًا باتريك مينان! ).
إذا كنت بحاجة إلى بعض المساعدة لإظهار السبب وراء تحديد أولويات السرعة ، أو كنت ترغب في تصور تسوس معدل التحويل أو زيادة معدل الارتداد مع أداء أبطأ ، أو ربما تحتاج إلى الدعوة إلى حل RUM في مؤسستك ، سيرجي قامت Chernyshev ببناء UX Speed Calculator ، وهي أداة مفتوحة المصدر تساعدك على محاكاة البيانات وتصورها لتوجيه وجهة نظرك.
يُنشئ CrUX نظرة عامة على توزيعات الأداء بمرور الوقت ، مع حركة المرور التي تم جمعها من مستخدمي Google Chrome. يمكنك إنشاء لوحة تحكم خاصة بك على Chrome UX Dashboard. (معاينة كبيرة) فقط عندما تحتاج إلى إثبات حالة الأداء لتوجيه وجهة نظرك: تصور UX Speed Calculator تأثير الأداء على معدلات الارتداد والتحويل وإجمالي الإيرادات - استنادًا إلى بيانات حقيقية. (معاينة كبيرة) في بعض الأحيان قد ترغب في التعمق قليلاً ، والجمع بين البيانات الواردة من CrUX وأي بيانات أخرى لديك بالفعل للعمل بسرعة حيث تكمن التباطؤ ، والبقع العمياء ، وعدم الكفاءة - لمنافسيك ، أو لمشروعك. في عمله ، استخدم هاري روبرتس جدول بيانات طبوغرافيا لسرعة الموقع والذي يستخدمه لتقسيم الأداء حسب أنواع الصفحات الرئيسية ، وتتبع مدى اختلاف المقاييس الرئيسية عبرها. يمكنك تنزيل جدول البيانات على هيئة جداول بيانات Google أو Excel أو مستند OpenOffice أو CSV.
تضاريس سرعة الموقع ، مع تمثيل المقاييس الرئيسية للصفحات الرئيسية على الموقع. (معاينة كبيرة) وإذا كنت ترغب في المضي قدمًا ، يمكنك إجراء تدقيق أداء Lighthouse على كل صفحة من صفحات الموقع (عبر Lightouse Parade) ، مع إخراج محفوظ بتنسيق CSV. سيساعدك ذلك في تحديد الصفحات (أو أنواع الصفحات) المحددة لمنافسيك ذات الأداء الأسوأ أو الأفضل ، وما الذي قد ترغب في تركيز جهودك عليه. (بالنسبة لموقعك ، من الأفضل على الأرجح إرسال البيانات إلى نقطة نهاية التحليلات!).
باستخدام Lighthouse Parade ، يمكنك إجراء تدقيق أداء Lighthouse على كل صفحة من الموقع ، مع إخراج محفوظ بتنسيق CSV. (معاينة كبيرة) اجمع البيانات ، وقم بإعداد جدول بيانات ، واستخلص 20٪ ، وقم بإعداد أهدافك ( ميزانيات الأداء ) بهذه الطريقة. الآن لديك شيء يمكن قياسه لاختباره. إذا كنت تضع الميزانية في الاعتبار وتحاول شحن الحد الأدنى من الحمولة للحصول على وقت سريع للتفاعل ، فأنت على طريق معقول.
هل تحتاج إلى موارد لتبدأ؟
- كتب Addy Osmani كتابة مفصلة للغاية حول كيفية بدء إعداد ميزانية الأداء ، وكيفية تحديد تأثير الميزات الجديدة وأين تبدأ عندما تتجاوز الميزانية.
- يمكن أن يوفر دليل لارا هوغان حول كيفية التعامل مع التصميمات بميزانية أداء مؤشرات مفيدة للمصممين.
- نشر هاري روبرتس دليلاً حول إعداد جدول بيانات Google لعرض تأثير نصوص الطرف الثالث على الأداء ، باستخدام خريطة الطلب ،
- يمكن أن تساعد حاسبة ميزانية الأداء من Jonathan Fielding ، وآلة حاسبة ميزانية الأداء من Katie Hempenius ومتصفح السعرات الحرارية في إنشاء الميزانيات (بفضل Karolina Szczur للحصول على الرؤوس).
- في العديد من الشركات ، لا ينبغي أن تكون ميزانيات الأداء طموحة ، بل يجب أن تكون واقعية ، حيث تعمل كإشارة ثابتة لتجنب الانزلاق إلى ما وراء نقطة معينة. في هذه الحالة ، يمكنك اختيار أسوأ نقطة بيانات في الأسبوعين الماضيين كحد أدنى ، وتأخذها من هناك. ميزانيات الأداء ، يوضح لك بشكل عملي إستراتيجية لتحقيق ذلك.
- أيضًا ، اجعل كلاً من ميزانية الأداء والأداء الحالي مرئيًا من خلال إعداد لوحات معلومات تحتوي على رسوم بيانية تبلغ عن أحجام الإنشاء. هناك العديد من الأدوات التي تسمح لك بتحقيق ذلك: SiteSpeed.io dashboard (مفتوح المصدر) و SpeedCurve و Caliber ليست سوى عدد قليل منهم ، ويمكنك العثور على المزيد من الأدوات على perf.rocks.
يساعدك متصفح السعرات الحرارية في تحديد ميزانية الأداء وقياس ما إذا كانت الصفحة تتجاوز هذه الأرقام أم لا. (معاينة كبيرة) بمجرد الانتهاء من وضع الميزانية ، قم بدمجها في عملية الإنشاء الخاصة بك باستخدام Webpack Performance Hints and Bundlesize أو Lighthouse CI أو PWMetrics أو Sitespeed CI لفرض الميزانيات على طلبات السحب وتوفير سجل النتائج في تعليقات العلاقات العامة.
لعرض ميزانيات الأداء للفريق بأكمله ، قم بدمج ميزانيات الأداء في Lighthouse عبر Lightwallet أو استخدم LHCI Action لتكامل إجراءات Github السريع. وإذا كنت بحاجة إلى شيء مخصص ، فيمكنك استخدام webpagetest-charts-api ، وهي واجهة برمجة تطبيقات لنقاط النهاية لإنشاء مخططات من نتائج WebPagetest.
يجب ألا يأتي الوعي بالأداء من ميزانيات الأداء وحدها. تمامًا مثل Pinterest ، يمكنك إنشاء قاعدة eslint مخصصة لا تسمح بالاستيراد من الملفات والدلائل المعروفة بأنها ثقيلة التبعية وستؤدي إلى زيادة حجم الحزمة. قم بإعداد قائمة بالحزم "الآمنة" التي يمكن مشاركتها عبر الفريق بأكمله.
أيضًا ، فكر في مهام العملاء الحاسمة الأكثر فائدة لعملك. قم بدراسة ومناقشة وتحديد الحدود الزمنية المقبولة للإجراءات الحاسمة وإنشاء علامات توقيت المستخدم "جاهزة لتجربة المستخدم" التي وافقت عليها المؤسسة بأكملها. في كثير من الحالات ، ستتطرق رحلات المستخدم إلى عمل العديد من الأقسام المختلفة ، لذا فإن التوافق من حيث التوقيتات المقبولة سيساعد في دعم أو منع مناقشات الأداء في المستقبل. تأكد من أن التكاليف الإضافية للموارد والميزات المضافة مرئية ومفهومة.
مواءمة جهود الأداء مع المبادرات التقنية الأخرى ، بدءًا من الميزات الجديدة للمنتج الذي يتم بناؤه لإعادة البناء إلى الوصول إلى جماهير عالمية جديدة. لذلك في كل مرة تحدث فيها محادثة حول مزيد من التطوير ، يكون الأداء جزءًا من تلك المحادثة أيضًا. من الأسهل بكثير الوصول إلى أهداف الأداء عندما تكون قاعدة التعليمات البرمجية حديثة أو يتم إعادة بنائها.
أيضًا ، كما اقترح باتريك مينان ، من المفيد التخطيط لتسلسل التحميل والمفاضلات أثناء عملية التصميم. إذا أعطيت الأولوية في وقت مبكر للأجزاء الأكثر أهمية ، وحددت الترتيب الذي يجب أن تظهر به ، فستعرف أيضًا ما يمكن أن يتأخر. من الناحية المثالية ، سيعكس هذا الطلب أيضًا تسلسل عمليات استيراد CSS و JavaScript ، لذا سيكون التعامل معها أثناء عملية الإنشاء أسهل. أيضًا ، ضع في اعتبارك ما يجب أن تكون عليه التجربة المرئية في "بين" الحالات ، أثناء تحميل الصفحة (على سبيل المثال ، عندما لا يتم تحميل خطوط الويب بعد).
بمجرد إنشاء ثقافة أداء قوية في مؤسستك ، استهدف أن تكون أسرع بنسبة 20٪ من نفسك السابقة للحفاظ على الأولويات في لباقة مع مرور الوقت ( شكرًا ، Guy Podjarny! ). لكن ضع في اعتبارك الأنواع المختلفة وسلوكيات الاستخدام لعملائك (والتي أطلق عليها توبياس بالدوف الإيقاع والأفواج) ، جنبًا إلى جنب مع حركة مرور الروبوتات والتأثيرات الموسمية.
التخطيط والتخطيط والتخطيط. قد يكون من المغري الدخول في بعض التحسينات السريعة "السريعة المعلقة" - في وقت مبكر - وقد تكون استراتيجية جيدة لتحقيق مكاسب سريعة - ولكن سيكون من الصعب جدًا الاحتفاظ بالأداء كأولوية دون التخطيط ووضع الشركة الواقعية أهداف أداء مفصلة.


- اختر المقاييس الصحيحة.
ليست كل المقاييس مهمة بنفس القدر. ادرس المقاييس الأكثر أهمية لتطبيقك: عادةً ، سيتم تحديدها من خلال مدى السرعة التي يمكنك بها البدء في عرض أهم وحدات البكسل في واجهتك ومدى السرعة التي يمكنك بها توفير استجابة الإدخال لوحدات البكسل المعروضة هذه. ستمنحك هذه المعرفة أفضل هدف تحسين للجهود المستمرة. في النهاية ، ليست أحداث التحميل أو أوقات استجابة الخادم هي التي تحدد التجربة ، ولكن إدراك مدى سرعة الواجهة .ماذا تعني؟ بدلاً من التركيز على وقت تحميل الصفحة بالكامل (عبر توقيتات onLoad و DOMContentLoaded ، على سبيل المثال) ، أعط الأولوية لتحميل الصفحة كما يراه عملاؤك. وهذا يعني التركيز على مجموعة مختلفة قليلاً من المقاييس. في الواقع ، يعد اختيار المقياس الصحيح عملية بدون فائزين واضحين.
استنادًا إلى بحث تيم كادليك وملاحظات ماركوس إغليسياس في حديثه ، يمكن تجميع المقاييس التقليدية في مجموعات قليلة. عادة ، سنحتاج منهم جميعًا للحصول على صورة كاملة للأداء ، وفي حالتك الخاصة سيكون بعضها أكثر أهمية من البعض الآخر.
- تقيس المقاييس المستندة إلى الكمية عدد الطلبات والوزن ودرجة الأداء. جيد لرفع الإنذارات ومراقبة التغييرات بمرور الوقت ، وليس جيدًا لفهم تجربة المستخدم.
- تستخدم مقاييس الإنجاز حالات في عمر عملية التحميل ، على سبيل المثال ، وقت الوصول إلى البايت الأول ووقت التفاعل . جيد لوصف تجربة المستخدم والمراقبة ، وليس جيدًا لمعرفة ما يحدث بين المراحل الرئيسية.
- توفر مقاييس العرض تقديرًا لمدى سرعة عرض المحتوى (مثل وقت بدء العرض ومؤشر السرعة ). جيد لقياس أداء العرض وتعديله ، ولكنه ليس جيدًا للقياس عند ظهور محتوى مهم ويمكن التفاعل معه.
- تقيس المقاييس المخصصة حدثًا مخصصًا معينًا للمستخدم ، على سبيل المثال Twitter's Time To First Tweet و Pinterest's PinnerWaitTime. جيد لوصف تجربة المستخدم بدقة ، وليس جيدًا لتوسيع المقاييس والمقارنة مع المنافسين.
لإكمال الصورة ، عادة ما نبحث عن مقاييس مفيدة بين كل هذه المجموعات. عادةً ما تكون أكثرها تحديدًا وذات صلة هي:
- وقت التفاعل (TTI)
النقطة التي استقر فيها التخطيط ، تكون خطوط الويب الرئيسية مرئية ، ويكون الخيط الرئيسي متاحًا بما يكفي للتعامل مع مدخلات المستخدم - بشكل أساسي علامة الوقت عندما يمكن للمستخدم التفاعل مع واجهة المستخدم. المقاييس الرئيسية لفهم مقدار الانتظار الذي يجب على المستخدم تجربته لاستخدام الموقع دون تأخير. كتب بوريس شابيرا منشورًا تفصيليًا حول كيفية قياس TTI بشكل موثوق. - تأخر الإدخال الأول (FID) ، أو استجابة الإدخال
الوقت من وقت تفاعل المستخدم لأول مرة مع موقعك إلى الوقت الذي يكون فيه المتصفح قادرًا بالفعل على الاستجابة لهذا التفاعل. يكمل TTI جيدًا لأنه يصف الجزء المفقود من الصورة: ماذا يحدث عندما يتفاعل المستخدم بالفعل مع الموقع. الغرض منه هو مقياس RUM فقط. توجد مكتبة JavaScript لقياس FID في المتصفح. - أكبر طلاء محتوى (LCP)
يحدد النقطة في المخطط الزمني لتحميل الصفحة عند تحميل المحتوى المهم للصفحة على الأرجح. يُفترض أن أهم عنصر في الصفحة هو أكبر عنصر مرئي في إطار عرض المستخدم. إذا تم عرض العناصر أعلى وأسفل الطية ، فسيتم اعتبار الجزء المرئي فقط ذا صلة. - إجمالي وقت الحظر ( TBT )
مقياس يساعد في تحديد مدى خطورة عدم تفاعل الصفحة قبل أن تصبح تفاعلية موثوقًا به (أي أن الخيط الرئيسي كان خاليًا من أي مهام تعمل أكثر من 50 مللي ثانية ( مهام طويلة ) لمدة 5 ثوانٍ على الأقل). يقيس المقياس إجمالي الوقت بين الطلاء الأول و Time to Interactive (TTI) حيث تم حظر الخيط الرئيسي لفترة كافية لمنع استجابة الإدخال. لا عجب إذن أن انخفاض TBT مؤشر جيد للأداء الجيد. (شكرا ، أرتيم ، فيل) - التحول في التخطيط التراكمي ( CLS )
يبرز المقياس عدد المرات التي يواجه فيها المستخدمون تغيرات غير متوقعة في التخطيط ( تدفقات إعادة التدفق) عند الوصول إلى الموقع. يفحص العناصر غير المستقرة وتأثيرها على التجربة الكلية. كلما انخفضت النتيجة ، كان ذلك أفضل. - مؤشر السرعة
يقيس مدى سرعة تعبئة محتويات الصفحة بشكل مرئي ؛ كلما انخفضت النتيجة ، كان ذلك أفضل. يتم حساب درجة مؤشر السرعة بناءً على سرعة التقدم المرئي ، لكنها مجرد قيمة محسوبة. كما أنها حساسة لحجم منفذ العرض ، لذلك تحتاج إلى تحديد مجموعة من تكوينات الاختبار التي تتناسب مع جمهورك المستهدف. لاحظ أنه أصبح أقل أهمية مع LCP الذي أصبح مقياسًا أكثر صلة ( شكرًا ، Boris ، Artem! ). - قضى وقت وحدة المعالجة المركزية
مقياس يوضح عدد المرات والمدة التي يتم فيها حظر الخيط الرئيسي ، والعمل على الرسم والعرض والبرمجة والتحميل. يعد ارتفاع وقت وحدة المعالجة المركزية مؤشرًا واضحًا على تجربة سيئة ، أي عندما يواجه المستخدم تأخرًا ملحوظًا بين عمله والاستجابة. باستخدام WebPageTest ، يمكنك تحديد "مخطط زمني لأدوات Capture Dev" في علامة التبويب "Chrome" لعرض تفاصيل سلسلة المحادثات الرئيسية أثناء تشغيلها على أي جهاز باستخدام WebPageTest. - تكاليف وحدة المعالجة المركزية على مستوى المكونات
تمامًا كما هو الحال مع وقت وحدة المعالجة المركزية (CPU) ، يستكشف هذا المقياس ، الذي اقترحه Stoyan Stefanov ، تأثير JavaScript على وحدة المعالجة المركزية . تكمن الفكرة في استخدام عدد تعليمات وحدة المعالجة المركزية لكل مكون لفهم تأثيره على التجربة الكلية ، بشكل منفصل. يمكن تنفيذه باستخدام محرك العرائس وكروم. - الإحباط
بينما تشرح العديد من المقاييس الموضحة أعلاه عند حدوث حدث معين ، يبحث Tim Vereecke's FrustratedIndex في الفجوات بين المقاييس بدلاً من النظر إليها بشكل فردي. إنه ينظر إلى المعالم الرئيسية التي يراها المستخدم النهائي ، مثل العنوان مرئي والمحتوى الأول مرئي وجاهز بصريًا وتبدو الصفحة جاهزة ويحسب النتيجة التي تشير إلى مستوى الإحباط أثناء تحميل الصفحة. كلما كبرت الفجوة ، زادت فرصة إحباط المستخدم. يحتمل أن يكون مؤشر أداء رئيسي جيد لتجربة المستخدم. نشر تيم منشورًا تفصيليًا حول FrustratedIndex وكيف يعمل. - تأثير وزن الإعلان
إذا كان موقعك يعتمد على الإيرادات الناتجة عن الإعلانات ، فمن المفيد تتبع وزن الشفرة المتعلقة بالإعلان. ينشئ البرنامج النصي Paddy Ganti عنواني URL (أحدهما عادي والآخر يحظر الإعلانات) ، ويحث على إنشاء مقارنة فيديو عبر WebPageTest ويبلغ عن دلتا. - مقاييس الانحراف
كما لاحظ مهندسو ويكيبيديا ، فإن بيانات مقدار التباين الموجود في نتائجك يمكن أن تخبرك بمدى موثوقية أجهزتك ، ومقدار الاهتمام الذي يجب أن توليه للانحرافات والأطراف الخارجية. التباين الكبير هو مؤشر على التعديلات المطلوبة في الإعداد. كما أنه يساعد في فهم ما إذا كان من الصعب قياس بعض الصفحات بشكل موثوق ، على سبيل المثال بسبب البرامج النصية لجهات خارجية التي تسبب تباينًا كبيرًا. قد يكون من الجيد أيضًا تتبع إصدار المتصفح لفهم المطبات في الأداء عند طرح إصدار جديد من المتصفح. - المقاييس المخصصة
يتم تحديد المقاييس المخصصة حسب احتياجات عملك وتجربة العملاء. يتطلب منك تحديد وحدات البكسل المهمة والنصوص الهامة و CSS الضرورية والأصول ذات الصلة وقياس مدى سرعة تسليمها إلى المستخدم. لذلك ، يمكنك مراقبة Hero Rendering Times ، أو استخدام Performance API ، مع تحديد طوابع زمنية معينة للأحداث المهمة لعملك. يمكنك أيضًا جمع مقاييس مخصصة باستخدام WebPagetest عن طريق تنفيذ JavaScript عشوائي في نهاية الاختبار.
لاحظ أن First Meaningful Paint (FMP) لا يظهر في النظرة العامة أعلاه. كان يستخدم لتوفير نظرة ثاقبة حول مدى سرعة إخراج الخادم لأي بيانات. عادةً ما يشير FMP الطويل إلى أن JavaScript يحظر الخيط الرئيسي ، ولكن يمكن أن يكون مرتبطًا بمشكلات النهاية الخلفية / الخادم أيضًا. ومع ذلك ، فقد تم إهمال المقياس مؤخرًا حيث يبدو أنه غير دقيق في حوالي 20٪ من الحالات. تم استبداله بشكل فعال بـ LCP وهو أكثر موثوقية وأسهل في التفكير. لم يعد مدعومًا في Lighthouse. تحقق جيدًا من أحدث مقاييس الأداء والتوصيات التي تركز على المستخدم للتأكد من أنك في الصفحة الآمنة ( شكرًا ، باتريك مينان ).
ستيف سودرس لديه شرح مفصل للعديد من هذه المقاييس. من المهم ملاحظة أنه بينما يتم قياس Time-To-Interactive عن طريق تشغيل عمليات تدقيق آلية في ما يسمى ببيئة المعمل ، فإن First Input Delay يمثل تجربة المستخدم الفعلية ، حيث يعاني المستخدمون الفعليون من تأخر ملحوظ. بشكل عام ، من الأفضل قياس كل منهما وتتبعهما دائمًا.
اعتمادًا على سياق التطبيق الخاص بك ، قد تختلف المقاييس المفضلة: على سبيل المثال ، بالنسبة إلى Netflix TV UI ، تعد استجابة الإدخال الرئيسي واستخدام الذاكرة و TTI أكثر أهمية ، وبالنسبة لـ Wikipedia ، تعد التغييرات المرئية الأولى / الأخيرة ووقت وحدة المعالجة المركزية أكثر أهمية.
ملاحظة : لا يأخذ كل من FID و TTI في الحسبان سلوك التمرير ؛ يمكن أن يحدث التمرير بشكل مستقل لأنه خارج السلسلة الرئيسية ، لذلك بالنسبة للعديد من مواقع استهلاك المحتوى ، قد تكون هذه المقاييس أقل أهمية ( شكرًا ، باتريك! ).


- قياس وتحسين "أساسيات الويب الحيوية" .
لفترة طويلة ، كانت مقاييس الأداء تقنية تمامًا ، مع التركيز على النظرة الهندسية لمدى سرعة استجابة الخوادم ، ومدى سرعة تحميل المتصفحات. لقد تغيرت المقاييس على مر السنين - في محاولة لإيجاد طريقة لالتقاط تجربة المستخدم الفعلية ، بدلاً من توقيتات الخادم. في مايو 2020 ، أعلنت Google عن Core Web Vitals ، وهي مجموعة من مقاييس الأداء الجديدة التي تركز على المستخدم ، ويمثل كل منها جانبًا مميزًا من تجربة المستخدم.لكل منهم ، توصي Google بمجموعة من أهداف السرعة المقبولة. يجب أن يتجاوز 75٪ على الأقل من جميع مشاهدات الصفحة النطاق الجيد لاجتياز هذا التقييم. اكتسبت هذه المقاييس قوة جذب سريعًا ، ومع تحول Core Web Vitals إلى إشارات ترتيب لبحث Google في مايو 2021 ( تحديث خوارزمية تصنيف Page Experience ) ، حولت العديد من الشركات انتباهها إلى نتائج أدائها.
دعنا نقسم كل عنصر من "أساسيات الويب الأساسية" ، واحدًا تلو الآخر ، جنبًا إلى جنب مع التقنيات والأدوات المفيدة لتحسين تجاربك مع وضع هذه المقاييس في الاعتبار. (من الجدير بالذكر أنك ستحصل على نتائج أفضل لـ Core Web Vitals باتباع نصيحة عامة في هذه المقالة.)
- أكبر طلاء محتوى ( LCP ) <2.5 ثانية.
يقيس تحميل الصفحة ويبلغ عن وقت عرض أكبر صورة أو كتلة نصية يمكن رؤيتها في إطار العرض. ومن ثم ، يتأثر LCP بكل شيء يؤخر عرض المعلومات المهمة - سواء كان ذلك بطيئًا في أوقات استجابة الخادم ، أو حظر CSS ، أو JavaScript أثناء الطيران (طرف أول أو طرف ثالث) ، أو تحميل خط ويب ، أو عمليات عرض أو رسم باهظة الثمن ، أو كسول الصور المحملة أو الشاشات الهيكلية أو التقديم من جانب العميل.
للحصول على تجربة جيدة ، يجب أن يحدث LCP في غضون 2.5 ثانية من وقت بدء تحميل الصفحة لأول مرة. هذا يعني أننا بحاجة إلى عرض الجزء الأول المرئي من الصفحة في أقرب وقت ممكن. سيتطلب ذلك CSS حرجًا مخصصًا لكل قالب ، مع تنظيم ترتيب<head>
وجلب الأصول الهامة مسبقًا (سنغطيها لاحقًا).عادةً ما يكون السبب الرئيسي لانخفاض درجة LCP هو الصور. لتقديم LCP في أقل من 2.5 ثانية على Fast 3G - مستضاف على خادم مُحسّن جيدًا ، وكلها ثابتة بدون عرض من جانب العميل وبصورة قادمة من صورة مخصصة CDN - يعني أن الحد الأقصى لحجم الصورة النظري لا يتجاوز 144 كيلو بايت . هذا هو سبب أهمية الصور سريعة الاستجابة ، بالإضافة إلى التحميل المسبق للصور المهمة مبكرًا (مع
preload
).نصيحة سريعة : لاكتشاف ما يعتبر LCP على الصفحة ، في DevTools ، يمكنك التمرير فوق شارة LCP ضمن "التوقيتات" في لوحة الأداء ( شكرًا ، Tim Kadlec !).
- أول تأخير للإدخال ( FID ) <100 مللي ثانية.
يقيس استجابة واجهة المستخدم ، أي المدة التي كان المتصفح مشغولاً فيها بالمهام الأخرى قبل أن يتفاعل مع حدث إدخال منفصل للمستخدم مثل نقرة أو نقرة. إنه مصمم لالتقاط التأخيرات التي تنتج عن انشغال سلسلة المحادثات الرئيسية ، خاصة أثناء تحميل الصفحة.
الهدف هو البقاء في حدود 50-100 مللي ثانية لكل تفاعل. للوصول إلى هناك ، نحتاج إلى تحديد المهام الطويلة (حظر الخيط الرئيسي لمدة> 50 مللي ثانية) وتقسيمها ، وتقسيم حزمة برمجية إلى أجزاء متعددة ، وتقليل وقت تنفيذ JavaScript ، وتحسين جلب البيانات ، وتأجيل تنفيذ البرنامج النصي للأطراف الثالثة ، انقل JavaScript إلى سلسلة الخلفية مع العاملين على الويب واستخدم الترطيب التدريجي لتقليل تكاليف معالجة الجفاف في SPA.نصيحة سريعة : بشكل عام ، تتمثل الإستراتيجية الموثوقة للحصول على درجة FID أفضل في تقليل العمل على الخيط الرئيسي عن طريق تقسيم الحزم الأكبر إلى حزم أصغر وتقديم ما يحتاجه المستخدم عندما يحتاج إليه ، لذلك لن تتأخر تفاعلات المستخدم . سنغطي المزيد عن ذلك بالتفصيل أدناه.
- التحول في التخطيط التراكمي ( CLS ) <0.1.
يقيس الثبات المرئي لواجهة المستخدم لضمان تفاعلات سلسة وطبيعية ، أي إجمالي كل درجات تغيير التخطيط الفردي لكل تغيير تخطيط غير متوقع يحدث أثناء العمر الافتراضي للصفحة. يحدث تحول التخطيط الفردي في أي وقت يغير فيه عنصر كان مرئيًا بالفعل موضعه على الصفحة. تم تسجيله بناءً على حجم المحتوى والمسافة التي تحركها.
لذلك في كل مرة يظهر فيها تحول - على سبيل المثال عندما يكون للخطوط الاحتياطية وخطوط الويب مقاييس خطوط مختلفة ، أو تأتي الإعلانات أو التضمينات أو إطارات iframe في وقت متأخر ، أو أن أبعاد الصورة / الفيديو غير محجوزة ، أو يفرض CSS المتأخر إعادة طلاء ، أو يتم إدخال التغييرات بواسطة أواخر JavaScript - لها تأثير على درجة CLS. القيمة الموصى بها للحصول على تجربة جيدة هي CLS <0.1.
تجدر الإشارة إلى أنه من المفترض أن تتطور "أساسيات الويب الأساسية" بمرور الوقت ، مع دورة سنوية يمكن التنبؤ بها . بالنسبة لتحديث العام الأول ، قد نتوقع ترقية First Contentful Paint إلى Core Web Vitals ، وعتبة FID مخفضة ودعم أفضل للتطبيقات أحادية الصفحة. We might also see the responding to user inputs after load gaining more weight, along with security, privacy and accessibility (!) considerations.
Related to Core Web Vitals, there are plenty of useful resources and articles that are worth looking into:
- Web Vitals Leaderboard allows you to compare your scores against competition on mobile, tablet, desktop, and on 3G and 4G.
- Core SERP Vitals, a Chrome extension that shows the Core Web Vitals from CrUX in the Google Search Results.
- Layout Shift GIF Generator that visualizes CLS with a simple GIF (also available from the command line).
- web-vitals library can collect and send Core Web Vitals to Google Analytics, Google Tag Manager or any other analytics endpoint.
- Analyzing Web Vitals with WebPageTest, in which Patrick Meenan explores how WebPageTest exposes data about Core Web Vitals.
- Optimizing with Core Web Vitals, a 50-min video with Addy Osmani, in which he highlights how to improve Core Web Vitals in an eCommerce case-study.
- Cumulative Layout Shift in Practice and Cumulative Layout Shift in the Real World are comprehensive articles by Nic Jansma, which cover pretty much everything about CLS and how it correlates with key metrics such as Bounce Rate, Session Time or Rage Clicks.
- What Forces Reflow, with an overview of properties or methods, when requested/called in JavaScript, that will trigger the browser to synchronously calculate the style and layout.
- CSS Triggers shows which CSS properties trigger Layout, Paint and Composite.
- Fixing Layout Instability is a walkthrough of using WebPageTest to identify and fix layout instability issues.
- Cumulative Layout Shift, The Layout Instability Metric, another very detailed guide by Boris Schapira on CLS, how it's calcualted, how to measure and how to optimize for it.
- How To Improve Core Web Vitals, a detailed guide by Simon Hearne on each of the metrics (including other Web Vitals, such as FCP, TTI, TBT), when they occur and how they are measured.
So, are Core Web Vitals the ultimate metrics to follow ? ليس تماما. They are indeed exposed in most RUM solutions and platforms already, including Cloudflare, Treo, SpeedCurve, Calibre, WebPageTest (in the filmstrip view already), Newrelic, Shopify, Next.js, all Google tools (PageSpeed Insights, Lighthouse + CI, Search Console etc.) and many others.
However, as Katie Sylor-Miller explains, some of the main problems with Core Web Vitals are the lack of cross-browser support, we don't really measure the full lifecycle of a user's experience, plus it's difficult to correlate changes in FID and CLS with business outcomes.
As we should be expecting Core Web Vitals to evolve, it seems only reasonable to always combine Web Vitals with your custom-tailored metrics to get a better understanding of where you stand in terms of performance.
- أكبر طلاء محتوى ( LCP ) <2.5 ثانية.
- Gather data on a device representative of your audience.
To gather accurate data, we need to thoroughly choose devices to test on. In most companies, that means looking into analytics and creating user profiles based on most common device types. Yet often, analytics alone doesn't provide a complete picture. A significant portion of the target audience might be abandoning the site (and not returning back) just because their experience is too slow, and their devices are unlikely to show up as the most popular devices in analytics for that reason. So, additionally conducting research on common devices in your target group might be a good idea.Globally in 2020, according to the IDC, 84.8% of all shipped mobile phones are Android devices. An average consumer upgrades their phone every 2 years, and in the US phone replacement cycle is 33 months. Average bestselling phones around the world will cost under $200.
A representative device, then, is an Android device that is at least 24 months old , costing $200 or less, running on slow 3G, 400ms RTT and 400kbps transfer, just to be slightly more pessimistic. This might be very different for your company, of course, but that's a close enough approximation of a majority of customers out there. In fact, it might be a good idea to look into current Amazon Best Sellers for your target market. ( Thanks to Tim Kadlec, Henri Helvetica and Alex Russell for the pointers! ).
When building a new site or app, always check current Amazon Best Sellers for your target market first. (معاينة كبيرة) What test devices to choose then? The ones that fit well with the profile outlined above. It's a good option to choose a slightly older Moto G4/G5 Plus, a mid-range Samsung device (Galaxy A50, S8), a good middle-of-the-road device like a Nexus 5X, Xiaomi Mi A3 or Xiaomi Redmi Note 7 and a slow device like Alcatel 1X or Cubot X19, perhaps in an open device lab. For testing on slower thermal-throttled devices, you could also get a Nexus 4, which costs just around $100.
Also, check the chipsets used in each device and do not over-represent one chipset : a few generations of Snapdragon and Apple as well as low-end Rockchip, Mediatek would be enough (thanks, Patrick!) .
If you don't have a device at hand, emulate mobile experience on desktop by testing on a throttled 3G network (eg 300ms RTT, 1.6 Mbps down, 0.8 Mbps up) with a throttled CPU (5× slowdown). Eventually switch over to regular 3G, slow 4G (eg 170ms RTT, 9 Mbps down, 9Mbps up), and Wi-Fi. To make the performance impact more visible, you could even introduce 2G Tuesdays or set up a throttled 3G/4G network in your office for faster testing.
Keep in mind that on a mobile device, we should be expecting a 4×–5× slowdown compared to desktop machines. Mobile devices have different GPUs, CPU, memory and different battery characteristics. That's why it's important to have a good profile of an average device and always test on such a device.
- Synthetic testing tools collect lab data in a reproducible environment with predefined device and network settings (eg Lighthouse , Calibre , WebPageTest ) and
- Real User Monitoring ( RUM ) tools evaluate user interactions continuously and collect field data (eg SpeedCurve , New Relic — the tools provide synthetic testing, too).
- use Lighthouse CI to track Lighthouse scores over time (it's quite impressive),
- run Lighthouse in GitHub Actions to get a Lighthouse report alongside every PR,
- run a Lighthouse performance audit on every page of a site (via Lightouse Parade), with an output saved as CSV,
- use Lighthouse Scores Calculator and Lighthouse metric weights if you need to dive into more detail.
- Lighthouse is available for Firefox as well, but under the hood it uses the PageSpeed Insights API and generates a report based on a headless Chrome 79 User-Agent.

Luckily, there are many great options that help you automate the collection of data and measure how your website performs over time according to these metrics. Keep in mind that a good performance picture covers a set of performance metrics, lab data and field data:
The former is particularly useful during development as it will help you identify, isolate and fix performance issues while working on the product. The latter is useful for long-term maintenance as it will help you understand your performance bottlenecks as they are happening live — when users actually access the site.
By tapping into built-in RUM APIs such as Navigation Timing, Resource Timing, Paint Timing, Long Tasks, etc., synthetic testing tools and RUM together provide a complete picture of performance in your application. You could use Calibre, Treo, SpeedCurve, mPulse and Boomerang, Sitespeed.io, which all are great options for performance monitoring. Furthermore, with Server Timing header, you could even monitor back-end and front-end performance all in one place.
Note : It's always a safer bet to choose network-level throttlers, external to the browser, as, for example, DevTools has issues interacting with HTTP/2 push, due to the way it's implemented ( thanks, Yoav, Patrick !). For Mac OS, we can use Network Link Conditioner, for Windows Windows Traffic Shaper, for Linux netem, and for FreeBSD dummynet.
As it's likely that you'll be testing in Lighthouse, keep in mind that you can:

- Set up "clean" and "customer" profiles for testing.
While running tests in passive monitoring tools, it's a common strategy to turn off anti-virus and background CPU tasks, remove background bandwidth transfers and test with a clean user profile without browser extensions to avoid skewed results (in Firefox, and in Chrome).DebugBear's report highlights 20 slowest extensions, including password managers, ad-blockers and popular applications like Evernote and Grammarly. (معاينة كبيرة) However, it's also a good idea to study which browser extensions your customers use frequently, and test with dedicated "customer" profiles as well. In fact, some extensions might have a profound performance impact (2020 Chrome Extension Performance Report) on your application, and if your users use them a lot, you might want to account for it up front. Hence, "clean" profile results alone are overly optimistic and can be crushed in real-life scenarios.
- شارك أهداف الأداء مع زملائك.
تأكد من أن أهداف الأداء مألوفة لكل عضو في فريقك لتجنب سوء الفهم في المستقبل. كل قرار - سواء كان تصميمًا أو تسويقًا أو أي شيء بينهما - له آثار على الأداء ، وتوزيع المسؤولية والملكية عبر الفريق بأكمله من شأنه تبسيط القرارات التي تركز على الأداء في وقت لاحق. ضع قرارات التصميم مقابل ميزانية الأداء والأولويات المحددة في وقت مبكر.
تحديد أهداف واقعية
- وقت استجابة 100 مللي ثانية ، 60 إطارًا في الثانية.
لكي يشعر التفاعل بسلاسة ، تحتوي الواجهة على 100 مللي ثانية للاستجابة لمدخلات المستخدم. أي فترة أطول من ذلك ، ويرى المستخدم أن التطبيق متأخر. يمنحك نموذج الأداء الذي يركز على المستخدم RAIL أهدافًا صحية : للسماح باستجابة أقل من 100 مللي ثانية ، يجب أن تعيد الصفحة التحكم مرة أخرى إلى مؤشر الترابط الرئيسي بعد كل أقل من 50 مللي ثانية. يخبرنا وقت الاستجابة المقدر للإدخال ما إذا كنا قد وصلنا إلى هذا الحد ، ومن الناحية المثالية ، يجب أن يكون أقل من 50 مللي ثانية. بالنسبة إلى نقاط الضغط المرتفع مثل الرسوم المتحركة ، من الأفضل عدم فعل أي شيء آخر حيث يمكنك والحد الأدنى المطلق حيث لا يمكنك ذلك.RAIL ، نموذج أداء يركز على المستخدم. أيضًا ، يجب إكمال كل إطار للرسوم المتحركة في أقل من 16 مللي ثانية ، وبالتالي تحقيق 60 إطارًا في الثانية (ثانية واحدة ÷ 60 = 16.6 مللي ثانية) - ويفضل أن يكون ذلك أقل من 10 مللي ثانية. نظرًا لأن المتصفح يحتاج إلى وقت لرسم الإطار الجديد على الشاشة ، يجب أن تنتهي التعليمات البرمجية الخاصة بك من التنفيذ قبل الوصول إلى علامة 16.6 مللي ثانية. لقد بدأنا في إجراء محادثات حول 120 إطارًا في الثانية (على سبيل المثال ، تعمل شاشات iPad Pro عند 120 هرتز) وقد غطت Surma بعض حلول أداء العرض لـ 120 إطارًا في الثانية ، ولكن ربما هذا ليس هدفًا نتطلع إليه الآن .
كن متشائمًا في توقعات الأداء ، ولكن كن متفائلًا في تصميم الواجهة واستخدم وقت الخمول بحكمة (تحقق من الخمول ، الخمول حتى العاجل ورد الفعل خاملاً). من الواضح أن هذه الأهداف تنطبق على أداء وقت التشغيل ، بدلاً من تحميل الأداء.
- FID <100 مللي ثانية ، LCP <2.5 ثانية ، TTI <5s على شبكة الجيل الثالث ، ميزانية حجم الملف الحرج <170 كيلو بايت (مضغوط).
على الرغم من أنه قد يكون من الصعب جدًا تحقيقه ، إلا أن الهدف النهائي الجيد هو "حان وقت التفاعل" دون سن الخامسة ، وبالنسبة للزيارات المتكررة ، يجب أن يكون الهدف أقل من ثانيتين (لا يمكن تحقيقه إلا مع عامل الخدمة). استهدف الحصول على أكبر لوحة ذات محتوى أقل من 2.5 ثانية وتقليل وقت الحظر الإجمالي وتغيير التخطيط التراكمي . يكون تأخير الإدخال الأول المقبول أقل من 100 مللي ثانية - 70 مللي ثانية. كما ذكرنا أعلاه ، نحن نفكر في أن خط الأساس هو هاتف Android بقيمة 200 دولار (مثل Moto G4) على شبكة 3G بطيئة ، تتم محاكاتها بسرعة نقل تبلغ 400 مللي ثانية RTT و 400 كيلوبت في الثانية.لدينا قيدان رئيسيان يشكلان بشكل فعال هدفًا معقولاً للتسليم السريع للمحتوى على الويب. من ناحية أخرى ، لدينا قيود على توصيل الشبكة بسبب بداية بطيئة لـ TCP. أول 14 كيلوبايت من HTML - 10 حزم TCP ، كل 1460 بايت ، مما يجعل حوالي 14.25 كيلوبايت ، وإن لم يتم أخذها حرفيًا - هو الجزء الأكثر أهمية للحمولة الصافية ، والجزء الوحيد من الميزانية الذي يمكن تسليمه في الرحلة الأولى ذهابًا وإيابًا ( وهو كل ما تحصل عليه في ثانية واحدة عند 400 مللي ثانية RTT بسبب أوقات إيقاظ الهاتف المحمول).
مع اتصالات TCP ، نبدأ بنافذة ازدحام صغيرة ونضاعفها لكل رحلة ذهاب وعودة. في الجولة الأولى ، يمكننا استيعاب 14 كيلوبايت. من: شبكة متصفح عالية الأداء بواسطة Ilya Grigorik. (معاينة كبيرة) ( ملاحظة : نظرًا لأن TCP بشكل عام لا يستخدم اتصال الشبكة بكمية كبيرة ، فقد طورت Google TCP Bottleneck Bandwidth و RRT ( BBR ) ، وهي خوارزمية للتحكم في تدفق TCP يتم التحكم فيها عن طريق التأخير. بدلاً من فقدان الحزم مثل TCP ، فهو أسرع بشكل ملحوظ ، مع إنتاجية أعلى وزمن انتقال أقل - وتعمل الخوارزمية بشكل مختلف. ( شكرًا ، فيكتور ، باري! )
من ناحية أخرى ، لدينا قيود على الأجهزة على الذاكرة ووحدة المعالجة المركزية بسبب تحليل JavaScript وأوقات التنفيذ (سنتحدث عنها بالتفصيل لاحقًا). لتحقيق الأهداف المذكورة في الفقرة الأولى ، علينا أن نأخذ في الاعتبار ميزانية حجم الملف الحرج لجافا سكريبت. تختلف الآراء حول ما يجب أن تكون عليه هذه الميزانية (وتعتمد بشكل كبير على طبيعة مشروعك) ، ولكن الميزانية التي تبلغ 170 كيلوبايت جافا سكريبت gzipped ستستغرق بالفعل ما يصل إلى 1 ثانية لتحليلها وتجميعها على هاتف متوسط المدى. بافتراض أن 170 كيلو بايت تتوسع إلى 3 × هذا الحجم عند فك الضغط (0.7 ميجا بايت) ، فقد يكون هذا بالفعل بمثابة ناقوس الموت لتجربة مستخدم "لائقة" على Moto G4 / G5 Plus.
في حالة موقع Wikipedia على الويب ، في عام 2020 ، أصبح تنفيذ الكود أسرع بنسبة 19٪ لمستخدمي ويكيبيديا. لذلك ، إذا ظلت مقاييس أداء الويب الخاصة بك على مدار العام ثابتًا ، فعادة ما تكون هذه علامة تحذير لأنك تتراجع بالفعل مع استمرار تحسن البيئة (التفاصيل في منشور مدونة بواسطة Gilles Dubuc).
إذا كنت ترغب في استهداف أسواق متنامية مثل جنوب شرق آسيا أو إفريقيا أو الهند ، فسيتعين عليك النظر في مجموعة مختلفة جدًا من القيود. يغطي Addy Osmani قيود الهاتف المميزة الرئيسية ، مثل عدد قليل من الأجهزة منخفضة التكلفة وعالية الجودة وعدم توفر شبكات عالية الجودة وبيانات الهاتف المحمول باهظة الثمن - جنبًا إلى جنب مع ميزانية PRPL-30 وإرشادات التطوير لهذه البيئات.
وفقًا لـ Addy Osmani ، فإن الحجم الموصى به للمسارات ذات التحميل البطيء أقل أيضًا من 35 كيلوبايت. (معاينة كبيرة) تقترح Addy Osmani ميزانية أداء PRPL-30 (30 كيلو بايت gzipped + حزمة أولية مصغرة) في حالة استهداف هاتف مميز. (معاينة كبيرة) في الواقع ، يوصي Alex Russell من Google باستهداف 130-170 كيلوبايت gzip كحد أعلى معقول. في سيناريوهات العالم الواقعي ، فإن معظم المنتجات ليست قريبة من هذا الحد: يبلغ متوسط حجم الحزمة اليوم حوالي 452 كيلوبايت ، وهو ما يزيد بنسبة 53.6٪ مقارنة بأوائل عام 2015. على جهاز محمول من الطبقة المتوسطة ، يستغرق ذلك 12-20 ثانية بالنسبة للوقت -تفاعلية .
معايير أداء وحدة المعالجة المركزية Geekbench للهواتف الذكية الأكثر مبيعًا على مستوى العالم في عام 2019. تؤكد JavaScript على الأداء أحادي النواة (تذكر ، أنها بطبيعتها أكثر ترابطًا فرديًا من بقية منصة الويب) وهي مرتبطة بوحدة المعالجة المركزية. من مقال Addy "تحميل صفحات الويب بسرعة على هاتف مميز بقيمة 20 دولارًا". (معاينة كبيرة) يمكننا أيضًا تجاوز ميزانية حجم الحزمة. على سبيل المثال ، يمكننا تعيين ميزانيات الأداء بناءً على أنشطة الخيط الرئيسي للمتصفح ، أي وقت الرسم قبل بدء التقديم ، أو تعقب خنازير وحدة المعالجة المركزية الأمامية. يمكن أن تساعدك أدوات مثل Caliber و SpeedCurve و Bundlesize في الحفاظ على ميزانياتك تحت السيطرة ، ويمكن دمجها في عملية البناء الخاصة بك.
أخيرًا ، ربما لا ينبغي أن تكون ميزانية الأداء قيمة ثابتة . اعتمادًا على اتصال الشبكة ، يجب أن تتكيف ميزانيات الأداء ، ولكن الحمل على اتصال أبطأ يكون أكثر "تكلفة" ، بغض النظر عن كيفية استخدامها.
ملاحظة : قد يبدو من الغريب تعيين مثل هذه الميزانيات الصارمة في أوقات انتشار HTTP / 2 على نطاق واسع ، و 5 G القادمة و HTTP / 3 ، والهواتف المحمولة سريعة التطور ومناطق SPA المزدهرة. ومع ذلك ، فإنها تبدو معقولة عندما نتعامل مع الطبيعة غير المتوقعة للشبكة والأجهزة ، بما في ذلك كل شيء من الشبكات المزدحمة إلى البنية التحتية المتطورة ببطء ، إلى حدود البيانات ، ومتصفحات الوكيل ، ووضع حفظ البيانات ، ورسوم التجوال المخادعة.


تعريف البيئة
- اختر وقم بإعداد أدوات البناء الخاصة بك.
لا تولي اهتمامًا كبيرًا لما يُفترض أنه رائع هذه الأيام. التزم ببيئتك للبناء ، سواء كانت Grunt أو Gulp أو Webpack أو Parcel أو مجموعة من الأدوات. طالما أنك تحصل على النتائج التي تحتاجها وليس لديك مشاكل في الحفاظ على عملية البناء ، فأنت على ما يرام.من بين أدوات البناء ، يستمر Rollup في اكتساب قوة دفع ، وكذلك Snowpack ، ولكن يبدو أن Webpack هو الأكثر رسوخًا ، مع مئات المكونات الإضافية المتاحة لتحسين حجم البنيات الخاصة بك. احترس من Webpack Roadmap 2021.
واحدة من أبرز الاستراتيجيات التي ظهرت مؤخرًا هي التقسيم الحبيبي باستخدام Webpack في Next.js و Gatsby لتقليل الكود المكرر. بشكل افتراضي ، يمكن طلب الوحدات النمطية التي لم تتم مشاركتها في كل نقطة إدخال للمسارات التي لا تستخدمها. ينتهي الأمر بأن يصبح هذا عبئًا حيث يتم تنزيل المزيد من التعليمات البرمجية أكثر من اللازم. باستخدام التقسيم الحبيبي في Next.js ، يمكننا استخدام ملف بيان بناء من جانب الخادم لتحديد الأجزاء الناتجة التي يتم استخدامها بواسطة نقاط إدخال مختلفة.
لتقليل الكود المكرر في مشاريع Webpack ، يمكننا استخدام التقسيم الدقيق ، المُمكّن في Next.js و Gatsby افتراضيًا. رصيد الصورة: آدي عثماني. (معاينة كبيرة) باستخدام SplitChunksPlugin ، يتم إنشاء مجموعات مقسمة متعددة بناءً على عدد من الشروط لمنع جلب رمز مكرر عبر مسارات متعددة. يؤدي ذلك إلى تحسين وقت تحميل الصفحة والتخزين المؤقت أثناء التنقل. تم الشحن في Next.js 9.2 وفي Gatsby v2.20.7.
قد يكون بدء استخدام Webpack صعبًا. لذلك إذا كنت تريد الغوص في Webpack ، فهناك بعض الموارد الرائعة المتوفرة:
- وثائق Webpack - من الواضح - هي نقطة بداية جيدة ، وكذلك Webpack - The Confusing Bits بواسطة Raja Rao و Annotated Webpack Config by Andrew Welch.
- لدى Sean Larkin دورة تدريبية مجانية على Webpack: The Core Concepts وأصدر Jeffrey Way دورة مجانية رائعة على Webpack للجميع. كلاهما مقدمات رائعة للغوص في Webpack.
- أساسيات Webpack هي دورة تدريبية شاملة لمدة 4 ساعات مع Sean Larkin ، صادرة عن FrontendMasters.
- تحتوي أمثلة Webpack على المئات من تكوينات Webpack الجاهزة للاستخدام ، مصنفة حسب الموضوع والغرض. المكافأة: هناك أيضًا مُكوِّن Webpack يقوم بإنشاء ملف تكوين أساسي.
- awesome-webpack عبارة عن قائمة منظمة من موارد Webpack المفيدة والمكتبات والأدوات ، بما في ذلك المقالات ومقاطع الفيديو والدورات التدريبية والكتب والأمثلة لمشاريع Angular و React والحيادية لإطار العمل.
- رحلة بناء أصول الإنتاج السريع مع Webpack هي دراسة حالة Etsy حول كيفية تحول الفريق من استخدام نظام بناء JavaScript قائم على RequireJS إلى استخدام Webpack وكيف قاموا بتحسين تصميماتهم ، وإدارة أكثر من 13200 أصل في 4 دقائق في المتوسط.
- نصائح أداء Webpack عبارة عن خيط منجم ذهب من إعداد Ivan Akulov ، ويضم العديد من النصائح التي تركز على الأداء ، بما في ذلك تلك التي تركز بشكل خاص على Webpack.
- awesome-webpack-perf عبارة عن مستودع GitHub منجم ذهب مع أدوات Webpack المفيدة والمكونات الإضافية للأداء. تحتفظ بها أيضا إيفان أكولوف.

- استخدم التحسين التدريجي كخيار افتراضي.
ومع ذلك ، بعد كل هذه السنوات ، فإن الحفاظ على التحسين التدريجي كمبدأ إرشادي لهندسة الواجهة الأمامية ونشرها يعد رهانًا آمنًا. صمم التجربة الأساسية وقم ببنائها أولاً ، ثم عزز التجربة بميزات متقدمة للمتصفحات القادرة ، وخلق تجارب مرنة. إذا كان موقع الويب الخاص بك يعمل بسرعة على جهاز بطيء مع شاشة ضعيفة في متصفح رديء على شبكة دون المستوى الأمثل ، فلن يعمل إلا بشكل أسرع على جهاز سريع مع متصفح جيد على شبكة مناسبة.في الواقع ، مع خدمة الوحدات التكيفية ، يبدو أننا نأخذ التحسينات التدريجية إلى مستوى آخر ، ونقدم تجارب أساسية "خفيفة" للأجهزة منخفضة الجودة ، ونعززها بميزات أكثر تعقيدًا للأجهزة المتطورة. من غير المحتمل أن يتلاشى التحسين التدريجي في أي وقت قريبًا.
- اختر أساس أداء قوي.
مع وجود الكثير من الأشياء المجهولة التي تؤثر على التحميل - الشبكة ، والاختناق الحراري ، وإخلاء ذاكرة التخزين المؤقت ، والبرامج النصية التابعة لجهات خارجية ، وأنماط حظر المحلل اللغوي ، و I / O القرص ، ووقت استجابة IPC ، والإضافات المثبتة ، وبرامج مكافحة الفيروسات والجدران النارية ، ومهام وحدة المعالجة المركزية في الخلفية ، وقيود الأجهزة والذاكرة ، الاختلافات في التخزين المؤقت L2 / L3 ، RTTS - تمتلك JavaScript أثقل تكلفة للتجربة ، بجانب خطوط الويب التي تمنع العرض افتراضيًا والصور التي غالبًا ما تستهلك قدرًا كبيرًا من الذاكرة. مع انتقال الاختناقات في الأداء بعيدًا عن الخادم إلى العميل ، كمطورين ، يتعين علينا النظر في كل هذه الأشياء المجهولة بمزيد من التفصيل.بميزانية تبلغ 170 كيلوبايت تحتوي بالفعل على المسار الحرج HTML / CSS / JavaScript ، وجهاز التوجيه ، وإدارة الحالة ، والأدوات المساعدة ، وإطار العمل ، ومنطق التطبيق ، يتعين علينا إجراء فحص شامل لتكلفة نقل الشبكة ، ووقت التحليل / التجميع ، وتكلفة وقت التشغيل من إطار اختيارنا. لحسن الحظ ، شهدنا تحسنًا كبيرًا خلال السنوات القليلة الماضية في مدى سرعة المتصفحات في تحليل النصوص البرمجية وتجميعها. ومع ذلك ، لا يزال تنفيذ JavaScript هو العقبة الرئيسية ، لذا فإن الاهتمام الشديد بوقت تنفيذ البرنامج النصي والشبكة يمكن أن يكون له تأثير كبير.
أجرى Tim Kadlec بحثًا رائعًا حول أداء الأطر الحديثة ، ولخصها في مقال "أطر JavaScript لها تكلفة". غالبًا ما نتحدث عن تأثير الأطر المستقلة ، ولكن كما يلاحظ تيم ، من الناحية العملية ، ليس من غير المألوف استخدام أطر عمل متعددة . ربما يتم ترحيل إصدار أقدم من jQuery ببطء إلى إطار عمل حديث ، إلى جانب بعض التطبيقات القديمة التي تستخدم إصدارًا أقدم من Angular. لذلك من المنطقي أكثر استكشاف التكلفة التراكمية لبايتات JavaScript ووقت تنفيذ وحدة المعالجة المركزية التي يمكن أن تجعل تجارب المستخدم بالكاد قابلة للاستخدام ، حتى على الأجهزة المتطورة.
بشكل عام ، لا تعطي الأطر الحديثة الأولوية للأجهزة الأقل قوة ، لذلك غالبًا ما تكون التجارب على الهاتف وعلى سطح المكتب مختلفة بشكل كبير من حيث الأداء. وفقًا للبحث ، تقضي المواقع التي تحتوي على React أو Angular وقتًا أطول على وحدة المعالجة المركزية أكثر من غيرها (وهو بالطبع لا يعني بالضرورة أن React أكثر تكلفة على وحدة المعالجة المركزية من Vue.js).
وفقًا لتيم ، هناك شيء واحد واضح: "إذا كنت تستخدم إطار عمل لبناء موقعك ، فأنت تقوم بمقايضة من حيث الأداء الأولي - حتى في أفضل السيناريوهات."


- تقييم الأطر والتبعيات.
الآن ، لا يحتاج كل مشروع إلى إطار عمل ولا تحتاج كل صفحة من صفحات تطبيق أحادي الصفحة إلى تحميل إطار عمل. في حالة Netflix ، "أدت إزالة React والعديد من المكتبات ورمز التطبيق المقابل من جانب العميل إلى تقليل إجمالي كمية JavaScript بأكثر من 200 كيلوبايت ، مما تسبب في تقليل وقت التفاعل على Netflix للصفحة الرئيسية التي تم تسجيل الخروج منها بنسبة تزيد عن 50٪ . " ثم استغل الفريق الوقت الذي يقضيه المستخدمون على الصفحة المقصودة لجلب React مسبقًا للصفحات اللاحقة التي من المحتمل أن يهبط عليها المستخدمون (اقرأ للحصول على التفاصيل).إذن ماذا لو قمت بإزالة إطار عمل موجود من الصفحات الهامة تمامًا؟ باستخدام Gatsby ، يمكنك التحقق من gatsby-plugin-no-javascript الذي يزيل جميع ملفات JavaScript التي أنشأها Gatsby من ملفات HTML الثابتة. في Vercel ، يمكنك أيضًا السماح بتعطيل وقت تشغيل JavaScript في الإنتاج لصفحات معينة (تجريبية).
بمجرد اختيار إطار العمل ، سنبقى معه لبضع سنوات على الأقل ، لذلك إذا احتجنا إلى استخدام واحد ، فنحن بحاجة إلى التأكد من أن اختيارنا مدروس ومدروس جيدًا - وهذا ينطبق بشكل خاص على مقاييس الأداء الرئيسية التي اهتم ب.
تُظهر البيانات أن الأطر ، افتراضيًا ، باهظة الثمن: 58.6٪ من صفحات React تشحن أكثر من 1 ميغابايت من JavaScript ، و 36٪ من تحميلات صفحات Vue.js بها أول محتوى محتوى <1.5 ثانية. وفقًا لدراسة أجراها Ankur Sethi ، " لن يتم تحميل تطبيق React الخاص بك مطلقًا أسرع من حوالي 1.1 ثانية على هاتف متوسط في الهند ، بغض النظر عن مدى تحسينه. سيستغرق تشغيل تطبيق Angular 2.7 ثانية على الأقل. The سيحتاج مستخدمو تطبيق Vue إلى الانتظار لمدة ثانية واحدة على الأقل قبل أن يتمكنوا من البدء في استخدامه. " قد لا تستهدف الهند كسوقك الأساسي على أي حال ، لكن المستخدمين الذين يصلون إلى موقعك بظروف شبكة دون المستوى الأمثل سيكون لديهم تجربة مماثلة.
بالطبع من الممكن جعل SPAs سريعة ، لكنها ليست سريعة خارج الصندوق ، لذلك نحن بحاجة إلى حساب الوقت والجهد اللازمين لإنجازها والحفاظ عليها بسرعة. من المحتمل أن يكون الأمر أسهل من خلال اختيار تكلفة أداء أساسية خفيفة الوزن في وقت مبكر.
إذن كيف نختار إطار العمل ؟ من الجيد مراعاة التكلفة الإجمالية على الحجم + أوقات التنفيذ الأولية على الأقل قبل اختيار أحد الخيارات ؛ خيارات خفيفة الوزن مثل Preact أو Inferno أو Vue أو Svelte أو Alpine أو Polymer يمكن أن تنجز المهمة على ما يرام. سيحدد حجم خط الأساس الخاص بك قيود كود التطبيق الخاص بك.
كما لاحظ سيب ماركاج ، فإن الطريقة الجيدة لقياس تكاليف بدء التشغيل لأطر العمل هي تقديم عرض أولاً ، ثم حذفه ثم عرضه مرة أخرى لأنه يمكن أن يخبرك بكيفية تحجيم إطار العمل. يميل التصيير الأول إلى إحماء مجموعة من التعليمات البرمجية المجمعة بشكل كسول ، والتي يمكن لشجرة أكبر الاستفادة منها عندما تتوسع. العرض الثاني هو في الأساس محاكاة لكيفية تأثير إعادة استخدام الكود على الصفحة في خصائص الأداء مع زيادة تعقيد الصفحة.
يمكنك الذهاب إلى أبعد من تقييم المرشحين (أو أي مكتبة JavaScript بشكل عام) على نظام درجات مقياس 12 نقطة من Sacha Greif من خلال استكشاف الميزات ، وإمكانية الوصول ، والاستقرار ، والأداء ، والنظام البيئي للحزمة ، والمجتمع ، ومنحنى التعلم ، والتوثيق ، والأدوات ، وسجل المسار التوافق والأمن على سبيل المثال.
يتتبع Perf Track أداء إطار العمل على نطاق واسع. (معاينة كبيرة) يمكنك أيضًا الاعتماد على البيانات التي تم جمعها على الويب على مدار فترة زمنية أطول. على سبيل المثال ، يتتبع Perf Track أداء إطار العمل على نطاق واسع ، ويعرض نتائج Core Web Vitals المجمعة من الأصل لمواقع الويب المبنية في Angular و React و Vue و Polymer و Preact و Ember و Svelte و AMP. يمكنك حتى تحديد ومقارنة مواقع الويب التي تم إنشاؤها باستخدام Gatsby أو Next.js أو Create React App ، بالإضافة إلى مواقع الويب التي تم إنشاؤها باستخدام Nuxt.js (Vue) أو Sapper (Svelte).
نقطة البداية الجيدة هي اختيار مكدس افتراضي جيد لتطبيقك . توفر Gatsby (React) و Next.js (React) و Vuepress (Vue) و Preact CLI و PWA Starter Kit إعدادات افتراضية معقولة للتحميل السريع خارج الصندوق على متوسط الأجهزة المحمولة. ألقِ نظرة أيضًا على إرشادات الأداء الخاصة بإطار عمل web.dev لـ React و Angular ( شكرًا ، Phillip! ).
وربما يمكنك اتباع نهج أكثر تحديثًا قليلاً لإنشاء تطبيقات ذات صفحة واحدة تمامًا - Turbolinks ، مكتبة جافا سكريبت بحجم 15 كيلوبايت تستخدم HTML بدلاً من JSON لعرض طرق العرض. لذلك عندما تتبع رابطًا ، تقوم Turbolinks تلقائيًا بجلب الصفحة وتبديلها في
<body>
ودمج<head>
الخاص بها ، كل ذلك دون تكبد تكلفة تحميل صفحة كاملة. يمكنك التحقق من البيانات السريعة والوثائق الكاملة حول المكدس (Hotwire).

- التقديم من جانب العميل أو التقديم من جانب الخادم؟ كلاهما!
هذه محادثة ساخنة للغاية. تتمثل الطريقة النهائية في إعداد نوع من التمهيد التدريجي: استخدم العرض من جانب الخادم للحصول على First Contenful Paint سريعًا ، ولكن قم أيضًا بتضمين بعض جافا سكريبت الضرورية للحفاظ على وقت التفاعل بالقرب من First Contentful Paint. إذا تأخر JavaScript بعد FCP ، فسيقفل المتصفح الخيط الرئيسي أثناء تحليل وتجميع وتنفيذ JavaScript المكتشف مؤخرًا ، وبالتالي تقييد تفاعل الموقع أو التطبيق.لتجنب ذلك ، قم دائمًا بتقسيم تنفيذ الوظائف إلى مهام منفصلة وغير متزامنة ، وحيثما أمكن استخدام
requestIdleCallback
. ضع في اعتبارك أجزاء التحميل البطيئة لواجهة المستخدم باستخدام دعمimport()
الديناميكي لـ WebPack ، وتجنب التحميل والتحليل والتجميع حتى يحتاج المستخدمون إليها حقًا ( شكرًا Addy! ).كما ذكرنا أعلاه ، يخبرنا Time to Interactive (TTI) بالوقت بين التنقل والتفاعل. بالتفصيل ، يتم تحديد المقياس من خلال النظر في أول نافذة مدتها خمس ثوانٍ بعد عرض المحتوى الأولي ، حيث لا تستغرق مهام JavaScript أكثر من 50 مللي ثانية ( مهام طويلة ). في حالة حدوث مهمة تزيد مدتها عن 50 مللي ثانية ، يبدأ البحث عن نافذة مدتها خمس ثوانٍ من جديد. نتيجة لذلك ، سيفترض المتصفح أولاً أنه وصل إلى Interactive ، فقط للتبديل إلى Frozen ، فقط للعودة في النهاية إلى Interactive .
بمجرد وصولنا إلى Interactive ، يمكننا بعد ذلك - إما عند الطلب أو كما يسمح الوقت - تمهيد الأجزاء غير الأساسية من التطبيق. لسوء الحظ ، كما لاحظ Paul Lewis ، لا تحتوي الأطر عادةً على مفهوم بسيط للأولوية يمكن أن يظهر للمطورين ، وبالتالي ليس من السهل تنفيذ التمهيد التدريجي مع معظم المكتبات والأطر.
مع ذلك ، نحن نصل إلى هناك. يوجد في هذه الأيام خياران يمكننا استكشافهما ، ويقدم كل من حسين جرده وجيسون ميلر نظرة عامة ممتازة على هذه الخيارات في حديثهما عن Rendering on the Web وكتابة Jason و Addy عن Modern Front-End Architectures. النظرة العامة أدناه تستند إلى عملهم الممتاز.
- العرض الكامل من جانب الخادم (SSR)
في SSR الكلاسيكي ، مثل WordPress ، تتم معالجة جميع الطلبات بالكامل على الخادم. يتم إرجاع المحتوى المطلوب كصفحة HTML منتهية ويمكن للمتصفحات عرضها على الفور. وبالتالي ، لا يمكن لتطبيقات SSR الاستفادة من واجهات برمجة تطبيقات DOM ، على سبيل المثال. عادة ما تكون الفجوة بين First Contentful Paint و Time to Interactive صغيرة ، ويمكن عرض الصفحة على الفور أثناء دفق HTML إلى المتصفح.هذا يتجنب رحلات الذهاب والإياب الإضافية لجلب البيانات والقوالب على العميل ، حيث يتم التعامل معها قبل أن يتلقى المتصفح استجابة. ومع ذلك ، فإننا ننتهي مع وقت أطول للتفكير في الخادم وبالتالي الوقت للبايت الأول ولا نستفيد من الميزات الغنية والمتجاوبة للتطبيقات الحديثة.
- عرض ثابت
نحن نبني المنتج كتطبيق صفحة واحدة ، ولكن يتم عرض جميع الصفحات مسبقًا إلى HTML ثابت مع الحد الأدنى من JavaScript كخطوة بناء. هذا يعني أنه من خلال العرض الثابت ، فإننا ننتج ملفات HTML فردية لكل عنوان URL محتمل مسبقًا ، وهو أمر لا تستطيع العديد من التطبيقات تحمله. ولكن نظرًا لأنه لا يلزم إنشاء HTML لصفحة ما بشكل سريع ، يمكننا تحقيق وقت سريع باستمرار للبايت الأول. وبالتالي ، يمكننا عرض الصفحة المقصودة بسرعة ثم إحضار إطار عمل SPA مسبقًا للصفحات اللاحقة. تبنت Netflix هذا الأسلوب لتقليل التحميل ووقت التفاعل بنسبة 50٪. - التقديم من جانب الخادم مع (إعادة) الترطيب (عرض عام ، SSR + CSR)
يمكننا محاولة استخدام أفضل ما في العالمين - مقاربات SSR و CSR. مع الترطيب في المزيج ، تحتوي صفحة HTML التي يتم إرجاعها من الخادم أيضًا على برنامج نصي يقوم بتحميل تطبيق كامل من جانب العميل. من الناحية المثالية ، يحقق ذلك رسمًا سريعًا للمحتوى الأول (مثل SSR) ثم يستمر في التقديم باستخدام (إعادة) الترطيب. لسوء الحظ ، هذا نادرًا ما يحدث. في كثير من الأحيان ، تبدو الصفحة جاهزة ولكنها لا تستطيع الاستجابة لإدخالات المستخدم ، مما ينتج عنه نقرات غاضبة وتجاهل.باستخدام React ، يمكننا استخدام وحدة
ReactDOMServer
على خادم Node مثل Express ، ثم استدعاء طريقةrenderToString
لتقديم مكونات المستوى الأعلى كسلسلة HTML ثابتة.باستخدام Vue.js ، يمكننا استخدام عارض خادم vue لتقديم مثيل Vue إلى HTML باستخدام
renderToString
. في Angular ، يمكننا استخدام@nguniversal
لتحويل طلبات العميل إلى صفحات HTML معروضة بالكامل على الخادم. يمكن أيضًا تحقيق تجربة عرض الخادم بالكامل بشكل خارج الصندوق باستخدام Next.js (React) أو Nuxt.js (Vue).النهج له سلبيات. نتيجة لذلك ، نكتسب المرونة الكاملة للتطبيقات من جانب العميل مع توفير عرض أسرع من جانب الخادم ، ولكننا في نهاية المطاف أيضًا مع وجود فجوة أطول بين First Contentful Paint و Time To Interactive وزيادة تأخير الإدخال الأول. معالجة الجفاف باهظة الثمن ، وعادة ما لن تكون هذه الإستراتيجية بمفردها جيدة بما يكفي لأنها تؤخر بشدة وقت التفاعل.
- عرض جانب الخادم المتدفق مع الترطيب التدريجي (SSR + CSR)
لتقليل الفجوة بين Time To Interactive و First Contentful Paint ، نقدم طلبات متعددة في وقت واحد ونرسل المحتوى في أجزاء عند إنشائها. لذلك لا يتعين علينا انتظار سلسلة HTML الكاملة قبل إرسال المحتوى إلى المتصفح ، وبالتالي تحسين Time To First Byte.في React ، بدلاً من
renderToString()
، يمكننا استخدام renderToNodeStream () لتوجيه الاستجابة وإرسال HTML في أجزاء. في Vue ، يمكننا استخدام renderToStream () يمكن توجيهه وبثه. مع React Suspense ، قد نستخدم العرض غير المتزامن لهذا الغرض أيضًا.من جانب العميل ، بدلاً من تشغيل التطبيق بالكامل مرة واحدة ، نقوم بتشغيل المكونات تدريجياً . يتم تقسيم أقسام التطبيقات أولاً إلى نصوص برمجية قائمة بذاتها مع تقسيم الكود ، ثم يتم ترطيبها تدريجياً (بترتيب أولوياتنا). في الواقع ، يمكننا ترطيب المكونات الحرجة أولاً ، بينما يمكن ترطيب الباقي لاحقًا. يمكن بعد ذلك تحديد دور العرض من جانب العميل ومن جانب الخادم بشكل مختلف لكل مكون. يمكننا بعد ذلك أيضًا تأجيل ترطيب بعض المكونات إلى أن تظهر أو تكون ضرورية لتفاعل المستخدم أو عندما يكون المتصفح في وضع الخمول.
بالنسبة إلى Vue ، نشر Markus Oberlehner دليلًا حول تقليل الوقت اللازم للتفاعل مع تطبيقات SSR باستخدام الترطيب على تفاعل المستخدم بالإضافة إلى vue-lazy-hydration ، وهو مكون إضافي في المرحلة المبكرة يتيح ترطيب المكونات على الرؤية أو تفاعل مستخدم محدد. يعمل فريق Angular على الترطيب التدريجي مع Ivy Universal. يمكنك تطبيق الترطيب الجزئي باستخدام Preact و Next.js أيضًا.
- عرض ثلاثي الأشكال
مع وجود عمال الخدمة في مكانهم الصحيح ، يمكننا استخدام عرض الخادم المتدفق للتنقل الأولي / غير التابع لـ JS ، ومن ثم جعل عامل الخدمة يأخذ عرض HTML للتنقل بعد تثبيته. في هذه الحالة ، يقوم عامل الخدمة بعرض المحتوى مسبقًا وتمكين التنقلات بأسلوب SPA لعرض طرق عرض جديدة في نفس الجلسة. يعمل بشكل جيد عندما يمكنك مشاركة نفس رمز القوالب والتوجيه بين الخادم وصفحة العميل وعامل الخدمة.
عرض ثلاثي الأشكال ، مع تقديم نفس الشفرة في أي 3 أماكن: على الخادم أو في DOM أو في عامل الخدمة. (مصدر الصورة: Google Developers) (معاينة كبيرة) - المسؤولية الاجتماعية للشركات مع العرض المسبق
يشبه العرض المسبق التقديم من جانب الخادم ولكن بدلاً من عرض الصفحات على الخادم ديناميكيًا ، فإننا نعرض التطبيق إلى HTML ثابت في وقت الإنشاء. بينما تكون الصفحات الثابتة تفاعلية بالكامل بدون الكثير من جافا سكريبت من جانب العميل ، فإن العرض المسبق يعمل بشكل مختلف . بشكل أساسي ، يلتقط الحالة الأولية لتطبيق من جانب العميل مثل HTML ثابت في وقت الإنشاء ، بينما مع العرض المسبق ، يجب تمهيد التطبيق على العميل حتى تكون الصفحات تفاعلية.باستخدام Next.js ، يمكننا استخدام تصدير HTML الثابت عن طريق عرض التطبيق مسبقًا على HTML ثابت. في Gatsby ، منشئ موقع ثابت مفتوح المصدر يستخدم React ، يستخدم طريقة
renderToStaticMarkup
بدلاً من طريقةrenderToString
أثناء عمليات الإنشاء ، مع تحميل جزء JS الرئيسي مسبقًا ويتم جلب المسارات المستقبلية مسبقًا ، بدون سمات DOM غير المطلوبة للصفحات الثابتة البسيطة.بالنسبة إلى Vue ، يمكننا استخدام Vuepress لتحقيق نفس الهدف. يمكنك أيضًا استخدام أداة التحميل المسبق مع Webpack. يوفر Navi عرضًا ثابتًا أيضًا.
والنتيجة هي وقت أفضل للبايت الأول و First Contentful Paint ، ونعمل على تقليل الفجوة بين Time To Interactive و First Contentful Paint. لا يمكننا استخدام النهج إذا كان من المتوقع أن يتغير المحتوى كثيرًا. بالإضافة إلى ذلك ، يجب أن تكون جميع عناوين URL معروفة مسبقًا لإنشاء جميع الصفحات. لذلك قد يتم عرض بعض المكونات باستخدام العرض المسبق ، ولكن إذا احتجنا إلى شيء ديناميكي ، فعلينا الاعتماد على التطبيق لجلب المحتوى.
- العرض الكامل من جانب العميل (CSR)
تتم جميع عمليات المنطق والتقديم والتمهيد على العميل. تكون النتيجة عادةً فجوة كبيرة بين Time To Interactive و First Contentful Paint. نتيجة لذلك ، غالبًا ما تشعر التطبيقات بالبطء حيث يجب تشغيل التطبيق بالكامل على العميل لتقديم أي شيء.نظرًا لأن JavaScript لها تكلفة أداء ، نظرًا لأن مقدار JavaScript ينمو مع تطبيق ما ، فإن تقسيم التعليمات البرمجية وتأجيلها القوي لـ JavaScript سيكون بالضرورة بالتأكيد لترويض تأثير JavaScript. في مثل هذه الحالات ، سيكون التقديم من جانب الخادم عادةً نهجًا أفضل في حالة عدم الحاجة إلى قدر كبير من التفاعل. إذا لم يكن خيارًا متاحًا ، ففكر في استخدام App Shell Model.
بشكل عام ، يعد SSR أسرع من CSR. ومع ذلك ، فإنه لا يزال تطبيقًا متكررًا للعديد من التطبيقات الموجودة هناك.
إذن ، من جانب العميل أم من جانب الخادم؟ بشكل عام ، من الجيد قصر استخدام أطر عمل من جانب العميل بالكامل على الصفحات التي تتطلبها تمامًا. بالنسبة للتطبيقات المتقدمة ، ليس من الجيد الاعتماد على العرض من جانب الخادم وحده أيضًا. يعتبر كل من عرض الخادم وتقديم العميل كارثة إذا تم إجراؤها بشكل سيء.
سواء كنت تميل نحو CSR أو SSR ، تأكد من أنك تعرض وحدات البكسل المهمة في أسرع وقت ممكن وتقليل الفجوة بين هذا العرض و Time To Interactive. ضع في اعتبارك العرض المسبق إذا لم تتغير صفحاتك كثيرًا ، وقم بتأجيل تمهيد الأطر إذا استطعت. قم بدفق HTML في أجزاء من خلال العرض من جانب الخادم ، وقم بتنفيذ الترطيب التدريجي للعرض من جانب العميل - وقم بالترطيب عند الرؤية أو التفاعل أو أثناء وقت الخمول للحصول على أفضل ما في كلا العالمين.
- العرض الكامل من جانب الخادم (SSR)


- كم يمكننا تقديم الخدمة بشكل ثابت؟
سواء كنت تعمل على تطبيق كبير أو موقع صغير ، يجدر بك التفكير في المحتوى الذي يمكن تقديمه بشكل ثابت من CDN (مثل JAM Stack) ، بدلاً من إنشائه ديناميكيًا بشكل سريع. حتى إذا كان لديك الآلاف من المنتجات ومئات المرشحات مع الكثير من خيارات التخصيص ، فقد لا تزال ترغب في خدمة صفحاتك المقصودة المهمة بشكل ثابت ، وفصل هذه الصفحات عن إطار العمل الذي تختاره.هناك الكثير من مولدات المواقع الثابتة وغالبًا ما تكون الصفحات التي تنشئها سريعة جدًا. The more content we can pre-build ahead of time instead of generating page views on a server or client at request time, the better performance we will achieve.
In Building Partially Hydrated, Progressively Enhanced Static Websites, Markus Oberlehner shows how to build out websites with a static site generator and an SPA, while achieving progressive enhancement and a minimal JavaScript bundle size. Markus uses Eleventy and Preact as his tools, and shows how to set up the tools, add partial hydration, lazy hydration, client entry file, configure Babel for Preact and bundle Preact with Rollup — from start to finish.
With JAMStack used on large sites these days, a new performance consideration appeared: the build time . In fact, building out even thousands of pages with every new deploy can take minutes, so it's promising to see incremental builds in Gatsby which improve build times by 60 times , with an integration into popular CMS solutions like WordPress, Contentful, Drupal, Netlify CMS and others.
Incremental static regeneration with Next.js. (Image credit: Prisma.io) (Large preview) Also, Next.js announced ahead-of-time and incremental static generation, which allows us to add new static pages at runtime and update existing pages after they've been already built, by re-rendering them in the background as traffic comes in.
Need an even more lightweight approach? In his talk on Eleventy, Alpine and Tailwind: towards a lightweight Jamstack, Nicola Goutay explains the differences between CSR, SSR and everything-in-between, and shows how to use a more lightweight approach — along with a GitHub repo that shows the approach in practice.
- Consider using PRPL pattern and app shell architecture.
Different frameworks will have different effects on performance and will require different strategies of optimization, so you have to clearly understand all of the nuts and bolts of the framework you'll be relying on. When building a web app, look into the PRPL pattern and application shell architecture. The idea is quite straightforward: Push the minimal code needed to get interactive for the initial route to render quickly, then use service worker for caching and pre-caching resources and then lazy-load routes that you need, asynchronously.


- Have you optimized the performance of your APIs?
APIs are communication channels for an application to expose data to internal and third-party applications via endpoints . When designing and building an API, we need a reasonable protocol to enable the communication between the server and third-party requests. Representational State Transfer ( REST ) is a well-established, logical choice: it defines a set of constraints that developers follow to make content accessible in a performant, reliable and scalable fashion. Web services that conform to the REST constraints, are called RESTful web services .As with good ol' HTTP requests, when data is retrieved from an API, any delay in server response will propagate to the end user, hence delaying rendering . When a resource wants to retrieve some data from an API, it will need to request the data from the corresponding endpoint. A component that renders data from several resources, such as an article with comments and author photos in each comment, may need several roundtrips to the server to fetch all the data before it can be rendered. Furthermore, the amount of data returned through REST is often more than what is needed to render that component.
If many resources require data from an API, the API might become a performance bottleneck. GraphQL provides a performant solution to these issues. Per se, GraphQL is a query language for your API, and a server-side runtime for executing queries by using a type system you define for your data. Unlike REST, GraphQL can retrieve all data in a single request , and the response will be exactly what is required, without over or under -fetching data as it typically happens with REST.
In addition, because GraphQL is using schema (metadata that tells how the data is structured), it can already organize data into the preferred structure, so, for example, with GraphQL, we could remove JavaScript code used for dealing with state management, producing a cleaner application code that runs faster on the client.
If you want to get started with GraphQL or encounter performance issues, these articles might be quite helpful:
- A GraphQL Primer: Why We Need A New Kind Of API by Eric Baer,
- A GraphQL Primer: The Evolution Of API Design by Eric Baer,
- Designing a GraphQL server for optimal performance by Leonardo Losoviz,
- GraphQL performance explained by Wojciech Trocki.

- Will you be using AMP or Instant Articles?
Depending on the priorities and strategy of your organization, you might want to consider using Google's AMP or Facebook's Instant Articles or Apple's Apple News. You can achieve good performance without them, but AMP does provide a solid performance framework with a free content delivery network (CDN), while Instant Articles will boost your visibility and performance on Facebook.The seemingly obvious benefit of these technologies for users is guaranteed performance , so at times they might even prefer AMP-/Apple News/Instant Pages-links over "regular" and potentially bloated pages. For content-heavy websites that are dealing with a lot of third-party content, these options could potentially help speed up render times dramatically.
Unless they don't. According to Tim Kadlec, for example, "AMP documents tend to be faster than their counterparts, but they don't necessarily mean a page is performant. AMP is not what makes the biggest difference from a performance perspective."
A benefit for the website owner is obvious: discoverability of these formats on their respective platforms and increased visibility in search engines.
Well, at least that's how it used to be. As AMP is no longer a requirement for Top Stories , publishers might be moving away from AMP to a traditional stack instead ( thanks, Barry! ).
Still, you could build progressive web AMPs, too, by reusing AMPs as a data source for your PWA. Downside? Obviously, a presence in a walled garden places developers in a position to produce and maintain a separate version of their content, and in case of Instant Articles and Apple News without actual URLs (thanks Addy, Jeremy!) .
- Choose your CDN wisely.
As mentioned above, depending on how much dynamic data you have, you might be able to "outsource" some part of the content to a static site generator, pushing it to a CDN and serving a static version from it, thus avoiding requests to the server. In fact, some of those generators are actually website compilers with many automated optimizations provided out of the box. As compilers add optimizations over time, the compiled output gets smaller and faster over time.Notice that CDNs can serve (and offload) dynamic content as well. So, restricting your CDN to static assets is not necessary. Double-check whether your CDN performs compression and conversion (eg image optimization and resizing at the edge), whether they provide support for servers workers, A/B testing, as well as edge-side includes, which assemble static and dynamic parts of pages at the CDN's edge (ie the server closest to the user), and other tasks. Also, check if your CDN supports HTTP over QUIC (HTTP/3).
Katie Hempenius has written a fantastic guide to CDNs that provides insights on how to choose a good CDN , how to finetune it and all the little things to keep in mind when evaluating one. In general, it's a good idea to cache content as aggressively as possible and enable CDN performance features like Brotli, TLS 1.3, HTTP/2, and HTTP/3.
Note : based on research by Patrick Meenan and Andy Davies, HTTP/2 prioritization is effectively broken on many CDNs, so be careful when choosing a CDN. Patrick has more details in his talk on HTTP/2 Prioritization ( thanks, Barry! ).
CDNPerf measures query speed for CDNs by gathering and analyzing 300 million tests every day. (معاينة كبيرة) When choosing a CDN, you can use these comparison sites with a detailed overview of their features:
- مقارنة CDN ، مصفوفة مقارنة CDN لكل من Cloudfront و Aazure و KeyCDN و Fastly و Verizon و Stackpach و Akamai وغيرها الكثير.
- يقيس CDN Perf سرعة الاستعلام لشبكات CDN من خلال جمع وتحليل 300 مليون اختبار كل يوم ، مع استناد جميع النتائج إلى بيانات RUM من المستخدمين في جميع أنحاء العالم. تحقق أيضًا من مقارنة أداء DNS ومقارنة أداء السحابة.
- توفر CDN Planet Guides نظرة عامة على شبكات CDN لموضوعات محددة ، مثل Serve Stale و Purge و Origin Shield والجلب المسبق والضغط.
- تقويم الويب: يوفر اعتماد واستخدام CDN رؤى حول أفضل مزودي شبكات CDN ، وإدارة RTT و TLS الخاصة بهم ، ووقت تفاوض TLS ، واعتماد HTTP / 2 وغيرها. (لسوء الحظ ، البيانات من عام 2019 فقط).
تحسينات الأصول
- استخدم Brotli لضغط النص العادي.
في عام 2015 ، قدمت Google تنسيق Brotli ، وهو تنسيق بيانات جديد مفتوح المصدر بدون فقدان البيانات ، وهو مدعوم الآن في جميع المتصفحات الحديثة. مكتبة Brotli مفتوحة المصدر ، والتي تنفذ برنامج تشفير وفك تشفير لـ Brotli ، لديها 11 مستوى جودة محدد مسبقًا لبرنامج التشفير ، مع مستوى جودة أعلى يتطلب المزيد من وحدة المعالجة المركزية في مقابل نسبة ضغط أفضل. سيؤدي الضغط الأبطأ في النهاية إلى معدلات ضغط أعلى ، ومع ذلك ، لا يزال Brotli يفك الضغط بسرعة. تجدر الإشارة إلى أن Brotli بمستوى الضغط 4 أصغر حجمًا ويتم ضغطه بشكل أسرع من Gzip.من الناحية العملية ، يبدو أن Brotli أكثر فعالية من Gzip. تختلف الآراء والتجارب ، ولكن إذا تم تحسين موقعك بالفعل باستخدام Gzip ، فقد تتوقع تحسينات من رقم واحد على الأقل وفي أحسن الأحوال تحسينات مكونة من رقمين في تقليل الحجم وتوقيت FCP. يمكنك أيضًا تقدير مدخرات ضغط Brotli لموقعك.
لن تقبل المتصفحات Brotli إلا إذا كان المستخدم يزور موقع ويب عبر HTTPS. Brotli مدعوم على نطاق واسع ، والعديد من شبكات CDN تدعمه (Akamai ، Netlify Edge ، AWS ، KeyCDN ، Fastly (حاليًا فقط كمرور) ، Cloudflare ، CDN77) ويمكنك تمكين Brotli حتى على شبكات CDN التي لا تدعمها بعد (مع عامل خدمة).
المهم هو أنه نظرًا لأن ضغط جميع الأصول باستخدام Brotli بمستوى ضغط مرتفع أمر مكلف ، فإن العديد من مزودي الاستضافة لا يمكنهم استخدامه على نطاق واسع لمجرد التكلفة الضخمة التي ينتجها. في الواقع ، عند أعلى مستوى من الضغط ، يكون Brotli بطيئًا للغاية بحيث يمكن إبطال أي مكاسب محتملة في حجم الملف بمقدار الوقت الذي يستغرقه الخادم لبدء إرسال الاستجابة أثناء انتظار ضغط الأصل ديناميكيًا. (ولكن إذا كان لديك وقت أثناء وقت الإنشاء باستخدام الضغط الثابت ، فبالطبع ، يفضل استخدام إعدادات ضغط أعلى.)
مقارنة بين أوقات النهاية الخلفية لطرق الضغط المختلفة. مما لا يثير الدهشة ، أن Brotli أبطأ من gzip (في الوقت الحالي). (معاينة كبيرة) قد يتغير هذا بالرغم من ذلك. يتضمن تنسيق ملف Brotli قاموسًا ثابتًا مضمنًا ، وبالإضافة إلى احتوائه على سلاسل متنوعة بلغات متعددة ، فإنه يدعم أيضًا خيار تطبيق تحويلات متعددة على هذه الكلمات ، مما يزيد من تعدد استخداماتها. اكتشف فيليكس هاناو في بحثه طريقة لتحسين الضغط عند المستويات من 5 إلى 9 باستخدام "مجموعة فرعية أكثر تخصصًا من القاموس من الافتراضي" والاعتماد على رأس
Content-Type
لإخبار الضاغط إذا كان يجب أن يستخدم قاموس HTML أو JavaScript أو CSS. وكانت النتيجة "تأثير ضئيل على الأداء (1٪ إلى 3٪ أكثر من وحدة المعالجة المركزية مقارنة بـ 12٪ عادةً) عند ضغط محتوى الويب بمستويات ضغط عالية ، باستخدام أسلوب استخدام قاموس محدود."من خلال نهج القاموس المحسّن ، يمكننا ضغط الأصول بشكل أسرع على مستويات ضغط أعلى ، كل ذلك أثناء استخدام وحدة المعالجة المركزية (CPU) بنسبة 1٪ إلى 3٪ فقط. عادةً ما يؤدي مستوى الضغط 6 على 5 إلى زيادة استخدام وحدة المعالجة المركزية بنسبة تصل إلى 12٪. (معاينة كبيرة) علاوة على ذلك ، من خلال بحث Elena Kirilenko ، يمكننا تحقيق إعادة ضغط Brotli بسرعة وكفاءة باستخدام أدوات الضغط السابقة. وفقًا لإيلينا ، "بمجرد أن يكون لدينا أحد الأصول مضغوطًا عبر Brotli ، ونحاول ضغط المحتوى الديناميكي أثناء التنقل ، حيث يشبه المحتوى المحتوى المتاح لنا مسبقًا ، يمكننا تحقيق تحسينات كبيرة في أوقات الضغط. "
كم مرة هذا هو الحال؟ على سبيل المثال ، عند تسليم مجموعات فرعية من حزم JavaScript (على سبيل المثال ، عند تخزين أجزاء من الشفرة مؤقتًا بالفعل على العميل أو مع خدمة الحزمة الديناميكية مع WebBundles). أو باستخدام HTML الديناميكي المستند إلى القوالب المعروفة مسبقًا ، أو خطوط WOFF2 المنقسمة ديناميكيًا . وفقًا لإيلينا ، يمكننا الحصول على تحسين بنسبة 5.3٪ على الضغط وتحسين بنسبة 39٪ على سرعة الضغط عند إزالة 10٪ من المحتوى ، ومعدلات ضغط أفضل بنسبة 3.2٪ وضغط أسرع بنسبة 26٪ ، عند إزالة 50٪ من المحتوى.
يتحسن ضغط Brotli ، لذلك إذا كان بإمكانك تجاوز تكلفة ضغط الأصول الثابتة ديناميكيًا ، فمن المؤكد أن الأمر يستحق كل هذا الجهد. وغني عن القول أنه يمكن استخدام Brotli لأي حمولة نص عادي - HTML و CSS و SVG و JavaScript و JSON وما إلى ذلك.
ملاحظة : اعتبارًا من أوائل عام 2021 ، يتم تسليم ما يقرب من 60٪ من استجابات HTTP بدون ضغط مستند إلى نص ، مع ضغط بنسبة 30.82٪ باستخدام Gzip ، وضغط بنسبة 9.1٪ باستخدام Brotli (سواء على الهاتف المحمول أو على سطح المكتب). على سبيل المثال ، 23.4٪ من الصفحات ذات الزاوية غير مضغوطة (عبر gzip أو Brotli). ومع ذلك ، يعد تشغيل الضغط في كثير من الأحيان أحد أسهل المكاسب لتحسين الأداء بضغطة بسيطة على مفتاح.
الاستراتيجية؟ قم بضغط الأصول الثابتة مسبقًا باستخدام Brotli + Gzip على أعلى مستوى وضغط HTML (ديناميكي) سريعًا باستخدام Brotli في المستوى 4-6. تأكد من أن الخادم يتعامل مع تفاوض المحتوى لـ Brotli أو Gzip بشكل صحيح.

- هل نستخدم تحميل الوسائط التكيفية وتلميحات العميل؟
إنها تأتي من أرض الأخبار القديمة ، لكنها دائمًا تذكير جيد لاستخدام الصور المتجاوبة معsrcset
sizes
والعنصر<picture>
. خاصة بالنسبة للمواقع ذات البصمة الإعلامية الثقيلة ، يمكننا أن نخطو خطوة إلى الأمام من خلال تحميل الوسائط التكيفية (في هذا المثال ، React + Next.js) ، حيث نقدم تجربة خفيفة لإبطاء الشبكات والأجهزة ذات الذاكرة المنخفضة وتجربة كاملة للشبكة السريعة والعالية - أجهزة الذاكرة. في سياق React ، يمكننا تحقيق ذلك من خلال تلميحات العميل على الخادم والخطافات التكيفية للتفاعل على العميل.قد يتغير مستقبل الصور سريعة الاستجابة بشكل كبير مع تبني تلميحات العميل على نطاق واسع. تلميحات العميل هي حقول رأس طلب HTTP ، مثل
DPR
وViewport-Width
وWidth
وSave-Data
وAccept
(لتحديد تفضيلات تنسيق الصورة) وغيرها. من المفترض أن يبلغوا الخادم بخصائص متصفح المستخدم وشاشته واتصاله وما إلى ذلك.نتيجة لذلك ، يمكن للخادم تحديد كيفية ملء التخطيط بالصور ذات الحجم المناسب ، وتقديم هذه الصور فقط بالتنسيقات المرغوبة. مع تلميحات العميل ، ننقل اختيار المورد من ترميز HTML إلى مفاوضات الاستجابة للطلب بين العميل والخادم.
الوسائط التكيفية قيد الاستخدام. نرسل عنصرًا نائبًا مع نص إلى المستخدمين غير المتصلين ، وصورة منخفضة الدقة لمستخدمي الجيل الثاني ، وصورة عالية الدقة لمستخدمي شبكة الجيل الثالث ، وفيديو عالي الدقة لمستخدمي الجيل الرابع. عبر تحميل صفحات الويب بسرعة على هاتف مميز بقيمة 20 دولارًا. (معاينة كبيرة) كما لاحظ Ilya Grigorik منذ فترة ، فإن تلميحات العميل تكمل الصورة - فهي ليست بديلاً للصور سريعة الاستجابة. "يوفر عنصر
<picture>
التحكم الضروري في الاتجاه الفني في ترميز HTML. توفر تلميحات العميل تعليقات توضيحية على طلبات الصور الناتجة التي تتيح أتمتة اختيار الموارد. يوفر عامل الخدمة إمكانات إدارة الطلبات والاستجابة الكاملة على العميل."يمكن لعامل الخدمة ، على سبيل المثال ، إلحاق قيم رؤوس تلميحات العميل الجديدة بالطلب ، وإعادة كتابة عنوان URL وتوجيه طلب الصورة إلى CDN ، وتكييف الاستجابة بناءً على الاتصال وتفضيلات المستخدم ، وما إلى ذلك. إلى حد كبير لجميع الطلبات الأخرى أيضًا.
بالنسبة للعملاء الذين يدعمون تلميحات العميل ، يمكن قياس توفير 42٪ بايت على الصور و 1 ميجا بايت + بايت أقل للشريحة 70 + المئوية. في مجلة Smashing ، يمكننا قياس تحسن بنسبة 19 إلى 32٪ أيضًا. يتم دعم تلميحات العميل في المتصفحات المستندة إلى Chromium ، لكنها لا تزال قيد الدراسة في Firefox.
ومع ذلك ، إذا قمت بتوفير كلٍ من ترميز الصور المتجاوبة العادي وعلامة
<meta>
لـ Client Hints ، فسيقوم المستعرض الداعم بتقييم ترميز الصور المتجاوبة ويطلب مصدر الصورة المناسب باستخدام رؤوس Client Hints HTTP. - هل نستخدم الصور المتجاوبة لصور الخلفية؟
يجب علينا بالتأكيد! معimage-set
، المدعومة الآن في Safari 14 وفي معظم المتصفحات الحديثة باستثناء Firefox ، يمكننا تقديم صور خلفية سريعة الاستجابة أيضًا:background-image: url("fallback.jpg"); background-image: image-set( "photo-small.jpg" 1x, "photo-large.jpg" 2x, "photo-print.jpg" 600dpi);
يمكننا أساسًا تقديم صور خلفية منخفضة الدقة بشكل مشروط مع واصف
1x
وصور عالية الدقة مع واصف2x
وحتى صورة بجودة الطباعة مع واصف600dpi
نقطة في البوصة. احذر على الرغم من ذلك: لا تقدم المتصفحات أي معلومات خاصة عن صور الخلفية للتقنية المساعدة ، لذلك من الأفضل أن تكون هذه الصور مجرد زخرفة. - هل نستخدم WebP؟
غالبًا ما يُعتبر ضغط الصور فوزًا سريعًا ، ومع ذلك لا يزال غير مستغل بشكل كبير في الممارسة العملية. بالطبع لا تمنع الصور العرض ، لكنها تساهم بشكل كبير في نقاط LCP الضعيفة ، وغالبًا ما تكون ثقيلة جدًا وكبيرة جدًا بالنسبة للجهاز الذي يتم استهلاكها عليه.لذلك على الأقل ، يمكننا استكشاف استخدام تنسيق WebP لصورنا. في الواقع ، اقتربت ملحمة WebP من نهايتها العام الماضي مع إضافة Apple الدعم لـ WebP في Safari 14. لذلك بعد سنوات عديدة من المناقشات والمناقشات ، اعتبارًا من اليوم ، يتم دعم WebP في جميع المتصفحات الحديثة. لذلك يمكننا تقديم صور WebP مع عنصر
<picture>
و JPEG احتياطيًا إذا لزم الأمر (انظر مقتطف رمز Andreas Bovens) أو باستخدام تفاوض المحتوى (باستخدامAccept
الرؤوس).لا يخلو WebP من سلبياته بالرغم من ذلك. في حين أن أحجام ملفات صور WebP مقارنة بأحجام Guetzli و Zopfli المكافئة ، فإن التنسيق لا يدعم العرض التدريجي مثل JPEG ، وهذا هو السبب في أن المستخدمين قد يرون الصورة النهائية بشكل أسرع باستخدام تنسيق ol 'JPEG الجيد على الرغم من أن صور WebP قد تزداد سرعة عبر الشبكة. باستخدام JPEG ، يمكننا تقديم تجربة مستخدم "لائقة" بنصف أو حتى ربع البيانات وتحميل الباقي لاحقًا ، بدلاً من الحصول على صورة نصف فارغة كما هو الحال في WebP.
سيعتمد قرارك على ما تسعى إليه: باستخدام WebP ، ستقلل من الحمولة ، وباستخدام JPEG ستحسن الأداء الملحوظ. يمكنك معرفة المزيد عن WebP في WebP Rewind talk بواسطة باسكال ماسيمينو من Google.
للتحويل إلى WebP ، يمكنك استخدام WebP Converter أو cwebp أو libwebp. لدى Ire Aderinokun برنامجًا تعليميًا مفصلاً للغاية حول تحويل الصور إلى WebP أيضًا - وكذلك فعل Josh Comeau في مقالته حول تبني تنسيقات الصور الحديثة.
حديث شامل عن WebP: WebP Rewind بواسطة باسكال ماسيمينو. (معاينة كبيرة) يدعم Sketch أصلاً WebP ، ويمكن تصدير صور WebP من Photoshop باستخدام مكون WebP الإضافي لـ Photoshop. لكن الخيارات الأخرى متاحة أيضًا.
إذا كنت تستخدم WordPress أو Joomla ، فهناك ملحقات لمساعدتك على تنفيذ دعم WebP بسهولة ، مثل Optimus و Cache Enabler for WordPress و Joomla's extension المدعوم (عبر Cody Arsenault). يمكنك أيضًا تجريد عنصر
<picture>
بعيدًا باستخدام React أو مكوّنات نمطية أو gatsby-image.آه - المكونات وقح! - نشر جيريمي واجنر كتاب Smashing على WebP والذي قد ترغب في التحقق مما إذا كنت مهتمًا بكل شيء يتعلق بـ WebP.
- هل نستخدم AVIF؟
ربما سمعت الخبر الكبير: لقد هبط AVIF. إنه تنسيق صورة جديد مشتق من الإطارات الرئيسية لفيديو AV1. إنه تنسيق مفتوح وخالي من حقوق الملكية يدعم ضغطًا ضياعًا وخاليًا من الضياع والرسوم المتحركة وقناة ألفا مع فقدان البيانات ويمكنه التعامل مع الخطوط الحادة والألوان الصلبة (التي كانت تمثل مشكلة مع JPEG) ، مع توفير نتائج أفضل في كليهما.في الواقع ، مقارنةً بـ WebP و JPEG ، يعمل AVIF بشكل أفضل بشكل ملحوظ ، مما يؤدي إلى توفير متوسط في حجم الملف يصل إلى 50٪ في نفس التشابه DSSIM ((dis) بين صورتين أو أكثر باستخدام خوارزمية تقترب من الرؤية البشرية). في الواقع ، في رسالته الشاملة حول تحسين تحميل الصور ، أشار Malte Ubl إلى أن AVIF "يتفوق باستمرار على JPEG بطريقة مهمة للغاية. وهذا يختلف عن WebP الذي لا ينتج دائمًا صورًا أصغر من JPEG وقد يكون في الواقع شبكة- الخسارة بسبب نقص الدعم للتحميل التدريجي. "
يمكننا استخدام AVIF كتعزيز تدريجي ، حيث يتم توصيل WebP أو JPEG أو PNG للمتصفحات القديمة. (معاينة كبيرة). انظر عرض النص العادي أدناه. ومن المفارقات أن AVIF يمكن أن يؤدي أداءً أفضل من SVGs الكبيرة على الرغم من أنه بالطبع لا ينبغي أن يُنظر إليه على أنه بديل لـ SVGs. وهو أيضًا أحد تنسيقات الصور الأولى التي تدعم دعم ألوان HDR ؛ تقدم سطوعًا أعلى وعمق بت لوني وتدرجات لونية أعلى. الجانب السلبي الوحيد هو أن AVIF حاليًا لا يدعم فك تشفير الصورة التدريجي (حتى الآن) ، وعلى غرار Brotli ، فإن ترميز معدل الضغط المرتفع حاليًا بطيء جدًا ، على الرغم من أن فك التشفير سريع.
يتم دعم AVIF حاليًا في Chrome و Firefox و Opera ، ومن المتوقع أن يتوفر الدعم في Safari قريبًا (نظرًا لأن Apple عضو في المجموعة التي أنشأت AV1).
ما هي أفضل طريقة لتقديم الصور هذه الأيام ؟ بالنسبة إلى الرسوم التوضيحية والصور المتجهة ، يعد SVG (المضغوط) هو الخيار الأفضل بلا شك. بالنسبة للصور ، نستخدم طرق التفاوض على المحتوى مع عنصر
picture
. إذا كان AVIF مدعومًا ، نرسل صورة AVIF ؛ إذا لم يكن الأمر كذلك ، فنعود إلى WebP أولاً ، وإذا لم يكن WebP مدعومًا أيضًا ، فسننتقل إلى JPEG أو PNG كبديل احتياطي (تطبيق شروط@media
إذا لزم الأمر):<picture> <source type="image/avif"> <source type="image/webp"> <img src="image.jpg" alt="Photo" width="450" height="350"> </picture>
بصراحة ، من الأرجح أننا سنستخدم بعض الشروط داخل عنصر
picture
على الرغم من:<picture> <source type="image/avif" /> <source type="image/webp" /> <source type="image/jpeg" /> <img src="fallback-image.jpg" alt="Photo" width="450" height="350"> </picture>
<picture> <source type="image/avif" /> <source type="image/webp" /> <source type="image/jpeg" /> <img src="fallback-image.jpg" alt="Photo" width="450" height="350"> </picture>
يمكنك الذهاب إلى أبعد من ذلك عن طريق تبديل الصور المتحركة بالصور الثابتة للعملاء الذين يختارون الحركة الأقل مع الحركة
prefers-reduced-motion
:<picture> <source media="(prefers-reduced-motion: reduce)" type="image/avif"></source> <source media="(prefers-reduced-motion: reduce)" type="image/jpeg"></source> <source type="image/avif"></source> <img src="motion.jpg" alt="Animated AVIF"> </picture>
<picture> <source media="(prefers-reduced-motion: reduce)" type="image/avif"></source> <source media="(prefers-reduced-motion: reduce)" type="image/jpeg"></source> <source type="image/avif"></source> <img src="motion.jpg" alt="Animated AVIF"> </picture>
على مدار الشهرين ، اكتسب AVIF بعض الجذب:
- يمكننا اختبار احتياطات WebP / AVIF في لوحة العرض في DevTools.
- يمكننا استخدام Squoosh و AVIF.io و libavif لترميز ملفات AVIF وفك تشفيرها وضغطها وتحويلها.
- يمكننا استخدام مكون AVIF Preact الخاص بـ Jake Archibald الذي يقوم بفك تشفير ملف AVIF في العامل ويعرض النتيجة على قماش ،
- لتقديم AVIF للمتصفحات الداعمة فقط ، يمكننا استخدام ملحق PostCSS مع نصي 315B لاستخدام AVIF في إعلانات CSS الخاصة بك.
- يمكننا تقديم تنسيقات صور جديدة بشكل تدريجي باستخدام CSS و Cloudlare Workers لتغيير مستند HTML الذي تم إرجاعه ديناميكيًا ، واستنتاج المعلومات من عنوان
accept
، ثم إضافةwebp/avif
وما إلى ذلك حسب الاقتضاء. - يتوفر AVIF بالفعل في Cloudinary (مع حدود الاستخدام) ، ويدعم Cloudflare AVIF في تغيير حجم الصورة ، ويمكنك تمكين AVIF مع رؤوس AVIF المخصصة في Netlify.
- عندما يتعلق الأمر بالرسوم المتحركة ، فإن AVIF يعمل مثل
<img src=mp4>
Safari ، متفوقًا على GIF و WebP بشكل عام ، لكن MP4 لا يزال يعمل بشكل أفضل. - بشكل عام ، بالنسبة إلى الرسوم المتحركة ، AVC1 (h264)> HVC1> WebP> AVIF> GIF ، بافتراض أن المتصفحات القائمة على Chromium ستدعم
<img src=mp4>
. - يمكنك العثور على مزيد من التفاصيل حول AVIF في AVIF من أجل حديث ترميز الصور من الجيل التالي بواسطة Aditya Mavlankar من Netflix ، و تحدث تنسيق صورة AVIF بواسطة Kornel Lesinski من Cloudflare.
- مرجع رائع لكل شيء AVIF: لقد وصل منشور Jake Archibald الشامل على AVIF.
إذن هل المستقبل AVIF إذن ؟ لا يوافق جون سنيرز على ذلك: إن أداء AVIF أسوأ بنسبة 60٪ من أداء JPEG XL ، وهو تنسيق مجاني ومفتوح آخر طورته Google و Cloudinary. في الواقع ، يبدو أن أداء JPEG XL يعمل بشكل أفضل في جميع المجالات. ومع ذلك ، لا يزال JPEG XL في المراحل النهائية للتوحيد القياسي ، ولا يعمل حتى الآن في أي متصفح. (عدم الخلط مع Microsoft JPEG-XR الذي يأتي من Internet Explorer 9 مرات).

- هل تم تحسين ملفات JPEG / PNG / SVG بشكل صحيح؟
عندما تعمل على صفحة مقصودة يكون من المهم فيها تحميل صورة بطل بسرعة فائقة ، تأكد من أن ملفات JPEG تقدمية ومضغوطة باستخدام mozJPEG (الذي يحسن وقت بدء العرض من خلال معالجة مستويات المسح) أو Guetzli ، المصدر المفتوح من Google برنامج تشفير يركز على الأداء الإدراكي ، والاستفادة من الدروس المستفادة من Zopfli و WebP. الجانب السلبي الوحيد: بطء أوقات المعالجة (دقيقة لوحدة المعالجة المركزية لكل ميجابيكسل).بالنسبة إلى PNG ، يمكننا استخدام Pingo و SVG ، يمكننا استخدام SVGO أو SVGOMG. وإذا كنت بحاجة إلى معاينة جميع أصول SVG ونسخها أو تنزيلها بسرعة من أحد مواقع الويب ، فيمكن لـ svg-grabber القيام بذلك نيابةً عنك أيضًا.
ستوضح كل مقالة تحسين صورة واحدة ، لكن الحفاظ على أصول المتجهات نظيفة وضيقة يستحق دائمًا الذكر. تأكد من تنظيف الأصول غير المستخدمة وإزالة البيانات الوصفية غير الضرورية وتقليل عدد نقاط المسار في العمل الفني (وبالتالي رمز SVG). ( شكرا جيريمي! )
هناك أيضًا أدوات مفيدة متاحة عبر الإنترنت على الرغم من:
- استخدم Squoosh لضغط الصور وتغيير حجمها ومعالجتها بمستويات الضغط المثلى (ضياع أو بدون فقدان) ،
- استخدم Guetzli.it لضغط وتحسين صور JPEG باستخدام Guetzli ، والذي يعمل بشكل جيد مع الصور ذات الحواف الحادة والألوان الصلبة (ولكن قد يكون أبطأ قليلاً)).
- استخدم منشئ نقاط توقف الصور المتجاوبة أو خدمة مثل Cloudinary أو Imgix لأتمتة تحسين الصورة. أيضًا ، في كثير من الحالات ، سيحقق استخدام
srcset
sizes
وحدها فوائد كبيرة. - للتحقق من كفاءة الترميز سريع الاستجابة ، يمكنك استخدام imaging-heap ، وهي أداة سطر أوامر تقيس الكفاءة عبر أحجام منفذ العرض ونسب بكسل الجهاز.
- يمكنك إضافة ضغط تلقائي للصور إلى تدفقات عمل GitHub ، لذلك لا يمكن لأي صورة أن تصل إلى الإنتاج غير مضغوط. يستخدم الإجراء mozjpeg و libvips اللذان يعملان مع PNGs و JPG.
- لتحسين التخزين بشكل داخلي ، يمكنك استخدام تنسيق Lepton الجديد من Dropbox لضغط ملفات JPEG بدون خسارة بمعدل 22٪.
- استخدم BlurHash إذا كنت ترغب في إظهار صورة عنصر نائب مبكرًا. يأخذ BlurHash صورة ، ويمنحك سلسلة قصيرة (20-30 حرفًا فقط!) تمثل العنصر النائب لهذه الصورة. السلسلة قصيرة بما يكفي لإضافتها بسهولة كحقل في كائن JSON.
BlurHash هو تمثيل صغير ومضغوط لعنصر نائب للصورة. (معاينة كبيرة) في بعض الأحيان ، لن يؤدي تحسين الصور وحده إلى حل المشكلة. لتحسين الوقت اللازم لبدء عرض صورة مهمة ، قم بتحميل الصور الأقل أهمية بشكل كسول وتأجيل أي برامج نصية ليتم تحميلها بعد عرض الصور المهمة بالفعل. الطريقة الأكثر مقاومة للرصاص هي التحميل البطيء المختلط ، عندما نستخدم التحميل البطيء الأصلي والتحميل البطيء ، وهي مكتبة تكتشف أي تغييرات في الرؤية تحدث من خلال تفاعل المستخدم (مع خادم IntersectionObserver الذي سنستكشفه لاحقًا). بالإضافة إلى ذلك:
- ضع في اعتبارك تحميل الصور المهمة مسبقًا ، حتى لا يكتشفها المتصفح بعد فوات الأوان. بالنسبة لصور الخلفية ، إذا كنت تريد أن تكون أكثر عدوانية من ذلك ، يمكنك إضافة الصورة كصورة عادية باستخدام
<img src>
، ثم إخفائها عن الشاشة. - ضع في اعتبارك تبديل الصور بسمة الأحجام عن طريق تحديد أبعاد عرض مختلفة للصور بناءً على استعلامات الوسائط ، على سبيل المثال لمعالجة
sizes
لتبديل المصادر في مكون المكبر. - راجع تناقضات تنزيل الصور لمنع التنزيلات غير المتوقعة لصور المقدمة والخلفية. احترس من الصور التي يتم تحميلها افتراضيًا ، ولكن قد لا يتم عرضها مطلقًا - على سبيل المثال في الدوارات ، والأكورديون ، ومعارض الصور.
- تأكد دائمًا من ضبط
width
height
على الصور. احترس من خاصيةaspect-ratio
في CSS والسمةintrinsicsize
التي ستسمح لنا بتعيين نسب العرض إلى الارتفاع والأبعاد للصور ، بحيث يمكن للمتصفح حجز فتحة تخطيط محددة مسبقًا في وقت مبكر لتجنب قفزات التخطيط أثناء تحميل الصفحة.
يجب أن يستغرق الأمر أسابيع أو شهور فقط الآن ، مع هبوط نسبة العرض إلى الارتفاع في المتصفحات. في Safari Technical Preview 118 بالفعل. حاليا وراء العلم في Firefox و Chrome. (معاينة كبيرة) إذا كنت تشعر بالمغامرة ، فيمكنك قطع وإعادة ترتيب تدفقات HTTP / 2 باستخدام عمال Edge ، وهو مرشح في الوقت الفعلي يعيش على CDN ، لإرسال الصور بشكل أسرع عبر الشبكة. يستخدم عمال Edge تدفقات JavaScript التي تستخدم أجزاء يمكنك التحكم فيها (في الأساس هم JavaScript يتم تشغيله على حافة CDN التي يمكنها تعديل استجابات الدفق) ، بحيث يمكنك التحكم في تسليم الصور.
مع عامل الخدمة ، فات الأوان لأنك لا تستطيع التحكم في ما هو على السلك ، لكنه يعمل مع عمال Edge. لذا يمكنك استخدامها فوق ملفات JPEG الثابتة المحفوظة تدريجيًا لصفحة مقصودة معينة.
عينة إخراج بواسطة imaging-heap ، أداة سطر أوامر تقيس الكفاءة عبر أحجام منفذ العرض ونسب بكسل الجهاز. (مصدر الصورة) (معاينة كبيرة) ليس جيدا بما فيه الكفاية؟ حسنًا ، يمكنك أيضًا تحسين الأداء المتصور للصور باستخدام تقنية صور الخلفية المتعددة. ضع في اعتبارك أن اللعب بالتباين وطمس التفاصيل غير الضرورية (أو إزالة الألوان) يمكن أن يقلل حجم الملف أيضًا. آه ، تحتاج إلى تكبير صورة صغيرة دون فقدان الجودة؟ ضع في اعتبارك استخدام Letsenhance.io.
تغطي هذه التحسينات حتى الآن الأساسيات فقط. نشرت Addy Osmani دليلاً مفصلاً للغاية حول Essential Image Optimization والذي يتعمق في تفاصيل ضغط الصور وإدارة الألوان. على سبيل المثال ، يمكنك طمس الأجزاء غير الضرورية من الصورة (عن طريق تطبيق مرشح ضباب غاوسي عليها) لتقليل حجم الملف ، وفي النهاية قد تبدأ في إزالة الألوان أو تحويل الصورة إلى أبيض وأسود لتقليل الحجم بدرجة أكبر . بالنسبة لصور الخلفية ، يمكن أن يكون تصدير الصور من Photoshop بجودة من 0 إلى 10٪ مقبولًا تمامًا أيضًا.
في مجلة Smashing ، نستخدم خيار postfix
-opt
الصور - على سبيل المثال ،brotli-compression-opt.png
؛ كلما احتوت الصورة على هذا postfix ، يعلم كل فرد في الفريق أن الصورة قد تم تحسينها بالفعل.آه ، ولا تستخدم JPEG-XR على الويب - "تؤدي معالجة جانب برنامج فك تشفير JPEG-XRs على وحدة المعالجة المركزية إلى إبطال التأثير الإيجابي المحتمل لتوفير حجم البايت ، خاصة في سياق SPA" (لا لخلطها مع Cloudinary / Google's JPEG XL بالرغم من ذلك).

- هل تم تحسين مقاطع الفيديو بشكل صحيح؟
لقد غطينا الصور حتى الآن ، لكننا تجنبنا الحديث عن صور GIF الجيدة. على الرغم من حبنا لملفات GIF ، فقد حان الوقت حقًا للتخلي عنها نهائيًا (على الأقل في مواقعنا الإلكترونية وتطبيقاتنا). بدلاً من تحميل صور GIF متحركة ثقيلة تؤثر على كل من أداء العرض والنطاق الترددي ، من المستحسن التبديل إما إلى WebP المتحرك (مع كون GIF احتياطيًا) أو استبدالها بمقاطع فيديو HTML5 متكررة تمامًا.على عكس الصور ، لا تقوم المتصفحات بتحميل محتوى
<video>
مسبقًا ، لكن مقاطع فيديو HTML5 تميل إلى أن تكون أخف وأصغر بكثير من ملفات GIF. ليس خيارا؟ حسنًا ، على الأقل يمكننا إضافة ضغط ضائع إلى ملفات GIF باستخدام ملف GIF أو gifsicle أو giflossy.تُظهر الاختبارات التي أجراها Colin Bendell أن مقاطع الفيديو المضمنة ضمن علامات
img
في Safari Technology Preview تعرض على الأقل 20 × أسرع وفك تشفير 7 × أسرع من مكافئ GIF ، بالإضافة إلى كونها جزءًا صغيرًا من حجم الملف. ومع ذلك ، فهو غير مدعوم في المتصفحات الأخرى.في أرض الأخبار السارة ، شهدت تنسيقات الفيديو تقدمًا هائلاً على مر السنين. لفترة طويلة ، كنا نأمل أن يصبح WebM هو التنسيق الذي يحكمهم جميعًا ، وسيصبح WebP (وهو في الأساس صورة ثابتة داخل حاوية فيديو WebM) بديلاً لتنسيقات الصور المؤرخة. في الواقع ، يدعم Safari الآن WebP ، ولكن على الرغم من حصول WebP و WebM على الدعم هذه الأيام ، فإن الاختراق لم يحدث حقًا.
ومع ذلك ، يمكننا استخدام WebM لمعظم المتصفحات الحديثة:
<!-- By Houssein Djirdeh. https://web.dev/replace-gifs-with-videos/ --> <!-- A common scenartio: MP4 with a WEBM fallback. --> <video autoplay loop muted playsinline> <source src="my-animation.webm" type="video/webm"> <source src="my-animation.mp4" type="video/mp4"> </video>
لكن ربما يمكننا إعادة النظر فيه تمامًا. في عام 2018 ، أصدر تحالف Open Media تنسيق فيديو جديدًا واعدًا يسمى AV1 . يحتوي AV1 على ضغط مشابه لبرنامج الترميز H.265 (تطور H.264) ولكن على عكس الأخير ، فإن AV1 مجاني. دفع تسعير ترخيص H.265 بائعي المستعرضات إلى اعتماد AV1 ذو الأداء المماثل بدلاً من ذلك: يضغط AV1 (تمامًا مثل H.265) مرتين مثل WebM .
يتمتع AV1 بفرص جيدة في أن يصبح المعيار المطلق للفيديو على الويب. (رصيد الصورة: Wikimedia.org) (معاينة كبيرة) في الواقع ، تستخدم Apple حاليًا تنسيق HEIF و HEVC (H.265) ، ويتم حفظ جميع الصور ومقاطع الفيديو على أحدث إصدار من iOS بهذه التنسيقات ، وليس JPEG. بينما لم يتم عرض HEIF و HEVC (H.265) بشكل صحيح على الويب (حتى الآن) ، فإن AV1 - وهو يكتسب دعم المتصفح. لذا فإن إضافة مصدر
AV1
في علامة<video>
الخاصة بك أمر معقول ، حيث يبدو أن جميع بائعي المستعرضات على متنها.في الوقت الحالي ، الترميز الأكثر استخدامًا ودعمًا هو H.264 ، والذي يتم تقديمه بواسطة ملفات MP4 ، لذا قبل تقديم الملف ، تأكد من معالجة ملفات MP4 الخاصة بك بترميز متعدد المسارات ، غير واضح مع تأثير frei0r iirblur (إن أمكن) و يتم نقل البيانات الوصفية لـ moov atom إلى رأس الملف ، بينما يقبل الخادم خدمة البايت. يوفر Boris Schapira إرشادات دقيقة لـ FFmpeg لتحسين مقاطع الفيديو إلى أقصى حد. بالطبع ، قد يساعد توفير تنسيق WebM كبديل أيضًا.
هل تحتاج إلى بدء عرض مقاطع الفيديو بشكل أسرع ولكن ملفات الفيديو لا تزال كبيرة جدًا ؟ على سبيل المثال ، متى كان لديك مقطع فيديو كبير في الخلفية على صفحة مقصودة؟ الأسلوب الشائع الذي يجب استخدامه هو إظهار الإطار الأول كصورة ثابتة أولاً ، أو عرض مقطع حلقة قصيرة مُحسَّن بشكل كبير يمكن تفسيره كجزء من الفيديو ، وبعد ذلك ، كلما تم تخزين الفيديو مؤقتًا بدرجة كافية ، ابدأ التشغيل الفيديو الفعلي. يحتوي دوج سيلارز على دليل تفصيلي مكتوب لأداء الفيديو في الخلفية والذي يمكن أن يكون مفيدًا في هذه الحالة. ( شكرا ، جاي بودجارني! ).
بالنسبة للسيناريو أعلاه ، قد ترغب في تقديم صور ملصقات سريعة الاستجابة . بشكل افتراضي ، تسمح عناصر
video
بصورة واحدة فقط كملصق ، وهذا ليس بالضرورة هو الأمثل. يمكننا استخدام Respive Video Poster ، وهي مكتبة JavaScript تتيح لك استخدام صور ملصقات مختلفة لشاشات مختلفة ، مع إضافة تراكب انتقالي وتحكم كامل في التصميم لعناصر الفيديو النائبة.أظهر البحث أن جودة بث الفيديو تؤثر على سلوك المشاهد. في الواقع ، يبدأ المشاهدون في التخلي عن الفيديو إذا تجاوز تأخير بدء التشغيل ثانيتين تقريبًا. بعد هذه النقطة ، تؤدي زيادة التأخير بمقدار ثانية واحدة إلى زيادة بنسبة 5.8٪ تقريبًا في معدل التخلي. لذلك ليس من المستغرب أن يكون متوسط وقت بدء الفيديو هو 12.8 ثانية ، مع وجود 40٪ من مقاطع الفيديو بها توقف واحد على الأقل ، و 20٪ على الأقل 2 ثانية من توقف تشغيل الفيديو. في الواقع ، لا يمكن تجنب أكشاك الفيديو على شبكة الجيل الثالث ، حيث يتم تشغيل مقاطع الفيديو بشكل أسرع من قدرة الشبكة على توفير المحتوى.
إذن ما الحل؟ عادة لا تستطيع الأجهزة ذات الشاشات الصغيرة التعامل مع 720p و 1080 p نحن نخدم سطح المكتب. وفقًا لـ Doug Sillars ، يمكننا إما إنشاء إصدارات أصغر من مقاطع الفيديو الخاصة بنا ، واستخدام Javascript لاكتشاف المصدر للشاشات الأصغر لضمان التشغيل السريع والسلس على هذه الأجهزة. بدلاً من ذلك ، يمكننا استخدام دفق الفيديو. ستوفر تدفقات الفيديو HLS فيديو بالحجم المناسب للجهاز - مما يلخص الحاجة إلى إنشاء مقاطع فيديو مختلفة لشاشات مختلفة. سيتفاوض أيضًا على سرعة الشبكة ، وسيتكيف معدل بت الفيديو مع سرعة الشبكة التي تستخدمها.
لتجنب إهدار النطاق الترددي ، يمكننا فقط إضافة مصدر الفيديو للأجهزة التي يمكنها بالفعل تشغيل الفيديو بشكل جيد. بدلاً من ذلك ، يمكننا إزالة سمة
autoplay
من علامةvideo
تمامًا واستخدام JavaScript لإدراجautoplay
للشاشات الأكبر حجمًا. بالإضافة إلى ذلك ، نحتاج إلى إضافةpreload="none"
علىvideo
لإخبار المتصفح بعدم تنزيل أي من ملفات الفيديو حتى يحتاج إلى الملف بالفعل:<!-- Based on Doug Sillars's post. https://dougsillars.com/2020/01/06/hiding-videos-on-the-mbile-web/ --> <video preload="none" playsinline muted loop width="1920" height="1080" poster="poster.jpg"> <source src="video.webm" type="video/webm"> <source src="video.mp4" type="video/mp4"> </video>
ثم يمكننا استهداف المتصفحات التي تدعم AV1 على وجه التحديد:
<!-- Based on Doug Sillars's post. https://dougsillars.com/2020/01/06/hiding-videos-on-the-mbile-web/ --> <video preload="none" playsinline muted loop width="1920" height="1080" poster="poster.jpg"> <source src="video.av1.mp4" type="video/mp4; codecs=av01.0.05M.08"> <source src="video.hevc.mp4" type="video/mp4; codecs=hevc"> <source src="video.webm" type="video/webm"> <source src="video.mp4" type="video/mp4"> </video>
يمكننا بعد ذلك إعادة إضافة
autoplay
فوق حد معين (مثل 1000 بكسل):/* By Doug Sillars. https://dougsillars.com/2020/01/06/hiding-videos-on-the-mbile-web/ */ <script> window.onload = addAutoplay(); var videoLocation = document.getElementById("hero-video"); function addAutoplay() { if(window.innerWidth > 1000){ videoLocation.setAttribute("autoplay",""); }; } </script>
عدد الأكشاك حسب الجهاز وسرعة الشبكة. الأجهزة الأسرع الموجودة على الشبكات الأسرع لا تحتوي فعليًا على أكشاك. وفقًا لبحث دوج سيلارز. (معاينة كبيرة) يعد أداء تشغيل الفيديو قصة بحد ذاتها ، وإذا كنت ترغب في التعمق فيها بالتفصيل ، فقم بإلقاء نظرة على سلسلة أخرى لـ Doug Sillars حول الحالة الحالية للفيديو وأفضل ممارسات توصيل الفيديو التي تتضمن تفاصيل حول مقاييس توصيل الفيديو والتحميل المسبق للفيديو والضغط والتدفق. أخيرًا ، يمكنك التحقق من مدى بطء أو سرعة دفق الفيديو الخاص بك باستخدام Stream or Not.

- هل تم تحسين توصيل خطوط الويب؟
The first question that's worth asking is if we can get away with using UI system fonts in the first place — we just need to make sure to double check that they appear correctly on various platforms. If it's not the case, chances are high that the web fonts we are serving include glyphs and extra features and weights that aren't being used. We can ask our type foundry to subset web fonts or if we are using open-source fonts, subset them on our own with Glyphhanger or Fontsquirrel. We can even automate our entire workflow with Peter Muller's subfont, a command line tool that statically analyses your page in order to generate the most optimal web font subsets, and then inject them into our pages.WOFF2 support is great, and we can use WOFF as fallback for browsers that don't support it — or perhaps legacy browsers could be served system fonts. There are many, many, many options for web font loading, and we can choose one of the strategies from Zach Leatherman's "Comprehensive Guide to Font-Loading Strategies," (code snippets also available as Web font loading recipes).
Probably the better options to consider today are Critical FOFT with
preload
and "The Compromise" method. Both of them use a two-stage render for delivering web fonts in steps — first a small supersubset required to render the page fast and accurately with the web font, and then load the rest of the family async. The difference is that "The Compromise" technique loads polyfill asynchronously only if font load events are not supported, so you don't need to load the polyfill by default. Need a quick win? Zach Leatherman has a quick 23-min tutorial and case study to get your fonts in order.In general, it might be a good idea to use the
preload
resource hint to preload fonts, but in your markup include the hints after the link to critical CSS and JavaScript. Withpreload
, there is a puzzle of priorities, so consider injectingrel="preload"
elements into the DOM just before the external blocking scripts. According to Andy Davies, "resources injected using a script are hidden from the browser until the script executes, and we can use this behaviour to delay when the browser discovers thepreload
hint." Otherwise, font loading will cost you in the first render time.When everything is critical, nothing is critical. preload only one or a maximum of two fonts of each family. (Image credit: Zach Leatherman – slide 93) (Large preview) It's a good idea to be selective and choose files that matter most, eg the ones that are critical for rendering or that would help you avoiding visible and disruptive text reflows. In general, Zach advises to preload one or two fonts of each family — it also makes sense to delay some font loading if they are less critical.
It has become quite common to use
local()
value (which refers to a local font by name) when defining afont-family
in the@font-face
rule:/* Warning! Not a good idea! */ @font-face { font-family: Open Sans; src: local('Open Sans Regular'), local('OpenSans-Regular'), url('opensans.woff2') format ('woff2'), url('opensans.woff') format('woff'); }
The idea is reasonable: some popular open-source fonts such as Open Sans are coming pre-installed with some drivers or apps, so if the font is available locally, the browser doesn't need to download the web font and can display the local font immediately. As Bram Stein noted, "though a local font matches the name of a web font, it most likely isn't the same font . Many web fonts differ from their "desktop" version. The text might be rendered differently, some characters may fall back to other fonts, OpenType features can be missing entirely, or the line height may be different."
Also, as typefaces evolve over time, the locally installed version might be very different from the web font, with characters looking very different. So, according to Bram, it's better to never mix locally installed fonts and web fonts in
@font-face
rules. Google Fonts has followed suit by disablinglocal()
on the CSS results for all users, other than Android requests for Roboto.Nobody likes waiting for the content to be displayed. With the
font-display
CSS descriptor, we can control the font loading behavior and enable content to be readable immediately (withfont-display: optional
) or almost immediately (with a timeout of 3s, as long as the font gets successfully downloaded — withfont-display: swap
). (Well, it's a bit more complicated than that.)However, if you want to minimize the impact of text reflows, we could use the Font Loading API (supported in all modern browsers). Specifically that means for every font, we'd creata a
FontFace
object, then try to fetch them all, and only then apply them to the page. This way, we group all repaints by loading all fonts asynchronously, and then switch from fallback fonts to the web font exactly once. Take a look at Zach's explanation, starting at 32:15, and the code snippet):/* Load two web fonts using JavaScript */ /* Zach Leatherman: https://noti.st/zachleat/KNaZEg/the-five-whys-of-web-font-loading-performance#sWkN4u4 */ // Remove existing @font-face blocks // Create two let font = new FontFace("Noto Serif", /* ... */); let fontBold = new FontFace("Noto Serif, /* ... */); // Load two fonts let fonts = await Promise.all([ font.load(), fontBold.load() ]) // Group repaints and render both fonts at the same time! fonts.forEach(font => documents.fonts.add(font));
/* Load two web fonts using JavaScript */ /* Zach Leatherman: https://noti.st/zachleat/KNaZEg/the-five-whys-of-web-font-loading-performance#sWkN4u4 */ // Remove existing @font-face blocks // Create two let font = new FontFace("Noto Serif", /* ... */); let fontBold = new FontFace("Noto Serif, /* ... */); // Load two fonts let fonts = await Promise.all([ font.load(), fontBold.load() ]) // Group repaints and render both fonts at the same time! fonts.forEach(font => documents.fonts.add(font));
To initiate a very early fetch of the fonts with Font Loading API in use, Adrian Bece suggests to add a non-breaking space
nbsp;
at the top of thebody
, and hide it visually witharia-visibility: hidden
and a.hidden
class:<body class="no-js"> <!-- ... Website content ... --> <div aria-visibility="hidden" class="hidden"> <!-- There is a non-breaking space here --> </div> <script> document.getElementsByTagName("body")[0].classList.remove("no-js"); </script> </body>
<body class="no-js"> <!-- ... Website content ... --> <div aria-visibility="hidden" class="hidden"> <!-- There is a non-breaking space here --> </div> <script> document.getElementsByTagName("body")[0].classList.remove("no-js"); </script> </body>
This goes along with CSS that has different font families declared for different states of loading, with the change triggered by Font Loading API once the fonts have successfully loaded:
body:not(.wf-merriweather--loaded):not(.no-js) { font-family: [fallback-system-font]; /* Fallback font styles */ } .wf-merriweather--loaded, .no-js { font-family: "[web-font-name]"; /* Webfont styles */ } /* Accessible hiding */ .hidden { position: absolute; overflow: hidden; clip: rect(0 0 0 0); height: 1px; width: 1px; margin: -1px; padding: 0; border: 0; }
body:not(.wf-merriweather--loaded):not(.no-js) { font-family: [fallback-system-font]; /* Fallback font styles */ } .wf-merriweather--loaded, .no-js { font-family: "[web-font-name]"; /* Webfont styles */ } /* Accessible hiding */ .hidden { position: absolute; overflow: hidden; clip: rect(0 0 0 0); height: 1px; width: 1px; margin: -1px; padding: 0; border: 0; }
If you ever wondered why despite all your optimizations, Lighthouse still suggests to eliminate render-blocking resources (fonts), in the same article Adrian Bece provides a few techniques to make Lighthouse happy, along with a Gatsby Omni Font Loader, a performant asynchronous font loading and Flash Of Unstyled Text (FOUT) handling plugin for Gatsby.
Now, many of us might be using a CDN or a third-party host to load web fonts from. In general, it's always better to self-host all your static assets if you can, so consider using google-webfonts-helper, a hassle-free way to self-host Google Fonts. And if it's not possible, you can perhaps proxy the Google Font files through the page origin.
It's worth noting though that Google is doing quite a bit of work out of the box, so a server might need a bit of tweaking to avoid delays ( thanks, Barry! )
This is quite important especially as since Chrome v86 (released October 2020), cross-site resources like fonts can't be shared on the same CDN anymore — due to the partitioned browser cache. This behavior was a default in Safari for years.
But if it's not possible at all, there is a way to get to the fastest possible Google Fonts with Harry Roberts' snippet:
<!-- By Harry Roberts. https://csswizardry.com/2020/05/the-fastest-google-fonts/ - 1. Preemptively warm up the fonts' origin. - 2. Initiate a high-priority, asynchronous fetch for the CSS file. Works in - most modern browsers. - 3. Initiate a low-priority, asynchronous fetch that gets applied to the page - only after it's arrived. Works in all browsers with JavaScript enabled. - 4. In the unlikely event that a visitor has intentionally disabled - JavaScript, fall back to the original method. The good news is that, - although this is a render-blocking request, it can still make use of the - preconnect which makes it marginally faster than the default. --> <!-- [1] --> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <!-- [2] --> <link rel="preload" as="style" href="$CSS&display=swap" /> <!-- [3] --> <link rel="stylesheet" href="$CSS&display=swap" media="print" onload="this.media='all'" /> <!-- [4] --> <noscript> <link rel="stylesheet" href="$CSS&display=swap" /> </noscript>
Harry's strategy is to pre-emptively warm up the fonts' origin first. Then we initiate a high-priority, asynchronous fetch for the CSS file. Afterwards, we initiate a low-priority, asynchronous fetch that gets applied to the page only after it's arrived (with a print stylesheet trick). Finally, if JavaScript isn't supported, we fall back to the original method.
Ah, talking about Google Fonts: you can shave up to 90% of the size of Google Fonts requests by declaring only characters you need with
&text
. Plus, the support for font-display was added recently to Google Fonts as well, so we can use it out of the box.كلمة تحذير سريعة بالرغم من ذلك. إذا كنت تستخدم
font-display: optional
، فقد يكون استخدامpreload
دون المستوى الأمثل لأنه سيؤدي إلى تشغيل طلب خط الويب هذا مبكرًا (مما يتسبب في ازدحام الشبكة إذا كان لديك موارد مسار حرجة أخرى تحتاج إلى جلبها). استخدمpreconnect
لطلبات الخطوط عبر الأصل الأسرع ، ولكن كن حذرًا معpreload
لأن تحميل الخطوط مسبقًا من أصل مختلف يؤدي إلى تنازع الشبكة. كل هذه التقنيات مغطاة في وصفات تحميل خطوط الويب الخاصة بزاك.من ناحية أخرى ، قد يكون من الجيد إلغاء الاشتراك في خطوط الويب (أو عرض المرحلة الثانية على الأقل) إذا قام المستخدم بتمكين تقليل الحركة في تفضيلات إمكانية الوصول أو اختار وضع توفير البيانات (انظر رأس
Save-Data
) ، أو عندما يكون لدى المستخدم اتصال بطيء (عبر واجهة برمجة تطبيقات معلومات الشبكة).يمكننا أيضًا استخدام استعلام وسائط CSS
prefers-reduced-data
المختصرة المُفضلة لعدم تحديد تعريفات الخطوط إذا اختار المستخدم وضع توفير البيانات (هناك حالات استخدام أخرى أيضًا). قد يعرض الاستعلام عن الوسائط بشكل أساسي ما إذا كان رأس طلبSave-Data
من امتداد HTTP Hint في وضع التشغيل / الإيقاف للسماح بالاستخدام مع CSS. مدعوم حاليًا فقط في Chrome و Edge خلف العلم.المقاييس؟ لقياس أداء تحميل خط الويب ، ضع في اعتبارك مقياس All Text Visible (اللحظة التي يتم فيها تحميل جميع الخطوط وعرض كل المحتوى في خطوط الويب) ، و Time to Real Italics وكذلك عدد إعادة تدفق خط الويب بعد العرض الأول. من الواضح أنه كلما انخفض كلا المقياسين ، كان الأداء أفضل.
ماذا عن الخطوط المتغيرة ، قد تسأل؟ من المهم ملاحظة أن الخطوط المتغيرة قد تتطلب اعتبارًا كبيرًا للأداء. إنها توفر لنا مساحة تصميم أوسع بكثير لاختيارات الطباعة ، ولكنها تأتي على حساب طلب تسلسلي واحد مقابل عدد من طلبات الملفات الفردية.
بينما تقلل الخطوط المتغيرة بشكل كبير الحجم الإجمالي للملف المدمج لملفات الخطوط ، قد يكون هذا الطلب الفردي بطيئًا ، مما يحظر عرض كل المحتوى على الصفحة. لذا فإن تقسيم الخط وتقسيمه إلى مجموعات أحرف لا يزال مهمًا. على الجانب الجيد ، مع وجود خط متغير في مكانه ، سنحصل على تدفق واحد بالضبط افتراضيًا ، لذلك لن تكون هناك حاجة إلى JavaScript لتجميع عمليات إعادة الطلاء.
الآن ، ما الذي يجعل استراتيجية تحميل خط الويب المضاد للرصاص بعد ذلك؟ اجمع الخطوط وقم بإعدادها للعرض على مرحلتين ، وقم بتعريفها باستخدام واصف
font-display
، واستخدم Font Loading API لتجميع إعادة رسم الخطوط وتخزينها في ذاكرة التخزين المؤقت لعامل الخدمة الثابتة. في الزيارة الأولى ، قم بحقن التحميل المسبق للنصوص قبل حظر البرامج النصية الخارجية. يمكنك الرجوع إلى برنامج Font Face Observer الخاص بـ Bram Stein إذا لزم الأمر. وإذا كنت مهتمًا بقياس أداء تحميل الخط ، فإن Andreas Marschke يستكشف تتبع الأداء باستخدام Font API و UserTiming API.أخيرًا ، لا تنسَ تضمين
unicode-range
لتقسيم خط كبير إلى خطوط أصغر خاصة باللغة ، واستخدم أداة مطابقة نمط الخط في Monica Dinculescu لتقليل التغيير المتناقض في التخطيط ، بسبب الاختلافات في الحجم بين الخيار الاحتياطي و خطوط الويب.بدلاً من ذلك ، لمحاكاة خط ويب لخط احتياطي ، يمكننا استخدام واصفات @ font-face لتجاوز مقاييس الخط (عرض تم تمكينه في Chrome 87). (لاحظ أن عمليات الضبط معقدة مع حزم الخطوط المعقدة.)
هل يبدو المستقبل مشرقًا؟ من خلال تحسين الخط التدريجي ، قد نتمكن في النهاية من "تنزيل الجزء المطلوب فقط من الخط في أي صفحة معينة ، وللطلبات اللاحقة لهذا الخط من أجل" تصحيح "التنزيل الأصلي ديناميكيًا بمجموعات إضافية من الصور الرمزية كما هو مطلوب في الصفحة المتعاقبة المشاهدات "، كما يشرحها جايسون باتالي. العرض التوضيحي للتحويل التزايدي متاح بالفعل ، وجاري العمل عليه.
بناء التحسينات
- هل حددنا أولوياتنا؟
إنها لفكرة جيدة أن تعرف ما الذي تتعامل معه أولاً. قم بإجراء جرد لجميع الأصول الخاصة بك (جافا سكريبت ، الصور ، الخطوط ، نصوص الطرف الثالث والوحدات النمطية "باهظة الثمن" على الصفحة ، مثل الدوارات والرسوم البيانية المعقدة ومحتوى الوسائط المتعددة) ، وقم بتقسيمها في مجموعات.قم بإعداد جدول بيانات . حدد التجربة الأساسية الأساسية للمتصفحات القديمة (أي المحتوى الأساسي الذي يمكن الوصول إليه بالكامل) ، والتجربة المحسّنة للمتصفحات القادرة (أي تجربة غنية وكاملة) والإضافات (الأصول غير المطلوبة تمامًا ويمكن تحميلها كسولًا ، مثل خطوط الويب والأنماط غير الضرورية والنصوص الدائرية ومشغلات الفيديو وأدوات الوسائط الاجتماعية والصور الكبيرة). منذ سنوات ، نشرنا مقالًا بعنوان "تحسين أداء مجلة Smashing" ، يصف هذا النهج بالتفصيل.
عند تحسين الأداء ، نحتاج إلى عكس أولوياتنا. قم بتحميل التجربة الأساسية على الفور ، ثم التحسينات ، ثم الإضافات .
- هل تستخدم وحدات JavaScript أصلية في الإنتاج؟
هل تتذكر تقنية ol 'cut-the-mustard الجيدة لإرسال التجربة الأساسية إلى المتصفحات القديمة وتجربة محسّنة إلى المتصفحات الحديثة؟ يمكن أن يستخدم المتغير المحدث للتقنية ES2017 +<script type="module">
، المعروف أيضًا باسم نمط الوحدة النمطية / النموذجية (قدمه أيضًا Jeremy Wagner باعتباره خدمة تفاضلية ).تكمن الفكرة في تجميع حزمتين منفصلتين من جافا سكريبت وتقديمهما : الإصدار "العادي" ، والآخر مع تحويلات Babel و polyfills وتقديمها فقط للمتصفحات القديمة التي تحتاجها بالفعل ، وحزمة أخرى (نفس الوظيفة) لا تحتوي على تحويلات أو بوليفيل.
نتيجة لذلك ، نساعد في تقليل حظر سلسلة الرسائل الرئيسية عن طريق تقليل كمية البرامج النصية التي يحتاج المتصفح إلى معالجتها. نشر Jeremy Wagner مقالًا شاملاً حول الخدمة التفاضلية وكيفية إعدادها في خط أنابيب البناء ، بدءًا من إعداد Babel إلى التعديلات التي ستحتاج إلى إجرائها في Webpack ، فضلاً عن فوائد القيام بكل هذا العمل.
يتم تأجيل البرامج النصية لوحدة JavaScript الأصلية افتراضيًا ، لذلك أثناء إجراء تحليل HTML ، سيقوم المتصفح بتنزيل الوحدة النمطية الرئيسية.
يتم تأجيل وحدات JavaScript النمطية بشكل افتراضي. كل شيء تقريبًا عن وحدات JavaScript الأصلية. (معاينة كبيرة) ملاحظة واحدة للتحذير: يمكن أن يؤدي نمط الوحدة النمطية / الوحدة النمطية إلى نتائج عكسية على بعض العملاء ، لذلك قد ترغب في التفكير في حل بديل: نمط العرض التفاضلي الأقل خطورة لجيريمي والذي ، مع ذلك ، يتجنب الماسح الضوئي للتحميل المسبق ، مما قد يؤثر على الأداء بطرق قد لا يتوقع. ( شكرا جيريمي! )
في الواقع ، يدعم Rollup الوحدات النمطية كتنسيق إخراج ، لذا يمكننا تجميع التعليمات البرمجية ونشر الوحدات النمطية في الإنتاج. يحتوي Parcel على دعم للوحدة النمطية في Parcel 2. بالنسبة إلى Webpack ، تعمل الوحدة النمطية-Nomodule-plugin على أتمتة إنشاء البرامج النصية للوحدة / الوحدة النمطية.
ملاحظة : تجدر الإشارة إلى أن اكتشاف الميزة وحده لا يكفي لاتخاذ قرار مستنير بشأن الحمولة التي سيتم شحنها إلى ذلك المتصفح. في حد ذاته ، لا يمكننا استنتاج قدرة الجهاز من إصدار المتصفح. على سبيل المثال ، تعمل هواتف Android الرخيصة في البلدان النامية في الغالب على Chrome وستقطع الخردل على الرغم من محدودية الذاكرة وقدرات وحدة المعالجة المركزية.
في النهاية ، باستخدام رأس تلميحات عميل ذاكرة الجهاز ، سنكون قادرين على استهداف الأجهزة المنخفضة بشكل أكثر موثوقية. في وقت الكتابة ، يتم دعم العنوان في Blink فقط (ينطبق على تلميحات العميل بشكل عام). نظرًا لأن ذاكرة الجهاز تحتوي أيضًا على واجهة برمجة تطبيقات JavaScript متوفرة في Chrome ، فقد يكون أحد الخيارات هو اكتشاف الميزة استنادًا إلى واجهة برمجة التطبيقات ، والعودة إلى نمط الوحدة النمطية / الوحدة النمطية إذا لم يكن مدعومًا ( شكرًا ، Yoav! ).
- هل تستخدم اهتزاز الشجرة ورفع النطاق وتقسيم الشفرة؟
تعد Tree-shaking طريقة لتنظيف عملية الإنشاء الخاصة بك عن طريق تضمين التعليمات البرمجية المستخدمة بالفعل في الإنتاج والقضاء على عمليات الاستيراد غير المستخدمة في Webpack. مع Webpack و Rollup ، لدينا أيضًا نطاق رفع يسمح لكلا الأداتين باكتشاف مكان تسوية تسلسلimport
وتحويله إلى وظيفة مضمنة واحدة دون المساس بالشفرة. مع Webpack ، يمكننا أيضًا استخدام JSON Tree Shaking.تقسيم الكود هو ميزة أخرى في Webpack تقوم بتقسيم قاعدة التعليمات البرمجية الخاصة بك إلى "أجزاء" يتم تحميلها عند الطلب. لا يلزم تنزيل جميع جافا سكريبت وتحليلها وتجميعها على الفور. بمجرد تحديد نقاط الانقسام في التعليمات البرمجية الخاصة بك ، يمكن لـ Webpack الاهتمام بالتبعية والملفات الناتجة. يمكّنك من الحفاظ على التنزيل الأولي صغيرًا وطلب رمز عند الطلب عندما يطلبه التطبيق. لدى Alexander Kondrov مقدمة رائعة لتقسيم الشفرة باستخدام Webpack و React.
ضع في اعتبارك استخدام المكون الإضافي preload-webpack-plugin الذي يأخذ المسارات التي تقوم بتقسيم الشفرة ثم يطالب المتصفح بتحميلها مسبقًا باستخدام
<link rel="preload">
أو<link rel="prefetch">
. تمنح التوجيهات المضمنة في Webpack بعض التحكم فيpreload
/prefetch
. (احترس من مشكلات تحديد الأولويات.)أين تحدد نقاط الانقسام؟ من خلال تتبع أي أجزاء من CSS / JavaScript يتم استخدامها وأيها غير مستخدمة. يشرح Umar Hansa كيف يمكنك استخدام Code Coverage من Devtools لتحقيق ذلك.
عند التعامل مع التطبيقات ذات الصفحة الواحدة ، نحتاج إلى بعض الوقت لتهيئة التطبيق قبل أن نتمكن من عرض الصفحة. سيتطلب إعدادك حلك المخصص ، ولكن يمكنك الانتباه للوحدات والأساليب لتسريع وقت العرض الأولي. على سبيل المثال ، إليك كيفية تصحيح أخطاء أداء React والتخلص من مشكلات أداء React الشائعة ، وإليك كيفية تحسين الأداء في Angular. بشكل عام ، تأتي معظم مشكلات الأداء من الوقت الأولي لبدء تشغيل التطبيق.
إذن ، ما هي أفضل طريقة لتقسيم الشفرة بقوة ، ولكن ليس بقوة مفرطة؟ وفقًا لفيل والتون ، "بالإضافة إلى تقسيم الشفرة عبر عمليات الاستيراد الديناميكية ، [يمكننا] أيضًا استخدام تقسيم الكود على مستوى الحزمة ، حيث يتم وضع كل وحدة عقدة مستوردة في قطعة بناءً على اسم الحزمة الخاصة بها." يقدم Phil برنامجًا تعليميًا حول كيفية بنائه أيضًا.
- هل يمكننا تحسين إخراج Webpack؟
نظرًا لأن Webpack غالبًا ما يُعتبر غامضًا ، فهناك الكثير من مكونات Webpack الإضافية التي قد تكون مفيدة لتقليل إنتاج Webpack بشكل أكبر. فيما يلي بعض العناصر الأكثر غموضًا والتي قد تحتاج إلى مزيد من الاهتمام.واحدة من الأشياء المثيرة للاهتمام تأتي من خيط إيفان أكولوف. تخيل أن لديك دالة قمت باستدعاءها مرة واحدة ، وقم بتخزين نتيجتها في متغير ، ثم لا تستخدم هذا المتغير. سيؤدي اهتزاز الشجرة إلى إزالة المتغير ، ولكن ليس الوظيفة ، لأنه قد يتم استخدامه بطريقة أخرى. ومع ذلك ، إذا لم يتم استخدام الوظيفة في أي مكان ، فقد ترغب في إزالتها. للقيام بذلك ، قم بإرفاق استدعاء الوظيفة مسبقًا بـ
/*#__PURE__*/
الذي يدعمه Uglify و Terser - تم!لإزالة مثل هذه الوظيفة عندما لا يتم استخدام نتيجتها ، قم بإرفاق استدعاء الوظيفة مسبقًا بـ /*#__PURE__*/
. عبر إيفان أكولوف (معاينة كبيرة)فيما يلي بعض الأدوات الأخرى التي يوصي بها إيفان:
- يقوم المكون الإضافي purgecss-webpack بإزالة الفئات غير المستخدمة ، خاصةً عند استخدام Bootstrap أو Tailwind.
- تفعيل
optimization.splitChunks: 'all'
مع المكوّن الإضافي Split-chunks. هذا من شأنه أن يجعل حزمة الويب تقوم تلقائيًا بتقسيم حزم الإدخال الخاصة بك لتحسين التخزين المؤقت. - تعيين
optimization.runtimeChunk: true
. سيؤدي ذلك إلى نقل وقت تشغيل webpack إلى جزء منفصل - وسيؤدي أيضًا إلى تحسين التخزين المؤقت. - يقوم المكون الإضافي google-Fonts-webpack-plugin بتنزيل ملفات الخطوط ، حتى تتمكن من تقديمها من الخادم الخاص بك.
- يسمح لك المكون الإضافي workbox-webpack-بتوليد عامل خدمة بإعداد مسبق لجميع أصول webpack الخاصة بك. تحقق أيضًا من حزم عمال الخدمة ، وهو دليل شامل للوحدات التي يمكن تطبيقها على الفور. أو استخدم البرنامج الإضافي للتحميل المسبق webpack لإنشاء
preload
/prefetch
لجميع أجزاء JavaScript. - يقيس المكون الإضافي لقياس السرعة webpack سرعة إنشاء حزمة الويب الخاصة بك ، مما يوفر رؤى حول خطوات عملية الإنشاء التي تستغرق وقتًا طويلاً.
- يحذر المكون الإضافي المكرر للحزمة-المدقق-webpack-عندما تحتوي الحزمة الخاصة بك على إصدارات متعددة من نفس الحزمة.
- استخدم عزل النطاق واختصر أسماء فئات CSS ديناميكيًا في وقت التجميع.
- هل يمكنك إلغاء تحميل JavaScript إلى Web Worker؟
لتقليل التأثير السلبي على Time-to-Interactive ، قد يكون من الجيد النظر في تفريغ JavaScript ثقيل في Web Worker.مع استمرار نمو قاعدة الشفرة ، ستظهر اختناقات أداء واجهة المستخدم ، مما يؤدي إلى إبطاء تجربة المستخدم. ذلك لأن عمليات DOM تعمل جنبًا إلى جنب مع JavaScript في السلسلة الرئيسية. مع العاملين على الويب ، يمكننا نقل هذه العمليات باهظة الثمن إلى عملية في الخلفية تعمل على مؤشر ترابط مختلف. حالات الاستخدام النموذجية للعاملين على الويب هي الجلب المسبق للبيانات وتطبيقات الويب التقدمية لتحميل بعض البيانات وتخزينها مسبقًا بحيث يمكنك استخدامها لاحقًا عند الحاجة. ويمكنك استخدام Comlink لتبسيط الاتصال بين الصفحة الرئيسية والعامل. لا يزال هناك بعض العمل الذي يتعين القيام به ، لكننا نصل إلى هناك.
هناك عدد قليل من دراسات الحالة المثيرة للاهتمام حول العاملين على الويب والتي تُظهر مناهج مختلفة لنقل الإطار ومنطق التطبيق للعاملين على الويب. الاستنتاج: بشكل عام ، لا تزال هناك بعض التحديات ، ولكن هناك بعض حالات الاستخدام الجيدة بالفعل ( شكرًا إيفان أكولوف! ).
بدءًا من Chrome 80 ، تم طرح وضع جديد للعاملين على الويب مع مزايا أداء وحدات جافا سكريبت ، يسمى عمال الوحدة. يمكننا تغيير تحميل البرنامج النصي وتنفيذه لمطابقة
script type="module"
، بالإضافة إلى أنه يمكننا أيضًا استخدام عمليات الاستيراد الديناميكية لرمز التحميل البطيء دون حظر تنفيذ العامل.كيف تبدأ؟ إليك بعض الموارد التي تستحق البحث فيها:
- نشرت Surma دليلاً ممتازًا حول كيفية تشغيل JavaScript من الخيط الرئيسي للمتصفح وأيضًا متى يجب أن تستخدم Web Workers؟
- تحقق أيضًا من حديث سورما عن هندسة الخيط الرئيسي.
- يوفر مسعى لضمان الاستجابة من قبل Shubhie Panicker و Jason Miller نظرة ثاقبة حول كيفية استخدام العاملين على الويب ، ومتى يتم تجنبهم.
- الخروج من طريقة المستخدمين: يسلط أقل العبث مع عمال الويب الضوء على أنماط مفيدة للعمل مع عمال الويب ، والطرق الفعالة للتواصل بين العمال ، والتعامل مع معالجة البيانات المعقدة من السلسلة الرئيسية ، واختبارها وتصحيحها.
- يسمح لك Workerize بنقل وحدة نمطية إلى Web Worker ، مما يعكس تلقائيًا الوظائف التي تم تصديرها كوكلاء وكلاء غير متزامنين.
- إذا كنت تستخدم Webpack ، فيمكنك استخدام أداة تحميل عاملة. بدلاً من ذلك ، يمكنك استخدام العامل الإضافي أيضًا.
استخدم العاملين على الويب عند حظر التعليمات البرمجية لفترة طويلة ، ولكن تجنبهم عندما تعتمد على DOM ، والتعامل مع استجابة الإدخال وتحتاج إلى أدنى حد من التأخير. (عبر آدي عثماني) (معاينة كبيرة) لاحظ أن عمال الويب ليس لديهم حق الوصول إلى DOM لأن DOM ليس "آمنًا لمؤشر الترابط" ، وأن الكود الذي ينفذه يجب أن يتم تضمينه في ملف منفصل.
- هل يمكنك إلغاء تحميل "المسارات الفعالة" إلى WebAssembly؟
يمكننا إلغاء تحميل المهام الثقيلة من الناحية الحسابية إلى WebAssembly ( WASM ) ، وهو تنسيق تعليمات ثنائي ، مصمم كهدف محمول لتجميع اللغات عالية المستوى مثل C / C ++ / Rust. يعد دعم المستعرض الخاص به رائعًا ، وقد أصبح مؤخرًا قابلاً للتطبيق حيث تزداد سرعة استدعاءات الوظائف بين JavaScript و WASM. بالإضافة إلى أنه مدعوم حتى على سحابة Fastly's edge.بالطبع ، ليس من المفترض أن يحل WebAssembly محل JavaScript ، ولكنه يمكن أن يكملها في الحالات التي تلاحظ فيها وجود خراطيم في وحدة المعالجة المركزية. بالنسبة لمعظم تطبيقات الويب ، تعد JavaScript أكثر ملاءمة ، ويتم استخدام WebAssembly بشكل أفضل لتطبيقات الويب كثيفة العمليات الحسابية ، مثل الألعاب.
إذا كنت ترغب في معرفة المزيد حول WebAssembly:
- كتب Lin Clark سلسلة شاملة إلى WebAssembly ويقدم Milica Mihajlija نظرة عامة عامة على كيفية تشغيل التعليمات البرمجية الأصلية في المتصفح ، ولماذا قد ترغب في القيام بذلك ، وما يعنيه كل ذلك لجافا سكريبت ومستقبل تطوير الويب.
- كيف استخدمنا WebAssembly لتسريع تطبيق الويب الخاص بنا بحلول 20X (دراسة حالة) يسلط الضوء على دراسة حالة عن كيفية استبدال حسابات JavaScript البطيئة بحساب WebAssembly المجمع وإدخال تحسينات كبيرة على الأداء.
- كان باتريك هامان يتحدث عن الدور المتنامي لـ WebAssembly ، وقد كشف زيف بعض الأساطير حول WebAssembly ، ويستكشف تحدياته ويمكننا استخدامه عمليًا في التطبيقات اليوم.
- توفر Google Codelabs مقدمة إلى WebAssembly ، وهي دورة تدريبية مدتها 60 دقيقة ستتعلم فيها كيفية أخذ التعليمات البرمجية الأصلية - في لغة C وترجمتها إلى WebAssembly ، ثم استدعائها مباشرةً من JavaScript.
- شرح أليكس دانيلو WebAssembly وكيف يعمل في حديثه في Google I / O. أيضًا ، شارك Benedek Gagyi دراسة حالة عملية حول WebAssembly ، وتحديدًا كيف يستخدمه الفريق كتنسيق إخراج لقاعدة رموز C ++ الخاصة بهم إلى iOS و Android والموقع الإلكتروني.
هل ما زلت غير متأكد من موعد استخدام Web Workers أو Web Assembly أو التدفقات أو ربما WebGL JavaScript API للوصول إلى وحدة معالجة الرسومات؟ يعد Accelerating JavaScript دليلًا قصيرًا ولكنه مفيد يشرح متى يجب استخدام ماذا ولماذا - أيضًا مع مخطط انسيابي سهل الاستخدام والكثير من الموارد المفيدة.

- هل نقدم الكود القديم فقط للمتصفحات القديمة؟
نظرًا لكون ES2017 مدعومًا بشكل ملحوظ في المتصفحات الحديثة ، يمكننا استخدامbabelEsmPlugin
لتحويل ميزات ES2017 + غير المدعومة من المتصفحات الحديثة التي تستهدفها فقط.نشر حسين جرده وجيسون ميللر مؤخرًا دليلًا شاملاً حول كيفية تحويل جافا سكريبت الحديثة والقديمة وخدمةهما ، مع الخوض في تفاصيل جعلها تعمل مع Webpack و Rollup ، والأدوات اللازمة. يمكنك أيضًا تقدير مقدار JavaScript الذي يمكنك تقليله على موقعك أو حزم التطبيق.
يتم دعم وحدات JavaScript النمطية في جميع المتصفحات الرئيسية ، لذا استخدم
script type="module"
للسماح للمتصفحات التي تدعم وحدة ES بتحميل الملف ، بينما يمكن للمتصفحات القديمة تحميل الإنشاءات القديمة باستخدامscript nomodule
.في هذه الأيام ، يمكننا كتابة JavaScript قائم على الوحدة النمطية يتم تشغيله أصلاً في المتصفح ، بدون تحويلات أو حزم. يوفر رأس
<link rel="modulepreload">
طريقة لبدء التحميل المبكر (وذات الأولوية العالية) للنصوص البرمجية للوحدة. في الأساس ، إنها طريقة رائعة للمساعدة في تعظيم استخدام النطاق الترددي ، من خلال إخبار المتصفح بما يحتاج إلى جلبه حتى لا يتعطل بأي شيء يمكن القيام به خلال تلك الرحلات الطويلة ذهابًا وإيابًا. أيضًا ، نشر Jake Archibald مقالًا تفصيليًا يحتوي على مشاكل وأشياء يجب وضعها في الاعتبار مع ES Modules التي تستحق القراءة.

- تحديد وإعادة كتابة التعليمات البرمجية القديمة بفصل تزايدي .
تميل المشاريع طويلة العمر إلى جمع الغبار والتعليمات البرمجية القديمة. قم بإعادة النظر في تبعياتك وتقييم مقدار الوقت المطلوب لإعادة بناء أو إعادة كتابة التعليمات البرمجية القديمة التي تسببت في حدوث مشكلات مؤخرًا. بالطبع ، إنها مهمة كبيرة دائمًا ، ولكن بمجرد معرفة تأثير الشفرة القديمة ، يمكنك البدء بالفصل التدريجي.أولاً ، قم بإعداد المقاييس التي تتعقب ما إذا كانت نسبة مكالمات الشفرة القديمة تظل ثابتة أم تنخفض أم لا. ثني الفريق علنًا عن استخدام المكتبة وتأكد من أن CI الخاص بك ينبه المطورين إذا تم استخدامه في طلبات السحب. يمكن أن تساعد polyfills في الانتقال من التعليمات البرمجية القديمة إلى التعليمات البرمجية المعاد كتابتها التي تستخدم ميزات المتصفح القياسية.
- تحديد وإزالة CSS / JS غير المستخدمة .
تتيح لك تغطية كود CSS وجافا سكريبت في Chrome معرفة الكود الذي تم تنفيذه / تطبيقه وأيها لم يتم تنفيذه. يمكنك البدء في تسجيل التغطية ، وتنفيذ الإجراءات على الصفحة ، ثم استكشاف نتائج تغطية الكود. بمجرد اكتشاف الكود غير المستخدم ، ابحث عن تلك الوحدات وحملها كسول معimport()
(انظر الموضوع بأكمله). ثم كرر ملف تعريف التغطية وتحقق من أنه يشحن الآن رمزًا أقل عند التحميل الأولي.يمكنك استخدام محرك العرائس لتجميع تغطية الكود برمجيًا. يسمح لك Chrome بتصدير نتائج تغطية التعليمات البرمجية أيضًا. كما لاحظ Andy Davies ، قد ترغب في جمع تغطية التعليمات البرمجية لكل من المتصفحات الحديثة والقديمة.
هناك العديد من حالات الاستخدام والأدوات الأخرى لـ Puppetter التي قد تحتاج إلى مزيد من التعرض قليلاً:
- حالات الاستخدام لمحرك العرائس ، مثل ، على سبيل المثال ، التوزيع البصري التلقائي أو مراقبة CSS غير المستخدمة مع كل بناء ،
- وصفات أداء الويب باستخدام محرك العرائس ،
- أدوات مفيدة لتسجيل وإنشاء سيناريوهات Pupeeteer وكاتب المسرحي ،
- بالإضافة إلى ذلك ، يمكنك تسجيل الاختبارات مباشرة في DevTools ،
- نظرة عامة شاملة على محرك العرائس من تأليف نيتاي نيمان ، مع أمثلة وحالات استخدام.
يمكننا استخدام Puppeteer Recorder و Puppeteer Sandbox لتسجيل تفاعل المتصفح وإنشاء نصوص لمحرك الدمى وكاتب المسرحي. (معاينة كبيرة) علاوة على ذلك ، يمكن أن تساعدك purgecss و UnCSS و Helium على إزالة الأنماط غير المستخدمة من CSS. وإذا لم تكن متأكدًا من استخدام جزء مشبوه من التعليمات البرمجية في مكان ما ، فيمكنك اتباع نصيحة Harry Roberts: قم بإنشاء صورة GIF شفافة 1 × 1 بكسل لفئة معينة وقم بإسقاطها في دليل
dead/
، على سبيل المثال/assets/img/dead/comments.gif
.بعد ذلك ، يمكنك تعيين تلك الصورة المحددة كخلفية على المحدد المقابل في CSS الخاص بك ، والجلوس والانتظار لبضعة أشهر إذا كان الملف سيظهر في سجلاتك. إذا لم تكن هناك إدخالات ، فلن يتم عرض هذا المكون القديم على شاشته: ربما يمكنك المضي قدمًا وحذفه جميعًا.
بالنسبة إلى قسم "أنا أشعر بالمغامرة" ، يمكنك حتى أتمتة عملية التجميع على CSS غير المستخدمة من خلال مجموعة من الصفحات من خلال مراقبة DevTools باستخدام DevTools.

- قلص حجم حزم JavaScript الخاصة بك.
كما لاحظت Addy Osmani ، هناك فرصة كبيرة لشحن مكتبات JavaScript كاملة عندما تحتاج فقط إلى جزء صغير ، إلى جانب polyfills مؤرخة للمتصفحات التي لا تحتاج إليها ، أو مجرد رمز مكرر. لتجنب الحمل الزائد ، ضع في اعتبارك استخدام تحسينات webpack-libs التي تزيل الطرق غير المستخدمة والحشوات المتعددة أثناء عملية الإنشاء.تحقق ومراجعة polyfills التي ترسلها إلى المتصفحات القديمة وإلى المتصفحات الحديثة ، وكن أكثر استراتيجية فيما يتعلق بها. ألق نظرة على polyfill.io وهي خدمة تقبل طلبًا لمجموعة من ميزات المتصفح وتعيد فقط polyfill التي يحتاجها المتصفح الطالب.
أضف تدقيق الحزمة إلى سير عملك المعتاد أيضًا. قد تكون هناك بعض البدائل الخفيفة للمكتبات الثقيلة التي أضفتها منذ سنوات ، على سبيل المثال ، يمكن استبدال Moment.js (التي تم إيقافها الآن) بـ:
- واجهة برمجة تطبيقات التدويل الأصلية ،
- Day.js باستخدام واجهة برمجة تطبيقات وأنماط Moment.js مألوفة ،
- تاريخ fns أو
- لوكسون.
- يمكنك أيضًا استخدام Skypack Discover الذي يجمع بين توصيات الحزم التي تمت مراجعتها بواسطة الإنسان والبحث الذي يركز على الجودة.
أظهر بحث Benedikt Rotsch أن التبديل من Moment.js إلى date-fns يمكن أن يحلق حوالي 300 مللي ثانية لطلاء First على 3G وهاتف محمول منخفض التكلفة.
لتدقيق الحزم ، يمكن أن تساعد Bundlephobia في العثور على تكلفة إضافة حزمة npm إلى حزمتك. يمتد حد الحجم لفحص حجم الحزمة الأساسي بتفاصيل عن وقت تنفيذ JavaScript. يمكنك حتى دمج هذه التكاليف مع Lighthouse Custom Audit. هذا ينطبق أيضا على الأطر. عن طريق إزالة أو قص محول Vue MDC (المكونات المادية لـ Vue) ، تنخفض الأنماط من 194 كيلو بايت إلى 10 كيلو بايت.
هناك العديد من الأدوات الأخرى لمساعدتك على اتخاذ قرار مستنير بشأن تأثير التبعيات والبدائل القابلة للتطبيق:
- محلل حزمة حزمة الويب
- مستكشف خريطة المصدر
- حزمة الأصدقاء
- رهاب البوندلفوبيا
- يوضح تحليل Webpack سبب تضمين وحدة نمطية معينة في الحزمة.
- يُنشئ bundle-wizard أيضًا خريطة التبعيات للصفحة بأكملها.
- حجم البرنامج المساعد Webpack
- تكلفة استيراد الكود المرئي
بدلاً من شحن إطار العمل بالكامل ، يمكنك قص إطار العمل الخاص بك وتجميعه في حزمة JavaScript خام لا تتطلب رمزًا إضافيًا. يقوم Svelte بذلك ، وكذلك المكون الإضافي Rawact Babel الذي يقوم بنقل مكونات React.js إلى عمليات DOM الأصلية في وقت الإنشاء. لماذا ا؟ حسنًا ، كما يشرح المسؤولون عن الصيانة ، "يشتمل رد فعل دوم على رمز لكل مكون / HTMLElement محتمل يمكن تقديمه ، بما في ذلك رمز للعرض المتزايد والجدولة ومعالجة الأحداث وما إلى ذلك. ولكن هناك تطبيقات لا تحتاج إلى كل هذه الميزات (في البداية صفحة تحميل). بالنسبة لمثل هذه التطبيقات ، قد يكون من المنطقي استخدام عمليات DOM الأصلية لبناء واجهة مستخدم تفاعلية. "

- هل نستخدم الترطيب الجزئي؟
مع كمية JavaScript المستخدمة في التطبيقات ، نحتاج إلى اكتشاف طرق لإرسال أقل قدر ممكن إلى العميل. إحدى طرق القيام بذلك - وقد قمنا بتغطيتها لفترة وجيزة بالفعل - هي الترطيب الجزئي. الفكرة بسيطة للغاية: بدلاً من إجراء SSR ثم إرسال التطبيق بالكامل إلى العميل ، سيتم إرسال أجزاء صغيرة فقط من JavaScript للتطبيق إلى العميل ثم ترطيبها. يمكننا التفكير في الأمر على أنه العديد من تطبيقات React الصغيرة التي لها جذور عرض متعددة على موقع ويب ثابت بخلاف ذلك.في مقال بعنوان "حالة الترطيب الجزئي (مع Next and Preact)" ، يشرح Lukas Bombach كيف حقق الفريق الذي يقف وراء Welt.de ، أحد المنافذ الإخبارية في ألمانيا ، أداءً أفضل مع الترطيب الجزئي. يمكنك أيضًا التحقق من GitHub repo ذي الأداء الفائق التالي مع التوضيحات ومقتطفات التعليمات البرمجية.
يمكنك أيضًا التفكير في خيارات بديلة:
- ترطيب جزئي مع Preact و Eleventy ،
- ترطيب تدريجي في React GitHub repo ،
- ترطيب كسول في Vue.js (GitHub repo) ،
- الاستيراد على نمط التفاعل للتحميل البطيء للموارد غير الحرجة (مثل المكونات والتضمينات) عندما يتفاعل المستخدم مع واجهة المستخدم التي تحتاجها.
نشر Jason Miller عروضًا توضيحية عملية حول كيفية تنفيذ الترطيب التدريجي باستخدام React ، بحيث يمكنك استخدامها على الفور: العرض 1 ، العرض 2 ، العرض 3 (متاح أيضًا على GitHub). بالإضافة إلى ذلك ، يمكنك البحث في مكتبة مكونات التفاعل المسبق.
يجب ألا يتم الاستيراد عند التفاعل لرمز الطرف الأول إلا إذا كنت غير قادر على الجلب المسبق للموارد قبل التفاعل. (معاينة كبيرة) - هل قمنا بتحسين استراتيجية React / SPA؟
هل تواجه صعوبة في الأداء في تطبيق التطبيق أحادي الصفحة؟ استكشف Jeremy Wagner تأثير أداء إطار العمل من جانب العميل على مجموعة متنوعة من الأجهزة ، وسلط الضوء على بعض الآثار والإرشادات التي قد نرغب في أن نكون على دراية بها عند استخدام أحدها.نتيجةً لذلك ، إليك إستراتيجية SPA التي اقترحها جيريمي لاستخدامها في إطار عمل React (ولكن لا ينبغي أن تتغير بشكل كبير في الأطر الأخرى):
- إعادة بناء المكونات ذات الحالة الخاصة كمكونات عديمة الحالة كلما أمكن ذلك.
- عرض المكونات عديمة الحالة مسبقًا عندما يكون ذلك ممكنًا لتقليل وقت استجابة الخادم. تقدم فقط على الخادم.
- بالنسبة للمكونات ذات الحالة ذات التفاعل البسيط ، ضع في اعتبارك العرض المسبق أو عرض الخادم لهذا المكون ، واستبدل تفاعله مع مستمعين للحدث لا يعتمد على إطار العمل .
- إذا كان يجب عليك ترطيب المكونات ذات الحالة على العميل ، فاستخدم الترطيب الكسول في الرؤية أو التفاعل.
- بالنسبة للمكونات ذات الترطيب البطيء ، قم بجدولة ترطيبها أثناء وقت خمول الخيط الرئيسي مع
requestIdleCallback
.
هناك بعض الاستراتيجيات الأخرى التي قد ترغب في متابعتها أو مراجعتها:
- اعتبارات الأداء لـ CSS-in-JS في تطبيقات React
- قم بتقليل حجم حزمة Next.js عن طريق تحميل polyfill فقط عند الضرورة ، باستخدام الواردات الديناميكية والترطيب البطيء.
- أسرار جافا سكريبت: قصة التفاعل وتحسين الأداء والترابط المتعدد ، سلسلة طويلة من 7 أجزاء حول تحسين تحديات واجهة المستخدم باستخدام React ،
- كيفية قياس أداء React وكيفية تكوين ملف تعريف تطبيقات React.
- بناء الرسوم المتحركة للويب على الهاتف المحمول لأول مرة في React ، حديث رائع بواسطة Alex Holachek ، جنبًا إلى جنب مع الشرائح و GitHub repo ( شكرًا للنصيحة ، Addy! ).
- تعد تحسينات webpack-libs بمثابة مستودع GitHub رائع مع الكثير من التحسينات المفيدة المتعلقة بالأداء الخاصة بـ Webpack. احتفظ بها إيفان أكولوف.
- تفاعل تحسينات الأداء في Notion ، وهو دليل بواسطة Ivan Akulov حول كيفية تحسين الأداء في React ، مع الكثير من المؤشرات المفيدة لجعل التطبيق أسرع بنسبة 30٪ تقريبًا.
- يتيح لك المكون الإضافي لـ React Refresh Webpack (تجريبي) إعادة التحميل السريع الذي يحافظ على حالة المكون ، ويدعم الخطافات ومكونات الوظيفة.
- احترس من مكونات خادم React ذات الحجم الصفري ، وهي نوع جديد مقترح من المكونات التي لن يكون لها أي تأثير على حجم الحزمة. المشروع قيد التطوير حاليًا ، ولكن أي ملاحظات من المجتمع محل تقدير كبير (الشرح الرائع بقلم صوفي ألبرت).
- هل تستخدم الجلب المسبق التنبئي لأجزاء JavaScript؟
يمكننا استخدام الاستدلال لتحديد وقت تحميل أجزاء JavaScript مسبقًا. Guess.js عبارة عن مجموعة من الأدوات والمكتبات التي تستخدم بيانات Google Analytics لتحديد الصفحة التي من المرجح أن يزورها المستخدم بعد ذلك من صفحة معينة. استنادًا إلى أنماط تنقل المستخدم التي تم جمعها من Google Analytics أو من مصادر أخرى ، يبني Guess.js نموذجًا للتعلم الآلي للتنبؤ بجافا سكريبت وجلبه مسبقًا والذي سيكون مطلوبًا في كل صفحة لاحقة.ومن ثم ، يتلقى كل عنصر تفاعلي درجة احتمالية للمشاركة ، وبناءً على هذه النتيجة ، يقرر البرنامج النصي من جانب العميل إحضار مورد مسبقًا في وقت مبكر. يمكنك دمج التقنية مع تطبيق Next.js الخاص بك ، Angular و React ، وهناك ملحق Webpack الذي يعمل على أتمتة عملية الإعداد أيضًا.
من الواضح أنك قد تطالب المتصفح باستهلاك البيانات غير الضرورية والجلب المسبق للصفحات غير المرغوب فيها ، لذلك من الجيد أن تكون متحفظًا تمامًا في عدد الطلبات التي تم جلبها مسبقًا. قد تكون حالة الاستخدام الجيد هي الإحضار المسبق للنصوص البرمجية للتحقق من الصحة المطلوبة في عملية الدفع ، أو الجلب المسبق التخميني عندما تأتي عبارة مهمة تحث المستخدم على اتخاذ إجراء في منفذ العرض.
هل تحتاج إلى شيء أقل تعقيدًا؟ يقوم DNStradamus بإحضار DNS مسبقًا للروابط الصادرة كما تظهر في منفذ العرض. تعد Quicklink و InstantClick و Instant.page مكتبات صغيرة تقوم تلقائيًا بإحضار الروابط مسبقًا في منفذ العرض أثناء وقت الخمول في محاولة لجعل تنقلات الصفحة التالية يتم تحميلها بشكل أسرع. يتيح Quicklink إمكانية الجلب المسبق لمسارات React Router و Javascript ؛ بالإضافة إلى أنها تراعي البيانات ، لذا فهي لا تجلب مسبقًا على 2G أو إذا كان
Data-Saver
قيد التشغيل. وكذلك الحال بالنسبة إلى Instant.page إذا تم تعيين الوضع على استخدام الجلب المسبق لإطار العرض (وهو افتراضي).إذا كنت ترغب في النظر في علم الجلب المسبق التنبئي بالتفصيل الكامل ، فإن Divya Tagtachian لديها محادثة رائعة حول The Art of Predictive Prefetch ، تغطي جميع الخيارات من البداية إلى النهاية.
- استفد من التحسينات لمحرك JavaScript المستهدف.
ادرس ما تهيمن عليه محركات JavaScript في قاعدة المستخدمين لديك ، ثم استكشف طرق تحسينها. على سبيل المثال ، عند تحسين V8 الذي يتم استخدامه في متصفحات Blink ووقت تشغيل Node.js و Electron ، يمكنك الاستفادة من دفق البرنامج النصي للنصوص المتجانسة.يسمح دفق البرنامج النصي بتحليل
defer scripts
غيرasync
أو المؤجلة على سلسلة خلفية منفصلة بمجرد بدء التنزيل ، وبالتالي في بعض الحالات يتم تحسين أوقات تحميل الصفحة بنسبة تصل إلى 10٪. Practically, use<script defer>
in the<head>
, so that the browsers can discover the resource early and then parse it on the background thread.Caveat : Opera Mini doesn't support script deferment, so if you are developing for India or Africa,
defer
will be ignored, resulting in blocking rendering until the script has been evaluated (thanks Jeremy!) .You could also hook into V8's code caching as well, by splitting out libraries from code using them, or the other way around, merge libraries and their uses into a single script, group small files together and avoid inline scripts. Or perhaps even use v8-compile-cache.
When it comes to JavaScript in general, there are also some practices that are worth keeping in mind:
- Clean Code concepts for JavaScript, a large collection of patterns for writing readable, reusable, and refactorable code.
- You can Compress data from JavaScript with the CompressionStream API, eg to gzip before uploading data (Chrome 80+).
- Detached window memory leaks and Fixing memory leaks in web apps are detailed guides on how to find and fix tricky JavaScript memory leaks. Plus, you can use queryObjects(SomeConstructor) from the DevTools Console ( thanks, Mathias! ).
- Reexports are bad for loading and runtime performance, and avoiding them can help reduce the bundle size significantly.
- We can improve scroll performance with passive event listeners by setting a flag in the
options
parameter. So browsers can scroll the page immediately, rather than after the listener has finished. (via Kayce Basques). - If you have any
scroll
ortouch*
listeners, passpassive: true
to addEventListener. This tells the browser you're not planning to callevent.preventDefault()
inside, so it can optimize the way it handles these events. (via Ivan Akulov) - We can achieve better JavaScript scheduling with isInputPending(), a new API that attempts to bridge the gap between loading and responsiveness with the concepts of interrupts for user inputs on the web, and allows for JavaScript to be able to check for input without yielding to the browser.
- You can also automatically remove an event listener after it has executed.
- Firefox's recently released Warp, a significant update to SpiderMonkey (shipped in Firefox 83), Baseline Interpreter and there are a few JIT Optimization Strategies available as well.



- Always prefer to self-host third-party assets.
Yet again, self-host your static assets by default. It's common to assume that if many sites use the same public CDN and the same version of a JavaScript library or a web font, then the visitors would land on our site with the scripts and fonts already cached in their browser, speeding up their experience considerably. However, it's very unlikely to happen.For security reasons, to avoid fingerprinting, browsers have been implementing partitioned caching that was introduced in Safari back in 2013, and in Chrome last year. So if two sites point to the exact same third-party resource URL, the code is downloaded once per domain , and the cache is "sandboxed" to that domain due to privacy implications ( thanks, David Calhoun! ). Hence, using a public CDN will not automatically lead to better performance.
Furthermore, it's worth noting that resources don't live in the browser's cache as long as we might expect, and first-party assets are more likely to stay in the cache than third-party assets. Therefore, self-hosting is usually more reliable and secure, and better for performance, too.
- Constrain the impact of third-party scripts.
With all performance optimizations in place, often we can't control third-party scripts coming from business requirements. Third-party-scripts metrics aren't influenced by end-user experience, so too often one single script ends up calling a long tail of obnoxious third-party scripts, hence ruining a dedicated performance effort. To contain and mitigate performance penalties that these scripts bring along, it's not enough to just defer their loading and execution and warm up connections via resource hints, iedns-prefetch
orpreconnect
.Currently 57% of all JavaScript code excution time is spent on third-party code. The median mobile site accesses 12 third-party domains , with a median of 37 different requests (or about 3 requests made to each third party).
Furthermore, these third-parties often invite fourth-party scripts to join in, ending up with a huge performance bottleneck, sometimes going as far as to the eigth-party scripts on a page. So regularly auditing your dependencies and tag managers can bring along costly surprises.
Another problem, as Yoav Weiss explained in his talk on third-party scripts, is that in many cases these scripts download resources that are dynamic. The resources change between page loads, so we don't necessarily know which hosts the resources will be downloaded from and what resources they would be.
Deferring, as shown above, might be just a start though as third-party scripts also steal bandwidth and CPU time from your app. We could be a bit more aggressive and load them only when our app has initialized.
/* Before */ const App = () => { return <div> <script> window.dataLayer = window.dataLayer || []; function gtag(){...} gtg('js', new Date()); </script> </div> } /* After */ const App = () => { const[isRendered, setRendered] = useState(false); useEffect(() => setRendered(true)); return <div> {isRendered ? <script> window.dataLayer = window.dataLayer || []; function gtag(){...} gtg('js', new Date()); </script> : null} </div> }
In a fantastic post on "Reducing the Site-Speed Impact of Third-Party Tags", Andy Davies explores a strategy of minimizing the footprint of third-parties — from identifying their costs towards reducing their impact.
According to Andy, there are two ways tags impact site-speed — they compete for network bandwidth and processing time on visitors' devices, and depending on how they're implemented, they can delay HTML parsing as well. So the first step is to identify the impact that third-parties have, by testing the site with and without scripts using WebPageTest. With Simon Hearne's Request Map, we can also visualize third-parties on a page along with details on their size, type and what triggered their load.
Preferably self-host and use a single hostname, but also use a request map to exposes fourth-party calls and detect when the scripts change. You can use Harry Roberts' approach for auditing third parties and produce spreadsheets like this one (also check Harry's auditing workflow).
Afterwards, we can explore lightweight alternatives to existing scripts and slowly replace duplicates and main culprits with lighter options. Perhaps some of the scripts could be replaced with their fallback tracking pixel instead of the full tag.
Loading YouTube with facades, eg lite-youtube-embed that's significantly smaller than an actual YouTube player. (مصدر الصورة) (معاينة كبيرة) If it's not viable, we can at least lazy load third-party resources with facades, ie a static element which looks similar to the actual embedded third-party, but is not functional and therefore much less taxing on the page load. The trick, then, is to load the actual embed only on interaction .
For example, we can use:
- lite-vimeo-embed for the Vimeo player,
- lite-vimeo for the Vimeo player,
- lite-youtube-embed for the YouTube player,
- react-live-chat-loader for a live chat (case study, and another case-study),
- lazyframe for iframes.
One of the reasons why tag managers are usually large in size is because of the many simultaneous experiments that are running at the same time, along with many user segments, page URLs, sites etc., so according to Andy, reducing them can reduce both the download size and the time it takes to execute the script in the browser.
And then there are anti-flicker snippets. Third-parties such as Google Optimize, Visual Web Optimizer (VWO) and others are unanimous in using them. These snippets are usually injected along with running A/B tests : to avoid flickering between the different test scenarios, they hide the
body
of the document withopacity: 0
, then adds a function that gets called after a few seconds to bring theopacity
back. This often results in massive delays in rendering due to massive client-side execution costs.With A/B testing in use, customers would often see flickering like this one. Anti-Flicker snippets prevent that, but they also cost in performance. Via Andy Davies. (معاينة كبيرة) Therefore keep track how often the anti-flicker timeout is triggered and reduce the timeout. Default blocks display of your page by up to 4s which will ruin conversion rates. According to Tim Kadlec, "Friends don't let friends do client side A/B testing". Server-side A/B testing on CDNs (eg Edge Computing, or Edge Slice Rerendering) is always a more performant option.
If you have to deal with almighty Google Tag Manager , Barry Pollard provides some guidelines to contain the impact of Google Tag Manager. Also, Christian Schaefer explores strategies for loading ads.
انتبه: بعض أدوات الطرف الثالث تخفي نفسها عن أدوات التدقيق ، لذلك قد يكون من الصعب اكتشافها وقياسها. لاختبار الضغط على الأطراف الثالثة ، افحص الملخصات التصاعدية في صفحة ملف تعريف الأداء في DevTools ، واختبر ما يحدث إذا تم حظر طلب ما أو انقضت مهلته - بالنسبة للأخير ، يمكنك استخدام خادم
blackhole.webpagetest.org
الخاص بـ WebPageTest's Blackhole.webpagetest.org يمكن أن يشير إلى مجالات معينة في ملفhosts
الخاص بك.ما هي الخيارات لدينا بعد ذلك؟ ضع في اعتبارك استخدام العاملين في الخدمة عن طريق السباق في تنزيل المورد مع انتهاء المهلة ، وإذا لم يستجب المورد خلال مهلة معينة ، فقم بإرجاع استجابة فارغة لإخبار المتصفح بالاستمرار في تحليل الصفحة. يمكنك أيضًا تسجيل أو حظر طلبات الجهات الخارجية غير الناجحة أو التي لا تفي بمعايير معينة. إذا استطعت ، فقم بتحميل البرنامج النصي الخاص بالطرف الثالث من الخادم الخاص بك بدلاً من خادم البائع وقم بتحميله كسولًا.
هناك خيار آخر يتمثل في إنشاء سياسة أمان المحتوى (CSP) لتقييد تأثير نصوص الطرف الثالث ، مثل عدم السماح بتنزيل الصوت أو الفيديو. الخيار الأفضل هو تضمين نصوص برمجية عبر
<iframe>
بحيث يتم تشغيل البرامج النصية في سياق iframe وبالتالي لا يمكنها الوصول إلى DOM للصفحة ، ولا يمكنها تشغيل تعليمات برمجية عشوائية على نطاقك. يمكن تقييد إطارات Iframe بشكل أكبر باستخدام سمةsandbox
، بحيث يمكنك تعطيل أي وظيفة قد تقوم بها iframe ، مثل منع تشغيل البرامج النصية ، ومنع التنبيهات ، وتقديم النماذج ، والمكونات الإضافية ، والوصول إلى التنقل العلوي ، وما إلى ذلك.يمكنك أيضًا إبقاء الجهات الخارجية تحت المراقبة من خلال فحص الأداء في المتصفح بسياسات الميزات ، وهي ميزة جديدة نسبيًا تتيح لك
الاشتراك أو إلغاء الاشتراك في بعض ميزات المتصفح على موقعك. (كإجراء جانبي ، يمكن استخدامه أيضًا لتجنب الصور كبيرة الحجم وغير المحسّنة والوسائط غير الحجم والبرامج النصية المزامنة وغيرها). مدعومة حاليًا في المتصفحات القائمة على Blink. /* Via Tim Kadlec. https://timkadlec.com/remembers/2020-02-20-in-browser-performance-linting-with-feature-policies/ */ /* Block the use of the Geolocation API with a Feature-Policy header. */ Feature-Policy: geolocation 'none'
/* Via Tim Kadlec. https://timkadlec.com/remembers/2020-02-20-in-browser-performance-linting-with-feature-policies/ */ /* Block the use of the Geolocation API with a Feature-Policy header. */ Feature-Policy: geolocation 'none'
نظرًا لأن العديد من البرامج النصية للجهات الخارجية تعمل في إطارات iframe ، فربما تحتاج إلى أن تكون دقيقًا في تقييد السماح لها. تعتبر إطارات iframe ذات وضع الحماية فكرة جيدة دائمًا ، ويمكن رفع كل القيود عبر عدد من القيم
allow
بها في سمة وضعsandbox
. يتم دعم Sandboxing في كل مكان تقريبًا ، لذا احرص على تقييد البرامج النصية التابعة لجهات خارجية إلى الحد الأدنى مما ينبغي السماح لها بفعله.يقوم ThirdPartyWeb.Today بتجميع جميع البرامج النصية التابعة لجهات خارجية حسب الفئة (التحليلات ، والاجتماعية ، والإعلانية ، والاستضافة ، ومدير العلامات ، وما إلى ذلك) ويصور المدة التي تستغرقها البرامج النصية للكيان في التنفيذ (في المتوسط). (معاينة كبيرة) ضع في اعتبارك استخدام مراقب التقاطع ؛ من شأنه أن يمكّن الإعلانات من أن تكون iframed مع الاستمرار في إرسال الأحداث أو الحصول على المعلومات التي يحتاجونها من DOM (مثل رؤية الإعلان). احترس من السياسات الجديدة مثل سياسة الميزات وحدود حجم الموارد وأولوية وحدة المعالجة المركزية / النطاق الترددي للحد من ميزات الويب الضارة والبرامج النصية التي من شأنها إبطاء المتصفح ، مثل البرامج النصية المتزامنة وطلبات XHR المتزامنة و document.write والتطبيقات القديمة.
أخيرًا ، عند اختيار خدمة جهة خارجية ، ضع في اعتبارك التحقق من موقع Patrick Hulce's ThirdPartyWeb. اليوم ، خدمة تجمع جميع البرامج النصية للجهات الخارجية حسب الفئة (التحليلات ، والاجتماعية ، والإعلانية ، والاستضافة ، ومدير العلامات ، وما إلى ذلك) وتصور المدة التي تستغرقها البرامج النصية للكيان يستغرق التنفيذ (في المتوسط). من الواضح أن الكيانات الأكبر لها تأثير أسوأ على أداء الصفحات التي تتواجد عليها. بمجرد تخطي الصفحة ، ستحصل على فكرة عن بصمة الأداء التي يجب أن تتوقعها.
آه ، ولا تنسَ المشتبه بهم المعتادون: بدلاً من أدوات الطرف الثالث للمشاركة ، يمكننا استخدام أزرار مشاركة اجتماعية ثابتة (مثل SSBG) وروابط ثابتة للخرائط التفاعلية بدلاً من الخرائط التفاعلية.

- قم بتعيين رؤوس ذاكرة التخزين المؤقت HTTP بشكل صحيح.
يبدو أن التخزين المؤقت أمر واضح ، ومع ذلك قد يكون من الصعب جدًا القيام به بشكل صحيح. نحتاج إلى التحقق مرة أخرى من أنexpires
وmax-age
وcache-control
ورؤوس HTTP المخبئية الأخرى قد تم ضبطها بشكل صحيح. بدون رؤوس ذاكرة التخزين المؤقت HTTP المناسبة ، ستقوم المتصفحات بتعيينها تلقائيًا عند 10٪ من الوقت المنقضي منذlast-modified
، وينتهي بها الأمر باحتمالية نقص وتخزين مؤقت زائد.بشكل عام ، يجب أن تكون الموارد قابلة للتخزين المؤقت إما لفترة قصيرة جدًا (إذا كان من المحتمل أن تتغير) أو إلى أجل غير مسمى (إذا كانت ثابتة) - يمكنك فقط تغيير نسختها في عنوان URL عند الحاجة. يمكنك تسميتها استراتيجية Cache-Forever ، حيث يمكننا نقل رؤوس
Cache-Control
وExpires
إلى المتصفح للسماح للأصول بانتهاء صلاحيتها فقط في غضون عام. ومن ثم ، لن يقوم المستعرض حتى بتقديم طلب للأصل إذا كان موجودًا في ذاكرة التخزين المؤقت.الاستثناءات هي استجابات API (على سبيل المثال
/api/user
). لمنع التخزين المؤقت ، يمكننا استخدامprivate, no store
، وليسmax-age=0, no-store
:Cache-Control: private, no-store
استخدام
Cache-control: immutable
لتجنب إعادة التحقق من فترات التخزين المؤقت الطويلة الصريحة عندما يضغط المستخدمون على زر إعادة التحميل. بالنسبة لحالة إعادة التحميل ، يحفظimmutable
طلبات HTTP ويحسّن وقت تحميل HTML الديناميكي حيث لم يعد يتنافس مع العديد من الردود البالغ عددها 304.من الأمثلة النموذجية حيث نريد استخدام الأصول
immutable
هي أصول CSS / JavaScript مع تجزئة في أسمائها. بالنسبة لهم ، ربما نرغب في التخزين المؤقت لأطول فترة ممكنة ، والتأكد من عدم إعادة التحقق من صحتها أبدًا:Cache-Control: max-age: 31556952, immutable
وفقًا لبحث Colin Bendell ، يقلل الثابت غير القابل
immutable
304 من عمليات إعادة التوجيه بحوالي 50٪ حتى معmax-age
الاستخدام ، لا يزال العملاء يعيدون التحقق من الصحة ويحظرون عند التحديث. إنه مدعوم في Firefox و Edge و Safari ولا يزال Chrome يناقش المشكلة.وفقًا لـ Web Almanac ، "نما استخدامه إلى 3.5٪ ، ويستخدم على نطاق واسع في ردود الأطراف الخارجية على Facebook و Google".
Cache-Control: Immutable يقلل من 304s بحوالي 50٪ ، وفقًا لأبحاث Colin Bendell في Cloudinary. (معاينة كبيرة) هل تتذكر الطيب القديم الذي لا معنى له أثناء إعادة التحقق؟ عندما نحدد وقت التخزين المؤقت برأس استجابة
Cache-Control
(على سبيل المثالCache-Control: max-age=604800
) ، بعد انتهاءmax-age
، سيعيد المتصفح جلب المحتوى المطلوب ، مما يتسبب في تحميل الصفحة بشكل أبطأ. يمكن تجنب هذا التباطؤ معstale-while-revalidate
؛ تحدد بشكل أساسي نافذة إضافية من الوقت يمكن خلالها لذاكرة التخزين المؤقت استخدام أصل قديم طالما أنه يعيد التحقق من عدم تزامنه في الخلفية. وبالتالي ، فإنه "يخفي" زمن الانتقال (سواء في الشبكة أو على الخادم) عن العملاء.في الفترة من يونيو إلى يوليو 2019 ، أطلق Chrome و Firefox دعمًا
stale-while-revalidate
في رأس HTTP Cache-Control ، ونتيجة لذلك ، يجب أن يحسن وقت استجابة تحميل الصفحة اللاحقة لأن الأصول القديمة لم تعد في المسار الحرج. النتيجة: صفر RTT لتكرار المشاهدات.كن حذرًا من الرأس المتنوع ، لا سيما فيما يتعلق بشبكات CDN ، واحترس من متغيرات تمثيل HTTP التي تساعد في تجنب رحلة ذهابًا وإيابًا إضافية للتحقق من الصحة عندما يختلف طلب جديد قليلاً (ولكن ليس بشكل كبير) عن الطلبات السابقة ( شكرًا ، Guy and Mark ! ).
أيضًا ، تحقق جيدًا من أنك لا ترسل رؤوسًا غير ضرورية (مثل
x-powered-by
وpragma
وx-ua-compatible
وexpires
وX-XSS-Protection
وغيرها) وأنك تقوم بتضمين رؤوس أمان وأداء مفيدة (مثل مثلContent-Security-Policy
وX-Content-Type-Options
وغيرها). أخيرًا ، ضع في اعتبارك تكلفة أداء طلبات CORS في تطبيقات الصفحة الواحدة.ملاحظة : غالبًا ما نفترض أنه يتم استرداد الأصول المخزنة مؤقتًا على الفور ، ولكن تظهر الأبحاث أن استرداد عنصر من ذاكرة التخزين المؤقت يمكن أن يستغرق مئات المللي ثانية. في الواقع ، وفقًا لسيمون هيرن ، "في بعض الأحيان قد تكون الشبكة أسرع من ذاكرة التخزين المؤقت ، وقد يكون استرداد الأصول من ذاكرة التخزين المؤقت مكلفًا مع وجود عدد كبير من الأصول المخزنة مؤقتًا (وليس حجم الملف) وأجهزة المستخدم. على سبيل المثال: متوسط استرداد ذاكرة التخزين المؤقت لنظام التشغيل Chrome يتضاعف من حوالي 50 مللي ثانية مع 5 موارد مخزنة مؤقتًا تصل إلى 100 مللي ثانية مع 25 موردًا ".
علاوة على ذلك ، غالبًا ما نفترض أن حجم الحزمة ليس مشكلة كبيرة وسيقوم المستخدمون بتنزيلها مرة واحدة ثم استخدام النسخة المخبأة. في الوقت نفسه ، باستخدام CI / CD ، نقوم بدفع الكود للإنتاج عدة مرات في اليوم ، يتم إبطال ذاكرة التخزين المؤقت في كل مرة ، لذا فإن أهمية التخزين المؤقت مهمة.
عندما يتعلق الأمر بالتخزين المؤقت ، هناك الكثير من الموارد التي تستحق القراءة:
- التحكم في ذاكرة التخزين المؤقت للمدنيين ، الغوص العميق في كل شيء يتم تخزينه مؤقتًا مع هاري روبرتس.
- كتاب Heroku التمهيدي عن رؤوس تخزين HTTP المؤقت ،
- أفضل ممارسات التخزين المؤقت بواسطة جيك أرشيبالد ،
- التمهيد التمهيدي لذاكرة التخزين المؤقت لـ HTTP بواسطة Ilya Grigorik ،
- الحفاظ على الأشياء طازجة مع إعادة التحقق من صحة الأشياء التي لا معنى لها بواسطة Jeff Posnick.
- CS مرئي: CORS من Lydia Hallie هو شرح رائع لـ CORS ، كيف يعمل وكيفية فهمه.
- بالحديث عن CORS ، إليك بعض المعلومات التنشيطية عن سياسة نفس المنشأ بقلم إريك بورتيس.

تحسينات التسليم
- هل نستخدم
defer
لتحميل JavaScript غير متزامن؟
عندما يطلب المستخدم صفحة ، يجلب المتصفح HTML وينشئ DOM ، ثم يجلب CSS ويبني CSSOM ، ثم ينشئ شجرة عرض عن طريق مطابقة DOM و CSSOM. إذا كانت هناك حاجة إلى حل أي JavaScript ، فلن يبدأ المتصفح في عرض الصفحة حتى يتم حلها ، مما يؤدي إلى تأخير العرض. بصفتنا مطورين ، يتعين علينا إخبار المتصفح صراحةً بعدم الانتظار والبدء في عرض الصفحة. طريقة القيام بذلك للنصوص هي باستخدام سماتdefer
وغيرasync
في HTML.من الناحية العملية ، اتضح أنه من الأفضل استخدام
defer
بدلاً من عدمasync
. آه ، ما الفرق مرة أخرى؟ وفقًا لستيف سودرس ، بمجرد وصول البرامج النصية غيرasync
، يتم تنفيذها على الفور - بمجرد أن يصبح النص جاهزًا. إذا حدث ذلك بسرعة كبيرة ، على سبيل المثال عندما يكون البرنامج النصي في ذاكرة التخزين المؤقت ، فيمكنه بالفعل حظر محلل HTML. معdefer
، لا ينفذ المستعرض البرامج النصية حتى يتم تحليل HTML. لذلك ، ما لم تكن بحاجة إلى تنفيذ JavaScript قبل بدء التصيير ، فمن الأفضل استخدامdefer
. أيضًا ، سيتم تنفيذ العديد من الملفات غير المتزامنة بترتيب غير حتمي.من الجدير بالذكر أن هناك بعض المفاهيم الخاطئة حول عدم
async
defer
الأهم من ذلك ، لا يعني عدمasync
أن الكود سيعمل عندما يكون البرنامج النصي جاهزًا ؛ هذا يعني أنه سيتم تشغيله عندما تكون البرامج النصية جاهزة ويتم الانتهاء من جميع أعمال المزامنة السابقة. في كلمات هاري روبرتس ، "إذا وضعت نصًا غيرasync
بعد نصوص المزامنة ، فإن النص غيرasync
الخاص بك يكون فقط بنفس سرعة أبطأ نص مزامنة لديك."أيضًا ، لا يوصى باستخدام كل من غير
async
defer
تدعم المتصفحات الحديثة كليهما ، ولكن كلما تم استخدام كلتا السمتين ، سيفوز غيرasync
دائمًا.إذا كنت ترغب في التعمق في مزيد من التفاصيل ، فقد كتبت Milica Mihajlija دليلًا تفصيليًا للغاية حول إنشاء DOM بشكل أسرع ، والذهاب إلى تفاصيل التحليل التأملي ، وعدم التزامن والتأجيل.
- تحميل كسول مكونات باهظة الثمن باستخدام IntersectionObserver وتلميحات الأولوية.
بشكل عام ، يوصى بالتحميل البطيء لجميع المكونات باهظة الثمن ، مثل JavaScript الثقيلة ، ومقاطع الفيديو ، وإطارات iframe ، والأدوات ، وربما الصور. يتوفر التحميل البطيء الأصلي بالفعل للصور وإطارات iframe التي تحتوي على سمةloading
(Chromium فقط). تحت الغطاء ، تعمل هذه السمة على تأجيل تحميل المورد حتى يصل إلى مسافة محسوبة من منفذ العرض.<!-- Lazy loading for images, iframes, scripts. Probably for images outside of the viewport. --> <img loading="lazy" ... /> <iframe loading="lazy" ... /> <!-- Prompt an early download of an asset. For critical images, eg hero images. --> <img loading="eager" ... /> <iframe loading="eager" ... />
يعتمد هذا الحد على بعض الأشياء ، من نوع مصدر الصورة الذي يتم جلبه إلى نوع الاتصال الفعال. لكن التجارب التي أُجريت باستخدام Chrome على Android تشير إلى أنه على شبكة 4G ، تم تحميل 97.5٪ من الصور الموجودة في الجزء السفلي غير المرئي من التحميل البطيء بالكامل في غضون 10 مللي ثانية من ظهورها ، لذا يجب أن تكون آمنة.
يمكننا أيضًا استخدام سمة
importance
(high
أوlow
) في عنصر<script>
أو<img>
أو<link>
(وميض فقط). في الواقع ، إنها طريقة رائعة لإلغاء ترتيب أولويات الصور في الدوارات ، وكذلك إعادة ترتيب البرامج النصية حسب الأولوية. ومع ذلك ، قد نحتاج في بعض الأحيان إلى مزيد من التحكم الدقيق.<!-- When the browser assigns "High" priority to an image, but we don't actually want that. --> <img src="less-important-image.svg" importance="low" ... /> <!-- We want to initiate an early fetch for a resource, but also deprioritize it. --> <link rel="preload" importance="low" href="/script.js" as="script" />
الطريقة الأكثر فاعلية للقيام بتحميل بطيء أكثر تعقيدًا هي استخدام واجهة برمجة تطبيقات Intersection Observer التي توفر طريقة لمراقبة التغييرات بشكل غير متزامن في تقاطع عنصر مستهدف مع عنصر سلف أو مع منفذ عرض للمستند ذي المستوى الأعلى. بشكل أساسي ، تحتاج إلى إنشاء كائن
IntersectionObserver
جديد ، والذي يتلقى وظيفة رد الاتصال ومجموعة من الخيارات. ثم نضيف هدفًا للمراقبة.يتم تنفيذ وظيفة رد الاتصال عندما يصبح الهدف مرئيًا أو غير مرئي ، لذلك عندما يعترض منفذ العرض ، يمكنك البدء في اتخاذ بعض الإجراءات قبل أن يصبح العنصر مرئيًا. في الواقع ، لدينا تحكم دقيق في الوقت الذي يجب فيه استدعاء رد نداء المراقب ، مع
rootMargin
(هامش حول الجذر)threshold
(رقم واحد أو مجموعة من الأرقام التي تشير إلى النسبة المئوية لرؤية الهدف التي نستهدفها).نشر Alejandro Garcia Anglada برنامجًا تعليميًا مفيدًا حول كيفية تنفيذه فعليًا ، كتب راهول نانواني منشورًا تفصيليًا عن التحميل البطيء للصور الأمامية والخلفية ، وتوفر أساسيات Google برنامجًا تعليميًا مفصلاً عن التحميل البطيء للصور والفيديو باستخدام Intersection Observer أيضًا.
هل تتذكر رواية القصص الطويلة التي تحتوي على أشياء متحركة ولزجة؟ يمكنك تنفيذ التمرير السريع مع Intersection Observer أيضًا.
تحقق مرة أخرى مما يمكنك تحميله كسول. حتى سلاسل الترجمة والرموز التعبيرية ذات التحميل البطيء يمكن أن تساعد. من خلال القيام بذلك ، تمكن Mobile Twitter من تحقيق تنفيذ JavaScript أسرع بنسبة 80 ٪ من خط أنابيب التدويل الجديد.
كلمة تحذير سريعة: من الجدير بالذكر أن التحميل البطيء يجب أن يكون استثناءً وليس قاعدة. ربما ليس من المعقول تحميل أي شيء بطيئًا تريد بالفعل أن يراه الأشخاص بسرعة ، على سبيل المثال ، صور صفحة المنتج أو صور البطل أو البرنامج النصي المطلوب ليصبح التنقل الرئيسي تفاعليًا.


- تحميل الصور بشكل تدريجي.
يمكنك حتى الانتقال إلى المستوى التالي من التحميل البطيء عن طريق إضافة تحميل الصورة التدريجي إلى صفحاتك. على غرار Facebook و Pinterest و Medium و Wolt ، يمكنك تحميل صور منخفضة الجودة أو حتى ضبابية أولاً ، وبعد ذلك مع استمرار تحميل الصفحة ، استبدلها بإصدارات كاملة الجودة باستخدام تقنية BlurHash أو LQIP (العناصر النائبة للصور منخفضة الجودة) تقنية.تختلف الآراء إذا كانت هذه التقنيات تعمل على تحسين تجربة المستخدم أم لا ، لكنها بالتأكيد تعمل على تحسين وقت First Contentful Paint. يمكننا حتى أتمتة ذلك باستخدام SQIP الذي يُنشئ نسخة منخفضة الجودة من صورة ما كعنصر نائب لـ SVG ، أو Gradient Image Placeholder مع تدرجات CSS الخطية.
يمكن تضمين هذه العناصر النائبة في HTML حيث يتم ضغطها بشكل جيد باستخدام طرق ضغط النص. وصف دين هيوم في مقالته كيف يمكن تنفيذ هذه التقنية باستخدام Intersection Observer.
تراجع؟ إذا كان المتصفح لا يدعم مراقب التقاطع ، فلا يزال بإمكاننا التحميل البطيء أو تحميل الصور على الفور. وهناك حتى مكتبة لها.
تريد أن تصبح مربي الحيوانات؟ يمكنك تتبع صورك واستخدام الأشكال والحواف البدائية لإنشاء عنصر نائب SVG خفيف الوزن ، وتحميله أولاً ، ثم الانتقال من صورة متجه العنصر النائب إلى الصورة النقطية (المحملة).
- هل تؤجل العرض مع
content-visibility
؟
بالنسبة للتخطيط المعقد الذي يحتوي على وفرة من كتل المحتوى والصور ومقاطع الفيديو ، قد يكون فك تشفير البيانات وعرض وحدات البكسل عملية مكلفة للغاية - خاصة على الأجهزة منخفضة التكلفة. باستخدامcontent-visibility: auto
، يمكننا مطالبة المتصفح بتخطي تخطيط الأطفال عندما تكون الحاوية خارج إطار العرض.على سبيل المثال ، يمكنك تخطي عرض التذييل والأقسام المتأخرة في التحميل الأولي:
footer { content-visibility: auto; contain-intrinsic-size: 1000px; /* 1000px is an estimated height for sections that are not rendered yet. */ }
لاحظ أن رؤية المحتوى: auto؛ يتصرف مثل الفائض: مخفي ؛ ، ولكن يمكنك إصلاحه عن طريق تطبيق
padding-left
وpadding-right
بدلاً منmargin-left: auto;
margin-right: auto;
وعرض معلن. تسمح الحشوة بشكل أساسي للعناصر بتجاوز مربع المحتوى والدخول إلى مربع الحشو دون مغادرة نموذج الصندوق ككل والانقطاع.أيضًا ، ضع في اعتبارك أنك قد تقدم بعض CLS عندما يتم عرض محتوى جديد في النهاية ، لذلك من الجيد استخدام
contain-intrinsic-size
مع عنصر نائب بحجم مناسب ( شكرًا ، Una! ).يحتوي Thijs Terluin على مزيد من التفاصيل حول كلتا الخاصيتين وكيفية حساب
contain-intrinsic-size
المحتوى الجوهري بواسطة المتصفح ، ويوضح Malte Ubl كيف يمكنك حسابه ويشرح شرح موجز بالفيديو بواسطة Jake و Surma كيف يعمل كل شيء.وإذا كنت بحاجة إلى مزيد من التفاصيل ، باستخدام احتواء CSS ، فيمكنك تخطي أعمال التخطيط والنمط والطلاء يدويًا لأحفاد عقدة DOM إذا كنت بحاجة فقط إلى الحجم أو المحاذاة أو الأنماط المحسوبة على عناصر أخرى - أو العنصر حاليًا خارج القماش.


content-visibility: auto
على مناطق المحتوى المقسمة تعزيز أداء تقديم 7 × عند التحميل الأولي. (معاينة كبيرة)- هل تؤجل فك التشفير باستخدام
decoding="async"
؟
يظهر المحتوى أحيانًا خارج الشاشة ، لكننا نريد التأكد من أنه متاح عندما يحتاجه العملاء - من الناحية المثالية ، لا يحظر أي شيء في المسار الحرج ، ولكن يتم فك التشفير والعرض بشكل غير متزامن. يمكننا استخدامdecoding="async"
لمنح المتصفح إذنًا لفك تشفير الصورة من الخيط الرئيسي ، وتجنب تأثير المستخدم لوقت وحدة المعالجة المركزية المستخدمة لفك تشفير الصورة (عبر Malte Ubl):<img decoding="async" … />
بدلاً من ذلك ، بالنسبة للصور خارج الشاشة ، يمكننا عرض عنصر نائب أولاً ، وعندما تكون الصورة داخل منفذ العرض ، باستخدام IntersectionObserver ، قم بتشغيل مكالمة شبكة للصورة المراد تنزيلها في الخلفية. أيضًا ، يمكننا تأجيل العرض حتى فك الشفرة باستخدام img.decode () أو تنزيل الصورة إذا كانت Image Decode API غير متوفرة.
عند تقديم الصورة ، يمكننا استخدام الرسوم المتحركة المتلاشية ، على سبيل المثال. تشارك Katie Hempenius و Addy Osmani المزيد من الأفكار في حديثهما Speed at Scale: Web Performance Tips and Tricks from the Trenches.
- هل تنشئ وتخدم CSS حرجة؟
للتأكد من أن المتصفحات تبدأ في عرض صفحتك في أسرع وقت ممكن ، فقد أصبح من الممارسات الشائعة جمع كل CSS المطلوبة لبدء عرض الجزء الأول المرئي من الصفحة (المعروف باسم "CSS الحرجة" أو "CSS في الجزء العلوي من الصفحة" ") وقم بتضمينها بشكل مضمن في<head>
من الصفحة ، وبالتالي تقليل الرحلات ذهابًا وإيابًا. نظرًا للحجم المحدود للحزم المتبادلة أثناء مرحلة البداية البطيئة ، فإن ميزانيتك الخاصة بـ CSS الحرجة تبلغ حوالي 14 كيلو بايت.إذا تجاوزت ذلك ، فسيحتاج المتصفح إلى جولات إضافية ذهابًا وإيابًا لجلب المزيد من الأنماط. يمكّنك CriticalCSS و Critical من إخراج CSS الهامة لكل قالب تستخدمه. على الرغم من تجربتنا ، لم يكن هناك نظام آلي أفضل من الجمع اليدوي لـ CSS الهامة لكل قالب ، وبالفعل هذا هو النهج الذي عدنا إليه مؤخرًا.
يمكنك بعد ذلك تضمين CSS الهامة وتحميل الباقي البطيء باستخدام المكون الإضافي Webpack المخلوقات. إذا كان ذلك ممكنًا ، ففكر في استخدام نهج التضمين الشرطي الذي تستخدمه Filament Group ، أو قم بتحويل التعليمات البرمجية المضمنة إلى أصول ثابتة أثناء التنقل.
إذا كنت تقوم حاليًا بتحميل CSS بالكامل بشكل غير متزامن مع مكتبات مثل loadCSS ، فهذا ليس ضروريًا حقًا. باستخدام
media="print"
، يمكنك خداع المتصفح لجلب CSS بشكل غير متزامن مع تطبيقه على بيئة الشاشة بمجرد تحميلها. ( شكرا سكوت! )<!-- Via Scott Jehl. https://www.filamentgroup.com/lab/load-css-simpler/ --> <!-- Load CSS asynchronously, with low priority --> <link rel="stylesheet" href="full.css" media="print" onload="this.media='all'" />
عند جمع كل CSS المهمة لكل قالب ، من الشائع استكشاف منطقة "الجزء المرئي من الصفحة" بمفردها. ومع ذلك ، بالنسبة للتخطيطات المعقدة ، قد يكون من الجيد تضمين الأساس للتخطيط أيضًا لتجنب إعادة الحساب الضخمة وتكاليف إعادة الطلاء ، مما يضر بنتائج Core Web Vitals كنتيجة لذلك.
ماذا لو حصل المستخدم على عنوان URL يرتبط مباشرة بمنتصف الصفحة ولكن لم يتم تنزيل CSS بعد؟ في هذه الحالة ، أصبح من الشائع إخفاء المحتوى غير النقدي ، على سبيل المثال مع
opacity: 0;
في CSS مضمّنopacity: 1
في ملف CSS كامل ، واعرضه عندما يكون CSS متاحًا. على الرغم من ذلك ، فإن له جانبًا سلبيًا كبيرًا ، حيث قد لا يتمكن المستخدمون الذين لديهم اتصالات بطيئة من قراءة محتوى الصفحة. لهذا السبب من الأفضل إبقاء المحتوى مرئيًا دائمًا ، حتى وإن لم يتم تصميمه بشكل صحيح.إن وضع CSS الهامة (وغيرها من الأصول المهمة) في ملف منفصل على النطاق الجذر له فوائد ، أحيانًا أكثر من التضمين ، بسبب التخزين المؤقت. يفتح Chrome افتراضيًا اتصال HTTP ثانيًا بمجال الجذر عند طلب الصفحة ، مما يلغي الحاجة إلى اتصال TCP لجلب CSS هذا. هذا يعني أنه يمكنك إنشاء مجموعة من ملفات CSS الهامة (على سبيل المثال الحرجة homepage.css ، الحرجة-product-page.css إلخ) وخدمتها من الجذر الخاص بك ، دون الحاجة إلى تضمينها. ( شكرا ، فيليب! )
كلمة تحذير: باستخدام HTTP / 2 ، يمكن تخزين CSS المهم في ملف CSS منفصل وتسليمه عبر دفع الخادم دون تضخيم HTML. المهم هو أن دفع الخادم كان مزعجًا مع العديد من حالات التعثر وظروف السباق عبر المتصفحات. لم يتم دعمه باستمرار وكان به بعض مشكلات التخزين المؤقت (انظر الشريحة 114 وما بعدها من عرض هومان بهشتي).
في الواقع ، يمكن أن يكون التأثير سالبًا ويؤدي إلى تضخم المخازن المؤقتة للشبكة ، مما يمنع تسليم الإطارات الأصلية في المستند. لذلك لم يكن مفاجئًا جدًا أنه في الوقت الحالي ، يخطط Chrome لإزالة دعم Server Push.
- جرب إعادة تجميع قواعد CSS الخاصة بك.
لقد اعتدنا على CSS المهمة ، ولكن هناك بعض التحسينات التي يمكن أن تتجاوز ذلك. أجرى هاري روبرتس بحثًا رائعًا بنتائج مفاجئة تمامًا. على سبيل المثال ، قد يكون من الجيد تقسيم ملف CSS الرئيسي إلى استعلامات وسائط فردية. بهذه الطريقة ، سيسترد المتصفح CSS المهمة ذات الأولوية العالية ، وكل شيء آخر له أولوية منخفضة - بعيدًا تمامًا عن المسار الحرج.أيضًا ، تجنب وضع
<link rel="stylesheet" />
قبل المقتطفاتasync
. إذا كانت البرامج النصية لا تعتمد على أوراق الأنماط ، ففكر في وضع نصوص الحظر فوق أنماط الحظر. إذا فعلوا ذلك ، فقم بتقسيم JavaScript إلى قسمين وقم بتحميله على جانبي CSS.قام Scott Jehl بحل مشكلة أخرى مثيرة للاهتمام عن طريق تخزين ملف CSS مضمن مع عامل خدمة ، وهي مشكلة شائعة مألوفة إذا كنت تستخدم CSS مهمًا. في الأساس ، نضيف سمة ID إلى عنصر
style
بحيث يسهل العثور عليها باستخدام JavaScript ، ثم تجد قطعة صغيرة من JavaScript CSS وتستخدم Cache API لتخزينها في ذاكرة التخزين المؤقت للمتصفح المحلي (بنوع محتوى منtext/css
) للاستخدام في الصفحات اللاحقة. لتجنب التضمين في الصفحات اللاحقة والإشارة بدلاً من ذلك إلى الأصول المخزنة مؤقتًا خارجيًا ، نقوم بعد ذلك بتعيين ملف تعريف ارتباط في أول زيارة للموقع. هاهو!من الجدير بالذكر أن التصميم الديناميكي يمكن أن يكون مكلفًا أيضًا ، ولكن عادةً فقط في الحالات التي تعتمد فيها على مئات من المكونات التي يتم عرضها بشكل متزامن. لذلك إذا كنت تستخدم CSS-in-JS ، فتأكد من أن مكتبة CSS-in-JS الخاصة بك تعمل على تحسين التنفيذ عندما لا يكون لـ CSS الخاص بك أي اعتمادات على السمة أو الدعائم ، ولا تفرط في تكوين المكونات ذات الأنماط. يشارك Aggelos Arvanitakis المزيد من الأفكار حول تكاليف أداء CSS-in-JS.
- هل تتدفق الردود؟
غالبًا ما يتم نسيانها وإهمالها ، توفر التدفقات واجهة لقراءة أو كتابة أجزاء غير متزامنة من البيانات ، والتي قد تكون مجموعة فرعية منها فقط متاحة في الذاكرة في أي وقت. بشكل أساسي ، يسمحون للصفحة التي قدمت الطلب الأصلي ببدء العمل مع الاستجابة بمجرد توفر الجزء الأول من البيانات ، واستخدام المحللون الذين تم تحسينهم للتدفق لعرض المحتوى تدريجيًا.يمكننا إنشاء دفق واحد من مصادر متعددة. على سبيل المثال ، بدلاً من تقديم غلاف واجهة مستخدم فارغ والسماح لجافا سكريبت بتعبئته ، يمكنك السماح لعامل الخدمة بإنشاء دفق حيث تأتي الصدفة من ذاكرة تخزين مؤقت ، ولكن يأتي الجسم من الشبكة. كما لاحظ Jeff Posnick ، إذا كان تطبيق الويب الخاص بك مدعومًا بواسطة CMS يقوم الخادم بعرض HTML عن طريق تجميع قوالب جزئية معًا ، فإن هذا النموذج يترجم مباشرةً إلى استخدام استجابات متدفقة ، مع تكرار منطق النموذج في عامل الخدمة بدلاً من الخادم الخاص بك. تسلط مقالة Jake Archibald's The Year of Web Streams الضوء على كيفية إنشائه بالضبط. تعزيز الأداء ملحوظ جدا.
تتمثل إحدى الميزات المهمة لدفق استجابة HTML بالكامل في أن HTML الذي يتم تقديمه أثناء طلب التنقل الأولي يمكن أن يستفيد استفادة كاملة من محلل HTML المتدفق في المتصفح. لا يمكن لأجزاء HTML التي يتم إدراجها في المستند بعد تحميل الصفحة (كما هو شائع مع المحتوى الذي يتم ملؤه عبر JavaScript) الاستفادة من هذا التحسين.
دعم المتصفح؟ لا يزال هناك دعم جزئي في Chrome و Firefox و Safari و Edge يدعمان API وعمال الخدمة الذين يتم دعمهم في جميع المتصفحات الحديثة. وإذا شعرت بالمغامرة مرة أخرى ، فيمكنك التحقق من التنفيذ التجريبي لطلبات البث ، مما يسمح لك ببدء إرسال الطلب أثناء إنشاء النص. متوفر في Chrome 85.

- ضع في اعتبارك جعل مكوناتك مدركة للاتصال.
قد تكون البيانات باهظة الثمن ومع تزايد الحمولة ، نحتاج إلى احترام المستخدمين الذين يختارون الاشتراك في توفير البيانات أثناء الوصول إلى مواقعنا أو تطبيقاتنا. يسمح لنا عنوان طلب تلميح عميل Save-Data بتخصيص التطبيق والحمولة للمستخدمين المقيدين بالتكلفة والأداء.في الواقع ، يمكنك إعادة كتابة طلبات صور DPI عالية إلى صور DPI منخفضة ، وإزالة خطوط الويب ، وتأثيرات المنظر الرائعة ، ومعاينة الصور المصغرة والتمرير اللانهائي ، وإيقاف تشغيل الفيديو التلقائي ، ودفع الخادم ، وتقليل عدد العناصر المعروضة وتقليل جودة الصورة ، أو حتى تغيير طريقة تقديم الترميز. نشر Tim Vereecke مقالة مفصلة للغاية عن استراتيجيات متوسط البيانات (s (h) التي تتميز بالعديد من الخيارات لحفظ البيانات.
من الذي يستخدم
save-data
، قد تتساءل؟ 18٪ من مستخدمي Android Chrome العالميين لديهم الوضع البسيط (معSave-Data
) ، ومن المرجح أن يكون الرقم أعلى. وفقًا لبحث Simon Hearne ، يكون معدل الاشتراك هو الأعلى في الأجهزة الأرخص ثمناً ، ولكن هناك الكثير من القيم المتطرفة. على سبيل المثال: يمتلك المستخدمون في كندا معدل اشتراك يزيد عن 34٪ (مقارنة بحوالي 7٪ في الولايات المتحدة) ويبلغ معدل الاشتراك في أحدث إصدار من Samsung حوالي 18٪ على مستوى العالم.مع تشغيل وضع
Save-Data
، سيوفر Chrome Mobile تجربة محسّنة ، أي تجربة ويب وكيل مع نصوص مؤجلة ، وفرضfont-display: swap
وفرض التحميل البطيء. من المنطقي أن تبني التجربة بنفسك بدلاً من الاعتماد على المتصفح لإجراء هذه التحسينات.الرأس مدعوم حاليًا فقط في Chromium ، أو على إصدار Android من Chrome أو عبر امتداد Data Saver على جهاز سطح المكتب. أخيرًا ، يمكنك أيضًا استخدام واجهة برمجة تطبيقات معلومات الشبكة لتقديم وحدات جافا سكريبت المكلفة وصور عالية الدقة ومقاطع فيديو بناءً على نوع الشبكة. واجهة برمجة تطبيقات معلومات الشبكة وخاصة
navigator.connection.effectiveType
تستخدم قيمRTT
downlink
وقيم النوعeffectiveType
(وعدد قليل من القيم الأخرى) لتوفير تمثيل للاتصال والبيانات التي يمكن للمستخدمين التعامل معها.في هذا السياق ، يتحدث Max Bock عن المكونات المدركة للاتصال وتتحدث Addy Osmani عن خدمة الوحدات التكيفية. على سبيل المثال ، باستخدام React ، يمكننا كتابة مكون يتم عرضه بشكل مختلف لأنواع الاتصال المختلفة. كما اقترح ماكس ، قد ينتج عن مكون
<Media />
في مقالة إخبارية:-
Offline
: عنصر نائب بنصalt
، -
2G
/ وضعsave-data
: صورة منخفضة الدقة ، -
3G
على شاشة غير Retina: صورة متوسطة الدقة ، -
3G
على شاشات Retina: صورة Retina عالية الدقة ، -
4G
: فيديو عالي الدقة.
يوفر Dean Hume تنفيذًا عمليًا لمنطق مماثل باستخدام عامل خدمة. بالنسبة لمقطع فيديو ، يمكننا عرض ملصق فيديو افتراضيًا ، ثم عرض رمز "تشغيل" بالإضافة إلى غلاف مشغل الفيديو والبيانات الوصفية للفيديو وما إلى ذلك على اتصالات أفضل. كبديل للمتصفحات غير الداعمة ، يمكننا الاستماع إلى
canplaythrough
event واستخدامPromise.race()
تحميل المصدر إذا لم يتم تشغيل حدثcanplaythrough
في غضون ثانيتين.إذا كنت تريد الغوص بشكل أعمق قليلاً ، فإليك بعض الموارد للبدء:
- توضح Addy Osmani كيفية تنفيذ الخدمة التكيفية في React.
- يوفر React Adaptive Loading Hooks & Utilities مقتطفات من التعليمات البرمجية لـ React ،
- يستكشف Netanel Basel مكونات الاتصال المدرك في Angular ،
- يشارك Theodore Vorilas كيفية عمل خدمة المكونات التكيفية باستخدام واجهة برمجة تطبيقات معلومات الشبكة في Vue.
- يوضح عمر هانسا كيفية تنزيل / تنفيذ JavaScript باهظ الثمن بشكل انتقائي.
-
- ضع في اعتبارك جعل مكونات جهازك مدركًا للذاكرة.
الاتصال بالشبكة يعطينا منظورًا واحدًا فقط في سياق المستخدم. للمضي قدمًا ، يمكنك أيضًا ضبط الموارد ديناميكيًا بناءً على ذاكرة الجهاز المتاحة ، باستخدام واجهة برمجة تطبيقات ذاكرة الجهاز.navigator.deviceMemory
returns how much RAM the device has in gigabytes, rounded down to the nearest power of two. The API also features a Client Hints Header,Device-Memory
, that reports the same value.Bonus : Umar Hansa shows how to defer expensive scripts with dynamic imports to change the experience based on device memory, network connectivity and hardware concurrency.

- Warm up the connection to speed up delivery.
Use resource hints to save time ondns-prefetch
(which performs a DNS lookup in the background),preconnect
(which asks the browser to start the connection handshake (DNS, TCP, TLS) in the background),prefetch
(which asks the browser to request a resource) andpreload
(which prefetches resources without executing them, among other things). Well supported in modern browsers, with support coming to Firefox soon.Remember
prerender
? The resource hint used to prompt browser to build out the entire page in the background for next navigation. The implementations issues were quite problematic, ranging from a huge memory footprint and bandwidth usage to multiple registered analytics hits and ad impressions.Unsurprinsingly, it was deprecated, but the Chrome team has brought it back as NoState Prefetch mechanism. In fact, Chrome treats the
prerender
hint as a NoState Prefetch instead, so we can still use it today. As Katie Hempenius explains in that article, "like prerendering, NoState Prefetch fetches resources in advance ; but unlike prerendering, it does not execute JavaScript or render any part of the page in advance."NoState Prefetch only uses ~45MiB of memory and subresources that are fetched will be fetched with an
IDLE
Net Priority. Since Chrome 69, NoState Prefetch adds the header Purpose: Prefetch to all requests in order to make them distinguishable from normal browsing.Also, watch out for prerendering alternatives and portals, a new effort toward privacy-conscious prerendering, which will provide the inset
preview
of the content for seamless navigations.Using resource hints is probably the easiest way to boost performance , and it works well indeed. When to use what? As Addy Osmani has explained, it's reasonable to preload resources that we know are very likely to be used on the current page and for future navigations across multiple navigation boundaries, eg Webpack bundles needed for pages the user hasn't visited yet.
Addy's article on "Loading Priorities in Chrome" shows how exactly Chrome interprets resource hints, so once you've decided which assets are critical for rendering, you can assign high priority to them. To see how your requests are prioritized, you can enable a "priority" column in the Chrome DevTools network request table (as well as Safari).
Most of the time these days, we'll be using at least
preconnect
anddns-prefetch
, and we'll be cautious with usingprefetch
,preload
andprerender
. Note that even withpreconnect
anddns-prefetch
, the browser has a limit on the number of hosts it will look up/connect to in parallel, so it's a safe bet to order them based on priority ( thanks Philip Tellis! ).Since fonts usually are important assets on a page, sometimes it's a good idea to request the browser to download critical fonts with
preload
. However, double check if it actually helps performance as there is a puzzle of priorities when preloading fonts: aspreload
is seen as high importance, it can leapfrog even more critical resources like critical CSS. ( thanks, Barry! )<!-- Loading two rendering-critical fonts, but not all their weights. --> <!-- crossorigin="anonymous" is required due to CORS. Without it, preloaded fonts will be ignored. https://github.com/w3c/preload/issues/32 via https://twitter.com/iamakulov/status/1275790151642423303 --> <link rel="preload" as="font" href="Elena-Regular.woff2" type="font/woff2" crossorigin="anonymous" media="only screen and (min-width: 48rem)" /> <link rel="preload" as="font" href="Mija-Bold.woff2" type="font/woff2" crossorigin="anonymous" media="only screen and (min-width: 48rem)" />
<!-- Loading two rendering-critical fonts, but not all their weights. --> <!-- crossorigin="anonymous" is required due to CORS. Without it, preloaded fonts will be ignored. https://github.com/w3c/preload/issues/32 via https://twitter.com/iamakulov/status/1275790151642423303 --> <link rel="preload" as="font" href="Elena-Regular.woff2" type="font/woff2" crossorigin="anonymous" media="only screen and (min-width: 48rem)" /> <link rel="preload" as="font" href="Mija-Bold.woff2" type="font/woff2" crossorigin="anonymous" media="only screen and (min-width: 48rem)" />
Since
<link rel="preload">
accepts amedia
attribute, you could choose to selectively download resources based on@media
query rules, as shown above.Furthermore, we can use
imagesrcset
andimagesizes
attributes to preload late-discovered hero images faster, or any images that are loaded via JavaScript, eg movie posters:<!-- Addy Osmani. https://addyosmani.com/blog/preload-hero-images/ --> <link rel="preload" as="image" href="poster.jpg" image image>
<!-- Addy Osmani. https://addyosmani.com/blog/preload-hero-images/ --> <link rel="preload" as="image" href="poster.jpg" image image>
We can also preload the JSON as fetch , so it's discovered before JavaScript gets to request it:
<!-- Addy Osmani. https://addyosmani.com/blog/preload-hero-images/ --> <link rel="preload" as="fetch" href="foo.com/api/movies.json" crossorigin>
We could also load JavaScript dynamically, effectively for lazy execution of the script.
/* Adding a preload hint to the head */ var preload = document.createElement("link"); link.href = "myscript.js"; link.rel = "preload"; link.as = "script"; document.head.appendChild(link); /* Injecting a script when we want it to execute */ var script = document.createElement("script"); script.src = "myscript.js"; document.body.appendChild(script);
A few gotchas to keep in mind:
preload
is good for moving the start download time of an asset closer to the initial request, but preloaded assets land in the memory cache which is tied to the page making the request.preload
plays well with the HTTP cache: a network request is never sent if the item is already there in the HTTP cache.Hence, it's useful for late-discovered resources, hero images loaded via
background-image
, inlining critical CSS (or JavaScript) and pre-loading the rest of the CSS (or JavaScript).Preload important images early; no need to wait on JavaScript to discover them. (Image credit: “Preload Late-Discovered Hero Images Faster” by Addy Osmani) (Large preview) A
preload
tag can initiate a preload only after the browser has received the HTML from the server and the lookahead parser has found thepreload
tag. Preloading via the HTTP header could be a bit faster since we don't to wait for the browser to parse the HTML to start the request (it's debated though).Early Hints will help even further, enabling preload to kick in even before the response headers for the HTML are sent (on the roadmap in Chromium, Firefox). Plus, Priority Hints will help us indicate loading priorities for scripts.
Beware : if you're using
preload
,as
must be defined or nothing loads, plus preloaded fonts without thecrossorigin
attribute will double fetch. If you're usingprefetch
, beware of theAge
header issues in Firefox.

- Use service workers for caching and network fallbacks.
No performance optimization over a network can be faster than a locally stored cache on a user's machine (there are exceptions though). If your website is running over HTTPS, we can cache static assets in a service worker cache and store offline fallbacks (or even offline pages) and retrieve them from the user's machine, rather than going to the network.As suggested by Phil Walton, with service workers, we can send smaller HTML payloads by programmatically generating our responses. A service worker can request just the bare minimum of data it needs from the server (eg an HTML content partial, a Markdown file, JSON data, etc.), and then it can programmatically transform that data into a full HTML document. So once a user visits a site and the service worker is installed, the user will never request a full HTML page again. The performance impact can be quite impressive.
Browser support? Service workers are widely supported and the fallback is the network anyway. Does it help boost performance ? Oh yes, it does. And it's getting better, eg with Background Fetch allowing background uploads/downloads via a service worker as well.
There are a number of use cases for a service worker. For example, you could implement "Save for offline" feature, handle broken images, introduce messaging between tabs or provide different caching strategies based on request types. In general, a common reliable strategy is to store the app shell in the service worker's cache along with a few critical pages, such as offline page, frontpage and anything else that might be important in your case.
There are a few gotchas to keep in mind though. With a service worker in place, we need to beware range requests in Safari (if you are using Workbox for a service worker it has a range request module). If you ever stumbled upon
DOMException: Quota exceeded.
error in the browser console, then look into Gerardo's article When 7KB equals 7MB.كما كتب جيراردو ، "إذا كنت تنشئ تطبيق ويب تقدميًا وتواجه تضخمًا في ذاكرة التخزين المؤقت عندما يقوم عامل الخدمة بتخزين الأصول الثابتة التي يتم عرضها من شبكات CDN ، فتأكد من وجود رأس استجابة CORS المناسب للموارد متعددة الأصول ، فأنت لا تخزن الاستجابات المبهمة مؤقتًا مع عامل الخدمة لديك عن غير قصد ، يمكنك تمكين أصول الصور المشتركة في وضع CORS عن طريق إضافة السمة
crossorigin
إلى علامة<img>
".هناك الكثير من الموارد الرائعة للبدء مع عمال الخدمة:
- عقلية عامل الخدمة ، والتي تساعدك على فهم كيفية عمل عمال الخدمة خلف الكواليس والأشياء التي يجب فهمها عند بناء واحد.
- يقدم Chris Ferdinandi سلسلة رائعة من المقالات حول العاملين في الخدمة ، ويشرح كيفية إنشاء تطبيقات غير متصلة بالإنترنت ويغطي مجموعة متنوعة من السيناريوهات ، من حفظ الصفحات التي تم عرضها مؤخرًا في وضع عدم الاتصال إلى تعيين تاريخ انتهاء صلاحية للعناصر الموجودة في ذاكرة التخزين المؤقت لعامل الخدمة.
- عيوب عامل الخدمة وأفضل الممارسات ، مع بعض النصائح حول النطاق ، وتأخير تسجيل عامل الخدمة والتخزين المؤقت لعامل الخدمة.
- سلسلة رائعة من تأليف Ire Aderinokun على "Offline First" مع Service Worker ، مع إستراتيجية حول تهيئة هيكل التطبيق مسبقًا.
- عامل الخدمة: مقدمة مع نصائح عملية حول كيفية استخدام عامل الخدمة للحصول على تجارب ثرية في وضع عدم الاتصال ، ومزامنة خلفية دورية وإشعارات دفع.
- يجدر دائمًا الإشارة إلى كتاب الطبخ غير المتصل بجيك أرشيبالد الجيد مع عدد من الوصفات حول كيفية خبز عامل الخدمة الخاص بك.
- Workbox عبارة عن مجموعة من مكتبات عمال الخدمة تم إنشاؤها خصيصًا لإنشاء تطبيقات ويب تقدمية.
- هل تقوم بتشغيل خوادم على CDN / Edge ، على سبيل المثال لاختبار A / B؟
في هذه المرحلة ، نحن معتادون تمامًا على تشغيل عمال الخدمة على العميل ، ولكن مع تنفيذ شبكات CDN على الخادم ، يمكننا استخدامها لتعديل الأداء على الحافة أيضًا.على سبيل المثال ، في اختبارات A / B ، عندما تحتاج HTML إلى تغيير محتواها لمستخدمين مختلفين ، يمكننا استخدام عمال الخدمة على خوادم CDN للتعامل مع المنطق. يمكننا أيضًا دفق إعادة كتابة HTML لتسريع المواقع التي تستخدم خطوط Google.

- تحسين أداء العرض.
عندما يكون التطبيق بطيئًا ، يمكن ملاحظته على الفور. لذلك نحن بحاجة إلى التأكد من عدم وجود تأخير عند تمرير الصفحة أو عندما يتم تحريك عنصر ، وأنك تصل باستمرار إلى 60 إطارًا في الثانية. إذا لم يكن ذلك ممكنًا ، فمن الأفضل جعل الإطارات متسقة في الثانية على الأقل أفضل من النطاق المختلط من 60 إلى 15. استخدمwill-change
في CSS لإعلام المتصفح بالعناصر والخصائص التي ستتغير.كلما واجهت ، صحح أخطاء عمليات إعادة الطلاء غير الضرورية في DevTools:
- قياس أداء عرض وقت التشغيل. تحقق من بعض النصائح المفيدة حول كيفية فهمها.
- للبدء ، تحقق من دورة Udacity المجانية لبول لويس حول تحسين عرض المتصفح ومقال جورجي ماركوك حول رسم المتصفح واعتبارات أداء الويب.
- قم بتمكين وميض الطلاء في "المزيد من الأدوات → العرض → وميض الطلاء" في Firefox DevTools.
- في React DevTools ، حدد "تمييز التحديثات" وقم بتمكين "تسجيل سبب عرض كل مكون" ،
- يمكنك أيضًا استخدام Why Did You Render ، لذلك عند إعادة تصيير أحد المكونات ، سيُعلمك الفلاش بالتغيير.
هل تستخدم تخطيط البناء؟ ضع في اعتبارك أنه قد يكون قادرًا على إنشاء تخطيط Masonry باستخدام شبكة CSS وحدها ، قريبًا جدًا.
إذا كنت ترغب في التعمق في الموضوع ، فقد شارك نولان لوسون الحيل لقياس أداء التخطيط بدقة في مقالته ، واقترح جيسون ميلر تقنيات بديلة أيضًا. لدينا أيضًا مقال صغير بقلم Sergey Chikuyonok حول كيفية الحصول على الرسوم المتحركة GPU بشكل صحيح.
يمكن للمتصفحات تحريك التحويل والتعتيم بثمن بخس. تعد CSS Triggers مفيدة للتحقق مما إذا كانت CSS تؤدي إلى إعادة التخطيطات أو إعادة التدفق. (رصيد الصورة: Addy Osmani) (معاينة كبيرة) ملاحظة : التغييرات على الطبقات المكونة من GPU هي الأقل تكلفة ، لذلك إذا كان بإمكانك الابتعاد عن طريق تشغيل التركيب فقط عبر
opacity
transform
، فستكون على المسار الصحيح. قدمت آنا ميجاس الكثير من النصائح العملية في حديثها عن تصحيح أداء عرض واجهة المستخدم أيضًا. ولفهم كيفية تصحيح أخطاء أداء الطلاء في DevTools ، تحقق من فيديو تدقيق أداء الطلاء من Umar. - هل قمت بتحسين الأداء الملحوظ؟
في حين أن تسلسل كيفية ظهور المكونات على الصفحة ، وإستراتيجية كيفية خدمة الأصول للمتصفح أمر مهم ، يجب ألا نقلل من دور الأداء المتصور أيضًا. يتعامل المفهوم مع الجوانب النفسية للانتظار ، مما يؤدي بشكل أساسي إلى إبقاء العملاء مشغولين أو مشاركين أثناء حدوث شيء آخر. هذا هو المكان الذي تلعب فيه إدارة الإدراك والبدء الوقائي والإنجاز المبكر وإدارة التسامح.ماذا يعني كل ذلك؟ أثناء تحميل الأصول ، يمكننا أن نحاول أن نكون دائمًا متقدمًا على العميل بخطوة واحدة ، لذلك تبدو التجربة سريعة بينما يحدث الكثير في الخلفية. للحفاظ على تفاعل العميل ، يمكننا اختبار الشاشات الهيكلية (عرض توضيحي للتنفيذ) بدلاً من تحميل المؤشرات وإضافة انتقالات / رسوم متحركة وخداع UX بشكل أساسي عندما لا يكون هناك شيء آخر يمكن تحسينه.
في دراسة الحالة الخاصة بهم حول The Art of UI Skeletons ، يشارك Kumar McMillan بعض الأفكار والتقنيات حول كيفية محاكاة القوائم الديناميكية والنص والشاشة النهائية ، بالإضافة إلى كيفية التفكير في التفكير الهيكلي باستخدام React.
احذر على الرغم من ذلك: يجب اختبار الشاشات الهيكلية قبل النشر حيث أظهرت بعض الاختبارات أن الشاشات الهيكلية يمكن أن تؤدي إلى أسوأ أداء بكل المقاييس.
- هل تمنع تغييرات التخطيط وإعادة الطلاء؟
في مجال الأداء المدرك ، من المحتمل أن تكون إحدى أكثر التجارب اضطرابًا هي تغيير التخطيط ، أو إعادة التدفق ، بسبب الصور ومقاطع الفيديو التي تم إعادة قياسها ، أو خطوط الويب ، أو الإعلانات المحقونة أو البرامج النصية المكتشفة مؤخرًا والتي تملأ المكونات بالمحتوى الفعلي. نتيجة لذلك ، قد يبدأ العميل في قراءة مقال لمجرد مقاطعته من خلال قفزة في التخطيط فوق منطقة القراءة. غالبًا ما تكون التجربة مفاجئة ومربكة للغاية: وربما تكون هذه حالة من أولويات التحميل التي تحتاج إلى إعادة النظر.طور المجتمع بضع تقنيات وطرق بديلة لتجنب التدفقات العائدة. بشكل عام ، من الجيد تجنب إدراج محتوى جديد فوق المحتوى الحالي ، ما لم يحدث ذلك استجابة لتفاعل المستخدم. قم دائمًا بتعيين سمات العرض والارتفاع على الصور ، لذلك تخصص المتصفحات الحديثة المربع وتحجز المساحة افتراضيًا (Firefox و Chrome).
لكل من الصور أو مقاطع الفيديو ، يمكننا استخدام عنصر نائب SVG لحجز مربع العرض الذي ستظهر فيه الوسائط. وهذا يعني أنه سيتم حجز المنطقة بشكل صحيح عندما تحتاج إلى الحفاظ على نسبة العرض إلى الارتفاع أيضًا. يمكننا أيضًا استخدام العناصر النائبة أو الصور الاحتياطية للإعلانات والمحتوى الديناميكي ، بالإضافة إلى تخصيص خانات التخطيط مسبقًا.
بدلاً من التحميل البطيء للصور ذات البرامج النصية الخارجية ، ضع في اعتبارك استخدام التحميل البطيء الأصلي أو التحميل البطيء المختلط عندما نقوم بتحميل برنامج نصي خارجي فقط إذا كان التحميل البطيء الأصلي غير مدعوم.
كما ذكرنا أعلاه ، قم دائمًا بتجميع خطوط الويب وإعادة رسمها والانتقال من جميع الخطوط الاحتياطية إلى جميع خطوط الويب في وقت واحد - فقط تأكد من أن هذا التبديل ليس مفاجئًا للغاية ، عن طريق ضبط ارتفاع الخط والتباعد بين الخطوط باستخدام أداة مطابقة نمط الخط .
لتجاوز مقاييس الخط لخط احتياطي لمحاكاة خط الويب ، يمكننا استخدام واصفات @ font-face لتجاوز مقاييس الخط (عرض توضيحي ، ممكّن في Chrome 87). (لاحظ أن عمليات الضبط معقدة مع حزم الخطوط المعقدة.)
بالنسبة إلى CSS المتأخر ، يمكننا التأكد من أن CSS ذات الأهمية الحاسمة للتخطيط مضمنة في رأس كل قالب. أبعد من ذلك: بالنسبة للصفحات الطويلة ، عند إضافة شريط التمرير العمودي ، فإنه ينقل المحتوى الرئيسي بمقدار 16 بكسل إلى اليسار. لعرض شريط التمرير مبكرًا ، يمكننا إضافة
overflow-y: scroll
علىhtml
لفرض شريط التمرير عند الرسم الأول. يساعد هذا الأخير لأن أشرطة التمرير يمكن أن تتسبب في تحولات غير تافهة في التخطيط بسبب إعادة تدفق محتوى الجزء العلوي عندما يتغير العرض. يجب أن يحدث غالبًا على الأنظمة الأساسية التي تحتوي على أشرطة تمرير غير متراكبة مثل Windows. لكن: يكسرposition: sticky
لأن هذه العناصر لن تخرج من الحاوية أبدًا.إذا كنت تتعامل مع الرؤوس التي أصبحت ثابتة أو مثبتة في أعلى الصفحة عند التمرير ، فاحتفظ بمساحة للرأس عندما تصبح متداخلة ، على سبيل المثال مع عنصر نائب أو
margin-top
المحتوى. يجب أن يكون الاستثناء هو لافتات الموافقة على ملفات تعريف الارتباط التي لا ينبغي أن يكون لها تأثير على CLS ، لكن في بعض الأحيان يحدث ذلك: يعتمد ذلك على التنفيذ. هناك بعض الاستراتيجيات والوجبات السريعة المثيرة للاهتمام في سلسلة محادثات Twitter هذه.بالنسبة لمكون علامة التبويب الذي قد يتضمن كمية مختلفة من النصوص ، يمكنك منع تغييرات التخطيط باستخدام حزم شبكة CSS. من خلال وضع محتوى كل علامة تبويب في نفس منطقة الشبكة ، وإخفاء واحدة منها في كل مرة ، يمكننا التأكد من أن الحاوية تأخذ دائمًا ارتفاع العنصر الأكبر ، لذلك لن تحدث أي تغييرات في التخطيط.
آه ، وبالطبع ، يمكن أن يتسبب التمرير اللانهائي و "تحميل المزيد" في حدوث تغييرات في التخطيط أيضًا إذا كان هناك محتوى أسفل القائمة (مثل التذييل). لتحسين CLS ، احتفظ بمساحة كافية للمحتوى الذي سيتم تحميله قبل أن يقوم المستخدم بالتمرير إلى هذا الجزء من الصفحة ، أو أزل التذييل أو أي عناصر DOM في أسفل الصفحة قد يتم دفعها لأسفل عن طريق تحميل المحتوى. أيضًا ، الجلب المسبق للبيانات والصور للمحتوى الموجود في الجزء السفلي غير المرئي من الصفحة بحيث يكون هناك بالفعل في الوقت الذي يقوم فيه المستخدم بالتمرير إلى هذا الحد. يمكنك استخدام مكتبات افتراضية القوائم مثل نافذة رد الفعل لتحسين القوائم الطويلة أيضًا ( شكرًا ، Addy Osmani! ).
للتأكد من احتواء تأثير التدفقات المعاد تدفقها ، قم بقياس استقرار التخطيط باستخدام Layout Instability API. باستخدامه ، يمكنك حساب درجة تغيير التخطيط التراكمي ( CLS ) وإدراجه كمتطلب في اختباراتك ، لذلك كلما ظهر انحدار ، يمكنك تتبعه وإصلاحه.
لحساب درجة تحول التخطيط ، ينظر المستعرض إلى حجم إطار العرض وحركة العناصر غير المستقرة في إطار العرض بين إطارين تم تقديمهما. من الناحية المثالية ، ستكون النتيجة قريبة من
0
. يوجد دليل رائع بقلم ميليكا ميهاجليا وفيليب والتون حول ماهية CLS وكيفية قياسه. إنها نقطة انطلاق جيدة لقياس الأداء المتصور والحفاظ عليه وتجنب الاضطراب ، خاصةً بالنسبة للمهام الحيوية للأعمال.نصيحة سريعة : لاكتشاف سبب تغيير التخطيط في DevTools ، يمكنك استكشاف تغييرات التخطيط ضمن "الخبرة" في لوحة الأداء.
المكافأة : إذا كنت ترغب في تقليل التدفقات العائدة وإعادة الطلاء ، فتحقق من دليل Charis Theodoulou لتقليل إعادة تدفق DOM / تخطيط Thrashing وقائمة Paul Irish لما يفرض التخطيط / إعادة التدفق بالإضافة إلى CSSTriggers.com ، وهو جدول مرجعي لخصائص CSS التي تؤدي إلى التخطيط والطلاء والتركيب.
الشبكات و HTTP / 2
- هل التدبيس OCSP ممكّن؟
من خلال تمكين تدبيس OCSP على الخادم الخاص بك ، يمكنك تسريع مصافحات TLS الخاصة بك. تم إنشاء بروتوكول حالة الشهادة عبر الإنترنت (OCSP) كبديل لبروتوكول قائمة إبطال الشهادات (CRL). يتم استخدام كلا البروتوكولين للتحقق مما إذا كان قد تم إبطال شهادة SSL.ومع ذلك ، فإن بروتوكول OCSP لا يتطلب من المتصفح قضاء بعض الوقت في التنزيل ثم البحث في قائمة للحصول على معلومات الشهادة ، وبالتالي تقليل الوقت المطلوب للمصافحة.
- هل قللت من تأثير إلغاء شهادة SSL؟
في مقالته عن "تكلفة أداء شهادات EV" ، يقدم Simon Hearne نظرة عامة رائعة على الشهادات الشائعة ، والتأثير الذي قد يكون لاختيار الشهادة على الأداء العام.كما كتب سايمون ، في عالم HTTPS ، هناك عدة أنواع من مستويات التحقق من صحة الشهادات المستخدمة لتأمين حركة المرور:
- التحقق من صحة المجال (DV) يتحقق من أن طالب الشهادة يمتلك المجال ،
- التحقق من صحة المؤسسة (OV) يتحقق من أن المؤسسة تمتلك المجال ،
- التحقق من الصحة الموسعة (EV) يتحقق من أن المؤسسة تمتلك المجال ، مع التحقق الصارم من الصحة.
من المهم ملاحظة أن جميع هذه الشهادات هي نفسها من حيث التكنولوجيا ؛ أنها تختلف فقط في المعلومات والخصائص المقدمة في تلك الشهادات.
شهادات EV باهظة الثمن وتستغرق وقتًا طويلاً لأنها تتطلب من الإنسان مراجعة الشهادة والتأكد من صحتها. من ناحية أخرى ، غالبًا ما يتم توفير شهادات DV مجانًا - على سبيل المثال من خلال Let's Encrypt - سلطة تصديق آلية مفتوحة ومتكاملة جيدًا في العديد من موفري الاستضافة وشبكات CDN. في الواقع ، في وقت كتابة هذا التقرير ، كان يشغل أكثر من 225 مليون موقع (PDF) ، على الرغم من أنه يمثل 2.69٪ فقط من الصفحات (المفتوحة في Firefox).
إذن ما هي المشكلة إذن؟ المشكلة هي أن شهادات EV لا تدعم تدبيس OCSP المذكور أعلاه بشكل كامل . بينما يسمح التدبيس للخادم بالتحقق من المرجع المصدق إذا تم إبطال الشهادة ثم إضافة ("تدبيس") هذه المعلومات إلى الشهادة ، دون تدبيس ، يتعين على العميل القيام بكل العمل ، مما يؤدي إلى طلبات غير ضرورية أثناء تفاوض TLS . في حالة الاتصالات الضعيفة ، قد ينتهي هذا الأمر بتكاليف أداء ملحوظة (1000 مللي ثانية +).
لا تعد شهادات EV خيارًا رائعًا لأداء الويب ، ويمكن أن تسبب تأثيرًا أكبر بكثير على الأداء من شهادات DV. للحصول على أفضل أداء للويب ، قم دائمًا بتقديم شهادة DV مدمجة OCSP. كما أنها أرخص بكثير من شهادات EV وأقل صعوبة في الحصول عليها. حسنًا ، على الأقل حتى يتوفر CRLite.
الضغط مهم: 40-43٪ من سلاسل الشهادات غير المضغوطة كبيرة جدًا بحيث لا تتناسب مع رحلة QUIC واحدة من 3 مخططات بيانات UDP. (رصيد الصورة :) بسرعة) (معاينة كبيرة) ملاحظة : مع استخدام QUIC / HTTP / 3 علينا ، تجدر الإشارة إلى أن سلسلة شهادات TLS هي المحتوى المتغير الحجم الذي يهيمن على عدد البايت في QUIC Handshake. يختلف الحجم بين بضع مئات من البايت وأكثر من 10 كيلوبايت.
لذا ، فإن الاحتفاظ بشهادات TLS صغيرة أمر مهم كثيرًا على QUIC / HTTP / 3 ، حيث أن الشهادات الكبيرة ستتسبب في العديد من المصافحة. أيضًا ، نحتاج إلى التأكد من أن الشهادات مضغوطة ، وإلا ستكون سلاسل الشهادات كبيرة جدًا بحيث لا يمكن وضعها في رحلة QUIC واحدة.
يمكنك العثور على مزيد من التفاصيل والمؤشرات للمشكلة والحلول على:
- شهادات EV تجعل الويب بطيئًا وغير موثوق به بواسطة آرون بيترز ،
- تأثير إبطال شهادة SSL على أداء الويب بواسطة Matt Hobbs ،
- تكلفة أداء شهادات EV بواسطة Simon Hearne ،
- هل تتطلب مصافحة QUIC الضغط لتكون سريعة؟ بواسطة باتريك مكمانوس.
- هل اعتمدت IPv6 حتى الآن؟
نظرًا لأن المساحة المتوفرة لدينا مع IPv4 تنفد ، وتعتمد شبكات المحمول الرئيسية IPv6 بسرعة (وصلت الولايات المتحدة تقريبًا إلى حد اعتماد IPv6 بنسبة 50٪) ، فمن المستحسن تحديث DNS الخاص بك إلى IPv6 للبقاء ضد الرصاص في المستقبل. فقط تأكد من توفير دعم المكدس المزدوج عبر الشبكة - فهو يسمح لـ IPv6 و IPv4 بالعمل في نفس الوقت جنبًا إلى جنب مع بعضهما البعض. بعد كل شيء ، IPv6 غير متوافق مع الإصدارات السابقة. تظهر الدراسات أيضًا أن IPv6 جعل هذه المواقع أسرع بنسبة 10 إلى 15٪ بسبب اكتشاف الجوار (NDP) وتحسين المسار. - تأكد من تشغيل جميع الأصول عبر HTTP / 2 (أو HTTP / 3).
مع دفع Google نحو شبكة HTTPS أكثر أمانًا على مدار السنوات القليلة الماضية ، يعد التحول إلى بيئة HTTP / 2 استثمارًا جيدًا بالتأكيد. في الواقع ، وفقًا لتقويم الويب Web Almanac ، فإن 64٪ من جميع الطلبات تعمل عبر HTTP / 2 بالفعل.من المهم أن نفهم أن HTTP / 2 ليس مثاليًا ولديه مشكلات في تحديد الأولويات ، ولكنه مدعوم جيدًا ؛ وفي معظم الحالات ، تكون أفضل حالًا معها.
كلمة تحذير: تتم إزالة HTTP / 2 Server Push من Chrome ، لذلك إذا كان التنفيذ يعتمد على Server Push ، فقد تحتاج إلى إعادة النظر فيه. بدلاً من ذلك ، ربما نبحث في Early Hints ، والتي تم دمجها كتجربة في Fastly بالفعل.
إذا كنت لا تزال تعمل على HTTP ، فستكون المهمة الأكثر استهلاكا للوقت هي الترحيل إلى HTTPS أولاً ، ثم ضبط عملية الإنشاء الخاصة بك لتلبية تعدد إرسال وتوازي HTTP / 2. إن إحضار HTTP / 2 إلى Gov.uk هو دراسة حالة رائعة لفعل ذلك بالضبط ، وإيجاد طريقة من خلال CORS و SRI و WPT على طول الطريق. بالنسبة لبقية هذه المقالة ، نفترض أنك إما تقوم بالتبديل إلى HTTP / 2 أو أنك قمت بالفعل بالتبديل إليه.

- نشر HTTP / 2 بشكل صحيح.
مرة أخرى ، يمكن أن يستفيد عرض الأصول عبر HTTP / 2 من الإصلاح الجزئي لكيفية خدمة الأصول حتى الآن. ستحتاج إلى إيجاد توازن دقيق بين وحدات التغليف وتحميل العديد من الوحدات الصغيرة بالتوازي. في نهاية اليوم ، لا يزال أفضل طلب هو عدم وجود طلب ، ومع ذلك ، فإن الهدف هو إيجاد توازن جيد بين التسليم الأول السريع للأصول والتخزين المؤقت.من ناحية أخرى ، قد ترغب في تجنب تجميع الأصول تمامًا ، بدلاً من تقسيم الواجهة بالكامل إلى العديد من الوحدات الصغيرة ، وضغطها كجزء من عملية الإنشاء وتحميلها بالتوازي. لن يتطلب التغيير في ملف واحد إعادة تنزيل ورقة الأنماط أو JavaScript بأكملها. كما أنه يقلل من وقت التحليل ويحافظ على انخفاض حمولات الصفحات الفردية.
من ناحية أخرى ، لا تزال التعبئة والتغليف مهمة. باستخدام العديد من البرامج النصية الصغيرة ، سيعاني الضغط الكلي وستزيد تكلفة استرداد الكائنات من ذاكرة التخزين المؤقت. سيستفيد ضغط الحزمة الكبيرة من إعادة استخدام القاموس ، بينما لن تستفيد الحزم المنفصلة الصغيرة. هناك عمل قياسي لمعالجة ذلك ، لكنه بعيد المنال في الوقت الحالي. ثانيًا ، لم يتم تحسين المستعرضات بعد لمهام سير العمل هذه. على سبيل المثال ، سيقوم Chrome بتشغيل اتصالات بين العمليات (IPCs) خطية لعدد الموارد ، لذلك فإن تضمين مئات الموارد سيكون له تكاليف وقت تشغيل المتصفح.
لتحقيق أفضل النتائج باستخدام HTTP / 2 ، ضع في اعتبارك تحميل CSS تدريجيًا ، كما اقترحه Jake Archibald من Chrome. ومع ذلك ، يمكنك محاولة تحميل CSS بشكل تدريجي. في الواقع ، لم يعد CSS داخل الجسم يحظر العرض لـ Chrome. ولكن هناك بعض مشكلات تحديد الأولويات ، لذا فهي ليست مباشرة بنفس القدر ، ولكنها تستحق التجربة.
يمكنك الابتعاد عن دمج اتصال HTTP / 2 ، والذي يسمح لك باستخدام تجزئة النطاق أثناء الاستفادة من HTTP / 2 ، ولكن تحقيق ذلك عمليًا أمر صعب ، وبشكل عام ، لا يعتبر ممارسة جيدة. أيضًا ، لا يتم دائمًا تشغيل HTTP / 2 و Subresource Integrity.
ما يجب القيام به؟ حسنًا ، إذا كنت تعمل عبر HTTP / 2 ، فإن إرسال حوالي 6-10 حزم يبدو وكأنه حل وسط لائق (وليس سيئًا للغاية بالنسبة للمتصفحات القديمة). قم بالتجربة والقياس للعثور على التوازن الصحيح لموقعك على الويب.
- هل نرسل جميع الأصول عبر اتصال HTTP / 2 واحد؟
تتمثل إحدى المزايا الرئيسية لـ HTTP / 2 في أنه يسمح لنا بإرسال الأصول عبر السلك عبر اتصال واحد. ومع ذلك ، في بعض الأحيان ربما نكون قد فعلنا شيئًا خاطئًا - على سبيل المثال ، لديك مشكلة في CORS ، أو أخطأنا في تكوين سمةcrossorigin
، لذلك سيضطر المتصفح إلى فتح اتصال جديد.للتحقق مما إذا كانت جميع الطلبات تستخدم اتصال HTTP / 2 واحدًا أو خطأ في تكوين شيء ما ، قم بتمكين عمود "معرف الاتصال" في DevTools → Network. على سبيل المثال ، تشترك جميع الطلبات هنا في نفس الاتصال (286) - باستثناء الملف manifest.json ، الذي يفتح اتصالاً منفصلاً (451).

- هل تدعم الخوادم وشبكات CDN بروتوكول HTTP / 2؟
الخوادم المختلفة وشبكات CDN (لا تزال) تدعم HTTP / 2 بشكل مختلف. استخدم مقارنة CDN للتحقق من خياراتك ، أو ابحث بسرعة عن كيفية أداء الخوادم والميزات التي يمكنك توقع دعمها.استشر بحث Pat Meenan المذهل حول أولويات HTTP / 2 (فيديو) واختبار دعم الخادم لتحديد أولويات HTTP / 2. وفقًا لبات ، يوصى بتمكين التحكم في ازدحام BBR وتعيين
tcp_notsent_lowat
على 16 كيلو بايت لتحديد أولويات HTTP / 2 للعمل بشكل موثوق على Linux 4.9 kernels والإصدارات الأحدث ( شكرًا ، Yoav! ). أجرى Andy Davies بحثًا مشابهًا لتحديد أولويات HTTP / 2 عبر المتصفحات وشبكات CDN وخدمات الاستضافة السحابية.أثناء تشغيله ، تحقق جيدًا مما إذا كان kernel الخاص بك يدعم TCP BBR وقم بتمكينه إذا كان ذلك ممكنًا. يتم استخدامه حاليًا على Google Cloud Platform و Amazon Cloudfront و Linux (مثل Ubuntu).
- هل ضغط HPACK قيد الاستخدام؟
إذا كنت تستخدم HTTP / 2 ، فتحقق جيدًا من أن خوادمك تنفذ ضغط HPACK لرؤوس استجابة HTTP لتقليل الحمل غير الضروري. قد لا تدعم بعض خوادم HTTP / 2 المواصفات بشكل كامل ، ويعتبر HPACK مثالاً على ذلك. H2spec هي أداة رائعة (إذا كانت مفصلة للغاية من الناحية الفنية) للتحقق من ذلك. خوارزمية ضغط HPACK رائعة للغاية ، وهي تعمل. - تأكد من أن الأمن على الخادم الخاص بك مضاد للرصاص.
تعمل جميع عمليات تنفيذ المستعرض لـ HTTP / 2 عبر TLS ، لذلك قد ترغب في تجنب التحذيرات الأمنية أو أن بعض العناصر في صفحتك لا تعمل. تحقق جيدًا من تعيين رؤوس الأمان بشكل صحيح ، وتخلص من الثغرات الأمنية المعروفة ، وتحقق من إعداد HTTPS.تأكد أيضًا من تحميل جميع المكونات الإضافية الخارجية ونصوص التتبع عبر HTTPS ، وأن البرمجة النصية عبر المواقع غير ممكنة وأنه تم تعيين رؤوس HTTP Strict Transport Security ورؤوس سياسة أمان المحتوى بشكل صحيح.
- هل تدعم الخوادم وشبكات CDN بروتوكول HTTP / 3؟
على الرغم من أن HTTP / 2 قد جلب عددًا من التحسينات الهامة في الأداء على الويب ، إلا أنه ترك أيضًا مجالًا للتحسين - خاصةً حظر رأس الخط في TCP ، والذي كان ملحوظًا على شبكة بطيئة مع فقد كبير في الحزمة. يقوم HTTP / 3 بحل هذه المشكلات إلى الأبد (مقال).لمعالجة مشكلات HTTP / 2 ، تعمل IETF جنبًا إلى جنب مع Google و Akamai وغيرهما على بروتوكول جديد تم توحيده مؤخرًا باعتباره HTTP / 3.
لقد شرح روبن ماركس HTTP / 3 جيدًا ، والتفسير التالي مبني على تفسيره. في جوهره ، يشبه HTTP / 3 إلى حد كبير HTTP / 2 من حيث الميزات ، ولكنه يعمل بشكل مختلف تمامًا تحت الغطاء. يوفر HTTP / 3 عددًا من التحسينات: مصافحة أسرع وتشفير أفضل وتدفق مستقل أكثر موثوقية وتشفير أفضل وتحكم في التدفق. يتمثل الاختلاف الملحوظ في أن HTTP / 3 يستخدم QUIC كطبقة نقل ، مع حزم QUIC مغلفة أعلى مخططات UDP ، بدلاً من TCP.
يدمج QUIC بشكل كامل TLS 1.3 في البروتوكول ، بينما في TCP يتم وضعه في الأعلى. في مكدس TCP النموذجي ، لدينا بضع مرات ذهابًا وإيابًا من النفقات العامة لأن TCP و TLS يحتاجان إلى إجراء مصافحة منفصلة خاصة بهما ، ولكن مع QUIC يمكن دمجهما وإكمالهما في رحلة واحدة ذهابًا وإيابًا فقط . نظرًا لأن TLS 1.3 يسمح لنا بإعداد مفاتيح التشفير لاتصال لاحق ، فمن الاتصال الثاني فصاعدًا ، يمكننا بالفعل إرسال واستقبال بيانات طبقة التطبيق في أول رحلة ذهابًا وإيابًا ، والتي تسمى "0-RTT".
أيضًا ، تمت إعادة كتابة خوارزمية ضغط الرأس لـ HTTP / 2 بالكامل ، جنبًا إلى جنب مع نظام تحديد الأولويات الخاص بها. بالإضافة إلى ذلك ، يدعم QUIC ترحيل الاتصال من Wi-Fi إلى الشبكة الخلوية عبر معرفات الاتصال في رأس كل حزمة QUIC. تتم معظم عمليات التنفيذ في مساحة المستخدم ، وليس في مساحة kernel (كما هو الحال مع TCP) ، لذلك يجب أن نتوقع تطور البروتوكول في المستقبل.
هل سيحدث كل ذلك فرقًا كبيرًا؟ ربما نعم ، حيث يكون لها تأثير خاص على أوقات التحميل على الهاتف المحمول ، ولكن أيضًا على كيفية تقديم الأصول للمستخدمين النهائيين. أثناء وجود طلبات متعددة في HTTP / 2 ، تشترك في الاتصال ، في HTTP / 3 ، تشارك الطلبات أيضًا اتصالًا ولكنها تتدفق بشكل مستقل ، لذلك لم تعد الحزمة التي تم إسقاطها تؤثر على جميع الطلبات ، بل على الدفق الواحد فقط.
هذا يعني أنه مع وجود حزمة جافا سكريبت كبيرة واحدة ، ستتم إبطاء معالجة الأصول عندما يتوقف أحد الدفقين مؤقتًا ، سيكون التأثير أقل أهمية عند تدفق ملفات متعددة بالتوازي (HTTP / 3). لذلك لا يزال التغليف مهمًا .
HTTP / 3 لا يزال قيد العمل. Chrome و Firefox و Safari بها تطبيقات بالفعل. بعض شبكات CDN تدعم QUIC و HTTP / 3 بالفعل. في أواخر عام 2020 ، بدأ Chrome في نشر HTTP / 3 و IETF QUIC ، وفي الواقع تعمل جميع خدمات Google (Google Analytics و YouTube وما إلى ذلك) بالفعل عبر HTTP / 3. يدعم LiteSpeed Web Server بروتوكول HTTP / 3 ، ولكن لا يدعمه أي من Apache أو nginx أو IIS حتى الآن ، ولكن من المحتمل أن يتغير بسرعة في عام 2021.
خلاصة القول : إذا كان لديك خيار استخدام HTTP / 3 على الخادم وعلى شبكة CDN الخاصة بك ، فمن المحتمل أن يكون القيام بذلك فكرة جيدة. ستأتي الفائدة الرئيسية من جلب كائنات متعددة في وقت واحد ، لا سيما في الاتصالات ذات زمن الانتقال العالي. لا نعرف على وجه اليقين حتى الآن لأنه لم يتم إجراء الكثير من الأبحاث في هذا المجال ، ولكن النتائج الأولى واعدة للغاية.
إذا كنت ترغب في التعمق أكثر في تفاصيل ومزايا البروتوكول ، فإليك بعض نقاط البداية الجيدة للتحقق منها:
- شرح HTTP / 3 ، جهد تعاوني لتوثيق بروتوكولات HTTP / 3 و QUIC. متوفر بلغات مختلفة ، أيضًا بصيغة PDF.
- رفع مستوى أداء الويب باستخدام HTTP / 3 مع Daniel Stenberg.
- يقدم الدليل الأكاديمي لـ QUIC مع Robin Marx المفاهيم الأساسية لبروتوكولات QUIC و HTTP / 3 ، ويشرح كيف يتعامل HTTP / 3 مع حظر رأس الخط وترحيل الاتصال ، وكيف تم تصميم HTTP / 3 ليكون دائمًا (شكرًا ، Simon ) !).
- يمكنك التحقق مما إذا كان الخادم الخاص بك يعمل على HTTP / 3 على HTTP3Check.net.
الاختبار والمراقبة
- هل قمت بتحسين سير عمل التدقيق الخاص بك؟
قد لا يبدو الأمر وكأنه مشكلة كبيرة ، ولكن وجود الإعدادات الصحيحة في متناول يدك قد يوفر لك الكثير من الوقت في الاختبار. ضع في اعتبارك استخدام Alfred Workflow الخاص بـ Tim Kadlec لـ WebPageTest لتقديم اختبار إلى المثيل العام لـ WebPageTest. في الواقع ، يحتوي WebPageTest على العديد من الميزات الغامضة ، لذا خذ الوقت الكافي لتعلم كيفية قراءة مخطط WebPageTest Waterfall View وكيفية قراءة مخطط WebPageTest Connection View لتشخيص مشاكل الأداء وحلها بشكل أسرع.يمكنك أيضًا قيادة WebPageTest من جدول بيانات Google ودمج إمكانية الوصول والأداء ونتائج تحسين محركات البحث في إعداد Travis باستخدام Lighthouse CI أو مباشرة في Webpack.
ألق نظرة على AutoWebPerf الذي تم إصداره مؤخرًا ، وهو أداة معيارية تتيح التجميع التلقائي لبيانات الأداء من مصادر متعددة. على سبيل المثال ، يمكننا تعيين اختبار يومي على صفحاتك المهمة لالتقاط البيانات الميدانية من CrUX API وبيانات معملية من تقرير Lighthouse من PageSpeed Insights.
وإذا كنت بحاجة إلى تصحيح أخطاء شيء ما بسرعة ولكن يبدو أن عملية الإنشاء بطيئة بشكل ملحوظ ، فضع في اعتبارك أن "إزالة المسافات البيضاء وتشويه الرموز يمثلان 95٪ من تقليل حجم الشفرة المصغرة لمعظم JavaScript - وليس تحويلات التعليمات البرمجية التفصيلية. يمكنك ما عليك سوى تعطيل الضغط لتسريع عمليات إنشاء Uglify بمقدار 3 إلى 4 مرات ".

- هل اختبرت في المتصفحات الوكيلة والمتصفحات القديمة؟
لا يكفي الاختبار في Chrome و Firefox. انظر في كيفية عمل موقع الويب الخاص بك في المتصفحات الوكيلة والمتصفحات القديمة. يمتلك متصفح UC و Opera Mini ، على سبيل المثال ، حصة سوقية كبيرة في آسيا (تصل إلى 35٪ في آسيا). قم بقياس متوسط سرعة الإنترنت في البلدان التي تهمك لتجنب المفاجآت الكبيرة في المستقبل. اختبر باستخدام التحكم في الشبكة ، وقم بمحاكاة جهاز عالي النقاط في البوصة. يعد BrowserStack رائعًا للاختبار على أجهزة حقيقية عن بُعد ، ويكمله على الأقل بعدد قليل من الأجهزة الحقيقية في مكتبك - إنه يستحق ذلك.
- هل اختبرت أداء صفحات 404 الخاصة بك؟
عادة لا نفكر مرتين عندما يتعلق الأمر بـ 404 صفحات. بعد كل شيء ، عندما يطلب العميل صفحة غير موجودة على الخادم ، سيرد الخادم برمز الحالة 404 وصفحة 404 المرتبطة. ليس هناك الكثير من ذلك ، أليس كذلك؟أحد الجوانب المهمة لردود 404 هو حجم نص الاستجابة الفعلي الذي يتم إرساله إلى المتصفح. وفقًا لبحث 404 صفحات أجراه Matt Hobbs ، فإن الغالبية العظمى من الردود البالغ عددها 404 تأتي من الرموز المفضلة المفقودة وطلبات تحميل WordPress وطلبات JavaScript المعطلة وملفات البيان بالإضافة إلى ملفات CSS وملفات الخطوط. في كل مرة يطلب فيها العميل أصلًا غير موجود ، سيحصل على استجابة 404 - وغالبًا ما تكون هذه الاستجابة ضخمة.
تأكد من فحص وتحسين استراتيجية التخزين المؤقت لصفحات 404 الخاصة بك. هدفنا هو تقديم HTML إلى المتصفح فقط عندما يتوقع استجابة HTML ، وإرجاع حمولة خطأ صغيرة لجميع الاستجابات الأخرى. وفقًا لمات ، "إذا وضعنا CDN أمام مصدرنا الأصلي ، فلدينا فرصة تخزين استجابة صفحة 404 مؤقتًا على CDN. وهذا مفيد لأنه بدونه ، يمكن استخدام صفحة 404 كمتجه لهجوم DoS ، بواسطة إجبار الخادم الأصلي على الاستجابة لكل طلب 404 بدلاً من السماح لـ CDN بالاستجابة بإصدار مخبأ. "
لا يمكن أن تضر أخطاء 404 بأدائك فحسب ، بل يمكن أن تكلف أيضًا حركة المرور ، لذلك من الجيد تضمين صفحة خطأ 404 في مجموعة اختبار Lighthouse الخاصة بك ، وتتبع درجاتها بمرور الوقت.
- هل اختبرت أداء مطالبات الموافقة على اللائحة العامة لحماية البيانات الخاصة بك؟
في أوقات القانون العام لحماية البيانات (GDPR) وقانون حماية خصوصية المستهلك (CCPA) ، أصبح من الشائع الاعتماد على جهات خارجية لتوفير خيارات لعملاء الاتحاد الأوروبي للاشتراك أو الانسحاب من التتبع. ومع ذلك ، كما هو الحال مع أي برنامج نصي آخر تابع لجهة خارجية ، يمكن أن يكون لأدائها تأثير مدمر للغاية على جهد الأداء بأكمله.بالطبع ، من المرجح أن تغير الموافقة الفعلية تأثير البرامج النصية على الأداء العام ، لذلك ، كما أشار بوريس شابيرا ، قد نرغب في دراسة بعض ملفات تعريف أداء الويب المختلفة:
- تم رفض الموافقة بالكامل ،
- تم رفض الموافقة جزئيًا ،
- تم إعطاء الموافقة بالكامل.
- لم يتصرف المستخدم بناءً على مطالبة الموافقة (أو تم حظر المطالبة بواسطة أداة حظر المحتوى) ،
عادةً لا يجب أن يكون لمطالبات الموافقة على ملفات تعريف الارتباط تأثير على CLS ، ولكن في بعض الأحيان يكون لها تأثير ، لذلك ضع في اعتبارك استخدام خيارات مجانية ومفتوحة المصدر Osano أو مربع موافقة ملف تعريف الارتباط.
بشكل عام ، يجدر النظر في أداء النوافذ المنبثقة حيث ستحتاج إلى تحديد الإزاحة الأفقية أو الرأسية لحدث الماوس ووضع النافذة المنبثقة بشكل صحيح نسبيًا على المرساة. يشارك نعوم روزنتال ما تعلمه فريق ويكيميديا في المقالة دراسة حالة أداء الويب: معاينات صفحة ويكيبيديا (متوفرة أيضًا كفيديو ودقائق).
- هل تحتفظ بتشخيص أداء CSS؟
بينما يمكننا تضمين جميع أنواع الشيكات لضمان نشر التعليمات البرمجية غير الفعالة ، غالبًا ما يكون من المفيد الحصول على فكرة سريعة عن بعض الثمار التي يمكن حلها بسهولة. لذلك ، يمكننا استخدام أداة تشخيص الأداء الرائعة الخاصة بـ Tim Kadlec (مستوحاة من مقتطف Harry Roberts الذي يسلط الضوء على الصور المحملة البطيئة والصور غير الحجم والصور ذات التنسيق القديم والنصوص المتزامنة.على سبيل المثال ، قد ترغب في التأكد من عدم تحميل أي صور في الجزء المرئي من الصفحة بشكل كسول. يمكنك تخصيص المقتطف حسب احتياجاتك ، على سبيل المثال لتمييز خطوط الويب غير المستخدمة أو اكتشاف خطوط الرموز. أداة صغيرة رائعة لضمان ظهور الأخطاء أثناء تصحيح الأخطاء ، أو لمجرد تدقيق المشروع الحالي بسرعة كبيرة.
/* Performance Diagnostics CSS */ /* via Harry Roberts. https://twitter.com/csswizardry/status/1346477682544951296 */ img[loading=lazy] { outline: 10px solid red; }
- Have you tested the impact on accessibility?
When the browser starts to load a page, it builds a DOM, and if there is an assistive technology like a screen reader running, it also creates an accessibility tree. The screen reader then has to query the accessibility tree to retrieve the information and make it available to the user — sometimes by default, and sometimes on demand. And sometimes it takes time.When talking about fast Time to Interactive, usually we mean an indicator of how soon a user can interact with the page by clicking or tapping on links and buttons. The context is slightly different with screen readers. In that case, fast Time to Interactive means how much time passes by until the screen reader can announce navigation on a given page and a screen reader user can actually hit keyboard to interact.
Leonie Watson has given an eye-opening talk on accessibility performance and specifically the impact slow loading has on screen reader announcement delays. Screen readers are used to fast-paced announcements and quick navigation, and therefore might potentially be even less patient than sighted users.
Large pages and DOM manipulations with JavaScript will cause delays in screen reader announcements. A rather unexplored area that could use some attention and testing as screen readers are available on literally every platform (Jaws, NVDA, Voiceover, Narrator, Orca).
- Is continuous monitoring set up?
Having a private instance of WebPagetest is always beneficial for quick and unlimited tests. However, a continuous monitoring tool — like Sitespeed, Calibre and SpeedCurve — with automatic alerts will give you a more detailed picture of your performance. Set your own user-timing marks to measure and monitor business-specific metrics. Also, consider adding automated performance regression alerts to monitor changes over time.Look into using RUM-solutions to monitor changes in performance over time. For automated unit-test-alike load testing tools, you can use k6 with its scripting API. Also, look into SpeedTracker, Lighthouse and Calibre.
انتصارات سريعة
This list is quite comprehensive, and completing all of the optimizations might take quite a while. So, if you had just 1 hour to get significant improvements, what would you do? Let's boil it all down to 17 low-hanging fruits . Obviously, before you start and once you finish, measure results, including Largest Contentful Paint and Time To Interactive on a 3G and cable connection.
- Measure the real world experience and set appropriate goals. Aim to be at least 20% faster than your fastest competitor. Stay within Largest Contentful Paint < 2.5s, a First Input Delay < 100ms, Time to Interactive < 5s on slow 3G, for repeat visits, TTI < 2s. Optimize at least for First Contentful Paint and Time To Interactive.
- Optimize images with Squoosh, mozjpeg, guetzli, pingo and SVGOMG, and serve AVIF/WebP with an image CDN.
- Prepare critical CSS for your main templates, and inline them in the
<head>
of each template. For CSS/JS, operate within a critical file size budget of max. 170KB gzipped (0.7MB decompressed). - Trim, optimize, defer and lazy-load scripts. Invest in the config of your bundler to remove redundancies and check lightweight alternatives.
- Always self-host your static assets and always prefer to self-host third-party assets. Limit the impact of third-party scripts. Use facades, load widgets on interaction and beware of anti-flicker snippets.
- Be selective when choosing a framework. For single-page-applications, identify critical pages and serve them statically, or at least prerender them, and use progressive hydration on component-level and import modules on interaction.
- Client-side rendering alone isn't a good choice for performance. Prerender if your pages don't change much, and defer the booting of frameworks if you can. If possible, use streaming server-side rendering.
- Serve legacy code only to legacy browsers with
<script type="module">
and module/nomodule pattern. - Experiment with regrouping your CSS rules and test in-body CSS.
- Add resource hints to speed up delivery with faster
dns-lookup
,preconnect
,prefetch
,preload
andprerender
. - Subset web fonts and load them asynchronously, and utilize
font-display
in CSS for fast first rendering. - Check that HTTP cache headers and security headers are set properly.
- Enable Brotli compression on the server. (If that's not possible, at least make sure that Gzip compression is enabled.)
- Enable TCP BBR congestion as long as your server is running on the Linux kernel version 4.9+.
- Enable OCSP stapling and IPv6 if possible. Always serve an OCSP stapled DV certificate.
- Enable HPACK compression for HTTP/2 and move to HTTP/3 if it's available.
- Cache assets such as fonts, styles, JavaScript and images in a service worker cache.
Download The Checklist (PDF, Apple Pages)
With this checklist in mind, you should be prepared for any kind of front-end performance project. Feel free to download the print-ready PDF of the checklist as well as an editable Apple Pages document to customize the checklist for your needs:
- Download the checklist PDF (PDF, 166 KB)
- Download the checklist in Apple Pages (.pages, 275 KB)
- Download the checklist in MS Word (.docx, 151 KB)
If you need alternatives, you can also check the front-end checklist by Dan Rublic, the "Designer's Web Performance Checklist" by Jon Yablonski and the FrontendChecklist.
فعلينا العودة!
Some of the optimizations might be beyond the scope of your work or budget or might just be overkill given the legacy code you have to deal with. That's fine! Use this checklist as a general (and hopefully comprehensive) guide, and create your own list of issues that apply to your context. But most importantly, test and measure your own projects to identify issues before optimizing. Happy performance results in 2021, everyone!
A huge thanks to Guy Podjarny, Yoav Weiss, Addy Osmani, Artem Denysov, Denys Mishunov, Ilya Pukhalski, Jeremy Wagner, Colin Bendell, Mark Zeman, Patrick Meenan, Leonardo Losoviz, Andy Davies, Rachel Andrew, Anselm Hannemann, Barry Pollard, Patrick Hamann, Gideon Pyzer, Andy Davies, Maria Prosvernina, Tim Kadlec, Rey Bango, Matthias Ott, Peter Bowyer, Phil Walton, Mariana Peralta, Pepijn Senders, Mark Nottingham, Jean Pierre Vincent, Philipp Tellis, Ryan Townsend, Ingrid Bergman, Mohamed Hussain SH, Jacob Groß, Tim Swalling, Bob Visser, Kev Adamson, Adir Amsalem, Aleksey Kulikov and Rodney Rehm for reviewing this article, as well as our fantastic community which has shared techniques and lessons learned from its work in performance optimization for everybody to use. أنت حقا تحطيم!