Улучшаем перфоманс рендеринга при помощи content-visibility



Нолан Лоусон делится интересным примером того, как одним осознанным применением полезного CSS-свойства можно принести много пользы.



Представьте, что у вас есть библиотека, которая помогает работать с тысячами различных картинок. У Нолана это веб-компонент emoji-picker-element, который как в Slack умеет в кастомные эмодзи. Если в такой компонент добавить 20000 эмодзи, то по сути это необходимость отрендерить не меньше 20000 DOM-элементов. Если же для каждого эмодзи нужно несколько DOM-элементов, простым умножением приходим в ужас.



Чтобы не писать свой виртуальный список, Нолан пошёл на следующие ухищрения:

1. Добавил для каждого списка эмодзи content-visibility: auto; и contain-intrinsic-size, который считался на основании количества эмодзи в списке. Такими командами вы разрешаете браузеру не рендерить контент, чтобы экономить время. Этим приёмом получилось ускориться уже на 15%.

2. Свёл количество DOM-элементов до минимального, то есть на один эмодзи — один элемент. Для этого саму картинку перенёс в background-image. Это не сломало a11y, так как оставшийся элемент всё ещё содержал всё необходимое.

3. Написал свой простой аналог loading=lazy для картинок на основе IntersectionObserver, чтобы избавиться от ненужных запросов за этими самыми картинками. В итоге получил общий прирост производительности от 35% в Firefox до 40% в Chrome.



Заодно из статьи я узнал, что существует ивент с именем contentvisibilityautostatechange. Это не кот по клавиатуре прогулялся, а специальный ивент для отслеживания изменения content-visibility: auto.



https://nolanlawson.com/2024/09/18/improving-rendering-performance-with-css-content-visibility/