في الوحدة السابقة، تم استكشاف بعض النظريات حول مسار العرض الحرج، وكيف يمكن أن تؤدي الموارد التي تحظر العرض وتحظر المحلّل إلى تأخير العرض الأوّلي للصفحة. بعد أن تعرّفت على بعض الأسس النظرية لهذا الموضوع، أصبحت مستعدًا للتعرّف على بعض الأساليب لتحسين مسار العرض الحرج.
أثناء تحميل الصفحة، تتم الإشارة إلى العديد من الموارد ضمن ملف 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 أو الوحدات التي يتم تحميلها باستخدام dynamicimport()
. - يتم عرض 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 عملية تحسين فعّالة يمكن أن تؤدي إلى تحسين مقياس FCP لموقعك الإلكتروني، وربما حتى مقياس LCP في بعض الحالات. يمكن لأدوات، مثل حزم التطبيقات، إجراء عملية التحسين هذه تلقائيًا في إصدارات الإنتاج.
إزالة خدمة CSS غير المُستخدَمة
قبل عرض أي محتوى، يحتاج المتصفّح إلى تنزيل جميع أوراق الأنماط وتحليلها. يشمل الوقت المطلوب لإكمال عملية التحليل أيضًا الأنماط غير المستخدَمة في الصفحة الحالية. إذا كنت تستخدم أداة تجميع تدمج جميع موارد CSS في ملف واحد، من المحتمل أنّ المستخدمين يضطرون إلى تنزيل كمية أكبر من CSS مما هو مطلوب لعرض الصفحة الحالية.
للعثور على صفحات CSS غير مستخدَمة في الصفحة الحالية، استخدِم أداة "التغطية" في "أدوات مطوّري البرامج في Chrome".

تؤدي إزالة محتوى 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 في الصفحة. يُعرف ذلك باسم العرض من جهة العميل، وهو أسلوب يُستخدم على نطاق واسع في تطبيقات الصفحة الواحدة.
يتجنّب الترميز الذي يتم عرضه باستخدام JavaScript أداة فحص التحميل المُسبَق، لأنّ الموارد المضمّنة في الترميز المعروض من جهة العميل لا يمكن لأداة الفحص اكتشافها. وقد يؤدي ذلك إلى تأخير تنزيل الموارد المهمة، مثل صورة أكبر محتوى مرئي على الصفحة. لا يبدأ المتصفّح في تنزيل صورة LCP إلا بعد تنفيذ النص البرمجي وإضافة العنصر إلى نموذج المستند (DOM). وبالتالي، لا يمكن تنفيذ النص البرمجي إلا بعد اكتشافه وتنزيله وتحليله. يُعرف ذلك باسم تسلسل الطلبات المهمة ويجب تجنُّبه.
بالإضافة إلى ذلك، من المرجّح أن يؤدي عرض الترميز باستخدام JavaScript إلى إنشاء مهام طويلة أكثر من الترميز الذي يتم تنزيله من الخادم استجابةً لطلب تنقّل. يمكن أن يؤثّر الاستخدام المكثّف للعرض من جهة العميل لملفات HTML سلبًا في وقت استجابة التفاعل. ويكون ذلك صحيحًا بشكل خاص في الحالات التي يكون فيها نموذج المستند الخاص بالصفحة كبيرًا جدًا، ما يؤدي إلى تشغيل عملية عرض كبيرة عندما تعدّل JavaScript نموذج المستند.
إزالة البيانات غير الضرورية
على غرار 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 متعددة في المتصفح؟
<link>
متعدّدة@import
في CSSما هي وظيفة فاحص التحميل المُسبَق في المتصفّح؟
<link rel="preload">
في مصدر HTML.
لماذا يحظر المتصفّح مؤقتًا تحليل HTML تلقائيًا عند تنزيل موارد JavaScript؟
التالي: مساعدة المتصفّح من خلال تلميحات الموارد
بعد أن تعرّفت على كيفية تأثير الموارد المحمَّلة في العنصر <head>
على سرعة تحميل الصفحة في البداية والمقاييس المختلفة، حان الوقت للانتقال إلى الخطوة التالية. في الوحدة التالية، سنتناول تلميحات الموارد وكيف يمكنها تقديم تلميحات قيّمة إلى المتصفّح لبدء تحميل الموارد وفتح الاتصالات مع الخوادم الخارجية في وقت أبكر من الوقت الذي كان سيستغرقه المتصفّح بدون هذه التلميحات.