صفحة طويلة بطيئة؟ content-visibility ينزل الرندر من 232ms لـ 30ms
مستوى القارئ: متوسط
هتكسب تحميل أولي أخف في الصفحات الطويلة، بدون ما تغيّر API أو تفكّر في Virtual Scrolling من أول يوم.
المشكلة باختصار
لو عندك صفحة فيها 80 كارت منتج، أو صفحة مقالة طويلة فيها صور وجداول وتعليقات، المتصفح غالبًا بيعمل style وlayout وpaint لأجزاء المستخدم لسه مش شايفها. الطريقة دي بتفشل لما المحتوى تحت الشاشة يبقى كبير، لأن الـ main thread بيتشغل في شغل غير مرئي بدل ما يجهز الجزء الأول بسرعة.
الافتراض هنا إن عندك صفحة طويلة ثابتة نسبيًا: كروت، أقسام، تعليقات، أو نتائج بحث. مش بنتكلم عن infinite list فيها 50 ألف عنصر. هنا نستخدم CSS صغير يقلل تكلفة الرندر للأقسام خارج الشاشة.
مثال بسيط قبل التعريف العلمي
ركز في المثال ده. عندك صفحة pricing فيها 60 بطاقة. المستخدم أول ما يفتح الصفحة شايف أول 8 بطاقات فقط. بدل ما المتصفح يرندر الـ 60 بطاقة كلها، خليه يرندر الظاهر الآن ويؤجل الباقي لحد ما يقرب من الشاشة.
.pricing-section,
.product-row,
.comment-block {
content-visibility: auto;
contain-intrinsic-size: auto 420px;
}اللي بيحصل فعلاً: `content-visibility: auto` يسمح للمتصفح يتخطى رندر subtree خارج الشاشة. و`contain-intrinsic-size` يديله حجمًا تقديريًا مؤقتًا، بدل ما الصفحة تنهار أو يحصل قفز مزعج في السكول.
التعريف الأدق: الخاصية بتضيف containment مناسب للرندر، وبالنسبة للعناصر خارج viewport المتصفح يقدر يؤجل layout وpaint والـ hit testing لأبنائها. لما العنصر يقرب من الشاشة، يرجع يرندره في الوقت المناسب.
خطوات التطبيق على صفحة حقيقية
- قسّم الصفحة لأقسام مستقلة: كارت منتج، block تعليقات، أو section من المقال.
- لا تضف الخاصية على عنصر صغير جدًا مثل زر أو عنوان. المكسب هناك شبه صفر.
- ابدأ بالأقسام التي ارتفاعها معروف تقريبًا، مثل 300 إلى 600px.
- قِس قبل وبعد من Chrome Performance panel أو Lighthouse timespan.
<main class="catalog">
<section class="product-row">... أول مجموعة منتجات ...</section>
<section class="product-row">... ثاني مجموعة منتجات ...</section>
<section class="product-row">... ثالث مجموعة منتجات ...</section>
</main>