TGViewer
Дивовижний світ веброзробки Дивовижний світ веброзробки @babichdev · 2.91K subscribers
Post #271 2.15K
#css_in_action
Бравзер читає CSS-селектори справа наліво.
Це загальновідомий факт, який, однак, потребує певного пояснення. По-перше, треба розуміти, коли це стається, а по-друге — чи завжди так.

Цей процес відбувається між етапом коли побудовані DOM та CSSOM та етапом render-tree. Це так званий style computation — крок, під час якого бравзер визначає, які стилі до якого елемента застосовуються. І саме тоді йому потрібно знайти відповідність між селектором та елементос в DOM.

Чому ж справа наліво? Усе просто — це зменшує кількість кандидатів для перевірки. Якби бравзер йшов селектором зліва направо, тобто зверху вниз DOM-деревом, йому б довелось перевіряти все дерево повністю. Натомість він відразу відсікає невідповідні кінцеві "листки" дерева, і прямує вгору від цільового елементу, який визначається найправішим простим селектором.

Погляньмо на приклад:
.card p ~ a.button


Тут бравзер відразу шукатиме усі a.button, потім пройдеться його попередніми сусідами, які є p, і для кожного з них знайде безпосереднього батька з класом .card. Що примітно, бравзер навіть не "шукатиме" ці елементи, бо побудує індекс за тегами й класами ще на етапі побудови DOM-дерева. Тому розпочне пошук відразу з потрібних вузлів.

Якби ми йшли зліва направо, то бравзер мусив би перебирати усі .card, незалежно від того, чи містять вони p, потім — усі p в таких .card, незалежно від того, чи є у них сусідні a.button.

Цей механізм, до речі, був закладений в CSS ще від самого початку появи технології.

А на цьому місці прийшов час поставити вподобайку та поширити допис. Хіба нє?

Взагалі, метчинг запускається доволі часто, коли постає потреба перезапустити style-calculation, наприклад, коли змінюються CSS-правила. Наприклад, на додачу до вище згаданого, коли ми змінюємо атрибути елементу з попереднім селектором (в цьому прикладі p або .card). Чи коли змінюється структура DOM: переміщення, додавання, видалення вузлів, а також коли є динамічні псевдокласи.

Але перерахунок відбувається точково, лише для потенційно зачеплених вузлів, а не по усьому дереву.

Важливо памʼятати, що DOM API не використовує саме цей рушій, але окремі операції можуть виглядати схоже. Наприклад, closest() ззовні може нагадувати рух селектором справа наліво, бо йде вгору по дереву. Проте під капотом він просто розбиває комплексний селектор на частини й викликає matches() на кожному предку. matches() же працює через Selector API, а не через CSS matching, тому алгоритм там зовсім інший.

Той же querySelector прямує вниз деревом, а селектор перебирає зліва направо. І операції з DOM використовують Selector API, а не іпмлементацію CSS-рушія, тож і алгоритми, і оптимізації, і підходи загалом можуть суттєво відрізнятись.

Загалом цей підхід спрямований не на якесь там "прискорення селекторів", а для забезпечення контрольованості інвалідації стилів. Завдяки такому напрямку браузер не перевіряє весь DOM, а працює локально — що й дозволяє CSS залишатися ефективним навіть на велетенських деревах.

Однак це не означає, що тепер можна видихнути і писати селектори на 15 складових. Треба памʼятати, що бравзеру однак доводиться виконувати титанічний обсяг роботи, особливо в умовах високодинамічних інтерфейсів. І якщо ми йому в цьому допоможемо, пишучи максимально прості селектори, він на нас точно не образиться.

Що почитати:
📖 The truth about CSS selector performance

@babichdev
  • ❤ 61
  • 👍 19
  • 🔥 8
More from @babichdev
  1. Sep 30, 2026Товариство, запрошую вас цієї суботи, 3 жовтня, на Fwdays Tech Summit — онлайн конференцію…
  2. Sep 28, 2026#збір_на_авто_для_21 Товариство, почнімо тиждень з доброго діла. Я би дуже хотів, аби ми ц…
  3. Sep 27, 2026Знайшов своє старезне резюме. Аж пустив скупу сльозу за тими часами, коли навіть з таким м…
  4. Sep 25, 2026Днями на редіті побачив допис, в якому автор питав, чому його лічильник часу на сторінці з…
  5. Sep 23, 2026Який ШІ найкращий для навчання? Відповідь проста — той, з яким ви чогось навчились. ШІ це…
  6. Sep 18, 2026Оце я, канєшна, провтикав. Конфа завтра, 19 вересня. Ще встигаєте взяти квиточок.
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →