في الوحدة السابقة، تم استكشاف بعض النظريات الكامنة وراء مسار العرض الحرج وكيف يمكن لموارد حظر العرض وحظر المحلل اللغوي تأخير العرض الأولي للصفحة. الآن بعد أن فهمت بعض النظرية الكامنة وراء ذلك، فأنت جاهز لتعلم بعض التقنيات لتحسين مسار العرض الحرج.
أثناء تحميل الصفحة، تتم الإشارة إلى العديد من الموارد ضمن ملف HTML الخاص بها والتي توفّر الصفحة مظهرها وتنسيقها من خلال CSS، إلى جانب تفاعلها من خلال JavaScript. في هذه الوحدة، يتم تناول عدد من المفاهيم المهمة المتعلقة بهذه الموارد وكيفية تأثيرها في وقت تحميل الصفحة.
حظر العرض
كما تمت مناقشته في الوحدة السابقة، تعتبر CSS موردًا يحظر العرض، لأنها تمنع المتصفِّح من عرض أي محتوى حتى يتم إنشاء نموذج كائن CSS (CSSOM). يحظر المتصفح العرض لمنع ظهور فلاش من المحتوى غير المصمم (FOUC)، وهو أمر غير مرغوب فيه من وجهة نظر المستخدم.
في الفيديو السابق، يوجد FOUC مختصر حيث يمكنك مشاهدة الصفحة بدون أي نمط. وبعد ذلك، يتم تطبيق جميع الأنماط بعد انتهاء تحميل CSS للصفحة من الشبكة، ويتم على الفور استبدال النسخة ذات النمط غير المصمَّم من الصفحة بالإصدار ذي النمط.
بشكل عام، إنّ FOUC هو أمر لا تراه عادةً، ولكن من المهم فهمه لتتمكن من معرفة سبب حظر المتصفّح لعرض الصفحة إلى أن يتم تنزيل CSS وتطبيقها على الصفحة. ليس بالضرورة أن يكون حظر العرض غير مرغوب فيه، ولكنك تحتاج إلى تقليل المدة التي يستمر خلالها ذلك من خلال الحفاظ على تحسين CSS.
حظر المحلل اللغوي
يقاطع مورد حظر المحلل اللغوي محلّل HTML، مثل عنصر <script>
بدون سمات async
أو defer
. عندما يصادف المحلّل اللغوي عنصر
<script>
، يحتاج المتصفّح إلى تقييم النص البرمجي وتنفيذه قبل متابعة تحليل بقية محتوى HTML. يتم ذلك عن طريق التصميم، حيث قد تقوم البرامج النصية
بتعديل عنصر DOM أو الوصول إليه خلال فترة لا تزال قيد الإنشاء.
<!-- This is a parser-blocking script: -->
<script src="/script.js"></script>
عند استخدام ملفات JavaScript خارجية (بدون async
أو defer
)، يتم حظر المحلِّل من وقت اكتشاف الملف إلى أن يتم تنزيله وتحليله وتنفيذه. عند استخدام JavaScript مضمَّن، يتم حظر المحلل بشكل مشابه إلى أن يتم تحليل النص البرمجي المضمَّن وتنفيذه.
أداة فحص التحميل المُسبق
إنّ أداة فحص التحميل المسبق عبارة عن تحسين للمتصفح في شكل محلل HTML ثانوي يفحص استجابة HTML الأولية للعثور على الموارد وجلبها بطريقة متأملة قبل أن يكتشفها محلّل HTML الأساسي بطريقة أخرى. على سبيل المثال، سيسمح فاحص التحميل المسبق للمتصفّح ببدء تنزيل مورد محدّد في عنصر <img>
، حتى عند حظر محلّل HTML أثناء جلب الموارد ومعالجتها، مثل CSS وJavaScript.
وللاستفادة من فاحص التحميل المسبق، يجب تضمين الموارد المهمة في ترميز HTML الذي يرسله الخادم. لا يمكن اكتشاف أنماط تحميل الموارد التالية بواسطة ماسح التحميل المُسبق:
- الصور التي حمَّلتها CSS باستخدام سمة
background-image
. مراجع الصور هذه موجودة في CSS، ولا يمكن اكتشافها بواسطة ماسح التحميل المسبق. - النصوص البرمجية التي تم تحميلها ديناميكيًا على شكل ترميز عنصر
<script>
الذي تم إدخاله في نموذج العناصر في المستند (DOM) باستخدام JavaScript أو وحدات تم تحميلها باستخدامimport()
ديناميكي - HTML يتم عرضه على العميل باستخدام JavaScript. ويكون هذا الترميز مضمَّنًا في سلاسل ضمن موارد JavaScript ولا يمكن اكتشافه من خلال أداة فحص التحميل المسبق.
- بيانات
@import
في CSS
أنماط تحميل الموارد هذه كلها موارد تم اكتشافها مؤخرًا، لذا
لا تستفيد من ماسح التحميل المسبق. تجنَّبها كلما أمكن ذلك. ومع ذلك، إذا
لم يكن من الممكن تجنُّب هذه الأنماط، قد تتمكّن من استخدام التلميح
preload
لتجنُّب التأخير في رصد الموارد.
CSS
تحدد CSS طريقة عرض الصفحة وتنسيقها. كما هو موضح سابقًا، CSS هي مورد يؤدي إلى حظر العرض، لذا قد يكون لتحسين CSS تأثيرًا كبيرًا في إجمالي وقت تحميل الصفحة.
تصغير
يؤدي تصغير ملفات CSS إلى تقليل حجم الملف لمورد CSS، ما يزيد سرعة تنزيلها. ويتم تحقيق ذلك بشكل أساسي من خلال إزالة محتوى من ملف CSS المصدر، مثل المسافات والأحرف غير المرئية الأخرى، وإخراج النتيجة إلى ملف محسَّن حديثًا:
/* Unminified CSS: */
/* Heading 1 */
h1 {
font-size: 2em;
color: #000000;
}
/* Heading 2 */
h2 {
font-size: 1.5em;
color: #000000;
}
/* Minified CSS: */
h1,h2{color:#000}h1{font-size:2em}h2{font-size:1.5em}
يُعدّ تصغير حجم CSS في أبسط صوره تحسينًا فعالاً قد يحسّن سرعة عرض المحتوى على موقعك الإلكتروني، وربما حتى سرعة عرض أكبر جزء من المحتوى على الصفحة (LCP) في بعض الحالات. يمكن لأدوات مثل الحزم تنفيذ هذا التحسين تلقائيًا في إصدارات الإنتاج.
إزالة خدمة مقارنة الأسعار (CSS) غير المستخدَمة
قبل عرض أي محتوى، يحتاج المتصفح إلى تنزيل جميع أوراق الأنماط وتحليلها. يتضمن الوقت اللازم لإكمال التحليل أيضًا الأنماط غير المستخدمة في الصفحة الحالية. إذا كنت تستخدم أداة تجميع تجمع كل موارد CSS في ملف واحد، من المحتمل أن ينزّل المستخدمون رموز CSS أكثر مما هو مطلوب لعرض الصفحة الحالية.
لاكتشاف محتوى CSS غير المستخدَم للصفحة الحالية، يمكنك استخدام أداة التغطية في Chrome DevTools.
لإزالة unused CSS تأثير مزدوج، فبالإضافة إلى تقليل وقت التنزيل، أنت تحسّن إنشاء شجرة العرض، لأنّ المتصفّح يحتاج إلى معالجة عدد أقل من قواعد CSS.
تجنُّب إعلانات @import
في خدمة مقارنة الأسعار (CSS)
قد يبدو ذلك ملائمًا، ولكن عليك تجنُّب استخدام تعريفات @import
في CSS:
/* Don't do this: */
@import url('style.css');
على غرار آلية عمل العنصر <link>
في HTML، يتيح لك التعريف @import
في CSS استيراد مورد CSS خارجي من داخل ورقة أنماط. يكمن الاختلاف الرئيسي بين هذين النهجين في أنّ عنصر <link>
في HTML هو جزء من استجابة HTML، وبالتالي تم اكتشافه في وقت أقرب بكثير من ملف CSS الذي تم تنزيله باستخدام إعلان @import
.
ويرجع السبب في ذلك إلى أنّه من أجل اكتشاف تعريف @import
، يجب تنزيل ملف CSS الذي يتضمّنه أولاً. وينتج عن ذلك ما يُعرف باسم سلسلة الطلبات التي تؤدي، في حالة CSS، إلى تأخير المدة التي تستغرقها الصفحة للعرض الأولي. ومن العيوب الأخرى
أنّ أوراق الأنماط التي يتم تحميلها باستخدام بيان @import
لا يمكن اكتشافها
من خلال أداة فحص التحميل المسبق، وبالتالي تصبح موارد لحظر العرض لم يتم اكتشافها بعد.
<!-- Do this instead: -->
<link rel="stylesheet" href="style.css">
في معظم الحالات، يمكنك استبدال @import
باستخدام عنصر <link rel="stylesheet">
. تسمح عناصر <link>
بتنزيل أوراق الأنماط
بشكل متزامن كما تقلل من إجمالي وقت التحميل، على عكس نماذج بيان @import
التي تعمل على تنزيل أوراق الأنماط بشكل متتابع.
تضمين محتوى CSS المهم
يمكن أن يؤدي الوقت الذي يستغرقه تنزيل ملفات CSS إلى زيادة سرعة عرض المحتوى على الصفحة. إنّ تضمين
الأنماط المهمة في المستند <head>
يؤدي إلى تقليل طلب الشبكة لمورد CSS، وعندما يتم ذلك بشكل صحيح، يمكن أن يؤدي إلى تحسين أوقات التحميل الأولي عندما لا تكون ذاكرة التخزين المؤقت لمتصفّح المستخدم جاهزة للاستخدام. يمكن تحميل محتوى CSS المتبقي
بشكل غير متزامن أو إلحاقه بنهاية العنصر <body>
.
<head>
<title>Page Title</title>
<!-- ... -->
<style>h1,h2{color:#000}h1{font-size:2em}h2{font-size:1.5em}</style>
</head>
<body>
<!-- Other page markup... -->
<link rel="stylesheet" href="non-critical.css">
</body>
أما الجانب السلبي، فيؤدي تضمين كمية كبيرة من CSS إلى إضافة المزيد من وحدات البايت إلى استجابة HTML الأولية. ولأنّ موارد HTML لا يمكن تخزينها مؤقتًا في أغلب الأحيان لفترة طويلة جدًا، أو على الإطلاق، يعني ذلك أنّه لا يتم تخزين CSS المضمّن مؤقتًا للصفحات اللاحقة التي قد تستخدم رمز CSS نفسه في أوراق أنماط خارجية. يمكنك اختبار أداء صفحتك وقياسه للتأكّد من أنّ المفاضلات تستحق الجهد المبذول.
الإصدارات التجريبية من خدمة مقارنة الأسعار (CSS)
JavaScript
تجذب لغة JavaScript معظم التفاعل على الويب، ولكنّها مقابل تكلفة. إنّ إضافة الكثير من رموز JavaScript قد تؤدي إلى بطء استجابة صفحتك على الويب أثناء تحميل الصفحة، ما قد يتسبب أيضًا في حدوث مشاكل في الاستجابة تؤدي إلى إبطاء التفاعلات، وكلاهما قد يكون مزعجًا للمستخدمين.
JavaScript لحظر العرض
عند تحميل عناصر <script>
بدون السمة defer
أو async
، يحظر المتصفّح التحليل والعرض إلى أن يتم تنزيل النص البرمجي وتحليله وتنفيذه. وبالمثل، تحظر النصوص البرمجية المضمّنة المحلل اللغوي إلى أن يتم تحليل النص البرمجي وتنفيذه.
async
ضد defer
يسمح السمتان async
وdefer
بتحميل النصوص البرمجية الخارجية بدون حظر محلّل HTML،
بينما يتم تلقائيًا تأجيل النصوص البرمجية (بما في ذلك النصوص البرمجية المضمّنة) باستخدام type="module"
. ومع ذلك، هناك بعض الاختلافات المهمة بين async
وdefer
.
يتم تحليل النصوص البرمجية التي تم تحميلها باستخدام async
وتنفيذها مباشرةً بعد تنزيلها،
بينما يتم تنفيذ النصوص البرمجية التي تم تحميلها باستخدام defer
عند الانتهاء من تحليل مستندات HTML، ويحدث ذلك في الوقت نفسه الذي يتم فيه تنزيل حدث DOMContentLoaded
للمتصفّح.
بالإضافة إلى ذلك، قد يتم تنفيذ async
نصوص برمجية بدون ترتيب، بينما يتم تنفيذ defer
نصوص برمجية بالترتيب الذي تظهر به في الترميز.
العرض من جهة العميل
بشكل عام، يجب تجنُّب استخدام JavaScript لعرض أي محتوى مهم أو عنصر LCP للصفحة. ويُعرَف ذلك باسم العرض من جهة العميل، وهو أسلوب يُستخدم على نطاق واسع في تطبيقات الصفحة الواحدة (SPA).
يتجنّب الترميز الذي يعرضه JavaScript عن طريق فاحص التحميل المُسبق، لأنّ الموارد التي يتضمّنها الترميز الذي يعرضه العميل لا تكون قابلة للاكتشاف من خلال هذا الترميز. وقد يؤدي ذلك إلى تأخير تنزيل الموارد المهمة، مثل صورة سرعة عرض أكبر جزء من المحتوى على الصفحة (LCP). لا يبدأ المتصفّح في تنزيل صورة LCP إلا بعد تنفيذ النص البرمجي وإضافة العنصر إلى DOM. وبالتالي، لا يمكن تنفيذ النص البرمجي إلا بعد اكتشافه وتنزيله وتحليله. ويُعرف ذلك باسم سلسلة الطلبات المُهمة ويجب تجنّبها.
بالإضافة إلى ذلك، يزيد احتمال إنشاء ترميز العرض باستخدام JavaScript لمهام طويلة مقارنةً بالترميز الذي يتم تنزيله من الخادم استجابةً لطلب التنقّل. إنّ الاستخدام المكثّف للعرض بتنسيق HTML من جهة العميل يمكن أن يؤثر سلبًا في وقت استجابة التفاعل. وينطبق هذا الأمر تحديدًا على الحالات التي يكون فيها نموذج العناصر في المستند (DOM) للصفحة كبيرًا جدًا، ما يؤدي إلى تنفيذ عمل عرض كبير عند تعديل JavaScript على نموذج العناصر في المستند (DOM).
تصغير
كما هي الحال في CSS، يؤدي تصغير JavaScript إلى تقليل حجم ملف مورد النص البرمجي. وقد يؤدي ذلك إلى إجراء عمليات تنزيل أسرع، ما يسمح للمتصفح بالانتقال إلى عملية تحليل وتجميع JavaScript بسرعة أكبر.
بالإضافة إلى ذلك، إنّ تصغير JavaScript يتخطى خطوة تقليص مواد العرض الأخرى مثل CSS. وعند تصغير JavaScript، لا تتم إزالتها من عناصر مثل المسافات وعلامات التبويب والتعليقات، بل يتم اختصار الرموز في JavaScript المصدر. تُعرف هذه العملية أحيانًا باسم uglification. لمعرفة الفرق، استخدِم رمز مصدر JavaScript التالي:
// Unuglified JavaScript source code:
export function injectScript () {
const scriptElement = document.createElement('script');
scriptElement.src = '/js/scripts.js';
scriptElement.type = 'module';
document.body.appendChild(scriptElement);
}
عند شرح رمز مصدر JavaScript السابق، قد تبدو النتيجة مشابهة لمقتطف الرمز التالي:
// Uglified JavaScript production code:
export function injectScript(){const t=document.createElement("script");t.src="/js/scripts.js",t.type="module",document.body.appendChild(t)}
في المقتطف السابق، يتضح لك أنّ المتغيّر الذي يمكن قراءته scriptElement
في المصدر تم اختصاره إلى t
. عند تطبيقها على مجموعة كبيرة من النصوص البرمجية، يمكن أن تكون المبالغ التي تم توفيرها كبيرة جدًا، بدون التأثير في الميزات التي توفرها لغة JavaScript لإنتاج موقع إلكتروني.
إذا كنت تستخدم أداة تجميع لمعالجة رمز المصدر الخاص بموقعك الإلكتروني، غالبًا ما يتم التفسير تلقائيًا لإصدارات الإنتاج. إنّ أدوات التعديل، مثل Terser، على سبيل المثال، قابلة للضبط بشكل كبير، ما يتيح لك تعديل مستوى قوة خوارزمية التشفير لتحقيق الحدّ الأقصى من عمليات التوفير. ومع ذلك، عادةً ما تكون الإعدادات التلقائية لأي أداة إخفاء كافية لتحقيق التوازن الصحيح بين حجم الإخراج والحفاظ على الإمكانات.
عروض JavaScript التوضيحية
اختبِر معلوماتك
ما هي أفضل طريقة لتحميل ملفات CSS متعددة في المتصفح؟
@import
في خدمة مقارنة الأسعار (CSS)<link>
متعددةما الذي يفعله فاحص التحميل المسبق في المتصفح؟
<link rel="preload">
في مورد HTML.
لماذا يحظر المتصفّح مؤقتًا تحليل HTML تلقائيًا عند تنزيل موارد JavaScript؟
التالي: مساعدة المتصفح من خلال تلميحات الموارد
والآن بعد أن تعرّفت على كيفية تأثير الموارد التي يتم تحميلها في العنصر <head>
في التحميل المبدئي للصفحة والمقاييس المختلفة، حان الوقت للمتابعة. في الوحدة التالية، يتم استكشاف تلميحات الموارد وكيفية تقديم تلميحات قيّمة إلى المتصفّح لبدء تحميل الموارد وفتح الاتصالات للخوادم المتعدّدة المصادر في وقت أقرب من وقت المتصفّح المتاح بدونها.