Content-visibility против виртуализации
Попроси AI-агента ускорить тормозящий список — он за минуты выдаст библиотеку виртуализации, правильно подключённую — и часто не тот фикс, который нужен. Два самых известных ответа на «мой список тормозит» решают совершенно разные проблемы.
content-visibility: auto оставляет каждую строку в DOM и откладывает рендер для тех, что вне экрана. Виртуализация вообще не создаёт offscreen-строки. Оба ускоряют скролл. Только один вариант сохраняет то, что браузер делал за тебя бесплатно.
Контракты, которые тихо исчезают с виртуализацией: поиск на странице перестаёт находить строки, которых нет в документе. Deep link вида #card-470 резолвится в ничто. Строка с фокусом клавиатуры уничтожается в момент, когда уезжает за экран, и фокус падает на document.body. Ничего из этого не видно в diff'е — это приходит вместе с библиотекой.
content-visibility сохраняет всё это, но не автоматически и не безопасно:
→ Он работает через CSS containment — карточка обещает, что ничего внутри неё не влияет на страницу снаружи. Это обещание действует постоянно, поэтому tooltip или dropdown, который раньше выходил за края карточки, теперь обрезается → Скрытая карточка забывает свою высоту, поэтому contain-intrinsic-size: auto 120px (не голый 120px — он никогда не запоминает) даёт плейсхолдер, который браузер корректирует после реального рендера → Поиск и accessibility tree реально ломались в браузерах: Safari 18 не показывал skipped-контент в find bar до версии 26 год спустя; Chrome 85–89 терял заголовки и лендмарки из accessibility tree до Chrome 90
Реальное правило выбора: сначала профайл. Долгий layout/paint при небольшом DOM — content-visibility, сохраняешь все контракты. Десятки тысяч тяжёлых строк, реально раздувающих память и accessibility tree — виртуализация, и закладывай в бюджет пересборку поиска, deep link'ов и фокуса как реальных продуктовых фич.
Цифра для масштаба: 50 000 полностью смонтированных карточек по 11 элементов каждая — это ≈550 000 узлов DOM. Но 200 тяжёлых карточек могут стоить дороже, чем 10 000 простых — это спектр для измерения, а не порог по количеству строк.
Полная статья с 7 интерактивными бенчмарками у Agustin Barrientos 👇 https://agustinbarrientos.com/writing/senior-eye/content-visibility-vs-virtualization/