اجتناب از رنگ های غیر ضروری

معرفی

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

نقاشی: یک تور فوق العاده سریع

یکی از کارهای اصلی که یک مرورگر باید انجام دهد تبدیل DOM و CSS شما به پیکسل روی صفحه است و این کار را از طریق یک فرآیند نسبتاً پیچیده انجام می دهد. با خواندن نشانه گذاری شروع می شود و از آن یک درخت DOM ایجاد می کند. این کار مشابهی را با CSS انجام می دهد و از آن CSSOM را ایجاد می کند. سپس DOM و CSSOM با هم ترکیب می‌شوند و در نهایت به ساختاری می‌رسیم که می‌توانیم از آنجا شروع به نقاشی چند پیکسل کنیم.

خود فرآیند نقاشی جالب است. در کروم، درخت ترکیبی DOM و CSS توسط نرم افزاری به نام Skia شطرنجی شده است. اگر تا به حال با عنصر canvas بازی کرده باشید، API Skia به طرز وحشتناکی برای شما آشنا به نظر می رسد. بسیاری از توابع moveTo - و lineTo -style و همچنین مجموعه ای از موارد پیشرفته تر وجود دارد. اساساً تمام عناصری که نیاز به رنگ آمیزی دارند به مجموعه ای از فراخوانی های Skia تقطیر می شوند که می توان آنها را اجرا کرد و خروجی آن یک دسته بیت مپ است. این بیت مپ ها در GPU آپلود می شوند و GPU با ترکیب آنها با هم کمک می کند تا تصویر نهایی را روی صفحه به ما ارائه دهد.

Dom به پیکسل

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

با تمام موارد گفته شده، انجام کار رنگ آمیزی به زمان نیاز دارد و اگر آن را کاهش ندهیم، بودجه فریم ما ~ 16 میلی ثانیه خواهد بود. کاربران متوجه می‌شوند که فریم‌ها را از دست داده‌ایم و آن را به‌عنوان جاک می‌بینند، که در نهایت به تجربه کاربری برنامه ما آسیب می‌زند. ما واقعاً این را نمی‌خواهیم، ​​بنابراین بیایید ببینیم چه چیزهایی باعث می‌شوند که رنگ‌کاری ضروری باشد، و چه کاری می‌توانیم در مورد آن انجام دهیم.

پیمایش

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

برای اینکه ببینید چه نواحی در حال رنگ‌آمیزی مجدد هستند، می‌توانید از ویژگی «نمایش مستطیل‌های رنگ آمیزی» در DevTools Chrome استفاده کنید. سپس، با باز بودن DevTools، به سادگی با صفحه خود تعامل کنید و مستطیل های چشمک زن را می بینید که نشان می دهد کروم کجا و چه زمانی بخشی از صفحه شما را نقاشی کرده است.

نمایش مستطیل های رنگ آمیزی در ابزار توسعه کروم
نمایش مستطیل های رنگ آمیزی در ابزار توسعه کروم

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

من قبلاً مقاله ای در مورد عملکرد اسکرول نوشته ام، بنابراین اگر می خواهید در مورد ویژگی های عملکرد اسکرول بیشتر بدانید، به آن نگاه کنید.

فعل و انفعالات

فعل و انفعالات یکی دیگر از دلایل کار رنگ هستند: شناور، کلیک، لمس، کشیدن. هر زمان که کاربر یکی از آن فعل و انفعالات را انجام دهد، مثلاً یک شناور، کروم باید عنصر آسیب‌دیده را دوباره رنگ آمیزی کند. و مانند اسکرول کردن، اگر رنگ بزرگ و پیچیده ای مورد نیاز باشد، شاهد کاهش نرخ فریم خواهید بود.

همه خواهان انیمیشن‌های زیبا، روان و تعاملی هستند، بنابراین دوباره باید ببینیم که آیا سبک‌هایی که در انیمیشن ما تغییر می‌کنند برای ما زمان زیادی را صرف می‌کنند یا خیر.

یک ترکیب تاسف بار

نسخه ی نمایشی با رنگ های گران قیمت
نسخه ی نمایشی با رنگ های گران قیمت

اگر همزمان اسکرول کنم و ماوس را حرکت دهم چه اتفاقی می افتد؟ این کاملا ممکن است که من به طور ناخواسته با یک عنصر "تعامل" کنم که از کنار آن عبور می کنم و باعث ایجاد یک رنگ گران قیمت می شود. این به نوبه خود، می‌تواند من را از بودجه 16.7 میلی‌ثانیه برای فریم عبور دهد (زمانی که برای رسیدن به 60 فریم در ثانیه به آن نیاز داریم). من یک نسخه نمایشی ایجاد کرده ام تا دقیقاً منظورم را به شما نشان دهم. امیدواریم همانطور که پیمایش می کنید و ماوس خود را حرکت می دهید، افکت های شناور را مشاهده کنید، اما بیایید ببینیم ابزار DevTools کروم از آن چه می سازد:

ابزار DevTools کروم فریم های گران قیمت را نشان می دهد
ابزار DevTools کروم فریم های گران قیمت را نشان می دهد

در تصویر بالا می بینید که DevTools در حال ثبت کار رنگ وقتی روی یکی از بلوک ها می شوم. من در نسخه ی نمایشی خود سبک های فوق العاده سنگینی را به کار برده ام تا به این نکته پی ببرم، و به همین دلیل بودجه فریم خود را گاه به گاه افزایش می دهم. آخرین چیزی که می‌خواهم این است که مجبور باشم این کار را بدون نیاز به رنگ انجام دهم، مخصوصاً در حین اسکرول وقتی کارهای دیگری باید انجام شود!

پس چگونه می توانیم جلوی این اتفاق را بگیریم؟ همانطور که اتفاق می افتد، رفع مشکل بسیار ساده است. ترفند اینجا این است که یک کنترلر scroll را وصل کنید که جلوه های شناور را غیرفعال می کند و یک تایمر برای فعال کردن دوباره آنها تنظیم می کند. این بدان معناست که ما تضمین می‌کنیم که وقتی پیمایش می‌کنید، نیازی به اجرای رنگ‌های تعاملی گران قیمت نخواهیم داشت. وقتی برای مدت کافی توقف کردید، فکر می کنیم دوباره روشن کردن آنها بی خطر است.

این هم کد:

// Used to track the enabling of hover effects
var enableTimer = 0;

/*
 * Listen for a scroll and use that to remove
 * the possibility of hover effects
 */
window.addEventListener('scroll', function() {
  clearTimeout(enableTimer);
  removeHoverClass();

  // enable after 1 second, choose your own value here!
  enableTimer = setTimeout(addHoverClass, 1000);
}, false);

/**
 * Removes the hover class from the body. Hover styles
 * are reliant on this class being present
 */
function removeHoverClass() {
  document.body.classList.remove('hover');
}

/**
 * Adds the hover class to the body. Hover styles
 * are reliant on this class being present
 */
function addHoverClass() {
  document.body.classList.add('hover');
}

همانطور که می بینید، ما از یک کلاس در بدنه استفاده می کنیم تا ردیابی کنیم که آیا افکت های شناور مجاز هستند یا نه، و سبک های زیربنایی برای وجود این کلاس متکی هستند:

/* Expect the hover class to be on the body
 before doing any hover effects */
.hover .block:hover {
 …
}

و این تمام چیزی است که در آن وجود دارد!

نتیجه

عملکرد رندر برای کاربرانی که از برنامه شما لذت می برند بسیار مهم است، و شما باید همیشه سعی کنید حجم کاری رنگ خود را کمتر از 16 میلی ثانیه نگه دارید. برای کمک به شما در انجام این کار، باید با استفاده از DevTools در طول فرآیند توسعه خود ادغام کنید تا گلوگاه ها را شناسایی و برطرف کنید.

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

به سایت ها و برنامه های خود نگاهی بیندازید، آیا می توانند با کمی محافظت از رنگ انجام دهند؟