أداء الواجهة الأمامية 2021: تحسينات التسليم

نشرت: 2022-03-10
ملخص سريع ↬ لنجعل 2021 ... سريعًا! قائمة مراجعة سنوية للأداء الأمامي تحتوي على كل ما تحتاج إلى معرفته لإنشاء تجارب سريعة على الويب اليوم ، من المقاييس إلى الأدوات وتقنيات الواجهة الأمامية. تم التحديث منذ عام 2016.

جدول المحتويات

  1. الاستعداد: التخطيط والقياسات
  2. تحديد أهداف واقعية
  3. تعريف البيئة
  4. تحسينات الأصول
  5. بناء التحسينات
  6. تحسينات التسليم
  7. الشبكات ، HTTP / 2 ، HTTP / 3
  8. الاختبار والمراقبة
  9. انتصارات سريعة
  10. كل شيء في صفحة واحدة
  11. قم بتنزيل قائمة التحقق (PDF ، Apple Pages ، MS Word)
  12. اشترك في النشرة الإخبارية عبر البريد الإلكتروني حتى لا تفوت الأدلة التالية.

تحسينات التسليم

  1. هل نستخدم 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 بشكل أسرع ، والذهاب إلى تفاصيل التحليل التأملي ، وعدم التزامن والتأجيل.

  2. تحميل كسول مكونات باهظة الثمن باستخدام 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 ٪ من خط أنابيب التدويل الجديد.

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

مثال يوضح حدًا قديمًا يبلغ 3000 بكسل مع تنزيلات 160 كيلوبايت (على اليسار) بينما الحد الجديد يبلغ 1250 بكسل مع تنزيلات 90 كيلوبايت فقط (على اليمين) تُظهر تحسينًا في img تحميل مدخرات البيانات البطيئة
في الاتصالات السريعة (على سبيل المثال 4G) ، تم تقليل عتبات المسافة من إطار العرض في Chrome مؤخرًا من 3000 بكسل إلى 1250 بكسل ، وفي الاتصالات الأبطأ (مثل 3G) ، تغيرت العتبة من 4000 بكسل إلى 2500 بكسل. (معاينة كبيرة)
يظهر رسم توضيحي بنص حول هاتف جوّال مع واجهة مستخدم Twitter ، يشرح تحسينات الأدوات من سلاسل الترجمة ذات التحميل البطيء
من خلال سلاسل الترجمة البطيئة التحميل ، تمكن Mobile Twitter من تحقيق تنفيذ JavaScript أسرع بنسبة 80٪ من خط أنابيب التدويل الجديد. (رصيد الصورة: Addy Osmani) (معاينة كبيرة)
  1. تحميل الصور بشكل تدريجي.
    يمكنك حتى الانتقال إلى المستوى التالي من التحميل البطيء عن طريق إضافة تحميل الصورة التدريجي إلى صفحاتك. على غرار Facebook و Pinterest و Medium و Wolt ، يمكنك تحميل صور منخفضة الجودة أو حتى ضبابية أولاً ، وبعد ذلك مع استمرار تحميل الصفحة ، استبدلها بإصدارات كاملة الجودة باستخدام تقنية BlurHash أو LQIP (العناصر النائبة للصور منخفضة الجودة) تقنية.

    تختلف الآراء إذا كانت هذه التقنيات تعمل على تحسين تجربة المستخدم أم لا ، لكنها بالتأكيد تعمل على تحسين وقت First Contentful Paint. يمكننا حتى أتمتة ذلك باستخدام SQIP الذي يُنشئ نسخة منخفضة الجودة من صورة ما كعنصر نائب لـ SVG ، أو Gradient Image Placeholder مع تدرجات CSS الخطية.

    يمكن تضمين هذه العناصر النائبة في HTML حيث يتم ضغطها بشكل جيد باستخدام طرق ضغط النص. وصف دين هيوم في مقالته كيف يمكن تنفيذ هذه التقنية باستخدام Intersection Observer.

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

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

  2. ثلاثة إصدارات مختلفة تُظهر تقنية التحميل البطيء لـ SVG بواسطة Jose M.
    تقنية التحميل البطيء SVG بواسطة خوسيه م. بيريز. (معاينة كبيرة)
  3. هل تؤجل العرض مع 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 إذا كنت بحاجة فقط إلى الحجم أو المحاذاة أو الأنماط المحسوبة على عناصر أخرى - أو العنصر حاليًا خارج القماش.

أداء العرض عند التحميل الأولي هو 2،288 مللي ثانية لخط الأساس (يسار) و 13464 مللي ثانية للقطع ذات رؤية المحتوى: تلقائي (يمين)
في العرض التوضيحي ، تطبيق content-visibility: auto على مناطق المحتوى المقسمة تعزيز أداء تقديم 7 × عند التحميل الأولي. (معاينة كبيرة)
  1. هل تؤجل فك التشفير باستخدام 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.

  2. هل تنشئ وتخدم 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.

  3. جرب إعادة تجميع قواعد 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.

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

    يمكننا إنشاء دفق واحد من مصادر متعددة. على سبيل المثال ، بدلاً من تقديم غلاف واجهة مستخدم فارغ والسماح لجافا سكريبت بتعبئته ، يمكنك السماح لعامل الخدمة بإنشاء دفق حيث تأتي الصدفة من ذاكرة تخزين مؤقت ، ولكن يأتي الجسم من الشبكة. كما لاحظ Jeff Posnick ، ​​إذا كان تطبيق الويب الخاص بك مدعومًا بواسطة CMS يقوم الخادم بعرض HTML عن طريق تجميع قوالب جزئية معًا ، فإن هذا النموذج يترجم مباشرةً إلى استخدام استجابات متدفقة ، مع تكرار منطق النموذج في عامل الخدمة بدلاً من الخادم الخاص بك. تسلط مقالة Jake Archibald's The Year of Web Streams الضوء على كيفية إنشائه بالضبط. تعزيز الأداء ملحوظ جدا.

    تتمثل إحدى الميزات المهمة لدفق استجابة HTML بالكامل في أن HTML الذي يتم تقديمه أثناء طلب التنقل الأولي يمكن أن يستفيد استفادة كاملة من محلل HTML المتدفق في المتصفح. لا يمكن لأجزاء HTML التي يتم إدراجها في المستند بعد تحميل الصفحة (كما هو شائع مع المحتوى الذي يتم ملؤه عبر JavaScript) الاستفادة من هذا التحسين.

    دعم المتصفح؟ لا يزال هناك دعم جزئي في Chrome و Firefox و Safari و Edge يدعمان API وعمال الخدمة الذين يتم دعمهم في جميع المتصفحات الحديثة. وإذا شعرت بالمغامرة مرة أخرى ، فيمكنك التحقق من التنفيذ التجريبي لطلبات البث ، مما يسمح لك ببدء إرسال الطلب أثناء إنشاء النص. متوفر في Chrome 85.

صورة تلخص استخدام حفظ البيانات على Android Chrome ومتوسط ​​نتائج البحث أو الجلسات التي اكتشفها Cloudinary Research في نوفمبر 2019 وأبريل 2020
18٪ من مستخدمي Android Chrome العالميين لديهم الوضع البسيط (المعروف أيضًا باسم Save-Data) ، وفقًا لأبحاث Cloudinary. (معاينة كبيرة)
  1. ضع في اعتبارك جعل مكوناتك مدركة للاتصال.
    قد تكون البيانات باهظة الثمن ومع تزايد الحمولة ، نحتاج إلى احترام المستخدمين الذين يختارون الاشتراك في توفير البيانات أثناء الوصول إلى مواقعنا أو تطبيقاتنا. يسمح لنا عنوان طلب تلميح عميل 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 باهظ الثمن بشكل انتقائي.
  2. ضع في اعتبارك جعل مكونات جهازك مدركًا للذاكرة.
    الاتصال بالشبكة يعطينا منظورًا واحدًا فقط في سياق المستخدم. للمضي قدمًا ، يمكنك أيضًا ضبط الموارد ديناميكيًا بناءً على ذاكرة الجهاز المتاحة ، باستخدام واجهة برمجة تطبيقات ذاكرة الجهاز. يعرض navigator.deviceMemory مقدار ذاكرة الوصول العشوائي (RAM) التي يمتلكها الجهاز بالجيجابايت ، مقربًا لأسفل إلى أقرب قوة اثنين. تتميز واجهة برمجة التطبيقات أيضًا برأس تلميحات العميل ، Device-Memory ، والتي تُبلغ عن نفس القيمة.

    المكافأة : يوضح Umar Hansa كيفية تأجيل البرامج النصية باهظة الثمن مع الواردات الديناميكية لتغيير التجربة بناءً على ذاكرة الجهاز والاتصال بالشبكة وتزامن الأجهزة.

تفصيل يوضح كيفية إعطاء الأولوية للموارد المختلفة في Blink بدءًا من Chrome 46 وما بعده
تفصيل يوضح كيفية إعطاء الأولوية للموارد المختلفة في Blink بدءًا من Chrome 46 وما بعده. (رصيد الصورة: Addy Osmani) (معاينة كبيرة)
  1. قم بتهيئة الاتصال لتسريع التسليم.
    استخدم تلميحات الموارد لتوفير الوقت في dns-prefetch (الذي يؤدي بحث DNS في الخلفية) ، preconnect (الذي يطلب من المتصفح بدء اتصال الاتصال (DNS ، TCP ، TLS) في الخلفية) ، prefetch (الذي يسأل المتصفح لطلب مورد) preload (الذي يجهز الموارد دون تنفيذها ، من بين أشياء أخرى). مدعوم جيدًا في المتصفحات الحديثة ، مع دعم قادم إلى Firefox قريبًا.

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

    بشكل غير متوقع ، تم إهماله ، لكن فريق Chrome أعاده كآلية NoState Prefetch. في الواقع ، يتعامل Chrome مع تلميح prerender باعتباره NoState Prefetch بدلاً من ذلك ، لذلك لا يزال بإمكاننا استخدامه اليوم. كما أوضحت كاتي هيمبينيوس في هذه المقالة ، "مثل العرض المسبق ، يجلب NoState Prefetch الموارد مقدمًا ؛ ولكن بخلاف العرض المسبق ، فإنه لا ينفذ جافا سكريبت أو يعرض أي جزء من الصفحة مقدمًا."

    يستخدم NoState Prefetch فقط حوالي 45 ميغا بايت من الذاكرة وسيتم جلب المصادر الفرعية التي تم جلبها مع أولوية Net IDLE . منذ Chrome 69 ، يضيف NoState Prefetch العنوان الغرض: الجلب المسبق لجميع الطلبات لجعلها مميزة عن التصفح العادي.

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

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

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

    في معظم الأوقات هذه الأيام ، سنستخدم على الأقل الاتصال المسبق والجلب المسبق لنظام dns-prefetch ، preconnect الحذر عند استخدام prefetch preload prerender . لاحظ أنه حتى مع الاتصال المسبق preconnect dns-prefetch ، فإن المتصفح له حد لعدد المضيفات التي سيبحث عنها / يتصل بها بشكل متوازٍ ، لذا فمن الرهان الآمن ترتيبها بناءً على الأولوية ( شكرًا Philip Tellis! ).

    نظرًا لأن الخطوط عادةً ما تكون أصولًا مهمة على الصفحة ، فمن المستحسن أحيانًا أن تطلب من المتصفح تنزيل الخطوط المهمة مع preload . ومع ذلك ، تحقق مرة أخرى مما إذا كان يساعد بالفعل في الأداء نظرًا لوجود لغز من الأولويات عند التحميل المسبق للخطوط: نظرًا لأن preload يعتبر ذا أهمية عالية ، يمكن أن يقفز حتى الموارد الأكثر أهمية مثل CSS الهامة. ( شكرا باري! )

    <!-- 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)" />

    نظرًا لأن <link rel="preload"> يقبل سمة media ، يمكنك اختيار تنزيل الموارد بشكل انتقائي بناءً على قواعد استعلام @media ، كما هو موضح أعلاه.

    علاوة على ذلك ، يمكننا استخدام imagesrcset السمات imagesizes صور البطل المكتشفة مؤخرًا بشكل أسرع ، أو أي صور يتم تحميلها عبر JavaScript ، مثل ملصقات الأفلام:

    <!-- 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>

    يمكننا أيضًا تحميل JSON مسبقًا عند الجلب ، لذلك يتم اكتشافه قبل أن يطلبه JavaScript:

    <!-- Addy Osmani. https://addyosmani.com/blog/preload-hero-images/ --> <link rel="preload" as="fetch" href="foo.com/api/movies.json" crossorigin>

    يمكننا أيضًا تحميل JavaScript ديناميكيًا ، بشكل فعال للتنفيذ البطيء للبرنامج النصي.

    /* 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);

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

    ومن ثم ، فهو مفيد للموارد المكتشفة مؤخرًا ، وصور البطل التي يتم تحميلها عبر background-image ، وتضمين CSS (أو JavaScript) الهامة والتحميل المسبق لبقية CSS (أو JavaScript).

    مثال باستخدام غلاف فيلم Greyhound بطولة Tom Hanks لإظهار أن الصور المحملة مسبقًا يتم تحميلها في وقت سابق حيث لا توجد حاجة لانتظار JavaScript لاكتشاف
    تحميل الصور المهمة مسبقًا في وقت مبكر ؛ لا داعي لانتظار JavaScript لاكتشافها. (رصيد الصورة: "التحميل المسبق لصور البطل المكتشفة مؤخرًا بشكل أسرع" بواسطة Addy Osmani) (معاينة كبيرة)

    يمكن لعلامة preload بدء التحميل المسبق فقط بعد أن يتلقى المتصفح HTML من الخادم وعثر المحلل اللغوي lookahead على علامة preload . يمكن أن يكون التحميل المسبق عبر رأس HTTP أسرع قليلاً لأننا لا ننتظر حتى يقوم المتصفح بتحليل HTML لبدء الطلب (بالرغم من ذلك).

    ستساعد التلميحات المبكرة بشكل أكبر ، مما يتيح بدء التحميل المسبق حتى قبل إرسال رؤوس استجابة HTML (على خارطة الطريق في Chromium و Firefox). بالإضافة إلى ذلك ، ستساعدنا تلميحات الأولوية في تحديد أولويات تحميل البرامج النصية.

    احذر : إذا كنت تستخدم preload ، as يجب تحديده أو لم يتم تحميل أي شيء ، بالإضافة إلى أن الخطوط المحملة مسبقًا بدون سمة crossorigin ستتم مضاعفة الجلب. إذا كنت تستخدم prefetch ، فاحذر من مشكلات رأس Age في Firefox.

رسم بياني يوضح الرسم الأول المحتوى (حسب حالة عامل الخادم) مع العد من 0 إلى 150 عبر فترة زمنية معينة (بالمللي ثانية)
مع عامل الخدمة ، يمكننا طلب الحد الأدنى من البيانات ، ثم تحويل تلك البيانات إلى مستند HTML كامل لتحسين FCP. (عبر فيل والتون) (معاينة كبيرة)
  1. استخدم عمال الخدمة للتخزين المؤقت والاحتياطات في الشبكة.
    لا يمكن أن يكون أي تحسين للأداء عبر الشبكة أسرع من ذاكرة التخزين المؤقت المخزنة محليًا على جهاز المستخدم (على الرغم من وجود استثناءات). إذا كان موقع الويب الخاص بك يعمل عبر HTTPS ، فيمكننا تخزين الأصول الثابتة مؤقتًا في ذاكرة التخزين المؤقت لعامل الخدمة وتخزين النسخ الاحتياطية دون اتصال بالإنترنت (أو حتى الصفحات غير المتصلة بالإنترنت) واستردادها من جهاز المستخدم ، بدلاً من الانتقال إلى الشبكة.

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

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

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

    هناك بعض المشاكل التي يجب وضعها في الاعتبار. مع وجود عامل خدمة في مكانه ، نحتاج إلى الحذر من طلبات النطاق في Safari (إذا كنت تستخدم Workbox لعامل خدمة ، فإنه يحتوي على وحدة طلب النطاق). إذا عثرت على DOMException: Quota exceeded. خطأ في وحدة تحكم المتصفح ، فراجع مقال جيراردو عندما يساوي 7 كيلوبايت 7 ميجابايت.

    كما كتب جيراردو ، "إذا كنت تنشئ تطبيق ويب تقدميًا وتواجه تضخمًا في ذاكرة التخزين المؤقت عندما يقوم عامل الخدمة بتخزين الأصول الثابتة التي يتم عرضها من شبكات CDN ، فتأكد من وجود رأس استجابة CORS المناسب للموارد متعددة الأصول ، فأنت لا تخزن الاستجابات المبهمة مؤقتًا مع عامل الخدمة لديك عن غير قصد ، يمكنك تمكين أصول الصور المشتركة في وضع CORS عن طريق إضافة السمة crossorigin إلى علامة <img> ".

    هناك الكثير من الموارد الرائعة للبدء مع عمال الخدمة:

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

    • عيوب عامل الخدمة وأفضل الممارسات ، مع بعض النصائح حول النطاق ، وتأخير تسجيل عامل الخدمة والتخزين المؤقت لعامل الخدمة.
    • سلسلة رائعة من تأليف Ire Aderinokun على "Offline First" مع Service Worker ، مع إستراتيجية حول تهيئة هيكل التطبيق مسبقًا.
    • عامل الخدمة: مقدمة مع نصائح عملية حول كيفية استخدام عامل الخدمة للحصول على تجارب ثرية في وضع عدم الاتصال ، ومزامنة خلفية دورية وإشعارات دفع.
    • يجدر دائمًا الإشارة إلى كتاب الطبخ غير المتصل بجيك أرشيبالد الجيد مع عدد من الوصفات حول كيفية خبز عامل الخدمة الخاص بك.
    • Workbox عبارة عن مجموعة من مكتبات عمال الخدمة تم إنشاؤها خصيصًا لإنشاء تطبيقات ويب تقدمية.
  2. هل تقوم بتشغيل خوادم على CDN / Edge ، على سبيل المثال لاختبار A / B؟
    في هذه المرحلة ، نحن معتادون تمامًا على تشغيل عمال الخدمة على العميل ، ولكن مع تنفيذ شبكات CDN على الخادم ، يمكننا استخدامها لتعديل الأداء على الحافة أيضًا.

    على سبيل المثال ، في اختبارات A / B ، عندما تحتاج HTML إلى تغيير محتواها لمستخدمين مختلفين ، يمكننا استخدام عمال الخدمة على خوادم CDN للتعامل مع المنطق. يمكننا أيضًا دفق إعادة كتابة HTML لتسريع المواقع التي تستخدم خطوط Google.

رسم بياني يوضح سلاسل زمنية لعمليات تثبيت عمال الخدمة على سطح المكتب والجوّال مع النسبة المئوية للصفحات عبر الوقت بين يناير 2016 ويوليو 2020
السلاسل الزمنية لتركيب عامل الخدمة. فقط 0.87٪ من جميع صفحات سطح المكتب تسجل عامل خدمة ، وفقًا لتقويم الويب. (معاينة كبيرة)
  1. تحسين أداء العرض.
    عندما يكون التطبيق بطيئًا ، يمكن ملاحظته على الفور. لذلك نحن بحاجة إلى التأكد من عدم وجود تأخير عند تمرير الصفحة أو عندما يتم تحريك عنصر ، وأنك تصل باستمرار إلى 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.

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

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

    في دراسة الحالة الخاصة بهم حول The Art of UI Skeletons ، يشارك Kumar McMillan بعض الأفكار والتقنيات حول كيفية محاكاة القوائم الديناميكية والنص والشاشة النهائية ، بالإضافة إلى كيفية التفكير في التفكير الهيكلي باستخدام React.

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

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

    طور المجتمع بضع تقنيات وطرق بديلة لتجنب التدفقات العائدة. بشكل عام ، من الجيد تجنب إدراج محتوى جديد فوق المحتوى الحالي ، ما لم يحدث ذلك استجابة لتفاعل المستخدم. قم دائمًا بتعيين سمات العرض والارتفاع على الصور ، لذلك تخصص المتصفحات الحديثة المربع وتحجز المساحة افتراضيًا (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 التي تؤدي إلى التخطيط والطلاء والتركيب.

جدول المحتويات

  1. الاستعداد: التخطيط والقياسات
  2. تحديد أهداف واقعية
  3. تعريف البيئة
  4. تحسينات الأصول
  5. بناء التحسينات
  6. تحسينات التسليم
  7. الشبكات ، HTTP / 2 ، HTTP / 3
  8. الاختبار والمراقبة
  9. انتصارات سريعة
  10. كل شيء في صفحة واحدة
  11. قم بتنزيل قائمة التحقق (PDF ، Apple Pages ، MS Word)
  12. اشترك في النشرة الإخبارية عبر البريد الإلكتروني حتى لا تفوت الأدلة التالية.