📰 IT Дайджест

← К выпуску 04.09.2026

Фронтенд-эксперты уходят или переключаются на AI — Claude Sonnet отвечает на вопросы CSS лучше людей

nolanlawson.com · #blog #complexity #frontend #webdev

Нолан Лоусон замечает, что многие известные фронтенд-педагоги (Аксель Раушмайер, Салма Алам-Нейлор, Джош Комо) сворачивают активность. Он попросил Claude Sonnet объяснить, как оптимизировать высокие затраты Style в Chrome trace — модель дала исчерпывающий ответ, включая совет включить Selector Stats.

Открыть оригинал →

Многие из преподавателей фронтенда, которыми я восхищаюсь, похоже, либо уходят, либо снижают активность: Аксель Раушмайер, Сальма Алама-Нейлор, Джош У. Комо — назову лишь некоторых. Другие известные светила, такие как Кент К. Доддс, Эдди Османи, Рэйчел Наборс и Лидия Халли, переключились с обсуждения фронтенд-разработки на обсуждение… ну, угадайте с трёх раз.

Я никогда не зарабатывал на жизнь разговорами о веб-разработке, но у меня есть этот блог, и я выступал на конференциях и в подкастах о том, что меня увлекает. Недавно, например, моей страстью было объяснение всех тонкостей производительности CSS: как работает теневой DOM, как работает механизм стилей браузера, ловушки CSS-in-JS и т.д.

Просто ради интереса я решил спросить Claude Sonnet, как бы он обработал Chrome-трейс с высокими затратами на «Style Calculation». Это одна из моих любимых головоломок, потому что это то, на чём, как я видел, веб-разработчики — даже опытные! — спотыкаются снова и снова. Claude дал безупречный ответ:

Нажмите, чтобы увидеть

Prompt: Ответьте без поиска в интернете: вы смотрите на Chrome-трейс и видите повторяющиеся промежутки высокой стоимости Style, но относительно низкой стоимости Layout. На какие вещи в веб-приложении вы обратите внимание для оптимизации? Что вы измерите дальше?

Что на самом деле означает стоимость «Style»
Фаза Style (Recalculate Style) — это когда браузер сопоставляет CSS-селекторы с DOM и вычисляет окончательные вычисленные стили для каждого затронутого элемента. Она дорогая независимо от того, движется или изменяет размеры что-либо фактически (это работа Layout). Итак, если Style высок, а Layout низок, вы, скорее всего, платите за сопоставление селекторов / инвалидацию на многих элементах, а не за дорогую геометрию.

На что обратить внимание в веб-приложении

  1. Сложность и количество селекторов
    • Чрезмерно сложные или глубоко вложенные селекторы (.a .b .c > .d + .e), особенно комбинаторы потомков, вынуждают движок проходить больше DOM/цепочки предков на каждую попытку сопоставления.
    • Универсальные селекторы или селекторы атрибутов ([data-foo="bar"]), применяемые широко.
    • Библиотеки CSS-in-JS, генерирующие огромное количество уникальных имён классов/правил (пересчёт стилей должен учитывать весь набор правил).
  1. Область инвалидации — обычно это самое важное
    • Переключение класса/атрибута/стиля высоко в дереве DOM (например, переключение класса на <body> или контейнере верхнего уровня) может вынудить пересчёт стилей на больших поддеревьях, даже если итоговые стили меняются лишь у нескольких элементов.
    • Проверьте, не инвалидирует ли одно изменение состояния (например, класс «theme», класс «loading», состояние hover) гораздо больше элементов, чем необходимо. «Selector Stats» в Chrome (включить в настройках DevTools Performance) покажет, какие селекторы медленные и на скольких элементах они проверялись — это самое полезное следующее измерение.
  1. Частота/усиление
    • Что-то, повторно запускающее пересчёт стилей много раз за кадр — например, чтение свойства стиля/макета в цикле сразу после изменения класса (вызывает синхронный пересчёт), или JS-анимация, использующая .classList.toggle() или обновления встроенных стилей на многих узлах на каждый тик rAF вместо пакетной обработки.
    • Повторяющиеся мелкие мутации DOM, каждая из которых вызывает проход стилей, вместо того чтобы быть сгруппированными в одну.
  1. Распространение наследуемых/вычисляемых свойств
    • Изменение наследуемого свойства (например, font-size или color на общем предке) вынуждает пересчёт вычисленных стилей всех потомков, даже без изменений макета (например, color, visibility, cursor — это только Style, не запускают Layout).
    • Изменение пользовательских свойств (CSS-переменных) в области высокого уровня — обновление --custom-prop на :root или общем предке пересчитывает стиль для каждого элемента, ссылающегося на него.
  1. Shadow DOM / границы компонентов
    • Если используется фреймворк с большим количеством теневых корней или изолированных стилей, проверьте, не повторяется ли пересчёт стилей без необходимости для каждого экземпляра компонента из-за неразделяемых таблиц стилей.

Что измерить дальше

  • Включите «Selector Stats» на панели Performance (иконка шестерёнки → Enable selector stats). Перезапишите трейс. Это даст вам для каждого события Recalculate Style самые медленные селекторы и количество совпадений — это прямо укажет, какие CSS-правила и сколько элементов ответственны.
  • Проверьте инициатор/стек вызова события «Recalculate Style» в трейсе, чтобы увидеть, какой JS его запустил — переключение класса, style.setProperty, колбэк анимационного кадра и т.д.
  • Подсчитайте, сколько элементов затронуто за один пересчёт — DevTools показывает «Elements Affected» для каждого события Recalculate Style на панели сводки. Сравните это число с тем, сколько элементов фактически изменили внешний вид — большой разрыв указывает на чрезмерно широкую инвалидацию.
  • Посмотрите, где в DOM происходит запускающая мутация — близко к корню (широкая инвалидация) или ограничена малым поддеревом (узкая, дешёвая).
  • Проверьте на принудительный синхронный стиль — ищите фиолетовые предупреждения «Forced reflow»; даже если вы сказали, что Layout низок, иногда принудительное чтение стиля (getComputedStyle), перемежающееся с записью в DOM, проявляется как множество мелких последовательных событий Style вместо одного группированного.

Типичные исправления после нахождения причины

  • Ограничьте переключение классов/состояний наименьшим возможным поддеревом вместо общего предка.
  • Упростите селекторы, предпочитайте одиночные селекторы классов цепочкам потомков.
  • Перенесите обновления CSS-пользовательских свойств в наименьшую необходимую область.
  • Группируйте изменения DOM/классов, чтобы пересчёт происходил один раз, а не на каждую мутацию.
  • Используйте content-visibility: auto или contain: style layout на независимых поддеревьях, чтобы ограничить область инвалидации.

В наши дни, получив медленно загружающийся сайт, даже будучи человеком, который годами писал о производительности браузера и буквально работал в команде производительности браузера, я, вероятно, просто скормил бы Chrome-трейс Claude Code и попросил бы предложить улучшения. На самом деле я делал это на своей основной работе и получил неплохие результаты.

Будущее фронтенда

Итак, что это означает для образования в области фронтенд-разработки? Очевидно, не в лучшем положении; хотелось бы мне иметь более обнадёживающие ответы для людей, которые (как и я) раньше получали большое удовлетворение от попыток поднять планку для фронтенд-разработчиков повсюду. Однако у меня есть некоторые догадки, и я думаю, что проблему всё ещё стоит обдумывать.

Ключевой вопрос в том, куда сама фронтенд-разработка придёт в эту новую эру. К сожалению, мне кажется, что есть несколько тенденций, указывающих против увеличения инвестиций в фронтенд-знания:

Фронтенд менее рискованно просто отдать агенту. Если вы используете агента для написания миграции базы данных, вы, вероятно, захотите пропустить её через несколько раундов AI-ревью кода, проверить её самостоятельно, сначала запустить на стейджинге и т.д. Однако если вы пишете React-компонент с агентом, риск просто «плюхнуть» его в продакшн (как правило) намного ниже.

Обратите внимание, я не говорю, что рисков нет: агент может испортить доступность, может вызвать бесконечный цикл, блокирующий пользователей, и т.д. Но в целом фронтенд-код гораздо более эфемерен и заменим, чем другие типы кода. Поэтому я ожидаю, что многие AI-кодеры будут чувствовать себя комфортно, позволяя своему агенту работать без контроля (во благо или во зло).

DevExp становится в целом менее критичным. Значительная часть дискуссий в сфере фронтенда до LLM была об эргономике против результатов: «The "developer experience" bait-and-switch» Алекса Рассела — отличный пример. Другой пример: Svelte и Solid долгое время утверждали, что их эргономика приводит к лучшим результатам, чем React: меньше кода, лучше производительность и т.д.

Тем временем Cursor и Viget писали в блогах о миграции своих кодовых баз с Solid и Lit соответственно на React. Поскольку переписывание с помощью агентов обходится дешевле, это может показаться удивительным: почему бы не перейти на более производительный/менее многословный фреймворк? Ответ (явно в случае Cursor, и я подозреваю, что для Viget тоже), конечно: «агенты знают React». К лучшему или худшему, React чрезмерно представлен в обучающих весах, и «агентский опыт» начинает значить больше, чем опыт разработчика.

Стандарты догонят. Я не был в сфере веб-стандартов пару лет, так что это чистое предположение с моей стороны. Но я представляю, что многие усилия по улучшению эргономики создания сайтов — лучшие сокращения CSS, более краткий синтаксис JavaScript и т.д. — станут восприниматься как менее важные по сравнению с вещами, которые действительно влияют на производительность, возможности и т.д. В конце концов, для агента не так уж важно написать 3 строки CSS вместо 1, и к тому же использование нового синтаксиса может быть даже сложнее, потому что нужно обучать агента вещам, которых нет в его обучающих данных.

В некотором смысле этот сдвиг, возможно, уже был в процессе. Я помню несколько лет назад на TPAC, задолго до бума AI-кодинга, я сказал кому-то из команды Chrome, что работаю над стандартами веб-компонентов. Они ответили, что это им неинтересно, потому что эти API влияют только на опыт разработчика и на самом деле не делают браузер более функциональным (например, Project Fugu). Это запомнилось мне, потому что это хороший аргумент: такие API, как теневой DOM и пользовательские элементы, не дают веб-разработчикам новых суперспособностей; они просто меняют то, где и как пишется код. Я ожидаю, что такие вещи уйдут из центра внимания по мере того, как AI-кодинг будет брать верх.

Это не значит, что стандарты исчезнут из тем, за которыми нужно следить фронтенд-разработчику, но я представляю, что это будет меньше о «используйте этот новый синтаксис» (вечный источник материала для конференционных докладов и статей) и больше о «вот эти новые возможности». И я предсказываю, что последняя группа будет намного меньше первой, поскольку они, как правило, более спорны для органов по стандартизации, и просто меньше пул функций, из которых можно черпать.

Куда движется образование в области фронтенда?

Итак, как область фронтенд-образования может адаптироваться к этому враждебному будущему? Чтобы не быть совершенно мрачным, вот некоторые позитивные направления, в которых, как я думаю, оно могло бы развиваться.

Во-первых, агентов всё ещё нужно обучать общей картине. Агенты и обвязки, похоже, любят писать React и, в частности, SPA, но SPA — это ответ не на всё. Вы можете сжечь много токенов, заставляя агента писать большой сложный SPA для вашего маркетингового сайта, а затем исправлять все ошибки с кнопкой «назад», состоянием фокуса, производительностью и т.д., или вы можете просто выбрать MPA-фреймворк, такой как Astro или Eleventy, и закончить на этом. Возможно, с этими фреймворками агентам будет немного сложнее работать (особенно с Astro, поскольку он отдалённо похож на React, но не является им), но я думаю, что поскольку вы пишете примерно на 50% меньше кода в целом, это не будет иметь значения.

Во-вторых, создание сайтов, которые хорошо работают с агентами, вероятно, будет плодотворным занятием в ближайшем будущем. is-agentic от Vercel — хороший пример этого. По иронии судьбы, это возвращает к хорошим основам, которые публичные сайты и так должны были делать: серверный рендеринг контента, надлежащая доступность, скорость загрузки страниц и т.д. Но если добавление слова «AI» — это то, что заставляет людей заботиться об этом, то я только за.

Обратите внимание, что я немного менее оптимистичен в отношении этого второго пункта, потому что я не уверен, что веб выживет в своей нынешней форме, поскольку агенты становятся всё более распространёнными. Если я хочу выяснить, сколько стоит полёт из Сиэтла в Париж, я гораздо охотнее спрошу агента, чем буду кликать через раздражающую серию кнопок на медленно загружающемся сайте. Единственная причина, по которой я не могу этого сделать, — это то, что эти сайты явно блокируют ботов, или они не предлагают MCP, но я уверен, что есть несколько стартапов, которые горят желанием решить эту проблему. Так что я не уверен, насколько устойчива текущая ситуация.

В-третьих, мы можем предлагать консультационные услуги для «вайб-кодированных» чудовищ. Огромное количество сгенерированного AI фронтенд-кода выкачивается прямо сейчас, и часть его (используя терминологию Клода) наверняка станет «несущей нагрузку». Если эти сайты медленные, несоответствующие стандартам и кишат дырами в безопасности, то может быть недостаточно просто попросить агента «почини мой сайт, пожалуйста». Здесь может быть возможность для настоящей экспертизы, особенно если на кону деньги, а знания вайб-кодера о веб-разработке не простираются дальше «сайты — это приложения, размещённые в интернете».

(Я признаю, что это самый шаткий из моих трёх пунктов, поскольку я вполне могу представить, что следующее поколение «самовосстанавливающихся» веб-приложений затмит среднего эксперта в 2027 или 2028 году. Но на данный момент: да, экспертиза всё ещё имеет значение.)

Заключение

Цель этого поста не в том, чтобы заставить себя чувствовать себя лучше или плясать на могилах всех тех карьер, которые были разрушены недавним бумом AI. Я по природе мрачный человек, и этот пост был моим позволением упиваться собственной мрачностью. Я не получаю удовольствия, отмечая, что огромный объём знаний, который я накопил за эти годы, стал почти устаревшим, и я не рад видеть то же самое, происходящее с моими гораздо более квалифицированными коллегами. Но притворяться, что этого не происходит, — тоже не вариант.

В некоторых блогах, которые я читаю в последнее время, есть настроение вроде «Я так устал говорить об AI» или «Пожалуйста, никогда больше не упоминайте при мне AI». Я уверен, что отчасти это своего рода умудрённый жизнью, надменный тон, который приятно носить как знак отличия. Но я думаю, что во многом это также исходит из реального страха. Страшно признать, что ты не знаешь, что произойдёт через год. Дестабилизирует представлять свою карьеру, идущую по определённой траектории, безмятежно приводящую к выходу на пенсию, а затем видеть, как всё рушится всего за несколько лет до твоей цели.

Метафора, которую я использую, такова: на землю только что упал астероид, и мы всё ещё осматриваем обломки. Трудно предсказать, что произойдёт, когда пыль осядет (не говоря уже о том, какие крошечные грызуны возвестят Эру Млекопитающих!), но игнорировать кратер — это, пожалуй, худший вид отрицания. Другая метафора — ковид: когда ударил ковид, я не припоминаю, чтобы думал: «Тьфу, я так устал говорить о ковиде» — вместо этого я хотел узнать всё, что мог, о вирусах, эпидемиологии, маскировке и т.д. Это оказалось хорошей идеей, поскольку ковид должен был доминировать в моей жизни в течение следующих нескольких лет (после чего да, я наконец устал говорить о нём!).

У меня едва ли есть хрустальный шар, но этот пост был моей попыткой обдумать, куда может двигаться моя самая дорогая область в будущем. Я признаю, что в наши дни у меня гораздо меньше личной заинтересованности: я вышел из веб-стандартов, я даже не работаю во фронтенде на своей текущей работе, и мой блог в основном состоял из множества стенаний и скрежета зубов об AI, а не из моего обычного меню браузеров, производительности, доступности и т.д. Тем не менее, я всё ещё испытываю большую любовь и уважение к области фронтенда, и мне небезразлично, что с ней будет в будущем. Возможно, через несколько лет она станет неузнаваемой, но, надеюсь, мои коллеги найдут способ ориентироваться во всех этих изменениях и преуспеть в этом странном новом мире.