Веб-страница
СтатистикаВсё по фронтенду, бэкенду и девопсу в одном месте Разместить рекламу: @tproger_sales_bot Правила общения: https://tprg.ru/rules Другие каналы: @tproger_channels Сайт: https://tprg.ru/site Регистрация в перечне РКН: https://tprg.ru/64ai
- Последний пост
- 11:21
- Последнее чтение
- 11:31
- Постов за неделю
- 17
- Всего постов
- 191
- Тип
- открытый
- Язык
- русский
- Категория
- Технологии (по похожим)
- В каталоге с
- 12 авг.
- 1/24сутки в ленте
- 1 508
- 1/48двое суток
- 1 689
- 1/72трое суток
- 1 821
Медиана по постам, которые мы застали свежими и померили через сутки.
Посты
Выбираем менеджер пакетов При десятке JS/TS-проектов вопрос — не «кто быстрее ставит», а «кто не раздует node_modules и не даст импортнуть левое». Автор сравнения оценил npm, Yarn, pnpm и Bun по этому критерию. Разбор по ссылке.
Утечки памяти в JS: почему фронтенд тормозит со временем Долгоживущие вкладки часто тормозят из-за мелких ссылок, которые не дают сборщику мусора освободить память. В JavaScript объект живёт, пока на него остаётся ссылка, и удаление последней ссылки отправляет его в следующий проход сборщика мусора. Чаще всего утечки дают забытые таймеры и обработчики событий, отсоединённые DOM-узлы, оставшиеся в массивах, и глобальные переменные без let, const или var. Замыкания тоже держат ссылки дольше, чем нужно. Проверить проще, чем кажется: в Chrome DevTools вкладка Memory покажет снимок кучи и найдёт объекты, которые висят дольше положенного. А для метаданных объектов посмотрите на WeakMap: при удалении основной ссылки данные уйдут вместе с ней. Подробнее в азборе от Sharique Siddiqui.
uBlock Origin больше не фильтрует рекламу в *Facebook Разработчик проекта объявил, что команда прекращает поддержку сайта: соцсеть меняет разметку быстрее, чем волонтёры успевают чинить фильтры. Правки со стороны примут пул-реквестом, но сами тянуть это больше не будут. Интереснее механика, из-за которой гонка проиграна. Слово Sponsored на карточке рекламы разбито на отдельные буквы, каждая живёт в своём элементе, и приёму этому около пяти лет. Порядок букв иногда перемешивают, а между ними подставляют фиктивные символы, так что фильтр, ловящий объявление по тексту, получает мусор. *Компания Meta и её продукты признаны экстремистскими, их деятельность запрещена на территории РФ.
Откройте свой логотип в Chrome и Firefox рядом: в одном он будет толще Растровая иконка размером пикселей в пятнадцать в двух браузерах выглядит по-разному: в Chrome штрихи полнее, в Firefox ближе к оригиналу. Оказалось, что некоторые изображения Chrome целиком даже не распаковывает. Разработчик разобрал, почему так: сколько мегабайт памяти браузер на этом экономит, при чём тут блоки 8 на 8 и почему тот же приём годится не только для уменьшения. Проверить у себя можно за минуту: откройте страницу в двух браузерах и приблизьте иконку. Если разница видна, читайте разбор целиком, он короткий и с примерами до и после. Заодно узнаете, чем это лечится.
Почему учиться в IT стало сложнее? Вайбкодинг создал иллюзию, что теперь любой может сделать продукт быстро и легко, всего лишь с парой подписок. Работает это не так: необходимость разбираться в том, как всё устроено, применять знания и читать код никуда не делась. Разбор задачи, на который раньше уходил месяц, теперь укладывается в десять минут. Именно за этот месяц набирался опыт, а теперь без хорошей базы почти невозможно оценить то, что модель выдала за минуты. Почему разбираться теперь приходится глубже и быстрее, и что с этим делать — читайте на Tproger: https://tproger.ru/articles/uchitsya-v-it-stalo-slozhnee-chto-na-samom-dele-izmenil-vajbkoding
Почему хорошие идеи так и остаются в заметках? «Инициатива наказуема» — знакомое выражение? Промолчал, ничего не сделал: не накажут. Предложил и ошибся: накажут почти наверняка. Например, некоторые компании переняли у Toyota контроль качества, только наоборот. У японцев за найденный брак поощряли, а в других компаниях стали наказывать. Так и пропадает желание что-то предлагать. В новом материале на Tproger разбираем три ловушки, которые убивают инициативу внутри компании. https://tproger.ru/articles/chto-mewaet-zapustit-novye-produkty-vnutri-kompanii
Ваш сайт может обслуживать ИИ-агентов напрямую, не заставляя их кликать по вёрстке Агенты уже ходят по вашим страницам, но работают с ними как человек: разбирают разметку, ищут поле поиска, кликают, заполняют форму. Токены при этом уходят на навигацию вместо самой задачи, а любая правка вёрстки сбивает агента с пути. WebMCP предлагает сайту объявить свои действия явно, чтобы искать их не приходилось. Стандарт экспериментально поехал в Chrome 146: на странице появляется document.modelContext, и сайт регистрирует через него инструменты, то есть именованные операции с описанием и параметрами, вроде search_products с поисковым запросом. Агент вызывает нужную операцию как функцию и получает готовый ответ. Руками это отдельная работа: решить, какие действия отдавать наружу, связать каждый инструмент с тем же кодом, который выполняет ваша кнопка, и поддерживать всё это, пока стандарт меняется. Cloudflare сделал из этого тумблер: их прокси дописывает одну строку со скриптом в каждую страницу, которую отдаёт ваш сайт, а скрипт регистрирует готовые наборы инструментов. Если браузер стандарта не понимает, скрипт молча завершается и страница работает как раньше. Отдельный набор пробрасывает наружу ваш собственный MCP-сервер, если он уже есть: скрипт запрашивает у него список инструментов, регистрирует каждый как свой, а вызовы отправляет на /mcp того же origin с сессией посетителя. То есть агент работает с вашим бэкендом под правами залогиненного пользователя. Пока это developer preview с двумя наборами инструментов, и всё исполняется в браузере посетителя. Прежде чем щёлкать тумблер, пройдитесь по списку инструментов: агенту станет доступно ровно то, что в нём объявлено, поэтому всё меняющее состояние, от оформления заказа до правки профиля, либо не выкладывайте, либо оставляйте за подтверждением пользователя. #mcp
В гриде и флексбоксе наконец заработали нативные разделители между элементами Линию между колонками мы до сих пор рисуем обходным путём: вешаем бордер на соседний элемент или заводим псевдоэлемент, а потом правим это на переносах строк и по краям сетки. Со 149-й версии Chrome и Edge задача закрывается штатно: свойство column-rule, работавшее раньше только в многоколоночной вёрстке, теперь понимают grid и flexbox, а для второй оси появилось row-rule. Firefox и Safari фичу пока не умеют. Разработчик из команды Edge рассказывает, что поменялось в фиче с раннего превью: — почему outset переименовали в inset; — зачем понадобились отдельные свойства для концов и пересечений линий; — как gap-rule-paint-order стал rule-overlap; — для чего появилось rule-visibility-items. Полифил для отставших браузеров только пишут. Значит, включать фичу можно там, где линии остаются украшением: без поддержки просто ничего не нарисуется, и вёрстка не поедет. А если без разделителей блоки визуально слипаются, придётся ждать полифила или Safari. #css
Карьерный потолок не щадит никого: время идёт, таски закрываются, приходит скука и предел. Можно ли вырваться из «Матрицы»? https://tproger.ru/articles/zhizn-posle-senora-kak-ya-haknul-matricu
Ваш сайт может обслуживать ИИ-агентов напрямую, не заставляя их кликать по вёрстке Агенты уже ходят по вашим страницам и работают с ними как человек: ищут нужную кнопку, разбираются в модалке, заполняют форму и ошибаются ровно там, где интерфейс неочевиден. WebMCP предлагает другой путь. Это экспериментальный стандарт, уже поехавший в Chrome 146: на странице появляется document.modelContext, сайт регистрирует через него свои инструменты, а агент вызывает их напрямую. Руками это отдельная работа: продумать набор инструментов, привязать их к интерфейсу и поддерживать, пока стандарт меняется. Cloudflare сделал из этого тумблер: их прокси дописывает в каждый HTML-ответ одну строку со скриптом-мостом, а тот регистрирует выбранные наборы инструментов. Не поддерживает браузер стандарт, мост молча завершается и страница ведёт себя как раньше. Один из наборов проксирует ваш собственный MCP-сервер: мост спрашивает у него список инструментов через tools/list и регистрирует каждый как свой. Когда агент такой инструмент вызывает, мост идёт на /mcp того же origin с сессией посетителя. То есть агент работает с вашим бэкендом под правами залогиненного пользователя. Пока это developer preview с двумя наборами инструментов, и всё исполняется в браузере посетителя. Прежде чем щёлкать тумблер, пройдитесь по tools/list: агенту станет доступно ровно то, что там объявлено, поэтому всё меняющее состояние, от оформления заказа до правки профиля, либо не выкладывайте, либо оставляйте за подтверждением пользователя. #mcp
Плавные переходы могут сломать интерактивность вашего сайта, но этого легко избежать Представьте, вы завернули в плавный переход сортировку таблицы, открытие картинки на весь экран или перестановку карточек в списке — всё то, ради чего и берут startViewTransition(). Пока анимация идёт, пользователь жмёт кнопку в другом углу экрана, и ничего не происходит. Он жмёт ещё раз, но ничего не происходит. Дело не в вашем коде. На время перехода браузер кладёт поверх страницы псевдоэлемент ::view-transition размером во весь вьюпорт, и клики достаются ему. Разобрал это Крис Койер, придумавший CSS-Tricks и CodePen: в его демке рядом с анимацией стоит кнопка с alert(), и пока идёт переход, она не отвечает. Проверить у себя просто: растяните длительность перехода секунд до десяти и откройте в DevTools дерево псевдоэлементов. Наведите курсор на ::view-transition — подсветится весь экран. К счастью, лечится проблема всего в две строки. Снимаем у :root дефолтный view-transition-name, чтобы корень не попадал в снимок, и разрешаем кликать сквозь оверлей: :root { view-transition-name: none; } ::view-transition { pointer-events: none; } Альтернатива — вызывать startViewTransition() не на document, а на контейнере с нужными элементами: тогда и оверлей накроет только его. Но поддержка у этого варианта хуже, так что по умолчанию проще держать две строки выше. #css
60–90 КБ в вашем бандле браузер уже умеет сам К package.json мы обычно ходим с вопросами про уязвимости и версии, но редко с вопросом, делает ли библиотека что-то, чего платформа ещё не умеет. Разбор в Smashing Magazine оценивает цену этой привычки: в среднем приложении 60–90 КБ после минификации и сжатия весят зависимости, которые дублируют то, что браузер уже умеет сам. Самый жирный кусок — форматирование. timeago.js на 1 КБ заменяется на Intl.RelativeTimeFormat, numeral на 3,9 КБ — на Intl.NumberFormat, humanize-duration на 6,6 КБ — на Intl.DurationFormat. Самописные функции, склеивающие массив в строку через запятую, закрывает Intl.ListFormat, вместе с оксфордской запятой. Отдельно разобран случай, когда менять не надо вовсе. Temporal лучше Date, но в стабильном Safari его пока нет, а официальный полифил весит 44 КБ против 3 КБ у dayjs. Сегодня такая замена не экономит, а добавляет к бандлу около 41 КБ, поэтому dayjs остаётся на месте до тех пор, пока Temporal не доедет до Safari. Рекомендую перепроверять зависимости раз в квартал, за это время как раз может выйти полезное обновление. Смотреть статус фич можно на webstatus.dev, значок Baseline есть на каждой странице MDN, а для проверки пачкой в сборке ставится пакет web-features. #javascript
Чему учиться взрослому профессионалу? Свою работу трудно оценить со стороны. Каждый день смотришь на неё одинаково и не замечаешь того же, чего не замечал вчера. Тут выручают чужие модели: короткая формулировка переворачивает привычную картину, и становится понятно, чего не хватало. Кажется, что хороший результат говорит сам за себя. Но код, о котором никто не узнал, карьеру не двигает. Кажется, что учится тот, кто проходит курс. А по-настоящему разбирается тот, кто объясняет материал другому. В новом материале на Tproger собрали семь таких моделей. Они помогают увидеть свою работу как систему и понять, куда двигаться дальше. https://tproger.ru/articles/kak-ponyat-chemu-uchitsya-vzroslomu-7-modelej-dlya-professionaln
CSS в письме умеет кликать за пользователя, и это самый безобидный приём в списке Гарет Хейс когда-то разобрал песочницу AngularJS. Последние месяцы он ломал почтовые клиенты: Gmail, Outlook, Fastmail, ProtonMail, Yahoo. Всё, что ниже, проходит через санитайзеры как безопасная разметка. Начинается скромно. Тег label, у которого в for стоит чужой id, отдаёт клик по элементу, до которого у письма доступа быть не должно. В Outlook так открывается лента интерфейса и закрепляется сообщение. Не починено до сих пор. Рядом лежат обходы прокси картинок, из-за которых отправитель видит, что письмо открыли, и его IP на экране в ProtonMail. Дальше становится ещё интереснее. Связка ::before, ::after и opacity разводит то, что видит человек, и то, что читает ИИ-браузер: письмо превращается в промпт-инъекцию. А вишенкой на торте в статье лежат кража токенов при CSP, который блокирует вообще все внешние ресурсы, и кража паролей. Я сохранил статью себе, хотя почтовых клиентов не пишу: разрыв между тем, что пропустил санитайзер, и тем, что отрисовал браузер, живёт везде, где вы принимаете чужой HTML. В комментариях, описаниях профилей, предпросмотрах ссылок. Запрещать label при этом не нужно, режьте у него for: опасна не подпись, а привязка к чужому id. Совет автора даже шире — отдавать чужую разметку в iframe с sandbox. И не пускайте в белый список :has, :checked, :focus и :not: на них собирают поддельные элементы интерфейса. #css #html #фронтенд #безопасность
Наверное, в каждом втором резюме среди навыков есть «системное мышление». С ним не рождаются, ему учатся в процессе работы, с накоплением опыта. Оно помогает видеть картину целиком и структурировать всё, что вы делаете. Сейчас у этого навыка появилось новое применение: с появлением ИИ-агентов умение поставить задачу и проверить результат стало ещё важнее. И ему можно научиться. Какие ошибки часто совершают разработчики, стараясь мыслить системно, и что с этим можно сделать, читайте в статье: https://tproger.ru/articles/sistemnoe-mywlenie-dlya-razrabotchika-owibki-kotorye-vy-delaete
Cloudflare решила, что агентам не нужен Chromium, и за 12 недель написала свой браузер Браузеры написаны для людей, а ходят в них теперь агенты, и платить за человеческую часть приходится памятью и процессорным временем. Агенту не нужны вкладки, темы, расширения и синхронизация между устройствами — ему нужны структурированный контент, размер контекста и цена запроса. Если CSS распарсился слегка неточно, модель это переживёт. Зато prompt injection для неё станет проблемой. Так появился Kitesurf. Он не запускает Chromium на отдельной машине, а работает прямо в Cloudflare Workers — там же, где крутятся обычные serverless-функции клиентов. Отсюда и вся экономика: поднять браузер на каждого агента перестаёт быть роскошью. Сам движок написан на Rust и скомпилирован в WebAssembly. Два решения в нём продиктованы именно тем, что за рулём не человек: 1. У сессий нет ничего общего. Агента задача отправляет куда угодно, поэтому каждая страница здесь считается чужим кодом, а каждая сессия начинается пустой — от предыдущей не остаётся ни данных, ни следов. 2. Браузеру нельзя падать. Если разметка кривая или скрипт сломался, страница теряет один элемент или отдаёт пустой кадр, но сессия живёт дальше. Человек в такой ситуации просто нажмёт F5, а у агента на середине задачи перезагрузка означает потерю всего, что он успел сделать. Но самое интересное — не сам браузер, а как его писали. Основную работу делали ИИ-агенты, и чтобы вместо браузера не получился правдоподобный мусор, им нужен был судья. Такой судья у веба есть: общий набор тестов, которым все браузеры проверяют себя на соответствие стандартам. Тысячи проверок, каждая отвечает «прошёл» или «не прошёл», и обсуждать там нечего. Люди же просто решали, какие фичи и в каком порядке отдавать агентам, и занимались архитектурой. А чтобы браузер нормально читал реальные сайты с их кривой разметкой, добавили второй этап. Один и тот же сценарий кликов прогоняли одновременно в Chromium и Kitesurf и проверяли, видит ли агент страницу такой же, какой её видит человек. Kitesurf сейчас бесплатен в бете внутри Browser Run. Подробный разбор устройства движка с архитектурой рендерера и тем, как гоняли агентов по тестам, можно прочитать в блоге компании. #браузеры #ии
Как измерить Core Web Vitals в SPA, где переходы не перезагружают страницу Классическая беда одностраничников: роутер меняет содержимое, а для браузера это всё та же первая загрузка. LCP, CLS и INP посчитаны один раз при входе, дальнейшие переходы не мерит никто. Отсюда и метрики, в которые никто в команде не верит. С Chrome 151 Soft Navigations работает без флага. Проверка поддержки и подписка выглядят так: ```if (PerformanceObserver.supportedEntryTypes.includes('soft-navigation')) { new PerformanceObserver(console.log) .observe({ type: 'soft-navigation', buffered: true }); }``` Дальше логика простая. В каждой записи есть name — URL, к которому относится новый экран, и navigationId — уникальный идентификатор перехода, потому что один и тот же URL за жизнь приложения можно открыть десять раз. Получили запись — финализируйте метрики предыдущего экрана, отправьте их под старым URL и начинайте копить заново. LCP для мягкой навигации приходит через interaction-contentful-paint, а у самой записи soft-navigation есть getLargestInteractionContentfulPaint() — он вернёт крупнейший такой пейнт, чтобы не буферизовать записи вручную. Главное — не сравнивайте новые цифры со старыми напрямую. Они почти наверняка окажутся хуже, но не потому, что вы что-то сломали: эти переходы просто впервые попали под замер. Соберите пару недель параллельно и только потом делайте выводы. https://developer.chrome.com/docs/web-platform/soft-navigations #перформанс #spa
Тултип, который сам перепрыгивает вниз, когда не влезает сверху Позиционирование поповеров годами было задачей для JS: посчитать координаты кнопки, прибавить размеры тултипа, проверить, не вылез ли он за вьюпорт, пересчитать всё это на скролле и ресайзе. Ровно ради этого в проект приходили Floating UI и Popper.js. Теперь то же самое умеет CSS: .btn { anchor-name: --btn; } .tooltip { position: absolute; position-anchor: --btn; position-area: block-start center; position-try-fallbacks: flip-block; } Последняя строка — самое интересное. Это та самая логика «не влезло сверху, покажем снизу», за которую раньше платили килобайтами зависимости. Браузер сам проверяет доступное место и применяет запасной вариант. Anchor positioning в Baseline и работает во всех четырёх движках. В State of CSS 2026 разработчики назвали её лучшей новой фичей года. Но там много и другой полезной информации: https://2026.stateofcss.com/en-US #css #лайфхак