دامنه و پیچیدگی محاسبات سبک را کاهش دهید

جاوا اسکریپت اغلب محرکی برای تغییرات بصری است. گاهی اوقات این تغییرات را مستقیماً از طریق دستکاری سبک ایجاد می کند، و گاهی اوقات از طریق محاسباتی که منجر به تغییرات بصری می شود، مانند جستجو یا مرتب سازی داده ها. جاوا اسکریپت با زمان نامناسب یا طولانی مدت می تواند یکی از دلایل رایج مشکلات عملکرد باشد، و شما باید تا جایی که می توانید تاثیر آن را به حداقل برسانید.

محاسبه سبک

تغییر DOM با افزودن و حذف عناصر، تغییر ویژگی‌ها، کلاس‌ها یا پخش انیمیشن‌ها باعث می‌شود که مرورگر سبک‌های عناصر و در بسیاری موارد، طرح‌بندی بخشی یا تمام صفحه را دوباره محاسبه کند. این فرآیند محاسبه سبک محاسبه شده نامیده می شود.

مرورگر محاسبه سبک ها را با ایجاد مجموعه ای از انتخابگرهای منطبق شروع می کند تا مشخص کند کدام کلاس ها، شبه انتخابگرها و شناسه ها برای هر عنصر خاص اعمال می شوند. سپس، قوانین سبک را از انتخابگرهای منطبق پردازش می کند و مشخص می کند که عنصر چه سبک های نهایی دارد.

زمان محاسبه مجدد سبک و تأخیر تعامل

Interaction to Next Paint (INP) یک معیار عملکرد زمان اجرا کاربر محور است که پاسخگویی کلی صفحه به ورودی کاربر را ارزیابی می کند. تأخیر تعامل را از زمانی که کاربر با صفحه تعامل می‌کند تا زمانی که مرورگر فریم بعدی را نشان می‌دهد که به‌روزرسانی‌های بصری مربوط به رابط کاربری را نشان می‌دهد، اندازه‌گیری می‌کند.

یکی از اجزای مهم یک تعامل، زمان لازم برای رنگ آمیزی فریم بعدی است. رندر کردن کار انجام شده برای ارائه فریم بعدی از بخش‌های زیادی تشکیل شده است، از جمله محاسبه سبک‌های صفحه که درست قبل از چیدمان، رنگ‌سازی و کار ترکیبی رخ می‌دهد. این صفحه بر هزینه‌های محاسبه سبک تمرکز دارد، اما کاهش هر بخشی از فاز رندر مربوط به تعامل نیز تأخیر کلی آن را کاهش می‌دهد، از جمله برای محاسبات سبک.

پیچیدگی انتخابگرهای خود را کاهش دهید

ساده کردن نام انتخابگر می تواند به سرعت بخشیدن به محاسبات سبک صفحه شما کمک کند. ساده ترین انتخابگرها به یک عنصر در CSS فقط با نام کلاس ارجاع می دهند:

.title {
  /* styles */
}

اما، همانطور که هر پروژه ای رشد می کند، احتمالاً به CSS پیچیده تری نیاز دارد و ممکن است در نهایت با انتخابگرهایی روبرو شوید که به این شکل هستند:

.box:nth-last-child(-n+1) .title {
  /* styles */
}

برای تعیین اینکه چگونه این سبک‌ها در صفحه اعمال می‌شوند، مرورگر باید به طور موثر بپرسد "آیا این عنصری با یک کلاس title است که والد آن عنصر فرزند منهای-nth-plus-1 با یک کلاس box است؟" فهمیدن این موضوع بسته به انتخابگر مورد استفاده و همچنین مرورگر مورد نظر، ممکن است زمان زیادی طول بکشد. برای ساده‌تر کردن این کار، می‌توانید انتخابگر را طوری تغییر دهید که فقط یک نام کلاس باشد:

.final-box-title {
  /* styles */
}

این نام‌های کلاس جایگزین ممکن است ناخوشایند به نظر برسند، اما کار مرورگر را بسیار ساده‌تر می‌کنند. به عنوان مثال، در نسخه قبلی، برای اینکه مرورگر بداند یک عنصر آخرین نوع خود است، ابتدا باید همه چیز را در مورد سایر عناصر بداند تا تعیین کند که آیا هر عنصری که بعد از آن می آید و می تواند n nth-last-child . این می تواند از نظر محاسباتی بسیار گرانتر از تطبیق یک انتخابگر با یک عنصر فقط به دلیل مطابقت کلاس آن باشد.

تعداد عناصر استایل دهی شده را کاهش دهید

یکی دیگر از ملاحظات عملکرد، و اغلب مهمتر از پیچیدگی انتخابگر، میزان کاری است که باید هنگام تغییر یک عنصر اتفاق بیفتد.

به طور کلی، بدترین هزینه برای محاسبه سبک عناصر محاسبه شده، تعداد عناصر ضرب در تعداد انتخابگر است، زیرا مرورگر باید هر عنصر را حداقل یک بار در برابر هر سبک بررسی کند تا ببیند آیا مطابقت دارد یا خیر.

محاسبات سبک می تواند به جای بی اعتبار کردن کل صفحه، مستقیماً چند عنصر را هدف قرار دهد. در مرورگرهای مدرن، این مشکل کمتر است، زیرا مرورگر همیشه نیازی به بررسی تمام عناصری که ممکن است یک تغییر بر آن تأثیر بگذارد، ندارد. از طرف دیگر، مرورگرهای قدیمی همیشه برای چنین کارهایی بهینه نیستند. تا جایی که می توانید، باید تعداد عناصر بی اعتبار را کاهش دهید .

هزینه محاسبه مجدد سبک خود را اندازه گیری کنید

یکی از راه‌های اندازه‌گیری هزینه محاسبات مجدد سبک، استفاده از پانل عملکرد در ابزار توسعه کروم است. برای شروع کارهای زیر را انجام دهید:

  1. DevTools را باز کنید.
  2. به تب Performance بروید.
  3. روی Record کلیک کنید.
  4. با صفحه تعامل داشته باشید.

وقتی ضبط را متوقف می کنید، چیزی شبیه تصویر زیر خواهید دید:

DevTools محاسبات سبک را نشان می دهد.
گزارش DevTools که محاسبات سبک را نشان می دهد.

نوار بالا یک نمودار شعله مینیاتوری است که فریم در ثانیه را نیز ترسیم می کند. هر چه فعالیت به پایین نوار نزدیک‌تر باشد، فریم‌ها سریع‌تر توسط مرورگر نقاشی می‌شوند. اگر نمودار شعله را دیدید که در بالا با نوارهای قرمز در بالای آن یکسان شده است، پس کاری دارید که باعث فریم های طولانی مدت می شود.

بزرگنمایی یک ناحیه مشکل در Chrome DevTools در خلاصه فعالیت پانل عملکرد پر شده در Chrome DevTools.
فریم های طولانی مدت در خلاصه فعالیت DevTools.

فریم های طولانی در طول تعاملی مانند اسکرول ارزش نگاه دقیق تر را دارند. اگر بلوک بنفش بزرگی را مشاهده کردید، روی فعالیت زوم کنید و هر اثری را با عنوان Recalculate Style انتخاب کنید تا اطلاعات بیشتری در مورد کار بالقوه گران قیمت محاسبه مجدد سبک بدست آورید.

دریافت جزئیات محاسبات طولانی مدت سبک، از جمله اطلاعات حیاتی مانند مقدار عناصر تحت تأثیر کار محاسبه مجدد سبک.
یک محاسبه مجدد سبک طولانی مدت که در خلاصه DevTools فقط بیش از 25 میلی ثانیه طول می کشد.

کلیک کردن روی رویداد، پشته تماس آن را نشان می دهد. اگر کار رندر ناشی از تعامل کاربر باشد، جاوا اسکریپت را فراخوانی می کند که باعث تغییر سبک شده است. همچنین تعداد عناصری را که این تغییر تحت تأثیر قرار می‌دهد - در این مورد فقط بیش از 900 عنصر - و مدت زمان محاسبه سبک را نشان می‌دهد. می توانید از این اطلاعات برای شروع تلاش برای یافتن راه حلی در کد خود استفاده کنید.

از Block، Element، Modifier استفاده کنید

رویکردهای کدنویسی مانند BEM (Block، Element، Modifier) ​​در انتخابگر با مزایای عملکرد مطابقت دارند. BEM توصیه می کند که همه چیز دارای یک کلاس واحد باشد، و در جایی که به سلسله مراتب نیاز دارید، این سلسله مراتب در نام کلاس نیز گنجانده می شود:

.list {
  /* Styles */
}

.list__list-item {
  /* Styles */
}

اگر به یک اصلاح کننده نیاز دارید، مانند مثال آخرین فرزند، می توانید آن را مانند این اضافه کنید:

.list__list-item--last-child {
  /* Styles */
}

BEM نقطه شروع خوبی برای سازماندهی CSS شما است، هم از منظر ساختار، و هم به دلیل ساده‌سازی جستجوی سبک که ترویج می‌کند.

اگر BEM را دوست ندارید، راه‌های دیگری برای نزدیک شدن به CSS وجود دارد، اما قبل از شروع باید عملکرد و ارگونومی آن‌ها را ارزیابی کنید.

منابع

تصویر قهرمان از Unsplash اثر مارکوس اسپیسکه .