جاوا اسکریپت اغلب محرک تغییرات بصری است. گاهی اوقات این به طور مستقیم از طریق دستکاری سبک انجام می شود، و گاهی اوقات این محاسبات است که منجر به تغییرات بصری، مانند جستجو یا مرتب کردن برخی از داده ها می شود. جاوا اسکریپت با زمان نامناسب یا طولانی مدت می تواند یکی از دلایل رایج مشکلات عملکرد باشد، و شما باید تا جایی که می توانید تاثیر آن را به حداقل برسانید.
تغییر DOM، از طریق افزودن و حذف عناصر، تغییر ویژگیها، کلاسها یا از طریق انیمیشن، همه باعث میشود که مرورگر سبکهای عنصر را دوباره محاسبه کند و در بسیاری از موارد، صفحه یا بخشهایی از آن را طرحبندی (یا جریان مجدد) کند. این فرآیند محاسبه سبک محاسبه شده نامیده می شود.
اولین بخش سبکهای محاسباتی ایجاد مجموعهای از انتخابگرهای منطبق است، که اساساً مرورگر است که تشخیص میدهد کدام کلاسها، شبه انتخابگرها و شناسهها برای هر عنصری اعمال میشوند.
بخش دوم فرآیند شامل گرفتن تمام قوانین سبک از انتخابگرهای منطبق و کشف سبک های نهایی عنصر است.
خلاصه
- چگونه کاهش هزینه های محاسبه سبک می تواند تأخیر تعامل را کاهش دهد.
- پیچیدگی انتخابگرهای خود را کاهش دهید. از یک روش کلاس محور (برای مثال BEM) استفاده کنید.
- تعداد عناصری را که باید بر اساس آنها محاسبه سبک محاسبه شود، کاهش دهید.
زمان محاسبه مجدد سبک و تأخیر تعامل
Interaction to Next Paint (INP) یک معیار عملکرد زمان اجرا کاربر محور است که پاسخگویی کلی صفحه به ورودی کاربر را ارزیابی می کند. هنگامی که تأخیر تعامل با این معیار ارزیابی میشود، زمان شروع از تعامل کاربر با صفحه تا زمانی که مرورگر فریم بعدی را نشان میدهد که بهروزرسانیهای بصری مربوطه را در رابط کاربری نشان میدهد، نشان میدهد.
یکی از اجزای مهم یک تعامل، زمان لازم برای رنگ آمیزی فریم بعدی است. رندر کردن کار انجام شده برای ارائه فریم بعدی از بخشهای زیادی تشکیل شده است، از جمله محاسبه سبکهای صفحه که درست قبل از طرحبندی، رنگسازی و کار ترکیبی رخ میدهد. در حالی که این مقاله صرفاً بر هزینههای محاسبه سبک تمرکز دارد، مهم است که تأکید کنیم که کاهش هر بخشی از فاز رندر ذاتی تعامل، تأخیر کلی آن را کاهش میدهد - محاسبه سبک نیز شامل میشود.
پیچیدگی انتخابگرهای خود را کاهش دهید
در ساده ترین حالت، می توانید تنها با یک کلاس به یک عنصر در CSS خود ارجاع دهید:
.title {
/* styles */
}
اما، همانطور که هر پروژه ای رشد می کند، احتمالاً منجر به CSS پیچیده تری می شود، به طوری که ممکن است با انتخابگرهایی روبرو شوید که به این شکل هستند:
.box:nth-last-child(-n+1) .title {
/* styles */
}
برای اینکه بدانیم این سبکها چگونه در صفحه اعمال میشوند، مرورگر باید به طور مؤثر بپرسد "آیا این عنصری با یک کلاس title
است که دارای یک والد است که اتفاقا فرزند منهای n به اضافه 1 عنصر با یک کلاس box
است؟" تعیین این موضوع بسته به انتخابگر مورد استفاده و همچنین مرورگر مورد نظر می تواند زمان زیادی را صرف کند. رفتار مورد نظر انتخابگر را می توان به یک کلاس تغییر داد:
.final-box-title {
/* styles */
}
شما می توانید با نام کلاس مشکل داشته باشید، اما کار برای مرورگر بسیار ساده تر شده است. در نسخه قبلی، برای اینکه بدانیم مثلاً عنصر آخرین نوع خود است، مرورگر ابتدا باید همه چیز را در مورد سایر عناصر بداند و اینکه آیا بعد از آن عنصری وجود دارد که n nth-last-child
باشد nth-last-child
، که به طور بالقوه گرانتر از تطبیق ساده انتخابگر با عنصر است زیرا کلاس آن مطابقت دارد.
تعداد عناصر استایل دهی شده را کاهش دهید
یکی دیگر از ملاحظات عملکرد - که معمولاً عامل مهمتر برای بسیاری از بهروزرسانیهای سبک است - حجم بسیار زیاد کاری است که باید هنگام تغییر یک عنصر انجام شود.
به طور کلی، بدترین هزینه برای محاسبه سبک محاسبه شده عناصر، تعداد عناصر ضرب در تعداد انتخابگر است، زیرا هر عنصر باید حداقل یک بار در برابر هر سبک بررسی شود تا ببینیم آیا مطابقت دارد یا خیر.
محاسبات سبک اغلب میتواند بهجای بیاعتبار کردن صفحه بهعنوان یک کل، مستقیماً برای چند عنصر مورد هدف قرار گیرد. در مرورگرهای مدرن، این مشکل کمتر است، زیرا مرورگر لزوماً نیازی به بررسی همه عناصری که بالقوه تحت تأثیر یک تغییر قرار می گیرند، ندارد. از طرف دیگر، مرورگرهای قدیمی لزوماً برای چنین کارهایی بهینه نیستند. تا جایی که می توانید، باید تعداد عناصر بی اعتبار را کاهش دهید .
هزینه محاسبه مجدد سبک خود را اندازه گیری کنید
یکی از راههای اندازهگیری هزینه محاسبات مجدد سبک، استفاده از پانل عملکرد در ابزار توسعه کروم است. برای شروع، DevTools را باز کنید، به برگه با عنوان Performance بروید، رکورد را بزنید و با صفحه تعامل داشته باشید. هنگامی که ضبط را متوقف می کنید، چیزی شبیه به تصویر زیر خواهید دید:
نوار بالا یک نمودار شعله مینیاتوری است که فریم در ثانیه را نیز ترسیم می کند. هر چه فعالیت به پایین نوار نزدیکتر باشد، فریمها سریعتر توسط مرورگر نقاشی میشوند. اگر نمودار شعله را در بالا با نوارهای قرمز در بالای آن صاف می بینید، پس کاری دارید که باعث طولانی شدن فریم ها می شود.
اگر در حین تعاملی مانند اسکرول، یک قاب طولانی در حال اجرا دارید، باید بررسی دقیقتری انجام شود. اگر بلوک بنفش بزرگی دارید، روی فعالیت زوم کنید و هر اثری را با عنوان Recalculate Style انتخاب کنید تا اطلاعات بیشتری در مورد کار بالقوه گران قیمت محاسبه مجدد سبک بدست آورید.
در این چنگ زدن، کار محاسبه مجدد سبک طولانی مدت وجود دارد که کمی بیش از 25 میلی ثانیه طول می کشد.
اگر روی خود رویداد کلیک کنید، یک پشته تماس به شما داده می شود. اگر کار رندر به دلیل تعامل کاربر باشد، مکانی در جاوا اسکریپت شما که مسئول ایجاد تغییر سبک است فراخوانی می شود. علاوه بر آن، تعداد عناصری را که تحت تأثیر این تغییر قرار گرفتهاند را نیز دریافت میکنید - در این مورد فقط بیش از 900 عنصر - و مدت زمانی که برای انجام کار محاسبه سبک طول کشیده است. می توانید از این اطلاعات برای شروع تلاش برای یافتن راه حلی در کد خود استفاده کنید.
از Block، Element، Modifier استفاده کنید
رویکردهای کدنویسی مانند BEM (Block، Element، Modifier) در واقع مزایای عملکردی را که در بالا تطبیق میدهند، در انتخابگر ایجاد میکنند، زیرا توصیه میکند که همه چیز دارای یک کلاس واحد باشد، و در جایی که شما به سلسله مراتب نیاز دارید، در نام کلاس نیز مشخص میشود. :
.list {
/* Styles */
}
.list__list-item {
/* Styles */
}
اگر به اصلاحکنندهای نیاز دارید، مانند موارد بالا که میخواهیم برای فرزند آخر کار خاصی انجام دهیم، میتوانید آن را مانند این اضافه کنید:
.list__list-item--last-child {
/* Styles */
}
اگر به دنبال یک راه خوب برای سازماندهی CSS خود هستید، BEM نقطه شروع خوبی است، هم از نظر ساختار، و هم به دلیل سادهسازی جستجوی سبک که متدولوژی ترویج میکند.
اگر BEM را دوست ندارید، راههای دیگری برای نزدیک شدن به CSS وجود دارد، اما ملاحظات عملکرد باید در کنار ارگونومی رویکرد ارزیابی شوند.
منابع
تصویر قهرمان از Unsplash اثر مارکوس اسپیسکه .