Layout trashing
HTML-код
- Опубликовано: 6 май 2022
- Дата выхода на Patreon: 2.04.2022
Материалы из видео:
* изначальный codesandbox: codesandbox.io/s/optimize-loo...
* финальное решение: codesandbox.io/s/optimize-loo...
* gist с layout trashing: gist.github.com/paulirish/5d5...
Видео создано благодаря подписчикам проекта на нашем Patreon.
Хотите получать контент на 3 месяца раньше остальных? Присоединяйтесь! / javascriptninja
задачка для джунов? надеюсь ты зарофлил...
очень крутой материал и подача. спасибо!
Дякую, цікаве відео!
Be aware, if you need to animate element size or position in the DOM, it's better to use transform instead css properties like (width, height, top, left etc.), it costs less and also improves performance.
В книге "Secrets of the js ninja" хорошо объяснен этот механизм. Глава так и называется - "Minimizing layout trashing".
Спасибо за видео, Илья!
Илья, спасибо, очень полезно
Интересная задача, но тут есть подвох в том, что в больших компаниях про DOM и тд в основном не спрашивают, а пичкают задачами с LeetCode, ибо по такой логике человек, который умеет писать и оценивать разные алгоритмы - сможет преодолеть всё. Не обессудь, но некоторым сеньором пришлось бы подумать перед задачей. Спасибо за задачу, делись еще!!
Это распространенное заблуждение. За пределами фаанга мало кто литкодит.
Гитлаб не спрашивает литкод, нетлифай не спрашивает литкод, stackblitz и airbnb тоже. Это из тех что я знаю
да это ж душная задача с трудным для понимания говнокодом ) про paint и layout можно гораздо проще спросить
Работаю уже пару лет, но с requestAnimationFrame сталкивался только при осваивании canvas, и я думаю что у меня бы это заняло куда больше 20 мин, и не каждый сеньер столкнется с такой проблемой. Спасибо за материал!
зато у автора каждый джун эту таску решает) 🤡
Вот так кодишь 15 лет на JS, но всего не знаешь, не знал что DOM такой "ленивый", спасибо огромное! А что не так с CSS? сейчас у себя попробовал, все работает отлично (могу гист предоставить). И код у вас конечно написан "не очень", ненужные походы в дом, промежуточные массивы, но я так понял так задумано, для собеседования =)
Все таки это layout thrashing, а не trashing. А так спасибо за видео.
Интересная штука , тоже как - то столкнулся с этим м пошел читать
а будет ли интересно еще лучше если width и height заменить на transform ?
Конечно, проблема вообще исчезнет, но будет другая (не в этом примере).... Но это совсем другая история... (с)
@@JavaScriptNinja речь идет не про баг в webkit, изза которого получается блюр-эффект(размытие)? сейчас точно не помню, как его воспроизвести. не знаю, возможно его уже пофиксили. было вроде както так: если у контейнера есть transform/translate и у дочернего элемента есть transform/translate, то дочерний элемент визуально получает размытие, например, текст может быть нечетким.
правда, в этой задаче вроде бы вложенность ни к чему.
Ты имел ввиду какой-то нюанс по производительности?
да, интересно. такое, наверняка, легче найдут и решат люди, кто уже использовал requestAnimationFrame напрямую. в этом случае уже как-то по-другому смотришь на анимации
Я б такое в доме в принципе делать не стал) в пикси каком нето топчик либа)
Есть хорошая презентация по теме на канале Frontend Channel
Называется "Как достичь производительного рендеринга в браузере / Глеб Михеев"
Там он как раз рассказывает о том как это все работает
Такие вещи лучше в канвасе делать. А так да, чисто чтоб выяснить как интервьюер думает и знаком ли как работает браузер можно спросить
Можно еще проще решить:
function tick() {
zone.querySelectorAll(".drop").forEach((drop) => { // Array.from не обязателен здесь
const currentSize = parseInt(getComputedStyle(drop).width, 10);
const newSize = currentSize + 1 + Math.random() * 6;
queueMicrotask(() => {
drop.style.width = `${newSize}px`;
drop.style.height = `${newSize}px`;
drop.style.opacity = (400 - newSize) / 400;
if (newSize > 400) {
drop.remove();
}
});
});
}
Я думал я миддл) но с этой задачей я вряд-ли бы справился с приемлемое время
просто надо было не использовать getComputedStyle.
Мне кажется суть видео вы не уловили :)
@@JavaScriptNinja мне вот кажется наоборот, что уловил.
Каким образом разнесение на 2 цикла одного и того же кода способствует производительности?
Очень похоже на баг в виртуальной машине js'a
Т.е. layout trashing срабатывает, когда последовательно вызывается getComputedStyle + присвоение размеров дом элементу?
а если в одном цикле сделать getComputedStyle , а в другом цикле присвоение, то уже не срабатывает?
Это просто особенность js интерпретатора, и с точки зрения программирования это знание ничего не дает.
Вполне возможно что в следующих версиях хромиума это вообще поправят.
А вообще да, нужно просто все размеры изначально хранить в коде, а не дергать из элементов на странице.
+ в копилку ко всему добавляет момент, что в sandbox'e в итоге это оптимизация не проканала.
@@unlike777 это вообще не про интерпретатор и суть не в двух циклах, а в том что layout trashing глобальный и вызывая его внутри цикла мы много раз пересчитываем разметку
@@JavaScriptNinja т.е. мы можем сколько угодно раз вызывать getComputedStyle без пересчета разметки,
но как только между вызовами появляется код, который изменяем дом элемент, то запускается пересчет разметки?
@@unlike777 да
Как не ковырял на маке этот код, перфоманс не снизился ни на долю((( кадры стабильные выдает, что за дичь
Аналогично. Может быть дело в М1? Поставил low end mobile, стабильно показывает 115 FPS...
или фикс проще - убрать getComputedStyle().width и читать свойство напрямую .style.width.trim("px");