<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
  <channel>
    <language>ru</language>
    <title>Фронтенд</title>
    <description/>
    <link>https://tproger.ru/tag/frontend</link>
    <atom:link href="https://tproger.ru/tag/frontend/feed" rel="self" type="application/rss+xml"/>
    <lastBuildDate>Sat, 03 Oct 2026 13:03:50 GMT</lastBuildDate>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>12</sy:updateFrequency>
    <image>
      <title>Фронтенд</title>
      <link>https://tproger.ru</link>
      <url>https://tproger.ru/apple-touch-icon.png</url>
    </image>
    <item>
      <title>Оптимизация изображений для веба: где теряются мегабайты</title>
      <link>https://tproger.ru/articles/optimizaciya-kartinok-dlya-veba-gde-teryayutsya-megabajty-i-kak-ih-v</link>
      <comments>https://tproger.ru/articles/optimizaciya-kartinok-dlya-veba-gde-teryayutsya-megabajty-i-kak-ih-v?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Tproger]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/optimizaciya-kartinok-dlya-veba-gde-teryayutsya-megabajty-i-kak-ih-v</guid>
      <description><![CDATA[<p>Оптимизация изображений для веба: размер в пикселях, формат под тип картинки, AVIF против WebP и сжатие в браузере. Проверьте свои картинки по чеклисту.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/optimizaciya-kartinok-dlya-veba-gde-teryayutsya-megabajty-i-kak-ih-v">Оптимизация изображений для веба: где теряются мегабайты</a>»</p>]]></description>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Оптимизация]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Алгоритмы сжатия]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 07 Sep 2026 09:00:41 GMT</pubDate>
      <content:encoded><![CDATA[<p>Картинки обычно оказываются самой тяжёлой частью страницы, и почти всегда они тяжелее, чем нужно. Скриншот интерфейса на 2,1 МБ ужимается до 102 КБ без заметной глазу разницы, а фотография на 4,7 МБ теряет три четверти веса ещё до того, как вы дотронетесь до качества сжатия.</p><p>Разница между четырёхсекундной загрузкой и загрузкой меньше секунды обычно лежит именно здесь, а не в бандле скриптов. Ниже пошаговая оптимизация изображений: что делать первым, какой формат выбирать под какой тип картинки и почему кодировать современные форматы нужно на сборке, а не на лету.</p><p>Первым делом уменьшайте размер в пикселях, а не качество: фотография 6000×4000 в карточке шириной 1200 пикселей это чистые потери. Один этот шаг убрал 77% веса тестового снимка.</p><p>Формат выбирается под тип картинки: фотографиям WebP или AVIF, скриншотам и интерфейсам сжатие без потерь, логотипам SVG, анимациям анимированный WebP вместо GIF.</p><p>AVIF при равном качестве весит вдвое меньше JPEG, но кодируется примерно в пятнадцать раз дольше, поэтому генерировать его нужно на этапе сборки.</p><p>Метаданные съёмки занимают от 10 до 30 КБ на файл и в вебе не нужны ни для чего.</p><p>Сжатие с потерями на тексте и резких границах даёт видимые артефакты: скриншоты и логотипы жмутся только без потерь, зато на 20–60%.</p><h2>Шаг, который экономит больше всех остальных</h2><p>Прежде чем подбирать кодек и качество, посмотрите на фактические размеры. Фотография 6000×4000 в карточке шириной 1200 CSS-пикселей отдаёт браузеру в двадцать пять раз больше пикселей, чем нужно обычному экрану, и вшестеро больше, чем нужно экрану с двойной плотностью.</p><p>В замерах автора чеклиста <a href="https://dev.to/_544bf5cbd223c35a49756/image-optimization-the-complete-2026-checklist-for-faster-websites-3pi5">одно только уменьшение до реально отображаемого размера ужало тестовое изображение с 4,7 МБ до 1,1 МБ</a>. Это минус 77% при нулевой потере качества: пиксели, которых не видно, просто перестали передаваться.</p><p><b>Как определить нужный размер:</b><br />Отправная точка это ширина контейнера в CSS-пикселях. На обычном экране она же и есть нужная ширина в физических пикселях, на плотных экранах нужно кратно больше: у части ноутбуков это двойка, у большинства современных смартфонов тройка. Поэтому правильный инструмент здесь не фиксированный множитель, а атрибут srcset с несколькими вариантами файла: браузер сам возьмёт тот, что соответствует плотности экрана посетителя.</p><h2>Формат под тип изображения, а не один на всё</h2><p>Самая частая ошибка — выбрать один формат и применять его ко всему подряд. Между фотографией с плавными градиентами и скриншотом с текстом и резкими границами разница принципиальная, и сжимаются они противоположными способами.</p><ul><li>Фотографии — WebP (на 30–50% меньше JPEG) или AVIF (ещё примерно на 30% меньше WebP).</li><li>Скриншоты и элементы интерфейса — PNG или WebP без потерь.</li><li>Логотипы и иконки — SVG: вектор весит копейки и масштабируется без предела.</li><li>Анимации — анимированный WebP вместо GIF, это экономит 60–80% веса.</li></ul><p>Отдельно про текст. Сжатие с потерями на буквах и резких границах создаёт заметные ореолы вокруг символов, поэтому скриншоты и логотипы обрабатываются только алгоритмами без потерь. Инструменты вроде oxipng ужимают такие файлы на 20–60%, не меняя при этом ни одного пикселя.</p><h3>Конвертация и сжатие — это два разных действия</h3><p>Перевод PNG в JPEG экономит место. Сжатие получившегося JPEG экономит ещё столько же, и про этот второй проход регулярно забывают. Для фотографий рабочий диапазон качества это 75–82%: от стопроцентного такая картинка визуально неотличима, а весит заметно меньше.</p><h3>Метаданные, которые вы отдаёте бесплатно</h3><p>В файле с камеры или из редактора лежат EXIF, координаты GPS, модель камеры и метки программы обработки. Для показа в браузере это бесполезный груз весом от 10 до 30 КБ на файл, за одним исключением: тег ориентации. Часть снимков с телефона хранит пиксели неповёрнутыми и полагается на него, поэтому поворот нужно применить к самим пикселям до того, как метаданные срежутся, иначе фотографии лягут набок. На каталоге из тысячи товарных снимков набегает до 30 МБ трафика ни за что, а координаты съёмки вдобавок могут оказаться данными, которые вы не собирались публиковать.</p><h2>AVIF: что это и почему его нельзя кодировать на лету</h2><p>AVIF (AV1 Image File Format) выпущен Alliance for Open Media в 2019 году и построен на внутрикадровом кодировании видеокодека AV1. По сути это инструменты сжатия одного кадра AV1, упакованные в самостоятельный контейнер для картинок.</p><p>Перед WebP у него два практических преимущества: выше степень сжатия при равном качестве и глубина цвета до 12 бит с поддержкой расширенного динамического диапазона, тогда как WebP ограничен восемью битами и обычным диапазоном. Достигается это за счёт заметно более богатого набора инструментов предсказания, унаследованного от видеокодека.</p><h3>Сколько это в килобайтах</h3><p>В сравнительном тесте <a href="https://dev.to/uglypeardata/avif-format-guide-the-next-generation-image-compression-std-4oa5">брали пейзажный кадр 1920×1080 с градиентами неба, текстурой листвы и границами зданий, исходник в BMP весил 5,93 МБ</a>. Целевое качество задавали по метрике структурного сходства: она сравнивает сжатую картинку с исходной, где единица означает полное совпадение, а 0,92 примерно соответствует порогу, за которым разницу перестают замечать глазом. Результаты:</p><p>На листве и градиентах неба разница видна и глазом: JPEG на низком битрейте показывает цветовые блоки, у AVIF артефактов практически нет. Отвечают за это многоуровневые фильтры внутри цикла кодирования, которые заглаживают границы блоков и восстанавливают детали текстур.</p><p>Плата за это — время. Кодирование AVIF примерно в пятнадцать раз дольше JPEG и вчетверо дольше WebP, потому что выбор разбиения и типа преобразования требует перебора с оптимизацией. Зато декодирование медленнее JPEG всего вдвое, и на просмотр это почти не влияет. Практический вывод прямой: генерируйте AVIF заранее, на этапе сборки. Сервисы доставки изображений кодируют его и по запросу, но только с кешированием результата, чтобы платить за кодирование один раз на вариант, а не на каждого посетителя. Чего делать нельзя, так это кодировать заново при каждом обращении.</p><h3>Как отдавать современный формат и не потерять старые браузеры</h3><p>Поддержка AVIF в браузерах составляет примерно 96%, но подстраховка всё равно нужна. Делается она тегом &lt;picture&gt;: браузер берёт первый формат, который понимает, и до остальных не доходит.</p><p>Атрибуты width и height здесь не декоративные: без них браузер не знает пропорций до загрузки файла и подвёрстывает страницу заново, когда картинка приходит. Это тот самый прыжок содержимого, который портит метрику визуальной стабильности. Атрибут loading=lazy убирает изображения за пределами первого экрана из очереди, конкурирующей за отрисовку главного элемента.</p><p>Именно за пределами: на картинку первого экрана его ставить нельзя. Отложенная загрузка задержит ровно тот элемент, скорость появления которого и меряет метрика отрисовки основного содержимого. Там уместен противоположный по смыслу fetchpriority=high.</p><h2>Сжатие в браузере: почему это вообще возможно</h2><p>Браузер умеет декодировать, преобразовывать и кодировать изображение прямо на устройстве, не отправляя файл никуда. Для товарных снимков, клиентских материалов и прочего чувствительного это снимает целый шаг из конвейера вместе с вопросом, где полежит копия.</p><p>Речь здесь уже не про ассеты вашего сайта, которые готовятся на сборке. Речь про картинки, которые в браузер приносит сам пользователь: форма загрузки в личном кабинете, объявление на маркетплейсе, вложение в заявку. Сжать их до отправки на сервер можно прямо во вкладке, и это снимает и трафик, и вопрос о том, где полежит оригинал.</p><p>Автор одного из таких инструментов <a href="https://dev.to/_544bf5cbd223c35a49756/how-i-built-a-browser-image-compressor-that-handles-30-images-at-once-56k4">разобрал устройство своего конвейера</a>, и его опыт пригодится всем, кто выносит тяжёлые вычисления во фронтенд.</p><h3>Вся тяжёлая работа уходит из главного потока</h3><p>Перекодирование снимка 4000×4000 нагружает процессор настолько, что в главном потоке интерфейс замирает, а браузер показывает предупреждение о зависшей странице. Поэтому весь конвейер живёт в Web Worker: главный поток отвечает за выбор файлов, превью и состояние, а рабочий поток декодирует через createImageBitmap, применяет преобразования и кодирует через OffscreenCanvas. Именно через него, а не через canvas.toBlob: последний это метод DOM-элемента, а DOM в рабочем потоке отсутствует, и нужный метод там называется convertToBlob.</p><p>Важная деталь производительности: передавать данные между потоками нужно как ArrayBuffer через механизм передачи владения, а не структурным клонированием. На пачке из тридцати изображений это разница между мгновенным откликом и лишними полусекундами нагрузки на сборщик мусора для каждого файла.</p><h3>Три ошибки, которые ищутся дольше всего</h3><p><b>Рабочий поток не имеет доступа к window.</b> Причём не только напрямую: достаточно подключить библиотеку, которая трогает window на верхнем уровне модуля. В консоли разработчика появляется ошибка обращения к неопределённому объекту, а вот в интерфейсе не появляется ничего: если сбой рабочего потока никак не показан пользователю, тот видит вечный спиннер. Лечится ревизией всех импортов рабочего потока: библиотеки, завязанные на браузерное окружение, остаются в главном потоке и передают в рабочий поток уже готовые данные.</p><p><b>Округление сломало масштабирование.</b> Быстрый путь изменения размера использовал округлённый шаг по пикселям. На больших изображениях округление уводило исходную координату за пределы строки, и картинка выходила разрезанной по горизонтали с чёрной мозаикой внизу. Помогли точные дробные коэффициенты и ограничение по границам в каждом ручном проходе по пикселям.</p><p><b>Асинхронный обработчик сообщений перепутал порядок.</b> Обработчик стал ждать преобразование уже после кодирования, а асинхронные обработчики порядок не сохраняют: состояние поворота разъехалось с готовым изображением. Полностью синхронным такой обработчик не сделать, декодирование и кодирование асинхронны по своей природе. Работает другое: обрабатывать сообщения строго по одному, не начиная следующее до завершения предыдущего, и хранить состояние вроде угла поворота рядом с данными конкретного сообщения, а не в общей переменной.</p><p><b>Заголовки безопасности ломают рабочие потоки молча:</b><br />Блокирует загрузку скрипта заголовок Cross-Origin-Embedder-Policy: он требует, чтобы каждый сторонний ресурс отдавал разрешающий заголовок, иначе браузер молча его отбрасывает. Cross-Origin-Opener-Policy на это не влияет, но включают их обычно парой, поэтому и ломается всё в одном релизе. Любое изменение заголовков безопасности проверяйте на настоящем развёрнутом стенде, а не только на машине разработчика.</p><h2>Что это даёт в цифрах</h2><p>Скриншот 1920×1080 проходит такой путь: исходный PNG весит 2,1 МБ, после уменьшения и перевода в WebP с качеством 75% — 186 КБ, то есть минус 91%. Тот же кадр в AVIF занимает 102 КБ, минус 95% от исходного.</p><p>Именно эти проценты и отделяют страницу, которая грузится четыре секунды, от страницы, которая укладывается в одну.</p><h2>Что забрать с собой</h2><p>Порядок действий важнее набора инструментов. Сначала пиксели, потом формат под тип изображения, потом второй проход сжатия, и только затем разговор про кодеки нового поколения. Обратный порядок даёт красивую строчку в отчёте и почти никакого эффекта на реальной странице.</p><p>Материалы разбора: <a href="https://dev.to/_544bf5cbd223c35a49756/image-optimization-the-complete-2026-checklist-for-faster-websites-3pi5">чеклист оптимизации с замерами</a>, <a href="https://dev.to/uglypeardata/avif-format-guide-the-next-generation-image-compression-std-4oa5">техническое устройство AVIF и сравнительный тест форматов</a> и <a href="https://dev.to/_544bf5cbd223c35a49756/how-i-built-a-browser-image-compressor-that-handles-30-images-at-once-56k4">разбор браузерного конвейера сжатия</a>.</p><p>Откройте свою главную страницу с открытой панелью сети и отсортируйте запросы по размеру. Первые три строки почти наверняка окажутся картинками, и это ваша ближайшая оптимизация изображений: уменьшить их вдвое реально за один вечер.</p>]]></content:encoded>
    </item>
    <item>
      <title>CSS-функции sibling-index() и sibling-count() заработали во всех движках</title>
      <link>https://tproger.ru/news/css-funkcii-sibling-index-i-sibling-count-zarabotali-vo-vseh</link>
      <comments>https://tproger.ru/news/css-funkcii-sibling-index-i-sibling-count-zarabotali-vo-vseh?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Tproger]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/css-funkcii-sibling-index-i-sibling-count-zarabotali-vo-vseh</guid>
      <description><![CDATA[<p>С Firefox 154 функции sibling-index() и sibling-count() есть во всех трёх движках. Как задать задержку анимации по номеру элемента без JS и где они вернут 0.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/css-funkcii-sibling-index-i-sibling-count-zarabotali-vo-vseh">CSS-функции sibling-index() и sibling-count() заработали во всех движках</a>»</p>]]></description>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[CSS]]></category>
      <category><![CDATA[Браузеры]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 03 Sep 2026 08:40:06 GMT</pubDate>
      <content:encoded><![CDATA[<p>Функции sibling-index() и sibling-count() стали доступны во всех трёх основных браузерных движках: последним 18 августа их <a href="https://web-platform-dx.github.io/web-features-explorer/features/sibling-count/">поддержал</a> Firefox 154, а 2 сентября разработчики <a href="https://www.reddit.com/r/css/comments/1w52o07/siblingindex_and_siblingcount_the_css_functions/">разобрали</a> в r/css, что это меняет. Функции возвращают номер элемента среди соседей и общее число детей у родителя, и оба значения можно использовать в calc().</p><p>Практический смысл простой: то, что раньше делали через --i в инлайн-стиле каждого элемента или через JavaScript, теперь считает сам браузер. Ступенчатые задержки анимации в списке, ширина колонок по числу карточек, позиционирование по индексу без нумерации в разметке. По данным Web Platform DX, функции получили статус «newly available» с 18 августа 2026 года; статус «widely available» по правилам Baseline ожидается 18 февраля 2029 года, то есть старые браузеры ещё долго будут требовать запасного варианта.</p><ul><li>sibling-index() возвращает позицию элемента среди соседей, начиная с 1; sibling-count() возвращает число прямых детей родителя, включая текущий.</li><li>Поддержка: Chrome и Edge 138 (июнь 2025), Safari 26.2 (декабрь 2025), Firefox 154 (18 августа 2026).</li><li>Функции считают по дереву DOM, а не по flat tree; при попытке пересечь границу Shadow DOM результат может быть 0.</li><li>Типичные применения: transition-delay и animation-delay по номеру, размер элемента в зависимости от числа соседей, раскладка без JavaScript.</li><li>CSSWG допускает будущую форму с фильтром of, чтобы считать только соседей по селектору.</li></ul><h2>Как это выглядит в коде</h2><p>Классический пример из обсуждения: список, где каждый следующий пункт появляется чуть позже предыдущего. Раньше для этого либо писали style="--i: 3" в каждом li, либо перечисляли :nth-child() вручную. Теперь достаточно одного правила:</p><p>Обе функции возвращают целое число без единиц, поэтому умножение на 80ms или на 100px внутри calc() работает как с обычной переменной. В спецификации CSS Values and Units Level 5 их называют tree-counting functions, функциями подсчёта по дереву.</p><h2>Где функции ведут себя не так, как ожидается</h2><ul><li>Считается дерево DOM, а не flat tree: слоты и элементы внутри Shadow DOM учитываются иначе, чем при рендеринге; на границе теневого дерева функция может вернуть 0, чтобы не раскрывать его содержимое.</li><li>Учитываются все элементы-соседи, а не только подходящие под селектор. Если в списке есть скрытый li, он всё равно попадёт в счёт; форма с фильтром of пока только обсуждается в CSSWG.</li><li>Индексация начинается с 1, как у :nth-child(), а не с 0.</li></ul><h2>Можно ли использовать в проде</h2><p>Для декоративных эффектов вроде задержек анимации можно уже сейчас: в браузере без поддержки calc(sibling-index() * 80ms) будет невалидным значением, и правило просто не применится, элементы появятся одновременно. Для раскладки, от которой зависит читаемость, стоит завернуть правило в @supports:</p><p>Кому это ничего не даст: проектам, которые обязаны поддерживать браузеры старше Chrome 138 и Safari 26.2, а также тем, кто уже генерирует индексы на сервере. По данным Web Platform DX, Chrome и Chrome Android получили функции в версии 138 от 24 июня 2025 года, Edge 138 от 26 июня 2025 года, Safari и iOS Safari в 26.2 от 12 декабря 2025 года, Firefox и Firefox Android в 154 от 18 августа 2026 года.</p><p>Из соседних CSS-новостей на сайте: Firefox 155 <a href="https://tproger.ru/news/firefox-dlya-ios-poluchil-vstroennyj-blokirovshhik-reklamy-a-firefo">добавил</a> функцию progress(), а в Chrome 154 beta появились режимы links и tabs у scroll-marker-group. Черновик спецификации с формальным описанием функций лежит на <a href="https://drafts.csswg.org/css-values-5/">сайте CSSWG</a>.</p><p>Источники: <a href="https://www.reddit.com/r/css/comments/1w52o07/siblingindex_and_siblingcount_the_css_functions/">Обсуждение в r/css</a>, <a href="https://web-platform-dx.github.io/web-features-explorer/features/sibling-count/">Web Platform DX: sibling-count и sibling-index</a>, <a href="https://drafts.csswg.org/css-values-5/">CSS Values and Units Module Level 5</a></p>]]></content:encoded>
    </item>
    <item>
      <title>WebLLM запускает языковую модель в браузере без сервера за один вечер</title>
      <link>https://tproger.ru/articles/webllm-zapuskaet-yazykovuyu-model-v-brauzere-bez-servera-za-odin</link>
      <comments>https://tproger.ru/articles/webllm-zapuskaet-yazykovuyu-model-v-brauzere-bez-servera-za-odin?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Tproger]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/webllm-zapuskaet-yazykovuyu-model-v-brauzere-bez-servera-za-odin</guid>
      <description><![CDATA[<p>Разбор WebLLM 0.2.84: установка, код чата со стримингом, видеопамять для 9 моделей от 0,7 до 6,4 ГБ, 71–80% нативной скорости и поддержка WebGPU в браузерах.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/webllm-zapuskaet-yazykovuyu-model-v-brauzere-bez-servera-za-odin">WebLLM запускает языковую модель в браузере без сервера за один вечер</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Open Source]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Браузеры]]></category>
      <category><![CDATA[WebAssembly]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 03 Sep 2026 06:49:32 GMT</pubDate>
      <content:encoded><![CDATA[<p><a href="https://github.com/mlc-ai/web-llm">WebLLM</a> — открытый движок команды MLC AI, который выполняет языковую модель внутри браузера на WebGPU и отдаёт её через API в стиле OpenAI. Сервера для инференса нет: веса скачиваются один раз, дальше промпты и ответы не покидают вкладку. Проект живёт с 2023 года, но 2 сентября 2026 года <a href="https://news.ycombinator.com/item?id=49536411">снова поднялся</a> на первую страницу Hacker News с 92 очками, а на GitHub у него 18 846 звёзд и 1 372 форка по данным API на 3 сентября.</p><p>Я разбираю WebLLM как рабочий инструмент: что нужно от железа и браузера, сколько весят модели, какой скоростью придётся заплатить за отказ от сервера и где проще остаться на облачном API. Все команды и фрагменты кода взяты из README репозитория, цифры производительности из статьи авторов на arXiv, требования к видеопамяти из файла конфигурации в исходниках.</p><p>Материал для фронтенд- и фулстек-разработчиков, которым нужен чат, классификатор или JSON-извлекатель на клиенте без счёта за токены и без передачи пользовательских данных третьей стороне.</p><ul><li>WebLLM выполняет модель в браузере на WebGPU, без сервера; API совместим с OpenAI Chat Completions: стриминг, JSON-режим, seed. Вызов функций помечен в README как незавершённый.</li><li>Актуальная версия пакета @mlc-ai/web-llm — 0.2.84 от 27 мая 2026 года; в 2025–2026 годах вышло всего 7 релизов против 63 за 2024 год по данным реестра npm.</li><li>По замерам авторов на MacBook Pro M3 Max WebLLM выдаёт 41,1 токена/с на Llama-3.1-8B и 71,1 токена/с на Phi-3.5-mini, то есть 71–80% от нативного MLC-LLM на том же железе.</li><li>Модели в 4-битной квантизации требуют от 0,7 ГБ видеопамяти (gemma3-1b) до 6,4 ГБ (Qwen3.5-9B) по значениям vram_required_MB в src/config.ts; первый запуск качает всё это с huggingface.co.</li><li>WebGPU по данным MDN есть в Chrome и Edge с версии 113, в Safari 26 с сентября 2025 года, в Firefox с 141 только частично: Linux и Intel-маки не поддерживаются.</li></ul><h2>Как WebLLM выполняет модель в браузере и при чём тут WebGPU?</h2><p>Модель считается на видеокарте пользователя через WebGPU, а всё, что не ложится на GPU, крутится в WebAssembly. Авторы <a href="https://arxiv.org/abs/2412.15803">описывают</a> схему так: родственный проект MLC LLM компилирует открытую модель заранее в два артефакта, конвертированные веса и WASM-библиотеку с WebGPU-ядрами и вспомогательными функциями. WebLLM в браузере загружает оба артефакта с хостинга, инициализирует WebGPU-устройство и дальше исполняет граф вычислений локально.</p><blockquote>Everything runs inside the browser with no server support and is accelerated with WebGPU.</blockquote><p>Отсюда же и главное ограничение, о котором в статье авторы говорят прямо: в отличие от CUDA у WebGPU нет готовых ускоренных библиотек для типовых ядер, поэтому матричные умножения и внимание команде пришлось писать и оптимизировать самой. Цена этого видна в замерах: на Apple MacBook Pro M3 Max в Chrome Canary 133 WebLLM версии 0.2.75 выдавал 41,1 токена/с на 4-битной Llama-3.1-8B против 57,7 у нативного MLC-LLM с Metal-ядрами на той же машине, и 71,1 против 89,3 токена/с на Phi-3.5-mini. Это 71,2% и 79,6% нативной скорости соответственно, замер вендора, другого железа в статье нет.</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-09-03/faf6a5ef-05f1-4c84-a5b3-0de9ac78a2a2.webp" alt="Столбчатая диаграмма: скорость декодирования WebLLM и MLC-LLM в токенах в секунду на Llama-3.1-8B (41,1 против 57,7) и Phi-3.5-mini (71,1 против 89,3)" /><figcaption>Скорость декодирования в браузере и нативно на одном MacBook Pro M3 Max, 4-битная квантизация. График: Tproger по данным статьи авторов WebLLM на arXiv 2412.15803</figcaption></figure><p>Второй компонент, о котором обычно забывают, это кэш. Веса и WASM-библиотека скачиваются при первом обращении и складываются в хранилище браузера. README перечисляет четыре бэкенда, которые задаются полем cacheBackend в AppConfig: Cache API по умолчанию, IndexedDB, Origin Private File System и экспериментальный cross-origin через расширение Chrome, чтобы одни и те же веса не качались заново для каждого сайта. Без расширения движок сам откатывается на Cache API.</p><p>JSON-режим, который в серверных API обычно реализован на стороне провайдера, здесь тоже выполняется локально: по README структурированная генерация встроена в WebAssembly-часть библиотеки модели, а попробовать её со своей JSON-схемой можно в <a href="https://huggingface.co/spaces/mlc-ai/WebLLM-JSON-Playground">JSON Playground</a> на Hugging Face. Про то, как WASM-рантаймы догоняют нативный код, мы писали в заметке про <a href="https://tproger.ru/news/wasmi-2-0-uskoril-interpretaciyu-webassembly-v-2-2-raza">Wasmi 2.0</a>.</p><h2>Что нужно, чтобы запустить первый чат?</h2><p>Достаточно npm-пакета, одного вызова фабрики и терпения на первую загрузку весов. README даёт три варианта установки и импорт через CDN для JSFiddle и CodePen без сборщика.</p><p>Движок создаётся функцией CreateMLCEngine: это асинхронная фабрика: она возвращает Promise, а готовый движок с загруженной моделью получают через await. Колбэк прогресса обязателен на практике, потому что без него пользователь смотрит на пустой экран, пока качаются гигабайты.</p><blockquote>loading models requires downloading and it can take a significant amount of time for the very first run without caching previously</blockquote><p>Дальше интерфейс тот же, что у клиента OpenAI: engine.chat.completions.create({ messages }). Одна ловушка: параметр model в запросе игнорируется, модель выбирается при создании движка или через engine.reload(model). Стриминг включается флагом stream: true, а статистика по токенам приходит только в последнем чанке, если попросить её через stream_options.</p><p>Готовый чат для проверки железа не нужно собирать самому: <a href="https://chat.webllm.ai/">WebLLM Chat</a> сделан на том же пакете, а его код открыт в отдельном репозитории.</p><h2>Какие модели доступны и сколько видеопамяти им нужно?</h2><p>В список prebuiltAppConfig.model_list в <a href="https://github.com/mlc-ai/web-llm/blob/main/src/config.ts">src/config.ts</a> на 3 сентября входят 165 записей: это варианты квантизации и длины контекста для семейств Llama 3.x, Qwen 2.5, Qwen 3 и Qwen 3.5, Phi 3.5 и Phi 4 mini, Gemma 2 и Gemma 3, Mistral и Ministral 3, дистилляты DeepSeek-R1, SmolLM2, OLMo 2, а также две модели эмбеддингов snowflake-arctic-embed. README при этом всё ещё перечисляет старый набор с Llama 2 и Qwen2, так что актуальный набор виден только в коде.</p><p>У каждой записи есть поле vram_required_MB, и это честнее любого «весит N гигабайт»: оно включает не только веса, но и память под KV-кэш при заданном контексте. Для 4-битных вариантов с половинной точностью (суффикс q4f16_1) разброс такой:</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-09-03/dd4f8b13-a996-4064-b90b-4c012e309271.webp" alt="Горизонтальная диаграмма: требуемая видеопамять в гигабайтах для девяти моделей WebLLM от 0,7 ГБ у gemma3-1b до 6,4 ГБ у Qwen3.5-9B" /><figcaption>Значение vram_required_MB для вариантов q4f16_1 с контекстом по умолчанию. График: Tproger по данным src/config.ts репозитория mlc-ai/web-llm, 3 сентября 2026</figcaption></figure><ul><li>gemma3-1b-it — 0,71 ГБ; Llama-3.2-1B-Instruct — 0,88 ГБ; Qwen2.5-0.5B-Instruct — 0,94 ГБ. Помечены флагом low_resource_required, это кандидаты для встроенной графики и ноутбуков.</li><li>Qwen3-0.6B — 1,40 ГБ; gemma-2-2b-it — 1,90 ГБ; Llama-3.2-3B-Instruct — 2,26 ГБ.</li><li>Qwen3-4B — 3,43 ГБ; Phi-3.5-mini-instruct — 3,67 ГБ; Llama-3.1-8B-Instruct — 5,00 ГБ; Qwen3-8B — 5,70 ГБ; Qwen3.5-9B — 6,43 ГБ.</li><li>Есть и Llama-3.1-70B-Instruct в 3-битной квантизации с требованием 31,15 ГБ; на потребительской видеокарте это не запустится.</li></ul><p>Варианты с суффиксом «-1k» урезают контекст до одной тысячи токенов и экономят память: у Llama-3.1-8B это 4,60 ГБ вместо 5,00, у Phi-3.5-mini 2,52 ГБ вместо 3,67. Все эти гигабайты приезжают с <a href="https://huggingface.co/mlc-ai">huggingface.co/mlc-ai</a>, поэтому доступность и скорость этого хоста в вашей сети стоит проверить до того, как обещать пользователям «работает без сервера». Свою модель в формате MLC подключают через appConfig.model_list, указав URL весов и WASM-библиотеки. Какие небольшие открытые модели вышли в августе и на чём их запускать дома, мы собирали в <a href="https://tproger.ru/news/otkrytye-nejroseti-avgusta-frontir-na-odnoj-videokarte-i-chto-za">обзоре открытых нейросетей</a>.</p><p>Полный каталог собранных моделей лежит на mlc.ai/models. Номер совместимой сборки библиотек зашит в пакет: для 0.2.84 это константа modelVersion со значением «v0_2_84/base», так что после обновления npm-пакета кэшированные WASM-библиотеки могут потребовать перезагрузки.</p><h2>Как не заморозить интерфейс: Web Worker или Service Worker?</h2><p>Для обычного приложения хватает выделенного Web Worker, а Service Worker нужен, когда модель должна переживать переходы между страницами. Оба варианта в README оформлены одинаково: в потоке живёт обработчик, в основном скрипте создаётся движок-прокси с тем же интерфейсом MLCEngineInterface.</p><p>С Service Worker сложнее. Его жизненным циклом управляет браузер и может убить поток без предупреждения; движок шлёт heartbeat каждые 10 секунд по умолчанию (значение keepAliveMs в src/service_worker.ts), но авторы просят закладывать обработку ошибок и в приложении. README отдельно требует создавать ServiceWorkerMLCEngineHandler на верхнем уровне скрипта и запрещает делать это внутри обработчиков activate или message: браузер перезапускает уже активный воркер без повторного события activate.</p><blockquote>Service Worker's life cycle is managed by the browser and can be killed any time without notifying the webapp. ServiceWorkerMLCEngine will try to keep the service worker thread alive by periodically sending heartbeat events, but your application should also include proper error handling.</blockquote><p>Отдельная ветка применения — расширения Chrome: в репозитории есть примеры базового расширения и расширения на Service Worker с WebGPU, которое держит модель в фоне. По данным MDN, в Firefox WebGPU недоступен именно в контексте Service Worker, так что этот сценарий пока привязан к Chromium.</p><h2>Где WebLLM выигрывает у серверного API, а где проигрывает?</h2><p>Выигрывает там, где важны приватность промптов и нулевая стоимость токена, проигрывает там, где нельзя выбирать пользователю железо. Разложу по пунктам, отделяя проверяемое от обещаний.</p><ul><li><b>Деньги.</b> Инференс идёт на GPU пользователя, счёт за токены равен нулю. Платите трафиком: каждый новый пользователь качает от 0,7 до 6,4 ГБ весов с Hugging Face; свой CDN нужен только тем, кто перехостит артефакты сам.</li><li><b>Приватность.</b> Промпты и ответы на сервер не уходят, это следует из архитектуры. Но сетевые запросы есть: веса и WASM скачиваются с huggingface.co и jsdelivr, поэтому формулировка «данные никогда не покидают устройство» некорректна, и в политике приватности так писать нельзя.</li><li><b>Скорость.</b> 71–80% от нативного инференса по замеру авторов на M3 Max. На ноутбуке с встроенной графикой цифр в статье нет, и обещать «десятки токенов в секунду» без своего замера нельзя.</li><li><b>Первый запуск.</b> Минуты загрузки против миллисекунд первого ответа у API. Кэш спасает повторные визиты, но не первый.</li><li><b>Браузеры.</b> По данным MDN, WebGPU есть в Chrome и Edge с версии 113 (полная поддержка на Linux только с 144 и только на Intel Gen12 и новее), в Safari 26 на macOS и iOS с 15 сентября 2025 года, в Firefox с 141 частично: есть Windows и Apple Silicon, нет Linux и Intel-маков. Проверка navigator.gpu обязательна.</li><li><b>Управление моделью.</b> Серверный API даёт одну версию модели для всех и мгновенную замену. В WebLLM версия модели живёт в кэше каждого браузера, а обновление пакета может потребовать перекачки библиотек.</li><li><b>Функции.</b> Вызов инструментов через tools и tool_choice в README помечен как WIP с предварительной поддержкой. Для агентских сценариев это стоп-фактор; про выбор стека для агентов у нас есть <a href="https://tproger.ru/articles/kak-vybrat-frejmvork-dlya-ii-agentov">отдельный разбор</a>.</li></ul><p>Есть и организационный риск. По реестру npm пакет обновлялся 19 раз в 2023 году, 63 раза в 2024-м, 3 раза в 2025-м и 4 раза с начала 2026 года; последний релиз 0.2.84 вышел 27 мая. Код в репозитории при этом продолжает меняться, последний push был 3 сентября. Для продакшена это означает, что свежие модели из config.ts могут ждать релиза месяцами.</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-09-03/4059bf51-0d09-422e-8e6b-ba9c40176049.webp" alt="Столбчатая диаграмма: число релизов пакета @mlc-ai/web-llm по годам: 19 в 2023, 63 в 2024, 3 в 2025, 4 в 2026" /><figcaption>Релизы пакета @mlc-ai/web-llm по годам, 2026 год по 3 сентября. График: Tproger по данным реестра npm</figcaption></figure><blockquote>Evaluations show that WebLLM can retain up to 80% native performance on the same device with room to close the gap further.</blockquote><h2>Что делать по шагам, чтобы собрать чат на WebLLM за вечер</h2><p>План ниже покрывает путь от проверки железа до защиты артефактов; команды и имена функций взяты из README для версии 0.2.84.</p><ol><li>Проверьте, что в браузере есть navigator.gpu, и покажите понятную заглушку тем, у кого его нет. По MDN это Chrome и Edge 113+, Safari 26+, Firefox 141+ с оговорками по ОС.</li><li>Установите пакет: npm install @mlc-ai/web-llm (версия 0.2.84). Для прототипа без сборки подойдёт импорт с https://esm.run/@mlc-ai/web-llm.</li><li>Выберите модель из prebuiltAppConfig.model_list по полю vram_required_MB. Для широкой аудитории начните с моделей с флагом low_resource_required: Llama-3.2-1B, Qwen2.5-0.5B, gemma3-1b.</li><li>Создайте движок через CreateMLCEngine с initProgressCallback и выведите прогресс загрузки на экран.</li><li>Перенесите инференс в Web Worker через CreateWebWorkerMLCEngine, чтобы интерфейс не замирал во время генерации.</li><li>Включите стриминг флагом stream: true; для извлечения структурированных данных используйте JSON-режим из раздела Full OpenAI Compatibility.</li><li>Если артефакты лежат на своём хостинге, добавьте в запись модели поле integrity с SRI-хэшами для конфига, WASM и токенизатора; хэш генерируется командой openssl из README.</li></ol><p>При несовпадении хэша движок бросает IntegrityError, либо пишет предупреждение и продолжает работу, если задать onFailure: "warn". Без поля integrity проверка не выполняется вовсе, как и в прежних версиях.</p><h2>Что дальше: чего нет в WebLLM и за чем следить</h2><p>Первое, за чем стоит следить, это релиз после 0.2.84: в src/config.ts уже есть Qwen3.5 и Ministral 3, и вопрос в том, когда они попадут в опубликованный пакет. Второе — статус вызова функций, который держится в README как WIP. Третье — cross-origin хранилище: сейчас это расширение Chrome и экспериментальный API, а без него каждый сайт качает свою копию весов.</p><p>Мы не проверяли скорость на встроенной графике и на Windows-ноутбуках; единственные опубликованные цифры относятся к MacBook Pro M3 Max. Доступность huggingface.co и esm.run из конкретной сети мы тоже не измеряли: перед запуском продукта на WebLLM стоит замерить время первой загрузки у своей аудитории или перехостить артефакты.</p><p>Источники: <a href="https://github.com/mlc-ai/web-llm">GitHub: mlc-ai/web-llm (README, лицензия Apache-2.0)</a>, <a href="https://github.com/mlc-ai/web-llm/blob/main/src/config.ts">src/config.ts: prebuiltAppConfig.model_list с vram_required_MB</a>, <a href="https://github.com/mlc-ai/web-llm/blob/main/src/service_worker.ts">src/service_worker.ts: keepAliveMs и heartbeat</a>, <a href="https://arxiv.org/abs/2412.15803">arXiv 2412.15803: WebLLM: A High-Performance In-Browser LLM Inference Engine</a>, <a href="https://blog.mlc.ai/2024/06/13/webllm-a-high-performance-in-browser-llm-inference-engine">Блог MLC: WebLLM, 13 июня 2024</a>, <a href="https://webllm.mlc.ai/docs/">Документация WebLLM</a>, <a href="https://registry.npmjs.org/@mlc-ai/web-llm">Реестр npm: @mlc-ai/web-llm (версии и даты)</a>, <a href="https://news.ycombinator.com/item?id=49536411">Hacker News: обсуждение WebLLM 2 сентября 2026</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API#browser_compatibility">MDN: WebGPU API, совместимость браузеров</a>, <a href="https://huggingface.co/mlc-ai">Hugging Face: модели mlc-ai</a>, <a href="https://huggingface.co/spaces/mlc-ai/WebLLM-JSON-Playground">WebLLM JSON Playground</a>, <a href="https://chat.webllm.ai/">WebLLM Chat</a>, <a href="https://mlc.ai/models">Каталог моделей MLC</a>, <a href="https://github.com/mlc-ai/mlc-llm">GitHub: mlc-ai/mlc-llm</a></p><p>Изображение на обложке: Скриншот: chat.webllm.ai</p>]]></content:encoded>
    </item>
    <item>
      <title>Zero на Three.js: инженерный разбор интерактивного сайта</title>
      <link>https://tproger.ru/articles/zero-na-three-js-inzhenernyj-razbor-interaktivnogo-sajta</link>
      <comments>https://tproger.ru/articles/zero-na-three-js-inzhenernyj-razbor-interaktivnogo-sajta?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/zero-na-three-js-inzhenernyj-razbor-interaktivnogo-sajta</guid>
      <description><![CDATA[<p>Разбираем, как BUNQ LABS сделала zero.university: виртуальный скролл, шейдеры, KTX2/DRACO, адаптивное качество и загрузка текстур без фризов. Проверьте техники.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/zero-na-three-js-inzhenernyj-razbor-interaktivnogo-sajta">Zero на Three.js: инженерный разбор интерактивного сайта</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Лучшая практика]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[Дизайн интерфейсов и UX]]></category>
      <category><![CDATA[Фреймворки и библиотеки]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 28 Jul 2026 04:19:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>Представьте, что вы заходите на сайт, а он не пускает. Нет кнопки «войти» — только поле, где нужно нарисовать ноль. Как только круг замыкается, из линии расходится инеевый узор, и сайт начинает рассказывать историю. Это не декоративная заглушка: так работает <a href="https://zero.university/">zero.university</a> — кейс, где первый жест пользователя сразу задаёт тон всему повествованию.</p><p><b>Zero</b> — иммерсивный лендинг индийского стартапа Zero University, который предлагает альтернативу классическому университетскому пути. Сайт превращает скролл в шестиактную историю: традиционное образование, разбитое стекло, горящие деньги, уничтоженные сертификаты, тоннель из логотипа ZERO и, наконец, интерактивная карта города с офисами реальных компаний. Цель — не просто показать красивую картинку, а провести пользователя через аргумент: диплом перестаёт быть гарантией, а навыки открывают дорогу в индустрию.</p><p>Проект разрабатывала студия <b>BUNQ LABS</b> четыре месяца. Исходные ассеты занимали больше гигабайта: несжатые Blender-сцены, 8K-текстуры и запечённые анимации. Финальная сборка уместилась в 10 МБ и держит 60 FPS даже на бюджетном Android. Команда опубликовала технический разбор на Codrops, а мы выделили решения, которые можно перенести в свои WebGL-проекты.</p><ul><li>Первый жест как ворота: распознавание нуля — это простая проверка угла, округлости и замкнутости, а не нейросеть.</li><li>Виртуальный скролл заменяет нативный: одно число управляет загрузкой, анимацией, шейдерами и текстом.</li><li>Ассеты важнее рендера: DRACO, KTX2/ETC1S, атласы и собственный превьювер сжали гигабайты до мегабайтов.</li><li>Текстурные загрузки — главный источник фризов; декодинг в воркере и очередь по requestIdleCallback решают проблему.</li><li>Адаптивное качество по frame time позволяет не гадать о мощности устройства.</li><li>Мобильная точность шейдеров: mediump на Adreno и Mali — это реальный 16-битный float, и его недостаточно для сложных эффектов.</li></ul><p>Разбираем, как это устроено изнутри, и что из этого можно взять в свою работу.</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-07-28/00e5f2ad-8fc7-49b9-88da-322a34a6bef1.webp" alt="Шесть этапов интерактивного повествования zero.university: от традиционного образования до интерактивной карты города." /><figcaption>Схема повествования: шесть этапов и пять «ворот», через которые проходит пользователь. Источник: Codrops / BUNQ LABS</figcaption></figure><h2>Сюжет из шести этапов и пяти ворот</h2><p>Интерактивный нарратив строится вокруг пяти «ворот» — точек, где скролл останавливается и ждёт действия пользователя. Сначала нужно нарисовать ноль, затем удерживать касание, чтобы разбить стекло, потом — чтобы запуститься сквозь тоннель. Каждый жест связан с сюжетным поворотом: обещание университетского пути буквально трескается, за ним появляется статистика безработицы, диплом превращается в горящую бумагу, сертификаты рвутся на полосы.</p><h3>От обещания к свободе</h3><p>Шесть этапов идут от иллюзии контролируемого пути к интерактивной карте, где пользователь сам выбирает, куда смотреть. Финальный экран — город с башней Zero University в центре. Можно приближать, панорамировать и открывать карточки ролей, сценариев и инструментов. Это не просто финал: после того как сайт вёл пользователя за руку, он отдаёт управление обратно.</p><h2>Архитектура: один скролл управляет всем</h2><p>Одно из главных архитектурных решений — отказ от нативного скролла браузера. Нет ScrollTrigger, нет огромного прокручиваемого DOM. Вместо этого события колёсика и тача обновляют виртуальное значение скролла, которое плавно догоняет цель. Всё остальное — загрузка ассетов, анимации, тайминги шейдеров, текст и оверлеи — читают это единственное число.</p><p>Проект разбит на девять таких сегментов; загрузчик одновременно выполняет роль первых ворот. Каждый сегмент самодостаточен: у него свой жизненный цикл, свои объекты и своя утилизация. Это упростило поддержку и отладку. Переход к любому этапу воспроизводит жизненные циклы всех предыдущих сегментов, поэтому состояние всегда консистентно — как будто пользователь дошёл до этого места естественным скроллом.</p><h2>Конвейер 3D-ассетов: как уместить 1 ГБ в 10 МБ</h2><p>Большую часть четырёх месяцев ушла не на код, а на подготовку ассетов. Исходники пришли из Blender: несжатая геометрия, 8K-текстуры, запечённые анимации — всё вместе больше гигабайта. Первый месяц команда тратила на то, чтобы выбрать формат для каждого типа ресурсов.</p><h3>DRACO и KTX2</h3><p>Вся геометрия отправляется со сжатием DRACO, декодеры для которого хостятся локально в public/vendor/. Урок команда усвоила на собственном опыте: замедление на gstatic и unpkg привело к тому, что все сжатые ассеты перестали декодироваться, хотя сами файлы лежали на ихних серверах. Если декодер зависит от чужого CDN, весь пайплайн зависит от него.</p><p>Самый большой выигрыш дали текстуры. PNG может быть маленьким на диске, но в видеопамять он загружается распакованным. Текстура 2048² занимает около 16 МБ VRAM независимо от размера файла. Формат KTX2 со сжатием ETC1S остаётся сжатым на GPU, занимает меньше памяти и загружается быстрее.</p><h3>Собственный превьювер компрессии</h3><p>С KTX2 есть проблема: ETC1S — lossy, и локально его не посмотреть обычным просмотрщиком. Чтобы не гадать с настройками, команда сделала внутренний дашборд: сжатая и несжатая версия каждой картинки и видео рядом. Так можно было подобрать степень сжатия индивидуально — усилить там, где артефакты не заметны, сохранить качество для ключевых объектов и отключить мипмапы, где они не нужны. Инструмент простой, но редко встречается в WebGL-пайплайнах, хотя экономит огромное количество времени и памяти.</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-07-28/3a57d9e3-14e7-4f55-8aad-78cee34f1da3.webp" alt="Внутренний дашборд команды для сравнения сжатой и несжатой версии каждого ассета." /><figcaption>Превьювер компрессии: сжатая и несжатая версии текстур и видео рядом. Источник: Codrops / BUNQ LABS</figcaption></figure><h3>Атласы вместо дюжин картинок</h3><p>Похожие текстуры собрали в общие атласы. Например, все текстуры рук уместили в один атлас 4×4, а каждая mesh сдвигала UV-координаты, чтобы взять свой кусок. Спрайты текста, сертификаты, бумажные обрывки, облака, монеты и осколки стекла тоже ушли в атласы. Больше 50 отдельных изображений превратились примерно в дюжину атласов, а большинство градиентных фонов заменили несколькими строками GLSL. Ранние сборки весили 35–40 МБ, финальная — меньше 10 МБ. При этом интерактивная карта мира вынесена в отдельную группу загрузки, чтобы не блокировать открытие сайта.</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-07-28/e1686dcf-b13a-494e-94b3-0e32f0eb880a.webp" alt="Атлас текстур рук 4×4: каждая mesh сдвигает UV-координаты, чтобы взять свой кусок." /><figcaption>Атлас рук: все текстуры рук упакованы в одну текстуру 4×4. Источник: Codrops / BUNQ LABS</figcaption></figure><h2>Текстурные загрузки: главный источник фризов</h2><p>Уменьшить скачивание — только половина дела. Сжатые текстуры всё равно нужно загрузить в GPU на главном потоке, и крупная текстура легко блокирует рендер на 50 мс — достаточно, чтобы потерять несколько кадров. Если эта загрузка случается впервые во время скролла, подёргивание заметно сразу. Сайт может хорошо показывать себя в бенчмарках и при этом чувствоваться вязким.</p><ul><li>Декодировать вне главного потока — через createImageBitmap(). Тогда во время рендера остаётся только загрузка в GPU.</li><li>Загружать в GPU в простое — декодированные текстуры ставят в очередь и выгружаются по requestIdleCallback, пока есть запас времени.</li><li>Разбивать большие атласы на плитки 256² и загружать по одной на кадр, чтобы не выбиваться из бюджета кадра.</li></ul><p>Когда известно, что следующий этап вот-вот появится — после загрузчика или во время перехода между воротами — очередь сбрасывается синхронно. Все нужные текстуры уже в видеопамяти, прежде чем они появятся на экране.</p><h2>Адаптивное качество по реальному frame time</h2><p>Невозможно заранее знать, на каком устройстве откроется сайт. Рендерер поэтому постоянно измеряет время кадра по скользящему окну и динамически меняет уровень качества. Если рендеринг замедляется — понижается tier. Если производительность стабильно высокая — tier снова растёт. Задержка между переключениями не даёт постоянно метаться у границы.</p><p>Уровни качества влияют только на визуальную полировку: devicePixelRatio, количество сэмплов размытия, геометрию монет, разрешение текста. Сама история остаётся неизменной и на флагмане, и на бюджетном телефоне. Для особо тяжёлых моментов — например, разбитие стекла — рендерер временно понижает пиксельное соотношение и отключает размытие и иней, прячет затраты внутри самого жеста.</p><h2>Шейдеры под каждый эффект</h2><p>Каждый ключевой момент использует собственный шейдер. ИИ помогал сгенерировать первые версии, но все финальные шейдеры переписывались и дорабатывались вручную. Вот несколько приёмов, которые стоит запомнить.</p><h3>Постпроцессинг из нескольких проходов</h3><p>Кадр собирается из цепочки проходов: основная 3D-сцена, процедурный фон, преломление стекла, иней и след от жеста, глубина резкости, foreground с зернистостью и тональной картой, отложенный текст, и в конце — разбитое стекло. Стеклянный, текстовый и шейдер разбития инициализируются лениво и прогреваются в простое, чтобы не попадать на критический путь загрузчика.</p><h3>Иней из нарисованного нуля</h3><p>Эффект инея строится на ping-pong-буфере из четырёх проходов: горизонталь, вертикаль и две диагонали. Каждый проход распространяет нарисованный штрих, захватывая самые яркие соседние пиксели и создавая восьмиугольный паттерн роста. Яркость текстуры льда модулирует шаг распространения, край получается кристаллическим. После замыкания контура центр масс штриха становится точкой отсчёта для радиального таяния.</p><h3>Освещение без источников света</h3><p>Реалтаймовое освещение скинненной меши рук было бы слишком дорогим, а свет должен был точно совпадать с оригинальным артом. Поэтому освещение запекли в текстуры и смешивают между ними. Используются два слота: один содержит текущий ключевой кадр, другой — следующий. По мере проигрывания анимации новый слот плавно вытесняет старый.</p><p>Перед смешиванием альфа предумножается, чтобы вокруг прозрачных краёв рук не появлялись тёмные ореолы. Обе текстуры освещения лежат в одном атласе, поэтому переключение между ключами требует только обновления двух UV-смещений и коэффициента смешивания.</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-07-28/cb760b51-b0f4-4804-aff6-58ce015d2fda.webp" alt="Две запечённые текстуры освещения рук внутри одного атласа для плавного переключения." /><figcaption>Запечённое освещение рук: два ключевых кадра в одном атласе смешиваются по прогрессу анимации. Источник: Codrops / BUNQ LABS</figcaption></figure><h3>Горящие деньги</h3><p>Эффект сгорания использует noise-driven distance field. Фронт горения проходит по купюре, слегка опережая точку дискарда. Перед ним появляется тонкий HDR-ободок углей, затем обугленная поверхность. FBM — самая дорогая часть шейдера, поэтому фрагменты отсекаются как можно раньше, если они ещё не достигли порога горения.</p><h3>Рвущиеся сертификаты</h3><p>Каждая вершина хранит индекс полосы, к которой принадлежит фрагмент диплома. Фронт разрыва движется слева направо, и каждая полоса отделяется и падает независимо со своим вращением. Нормали для освещения строятся аналитически из той же волновой функции, которая анимирует меш, поэтому normal map не нужен.</p><h3>Тоннель ZERO</h3><p>Тоннель получается выдавливанием поперечного сечения из логотипа ZERO. Импульс яркости распространяется по мировой координате Z, поэтому эффект остаётся бесшовным, даже когда секции тоннеля повторяются.</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-07-28/bfbebb17-dc15-4bbb-b00c-a1fb7f98c13f.webp" alt="Тоннель ZERO, полученный выдавливанием сечения логотипа." /><figcaption>Тоннель ZERO: импульс яркости распространяется по мировой координате Z, сохраняя бесшовность. Источник: Codrops / BUNQ LABS</figcaption></figure><h3>Текст, который приходит в фокус</h3><p>Нарративный текст появляется не мгновенно, а проявляется через семиотводное гексагональное размытие. Радиус размытия зависит от прогресса появления, поэтому буквы будто фокусируются. Проход выполняется в отложенном текстовом проходе и полностью пропускается, когда текст не виден.</p><h3>Точность на мобильных</h3><p>Одна из самых неприятных находок возникла на реальных мобильных GPU. Несколько шейдеров пришлось явно перевести на highp float, потому что на Adreno и Mali mediump — это настоящий 16-битный float. На десктопе ошибок не было, а на телефоне полосы диплома двигались одинаково, а эффект горения покрывался бэндами. Вывод: тестировать на реальных мобильных устройствах нужно с первых дней, а не перед релизом.</p><h2>Дизайн взаимодействий</h2><p>Исходный материал от заказчика состоял из картинок и видео, поэтому поведение каждых ворот проектировали с нуля. Большинство используют общую систему «нажми и удерживай». Общий конфиг задаёт момент появления подсказки и длительность удержания, а каждые ворота реализуют визуал через собственные хуки.</p><p>Пока пользователь удерживает касание, кадр постепенно смещается в тёмно-красный. Когда стекло разбивается, цвет возвращается примерно за 200 мс — это создаёт ощущение, что осколки выбивают темноту. Проверили вариант в 400 мс: он ощущался заметно слабее. Звук разбития привязан к первому отрисованному кадру, а не к таймеру: на медленных устройствах таймер может сыграть раньше анимации, и эффект рассинхронится.</p><h2>Финальная награда — интерактивный мир</h2><p>Последняя последовательность запуска выносит пользователя в открытое небо. Облака расступаются, открывая город с башней Zero University в центре, над которой появляется ореол — финальные ворота. Камера приземляется в интерактивную карту, где можно панорамировать, зумить и открывать карточки с ролями, сценариями и инструментами. Плашка Join Beta превращается в форму waitlist. После того как сайт вёл пользователя через историю, он отдаёт ему контроль — и просит остаться.</p><h2>FAQ</h2><h2>Выводы</h2><p>Самый важный урок проекта — подготовка ассетов и загрузка в GPU заслуживают не меньше внимания, чем сам рендеринг. Инструменты вроде превьювера компрессии, локальных декодеров, очереди загрузки и адаптивного менеджера качества редко выглядят героически, но именно они превратили гигабайт исходников в 10-мегабайтный сайт, который не тормозит на дешёвом телефоне.</p><blockquote>ИИ генерировала первые версии кода и прототип, который выиграл нам проект, за 48 часов. Но полировка — сотни мелких решений, тестирование на реальных устройствах и инженерная интуиция — осталась за людьми.</blockquote><p><b>Источник:</b> технический разбор команды BUNQ LABS на <a href="https://tympanus.net/codrops/2026/07/17/zero-the-engineering-behind-a-defiant-interactive-narrative/">Codrops</a>.<br />Попробуйте открыть <a href="https://zero.university/">zero.university</a> на десктопе и на бюджетном смартфоне — и сравните, где заметнее компромиссы качества.</p>]]></content:encoded>
    </item>
    <item>
      <title>Своя self-hosted двухсерверная VPN-архитектура. Подробный путь разработки и ошибки, с которыми вы можете столкнуться</title>
      <link>https://tproger.ru/articles/svoya-self-hosted-dvuhservernaya-vpn-arhitektura-podrobnyj-put-r</link>
      <comments>https://tproger.ru/articles/svoya-self-hosted-dvuhservernaya-vpn-arhitektura-podrobnyj-put-r?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Роман Фролов]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/svoya-self-hosted-dvuhservernaya-vpn-arhitektura-podrobnyj-put-r</guid>
      <description><![CDATA[<p>Проект представляет из себя быстрый способ воссоздать архитектуру состоящую из 2 серверов (локальный + удаленный) с определенными сервисами, которые решают специфические задачи. Проект сделан прежде всего для меня, а также для людей которые хотят свой готовый self-hosted сервер из коробки с полной системой обслуживания</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/svoya-self-hosted-dvuhservernaya-vpn-arhitektura-podrobnyj-put-r">Своя self-hosted двухсерверная VPN-архитектура. Подробный путь разработки и ошибки, с которыми вы можете столкнуться</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Тестирование]]></category>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Ruby]]></category>
      <category><![CDATA[unix]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[Музыка]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[DIY]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Навыки]]></category>
      <category><![CDATA[VPN]]></category>
      <category><![CDATA[Telegram]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[Cloudflare]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Мессенджер]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[NFT]]></category>
      <category><![CDATA[Машин]]></category>
      <category><![CDATA[1C]]></category>
      <category><![CDATA[DeFi]]></category>
      <category><![CDATA[Grafana]]></category>
      <category><![CDATA[VPS]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 26 Jul 2026 15:46:26 GMT</pubDate>
      <content:encoded><![CDATA[<p>Всё
 началось с того, что меня перестал устраивать мой подход к 
развертыванию личных сервисов. Я решил переписать всё с нуля. К тому же 
это был отличный повод получить новые навыки и попробовать инструменты, 
до которых давно не доходили руки.</p><p>Арендовать мощные VPS под 
ресурсоемкие задачи в текущих реалиях выходит неоправданно дорого. При 
этом дома у меня уже был выделенный неттоп (мини-ПК) с 16 ГБ оперативной
 памяти на базе энергоэффективного процессора Intel N95.</p><p>Пройдя 
путь от простых Bash-скриптов и сторонних туннелей до полностью 
автоматизированной инфраструктуры, я создал проект ServeHub-2. В этой 
статье я подробно разберу, как эволюционировала сеть проекта, почему 
декларативный подход победил императивный и с какими неочевидными багами
 пришлось столкнуться в процессе автоматизации.</p><h2>История настройки сетевой архитектуры</h2><h3>Использование Tuna</h3><p>В
 самом начале проекта я еще не думал о VPN как о способе пробития NAT и 
основе, на которой будет строиться вся система. Первое, к чему я пришел —
 сервис Tuna. Если кратко, это аналог Cloudflare Tunnel за условные 300 
рублей. У него очень приятный веб-интерфейс и невероятно простая 
настройка. Однако для полноценной независимой архитектуры он не подошел 
по двум причинам:</p><ul><li>Сервера Tuna находятся вне контроля пользователя.</li><li>На удаленном сервере нельзя развернуть свои сопутствующие сервисы.</li></ul><p>В целом сервис действительно удобный, но для моих задач он оказался слишком ограничивающим.</p><p>Вот
 пример конфига для tuna (все максимально просто, создаем контейнеры для
 ssh туннеля, чтобы был доступ ssh, а также основной http туннель с 
привязкой к nginx или любому другому прокси если такой есть):</p><h3>В поисках гибкости: тесты Pangolin и переход к FRP</h3><p>После Tuna я решил двигаться в сторону собственного контроля и попробовал Pangolin.
 Однако решение быстро отвалилось: для дешёвого сервера оно оказалось 
слишком «тяжёлым» и избыточным. Главные минусы — ощутимый оверхед по 
ресурсам и лишний слой принудительной веб-аутентификации перед самими 
сервисами. Это ломало нормальное взаимодействие с родными мобильными 
клиентами (вроде Element для Matrix или Bitwarden для паролей), где 
повторная авторизация в браузере просто не нужна.</p><p>На смену пришел FRP (Fast Reverse Proxy).
 Он выполнял ту же функцию проброса, но хостил я его уже на собственном 
арендованном VPS в режиме Layer 4 (TCP). Это дало абсолютную гибкость: 
внешний VPS не заглядывал внутрь пакетов и ничего не расшифровывал, а 
просто пересылал сырой поток домой. Кроме того, это отлично 
оптимизировало расходы: вместо 300 рублей за Tuna и ещё 300 рублей за 
отдельный VPN, я стал платить всего 500 рублей за один стойкий VPS, 
который мог настраивать как хочу. (к тому же можно было обойтись даже 
дешевле, так как VPS с 4 гб оперативки загружен всего лишь на 40%, 
процессор всего на 20%-40%)</p><p>FRP состоит из 2 конфигурационных 
файлов (один на удаленном сервере frp server, другой на локальном frp 
client), все также довольно просто, однако его можно использовать на 
разных слоях. У меня он брал трафик за стандартный TCP и передавал его 
на локальный сервер.</p><p>Также доп. фишка в том что основная 
конфигурация происходит именно в frpc, который, в свою очередь, передает
 часть настроек на frp на удаленном сервере.</p><p>frpc.toml:</p><p>frps.toml:</p><h3>Полноценный переезд на WireGuard (AmneziaWG) и 8 часов отладки</h3><p>Со временем архитектура эволюционировала в сторону полноценной VPN-сети на базе WireGuard, а точнее — его модификации AmneziaWG. Причин для этого шага было несколько:</p><ul><li>Безопасность: FRP всё же открывал внутренние ресурсы в публичный интернет, оставляя их доступными для сканеров портов.</li><li>Удобство маршрутизации:
 Все участники сети стали равноправными узлами в одной виртуальной 
локальной подсети. Больше не нужно было настраивать постоянные 
односторонние пробросы.</li><li>Дополнительный бонус:
 Поскольку удаленный VPS был куплен в Нидерландах, через этот же VPN я 
автоматически получил безопасный доступ ко всем зарубежным ресурсам.</li></ul><p>Для реализации схемы на удаленном VPS был развернут контейнер wg-easy с поддержкой AmneziaWG, а на домашнем мини-ПК — клиентский контейнер Amnezia (сборка из Dockerfile с использованием amnezia-tools  и модулем ядра хоста).</p><p>И
 именно здесь я поймал самый изнурительный баг проекта. После 
развертывания трафик упорно шёл только в одну сторону. Часов 8 ушло на 
диагностику iptables, маршрутов и чтение зарубежных форумов (что 
бесполезно, учитывая специфику наших блокировок). Оказалось, провайдер 
просто дропал обратный трафик стандартного WireGuard, так как пакеты шли
 без маскировки. Причина крылась в docker-compose.yml: у меня было прописано image: ghcr.io/wg-easy/wg-easy:latest. Как выяснилось, тег latest  на Docker Hub намертво прилип к старой 14-й версии, а поддержка параметров AmneziaWG появилась только в ветке 15.x. Изменение тега на конкретную версию (15.3) решило проблему за секунду.</p><p>Благодаря
 переходу конфигурация получилась максимально простой, основные отличия 
от стандартной документации выделил в коде: (в основном то, на что 
пришлось долго рыть информацию)</p><h3>Настройка Nginx</h3><p>Чтобы
 сервисы были доступны исключительно внутри подсети VPN, я задействовал 
Nginx. Доступ к приложениям был жестко ограничен на уровне конфигурации —
 веб-сервер принимает запросы только из диапазона IP-адресов 10.8.0.0/24. Любые попытки постучаться на сервер из внешнего интернета без активного VPN-туннеля автоматически сбрасываются Nginx.</p><p>Логика
 распределения завязана на proxy-протоколе: Nginx на удаленном VPS 
выступает основным входным узлом, принимает зашифрованный трафик, 
заворачивает его в заголовки с реальным IP-адресом клиента и через 
туннель перекидывает на локальный Nginx домашнего сервера. Локальный 
веб-сервер уже сам расшифровывает SSL и распределяет трафик по конечным 
Docker-контейнерам, сохраняя реальные IP в логах безопасности.</p><p>Вставлю
 один кусок кода из nginx на удаленной машине для примера, так все 
остальное примерно похоже (конфиги использовались в виде .template):</p><h3>SSL-сертификаты</h3><p>Для получения валидных SSL-сертификатов я настроил работу через автоматический Certbot по challenge-валидации DNS-01 c API Webnames. Сам домен привязан к внутреннему IP-адресу 10.8.0.1.
 Проверка через DNS позволила выпустить единый wildcard-сертификат на 
весь домен и его поддомены без необходимости держать открытым 80-й порт 
веб-сервера наружу.</p><p>Уточню, что certbot запускается автоматически 
во время выполнения Ansible плейбука, поэтому самому кроме указания 
переменных ничего делать не нужно.</p><p>В
 итоге получилась схема, при которой все сервисы доступны по красивым 
доменным именам с HTTPS, но абсолютно невидимы для внешнего интернета.</p><p>Вот настройка certbot:</p><h2>История софта</h2><p>Параллельно
 с сетевой структурой развивался и сам набор приложений. Изначально я 
хотел собрать в одном месте утилиты, которыми пользуюсь каждый день, но в
 процессе селфхостинга быстро понимаешь: нельзя просто накидать 
контейнеров и надеяться, что мини-ПК справится, а конфигурационные файлы
 не превратятся в кашу.</p><h3>Первый стек и оптимизация</h3><p>Первыми на домашнем сервере прижились медиа-сервисы: Navidrome для стриминга музыки и Audiobookshelf
 для аудиокниг и подкастов. Они легковесные, имеют отличные мобильные 
клиенты с синхронизацией прогресса и полностью закрывают мои 
потребности. Позже к ним добавился Nextcloud как единое независимое облако для файлов, контактов и семейных документов.</p><p>Затем встал вопрос безопасного хранения паролей. Сначала я смотрел в сторону оригинального Bitwarden, но в итоге я выбрал Vaultwarden
 — альтернативный сервер на Rust, полностью совместимый с API Bitwarden.
 Он потребляет считанные мегабайты оперативной памяти и работает 
идеально. Дополнительно для удобства управления всей этой распределенной
 Docker-инфраструктурой в локальный стек был добавлен Portainer. (+ Portainer Agent на удаленный сервер)</p><p>Из интересных моментов, где мне пришлось немного больше возиться, чем с остальными сервисами это nextcloud настройка:</p><h3>Ошибки проектирования: почему я удалил Matrix (Synapse)</h3><p>Не все решения прошли проверку временем. На этапе использования Tuna и FRP я развернул сервер Matrix (Synapse)
 для защищенного обмена сообщениями. Мне казалось это крутой идеей, но 
когда я окончательно перешел на AmneziaWG, целесообразность мессенджера 
внутри закрытого туннеля сошла на нет.</p><p>Synapse требовал слишком 
много ресурсов, впустую расходовал оперативку домашнего ПК и усложнял 
конфиг Nginx. При этом реальной пользы для семьи он не приносил. Для 
критических алертов инфраструктуры и повседневного общения проще и 
эффективнее оказалось использовать Telegram. (плюс алертинг настроен 
именно через него) В итоге я полностью выпилил Synapse из стека, 
освободив ресурсы.</p><p>Вместо него я добавил в связку к wg-easy локальный AdGuard Home.
 Теперь он работает прямо внутри VPN-сети: очищает весь трафик от 
рекламы и трекеров на лету, кэширует DNS-запросы и не дает истории 
веб-серфинга улетать внешним провайдерам.</p><p>Основной проблемой с 
которой я столкнулся при использовании AdGuard Home, так это то что я 
так и не понял как заставить использовать AmneziaVPN клиент AdGuard как 
основной DNS, при этом AmneziaWG работает прекрасно. Как я понимаю дело в
 том что AmneziaWG работает намного проще на уровне ip и у него нету 
никаких доп фильтров, настроек и подобного, поэтому он просто берет 
данные из конфига.</p><h3>От костылей на Bash к декларативному Ansible</h3><p>Весь
 стек на обоих серверах разворачивался через bash скрипты, что было уж 
очень плохо с точки зрения идемпотентности. Во первых из-за bash мне 
постоянно приходилось очищать сервера, так как нормальных проверок у 
меня не было и писать я их не хотел, а также было много костылей с 
импортом переменных, записями в файлы и подобным.</p><p>Так я пришел к декларативному подходу и Ansible.
 Теперь вся конфигурация описывается в виде плейбуков и ролей, 
отражающих конечное желаемое состояние серверов. Конфиденциальные данные
 перенесены в файл secrets.yml, а хрупкие конструкции 
автоматизированы через шаблоны Jinja2. Проект стал идемпотентным: если 
шаги уже выполнены, Ansible их просто пропускает.</p><p>В итоге 
получилось несколько yaml файлов для стандартной настройки системы 
(bootstrap_os.yml) и для настройки каждого из хостов (setup_local.yml и 
setup_remote.yml). В итоге теперь все что нужно чтобы полностью с нуля 
развернуть проект - скачать Ansible, несколько других зависимостей на 
свой рабочий пк и запустить один manage_deploy.sh, в котором можно будет
 выбрать сценарий как будет вести себя Ansible и спокойно дождаться 
разворачивания сервисов.</p><p>Также благодаря Ansible я удобно 
реализовал переносимость проекта. Так как я решил не использовать тома 
docker, и вместо этого храню все в папках, чтобы перенести старые данные
 проекта нужно просто скопировать папку apps-data и положить ее в нужное
 место и все само заработает после повторного развертывания проекта. В 
Ansible выделяется отдельная пауза для этого.</p><p>Вот пример основного плейбука deploy.yml:</p><h3>Тестирование мультидистрибутивности с помощью Vagrant</h3><p>Проект
 изначально затачивался под работу на трех дистрибутивах: Ubuntu, Debian
 и Arch Linux. Тестировать Ansible-плейбуки прямо на рабочей локальной 
машине (в моем случае — EndeavourOS) слишком рискованно, а создавать 
виртуальные машины руками — долго и неудобно.</p><p>Решением стал Vagrant,
 позволяющий за пару минут развернуть чистые ОС в VirtualBox из готовых 
образов. Но в процессе настройки мультивендорного стенда в режиме 
сетевого моста (public_network) всплыли две критические проблемы:</p><ol><li>Конфликт DNS:
 По умолчанию Vagrant создает NAT-интерфейс для управления нодой. При 
включении второго (публичного) интерфейса для локальной сети ломался 
дефолтный DNS-резолвер. Проблему пришлось решать принудительной очисткой
 и перезаписью файла /etc/resolv.conf через inline-скрипт автоматизации Vagrant.</li><li>Проблема с GRUB на Debian: В используемом базовом образе generic/debian12
 конфигурация GRUB сохраняла жесткую привязку к конкретному имени диска 
из окружения сборщика. При повторном развертывании плейбуков на тестовом
 стенде это приводило к сбоям загрузчика. Чтобы автоматизировать 
очистку, пришлось внедрить скрипт, который на лету определяет имя 
системного диска через lsblk и автоматически передает правильные параметры в загрузчик через утилиту debconf-set-selections.</li></ol><p>Вот код Vagrantfile: (в node.vm.provision происходит основное решение ошибок)</p><p>Надежная система бэкапов на базе BorgmaticДля создания резервных копий я внедрил Borgmatic
 (удобную надстройку над дедуплицирующим инструментом Borg Backup). Весь
 процесс автоматизирован с помощью связки системных юнитов borgmatic.service и borgmatic.timer. В бэкап уходят две ключевые директории: apps-data (конфигурации приложений и баз данных) и PersonalData (медиатека: музыка, книги, подкасты, файлы Nextcloud).</p><p>Развертывание
 системы бэкапов полностью берет на себя Ansible. Мне достаточно указать
 UUID внешнего жесткого диска — скрипт сам проверит его наличие в 
системе, примонтирует в нужную директорию, создаст зашифрованный 
репозиторий и настроит политику ротации (хранение 7 ежедневных, 4 
еженедельных и 6 ежемесячных копий). Также в Prometheus выведен 
мониторинг самого репозитория .borg для отслеживания его размера и статуса успешности архивации.</p><p>Главная
 проблема при бэкапе работающих Docker-контейнеров — риск скопировать 
базу данных в «битом» или неконсистентном состоянии, если в момент 
создания архива в нее шла активная запись. Чтобы решить эту проблему, я 
задействовал механизм хуков в конфигурации Borgmatic.</p><p>Перед началом резервного копирования автоматически срабатывает команда остановки контейнеров проекта (docker-compose down),
 а после успешного завершения (или в случае возникновения непредвиденной
 ошибки) контейнеры автоматически поднимаются обратно в фоновом режиме. 
Для удобного просмотра архивов и быстрого восстановления файлов я 
развернул веб-интерфейс Borg UI.</p><p>Конфигурация borgmatic: (использую как Jinja2 шаблон, чтобы Ansible в плейбуках сам подставил переменные)</p><h2>Наблюдаемость (Observability) уровня Enterprise</h2><p>В последних релизах (v1.2.0 и v1.3.0) фокус проекта сместился на мониторинг и работу с логами.</p><h3>Эволюция алертинга и переход на Gatus</h3><p>Изначально для мониторинга доступности я смотрел на Uptime Kuma, но отказался из-за отсутствия удобной декларативной настройки через конфиги. Затем я развернул связку Blackbox Exporter и Alertmanager
 с уведомлениями в Matrix. Но тут крылась логическая несостыковка: весь 
алертинг был завязан на локальном ПК, и в случае его аппаратного отказа я
 бы просто лишился уведомлений.</p><p>Тогда я решил вернуть Uptime Kuma,
 но развернуть его на удаленном VPS в качестве внешнего «сторожа» и 
автоматизировать его настройку через Python-скрипт с библиотекой uptime-kuma-api. Но и тут ждали «грабли» — библиотека не обновлялась три года и намертво ломалась на свежих версиях Kuma.</p><p>В итоге идеальным решением стал Gatus.
 Он изначально проектировался под управление через YAML-конфиги и 
поддерживает отправку алертов, если сервер не отвечает. Из-за специфики 
фронтенда Gatus (он не умеет работать из подкаталога типа /gatus), мне пришлось перенести его и wg-easy на полноценные субдомены gatus. и wireguard.</p><p>Для Gatus получился простой конфиг:</p><p>Для мониторинга аппаратных ресурсов удаленного и локального серверов была развернута связка node-exporter + cAdvisor. Все уведомления теперь приходят мгновенно в Telegram-бота. Чтобы 
избежать лавины одинаковых сообщений (например, при перезагрузке хоста),
 в Alertmanager настроена жесткая группировка и дедупликация событий. 
Также добавлен экспортер для AdGuard Home, выводящий статистику 
заблокированных запросов в Grafana.</p><h3>Централизованные логи: Loki + Grafana Alloy</h3><p>В релизе v1.3.0 в стек была добавлена централизованная система сбора логов Loki. Вместо устаревшего Promtail в качестве агента сбора я применил Grafana Alloy.</p><p>Он
 эффективно собирает логи со всех запущенных Docker-контейнеров, парсит 
их и передает в Loki. Теперь вся история событий, ошибок веб-сервера 
Nginx или падений внутренних приложений доступна в едином интерфейсе 
Grafana с возможностью удобной фильтрации через LogQL, что значительно 
упрощает отладку.</p><p>Конфиг Loki:</p><p>Конфиг Grafana Alloy: (локальный конфиг)</p><h2>Интерфейс: переход на Homepage</h2><p>Изначально для 
домашней страницы я написал кастомную минималистичную HTML-панель с 
Glassmorphism-дизайном. Выглядело это красиво, но добавлять новые 
сервисы вручную через постоянную правку исходного кода было крайне 
неудобно.</p><figure><img src="https://media.tproger.ru/user-uploads/139471/2026-07-15/8a8f2752-8aac-4aa5-898e-98affd01cdff.webp" alt="" /><figcaption>HTML + CSS</figcaption></figure><p>В итоге я заменил самописную страницу на полноценный комьюнити-проект Homepage.
 Это дало некоторую гибкость: вся панель настраивается через простые 
YAML-файлы и поддерживает встроенные виджеты интеграции. Пока что она 
простенькая, но возможно в будущем сделаю что-то более продвинутое.</p><figure><img src="https://media.tproger.ru/user-uploads/139471/2026-07-15/90c65d4a-1310-4a30-b1ad-9e4d3083959d.webp" alt="" /><figcaption>Homepage</figcaption></figure><h2>Заключение</h2><p>Постарался
 подробно рассказать о структуре проекта и как я к этому пришел, очень 
много я не добавил, если пост зайдет, то я обязательно более подробно 
пройдусь по некоторым моментам: как я настраивал Matrix и на каком 
моменте я решил его убрать, как собирал локальный amnezia 
контейнер-клиент, что нового я добавил в релизе 1.4.0 и другое.</p><p>Также
 я перешел с manage_deploy.sh на отдельный GUI клиент, который 
будет полностью автоматизировать процесс подготовки к deploy. (написан на Go Wails). Про это тоже возможно сделаю статью.</p><p>Вся кодовая база проекта, подробная документация, инструкции по развертыванию открыты и доступны для сообщества:</p><p>🔗 GitHub-репозиторий: <a href="https://github.com/canntstand/ServeHub-2" rel="noopener noreferrer nofollow">https://github.com/canntstand/ServeHub-2</a></p><p>Это
 моя первая статья на этом сайте и в то же время первый личный проект, которому я 
отдал так много времени (3 месяца). Буду рад вашему фидбеку в 
комментариях!</p>]]></content:encoded>
    </item>
    <item>
      <title>React-паттерн, который все используют, но он убивает производительность</title>
      <link>https://tproger.ru/articles/react-pattern-kotoryj-vse-ispolzuyut-no-on-ubivaet-proizvodite</link>
      <comments>https://tproger.ru/articles/react-pattern-kotoryj-vse-ispolzuyut-no-on-ubivaet-proizvodite?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/react-pattern-kotoryj-vse-ispolzuyut-no-on-ubivaet-proizvodite</guid>
      <description><![CDATA[<p>Почему React.memo перестаёт работать из-за inline-пропсов и как это исправить. Разбираем на примере со 200 строками и замерами.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/react-pattern-kotoryj-vse-ispolzuyut-no-on-ubivaet-proizvodite">React-паттерн, который все используют, но он убивает производительность</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Оптимизация]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 24 Jul 2026 04:56:37 GMT</pubDate>
      <content:encoded><![CDATA[<p>Вы обернули список в React.memo, добавили useCallback на обработчики и ждёте, что интерфейс полетит. Но при каждом вводе в поисковую строку список всё равно тормозит, а Profiler показывает 200 лишних рендеров. Чаще всего виноват не React, а один крошечный JSX-паттерн, который встречается в каждом втором компоненте.</p><p>В статье разбираем, почему React.memo сравнивает пропсы по ссылке, как inline-объекты и inline-функции обнуляют эту оптимизацию, и какие два простых приёма действительно возвращают производительность.</p><p>React.memo пропускает рендер только тогда, когда все пропсы равны по Object.is. Для объектов и функций это проверка по ссылке.</p><p>Inline-объекты и inline-колбэки в JSX создают новую ссылку на каждый рендер родителя, поэтому memo видит «новые» пропсы и снова рисует дочерний компонент.</p><p>В эксперименте со 200 memoизированными строками это дало 243,9 мс на один keystroke; после стабилизации ссылок — 6 мс.</p><p>Сначала выносите статические объекты за пределы компонента, а useCallback применяйте только там, где колбэк действительно пересекается с memoизированным потомком.</p><p>Оптимизировать всё подряд не нужно: измеряйте в Profiler, а не добавляйте хуки «на всякий случай».</p><h2>Как React решает, рендерить компонент заново или нет</h2><p>Когда родитель перерисовывается, React не делает послаблений дочерним элементам только потому, что они обёрнуты в React.memo. Он сравнивает новые пропсы со старыми. Если каждый проп проходит проверку Object.is, React может «отказаться» от рендера — bailout. Если хотя бы один проп не равен, компонент рисуется заново.</p><p>Для примитивов Object.is работает очевидно: 1 === 1 и 'hello' === 'hello'. А вот для объектов и функций сравнение идёт по ссылке.</p><p>Два объекта с одинаковым содержимым — это разные объекты в памяти. То же самое с функциями. Поэтому, когда вы пишете style=\{\{ padding: 16 \}\}, React получает новую ссылку на каждом рендере и считает проп изменившимся.</p><h2>Почему inline-пропсы — это не микрооптимизация, а поломка контракта</h2><p>Сам по себе объект в JSX не вреден. Если компонент дешёвый, редко перерисовывается и не обёрнут в memo, inline-пропсы почти не влияют на скорость. Проблема появляется, когда три условия накладываются друг на друга:</p><ul><li>родитель перерисовывается часто — поиск, скролл, фильтры, live-данные;</li><li>дочерний компонент или поддерево достаточно тяжёлые, чтобы лишний рендер был заметен;</li><li>вы уже добавили React.memo и ожидаете, что React будет пропускать работу.</li></ul><p>В такой ситуации нестабильные ссылки не просто добавляют накладных расходов — они полностью отменяют ту оптимизацию, ради которой вы взяли React.memo. UI продолжает работать, но лагает ввод, тормозят списки, а в Profiler видно, что дерево горит жёлтым при каждом чихе.</p><h3>Классический опасный пример</h3><p>Представьте список товаров из 200 строк. Каждая строка обёрнута в memo, но в месте вызова передаются inline-пропсы:</p><p>Здесь style и onAddToCart создаются заново при каждом рендере ProductList. Для memo это сигнал, что у каждой строки изменились пропсы, и все 200 компонентов рисуются снова.</p><h2>Эксперимент: от 243,9 мс до 6 мс на один keystroke</h2><p>Автор оригинальной статьи собрал контрольный пример: поисковый интерфейс со 200 memoизированными строками. Все строки получают одинаковые логические значения, но новые ссылки на объекты и функции. Результат после шести введённых символов: каждая видимая строка отрендерилась 14 раз.</p><p>В React DevTools Profiler один keystroke дал коммит длительностью 243,9 мс, в котором подсветились все 200 волокон строк. Инструмент @welldone-software/why-did-you-render прямо указал причину: props.style — «different objects that are equal by value», props.onAddToCart — «different functions with the same name».</p><p><b>Почему 14 рендеров?</b><br />
Каждый ввод в поиск меняет searchTerm, родитель перерисовывается, и inline-пропсы дают строкам новые ссылки. Счётчик рендеров растёт на каждый keystroke, даже если отфильтрованные товары не изменились.</p><h2>Как починить: два приёма вместо дюжины хуков</h2><p>Чтобы восстановить bailout, нужно сделать так, чтобы неизменяющиеся значения не получали новую ссылку на каждом рендере. Правило простое: сначала вынести, потом закешировать.</p><h3>1. Статические объекты — за пределы компонента</h3><p>Если объект не зависит от пропсов и состояния, создайте его один раз на уровне модуля. Это дешевле любого хука и не требует dependency-массива.</p><h3>2. Динамические колбэки — useCallback</h3><p>Если функция передаётся в memoизированный компонент и не должна меняться без причины, оберните её в useCallback со стабильным массивом зависимостей.</p><p>После этих двух изменений в эксперименте время рендера упало с 243,9 мс до 6 мс, счётчики строк застыли на 2, а Why Did You Render замолчал — avoidable re-renders исчезли.</p><h2>Когда не нужно ничего стабилизировать</h2><p>Главная ошибка — оборачивать в useCallback каждую функцию и выносить каждый объект за компонент. React сам по себе быстрый, а мемоизация — это контракт, а не стиль кодирования.</p><ul><li>Компонент дёшев и редко перерисовывается — не тратьте когнитивный бюджет команды.</li><li>Дочерний элемент не обёрнут в React.memo — тогда стабильные ссылки ничего не экономят.</li><li>Значение зависит от часто меняющегося состояния — useCallback с нестабильным массивом зависимостей всё равно будет пересоздаваться.</li><li>Вы ещё не замерили в Profiler — оптимизация без измерений почти всегда лишняя работа.</li></ul><p>React Compiler, который сейчас выходит в стабильное состояние, автоматически мемоизирует многое из того, что раньше делали вручную. Но и он не отменяет понимания ссылочной стабильности: useMemo и useCallback остаются полезными, когда нужен точный контроль, например для зависимостей эффектов.</p><h2>Часто задаваемые вопросы</h2><h2>Выводы</h2><p>Inline-объекты и inline-колбэки в JSX — не антипаттерн сами по себе. Они становятся проблемой только на границе memoизации, где React ожидает стабильные ссылки. Как только вы понимаете это правило, многие «таинственные» лишние рендеры перестают быть таинственными.</p><ol><li>Профилируйте до оптимизации, а не после.</li><li>Вынесите статические объекты за компонент — это самый дешёвый способ стабилизации.</li><li>Применяйте useCallback только для колбэков, которые уходят в memoизированные потомки.</li><li>Проверяйте себя через React DevTools Profiler и Why Did You Render.</li><li>Не забывайте про React Compiler, но не полагайтесь на него как на волшебную палочку.</li></ol><blockquote>Мемоизация — это контракт. Если потомок рассчитывает на стабильные ссылки, родитель должен их обеспечить. Нарушение этого контракта стоит намного дороже, чем отсутствие мемоизации вовсе.</blockquote><p><b>Источник:</b> <a href="https://blog.logrocket.com/react-pattern-everyone-uses-kills-performance/" rel="noopener noreferrer">LogRocket — The React pattern everyone uses that kills performance</a>.</p><p>Проверьте свой текущий проект: откройте React DevTools Profiler, введите что-нибудь в поиск и посмотрите, сколько компонентов подсветится жёлтым только из-за новой ссылки в пропсах.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как исправить hydration-ошибки RSC в Next.js: практический гид</title>
      <link>https://tproger.ru/articles/kak-ispravit-hydration-owibki-rsc-v-next-js-prakticheskij-gid</link>
      <comments>https://tproger.ru/articles/kak-ispravit-hydration-owibki-rsc-v-next-js-prakticheskij-gid?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-ispravit-hydration-owibki-rsc-v-next-js-prakticheskij-gid</guid>
      <description><![CDATA[<p>Разбираем, почему возникают hydration mismatches в React Server Components и Next.js App Router, и как находить, исправлять и предотвращать их в production.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-ispravit-hydration-owibki-rsc-v-next-js-prakticheskij-gid">Как исправить hydration-ошибки RSC в Next.js: практический гид</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Лучшая практика]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Отладка]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 21 Jul 2026 11:37:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Hydration mismatch в Next.js легко поймать в next dev, но в production он превращается в минимизированный код ошибки React и ссылку на декодер. В статье разбираем, почему ошибки гидратации особенно болезненны в приложениях с React Server Components, какие причины встречаются чаще всего и какой рабочий процесс помогает находить и предотвращать такие баги.</p><p>Речь пойдёт не о теории reconcile-алгоритма, а о практике: что проверять первым делом, как изолировать проблему через Suspense, куда смотреть в production-логах и как писать тесты, которые ловят регрессии до попадания к пользователям.</p><h2>Что такое hydration mismatch</h2><p>Гидратация — это процесс, при котором React берёт серверный HTML и навешивает на него обработчики событий, после чего страница становится интерактивной. React ожидает, что дерево, которое он отрендерил на клиенте, точно совпадёт с тем, что пришло с сервера. Если строки, атрибуты или структура различаются, возникает hydration mismatch.</p><p>В development-режиме React покажет предупреждение, текст расхождения и стек компонента. В production всё сводится к коротким кодам вроде #418 или #425. Без телеметрии вы не узнаете, на каком маршруте, в каком компоненте и из-за каких данных произошёл сбой.</p><h2>Почему это больно именно в RSC</h2><p>В классическом SSR обычно один серверный рендер и один клиентский проход гидратации. App Router добавляет Server Components, Client Components, потоковую передачу, Suspense-границы, динамические данные маршрута и RSC payload, который едет рядом с HTML.</p><p>Когда несовпадение происходит вне Suspense-границы, React может отбросить весь серверный HTML и перерендерить дерево на клиенте. Приложение заплатило цену серверного рендера, а пользователь не получил ни производительности, ни преимуществ стриминга. Это не просто предупреждение в консоли, а реальная потеря производительности.</p><h2>Ключевые выводы</h2><ul><li>Hydration mismatch в production без телеметрии почти невозможно локализовать: нужна инструментация на клиенте.</li><li>Основные причины: browser-only API, дата/время/локаль, состояние авторизации, невалидный HTML, расширения браузера, CSS-in-JS.</li><li>Граница 'use client' — это не только маркер сборки, но и граница гидратации: серверный рендер должен быть детерминирован.</li><li>Suspense-границы помогают изолировать сбой и не давать ему сломать всё дерево.</li><li>Проверяйте hydration только на production-сборке: next dev ведёт себя иначе.</li><li>Добавьте Playwright-smoke-тесты на критичные маршруты, чтобы ловить регрессии в CI.</li></ul><h2>Самые частые причины</h2><p>Перед тем как копать RSC payload или сравнивать HTML, стоит проверить шесть типовых сценариев. Они покрывают подавляющее большинство production-инцидентов.</p><ul><li><b>Browser-only API во время рендера:</b> window, document, localStorage, navigator — сервер не знает об этих значениях.</li><li><b>Дата, время и локаль:</b> Date, Intl.DateTimeFormat, относительное время — сервер обычно в UTC, пользователь в своей зоне.</li><li><b>Состояние авторизации:</b> сервер рендерит выклогнутый UI, клиент сразу видит авторизованного пользователя.</li><li><b>Невалидный HTML:</b> браузер чинит DOM до гидратации, а React сравнивает с исходным деревом.</li><li><b>Расширения и middleware:</b> браузерные плагины и edge-переписывания меняют HTML.</li><li><b>CSS-in-JS и порядок классов:</b> styled-components и Emotion могут генерировать разные имена классов при стриминге.</li></ul><h3>Browser-only API и сторонние провайдеры</h3><p>Самая частая причина — не ваш собственный код, а сторонний провайдер, который читает localStorage, window или navigator при инициализации. Под это попадают аналитика, фичер-флаги, A/B-тесты, session replay и персонализация.</p><p>Проблемный вариант: провайдер читает localStorage прямо при рендере.</p><p>Исправление: серверные флаги передаются в Client Component, а локальные оверрайды применяются после гидратации.</p><p><b>Принцип:</b> серверный и первый клиентский рендер должны получить одинаковый результат. Браузерные оверрайды включаются в useEffect после монтирования.</p><h3>Дата, время и локаль</h3><p>Сервер часто работает в UTC, а пользователь — в своей зоне. Date.toLocaleString(), Intl.DateTimeFormat и функции вроде formatDistanceToNow() дают разные строки в зависимости от часового пояса и времени между рендером и гидратацией.</p><p>Проблемный вариант: относительное время считается на сервере.</p><p>Исправление: сервер отдаёт стабильную абсолютную дату, клиент заменяет её на относительную после монтирования.</p><p>suppressHydrationWarning здесь уместен, потому что расхождение ожидаемо, ограничено листовым элементом  и управляется явно. Но оборачивать им большой контейнер, чтобы скрыть неизвестную ошибку, — значит замазать баг, а не починить его.</p><h3>Состояние авторизации</h3><p>Типичный сценарий: сервер рендерит UI для неавторизованного пользователя, потому что маршрут статический или не читает куки, а клиент сразу видит залогиненного пользователя. При каждой загрузке страница перерендеривается.</p><p>Решение — читать куки на сервере через cookies() из next/headers.</p><p>С cookies() маршрут становится динамическим — это обычно правильный компромисс для UI, зависящего от авторизации. Начиная с Next.js 15, cookies() асинхронный и требует await. В Next.js 16 синхронный доступ к request-time API полностью уходит.</p><h3>Невалидный HTML</h3><p>Браузер молча чинит невалидную вёрстку. React же гидратирует не исходную строку, а DOM, который построил браузер. Классический пример —  внутри <p></p>: браузер закроет параграф до div, и React увидит другое дерево.</p><p>Браузер превратит это в примерно такую структуру:</p><p>Если HTML приходит из CMS или редактора, валидируйте и нормализуйте его на сервере. Для собственных компонентов следите за предупреждениями validateDOMNesting в DevTools.</p><h3>Расширения браузера и middleware</h3><p>Менеджеры паролей, переводчики, грамматические плагины и другие расширения могут вставлять или переупорядочивать узлы до гидратации. Edge middleware и CDN-трансформации тоже могут переписывать HTML в пути.</p><p>Если несовпадение затрагивает только &lt;html&gt; или &lt;body&gt;, сначала подозревайте расширения. React 19 стал терпимее к инъекциям в head/body, но на старых версиях такие ошибки особенно шумные.</p><p>suppressHydrationWarning на корневых элементах — документированный escape hatch, но он работает только на один уровень вглубь и не должен использоваться для сокрытия неизвестных расхождений в продуктовом UI.</p><h3>CSS-in-JS и порядок классов</h3><p>В проектах со styled-components или Emotion имена классов могут зависеть от порядка рендера. Стриминг и Suspense меняют этот порядок, поэтому нужен registry с useServerInsertedHTML.</p><h2>Production workflow для отладки</h2><p>Не начинайте с diff-а огромных HTML-документов. Работайте по порядку, сужая область поиска.</p><ol><li>Настройте клиентскую телеметрию: перехватывайте console.error и отправляйте hydration-ошибки на свой endpoint.</li><li>Воспроизводите баг на production-сборке: next build &amp;&amp; next start, а не next dev.</li><li>Используйте Suspense-границы, чтобы изолировать проблемный участок и понять, в каком поддереве ошибка.</li><li>Сравнивайте серверный HTML (curl) и клиентский DOM после гидратации.</li><li>Когда найдёте расходящийся элемент, проверьте: browser-only API, дата/время, авторизацию, HTML-вложенность, расширения, стили.</li></ol><h3>Инструментация: instrumentation-client.ts</h3><p>Файл instrumentation-client.ts в Next.js запускается после загрузки документа, но до гидратации React. Это удобная точка для лёгкой клиентской телеметрии.</p><p>Если используете LogRocket, Sentry или другой инструмент, прикрепите тот же payload к текущей сессии — тогда можно будет увидеть, как выглядела страница в момент сбоя.</p><h3>Изоляция через Suspense</h3><p>Suspense-границы не только показывают fallback при загрузке. Если hydration mismatch случается внутри границы, React может ограничить восстановление этим поддеревом, а не переключать весь root на клиентский рендер.</p><p>Оберните поочерёдно основные секции. Если страничная ошибка исчезает после оборачивания конкретной секции, баг почти наверняка внутри неё.</p><h3>Сравнение HTML и DOM</h3><p>Получите серверный HTML через curl с нужными куками:</p><p>В Chrome DevTools после загрузки страницы скопируйте живой DOM:</p><p>Сохраните результат в /tmp/client-render.html и сравните:</p><p>Этот метод хорошо ловит HTML-слой, но может пропустить расхождения на уровне reconciler-а и RSC payload. Если raw HTML совпадает, проверяйте Client Components и браузерное состояние.</p><h2>Профилактика</h2><p>Лучше не допускать ошибки, чем потом их чинить. Несколько практик, которые помогают держать серверный и клиентский рендер синхронизированными.</p><ol><li>Server Component должен быть детерминированным: одни и те же входные данные дают одни и те же выходные HTML и RSC payload.</li><li>Все browser-only API, куки, заголовки, локаль и время должны оставаться за границей 'use client' или читаться через request-time API на сервере.</li><li>Для клиентского UI сначала рендерите стабильный baseline, а улучшения добавляйте в useEffect после гидратации.</li><li>Валидируйте HTML из внешних источников до того, как React его увидит.</li><li>Тестируйте hydration на production-сборке в CI.</li></ol><h3>Пример: стабильный baseline + клиентское улучшение</h3><p>Скелетон — это стабильная базовая разметка. Карточки товаров появляются после монтирования. Сервер и первый клиентский рендер совпадают, а пользователь получает нужный контент чуть позже.</p><h3>Smoke-тесты в CI</h3><p>Ручное тестирование пропустит регрессии. Добавьте Playwright-тест на критичные маршруты.</p><p>Запускайте такой тест только против production-сборки, никогда против next dev. Сделайте его обязательной проверкой для маршрутов, где hydration failure критичен: продуктовые страницы, дашборды, чекаут, личный кабинет.</p><h2>FAQ</h2><h2>Выводы</h2><p>Hydration mismatch — не придирка React, а реальный баг производительности и корректности. Каждое несовпадение означает, что приложение могло отбросить серверный HTML, за который уже заплатило ресурсами.</p><p>В приложениях с React Server Components, где цель — меньше клиентского JavaScript и более ранний стриминг полезного UI, hydration failures тихо отменяют эти преимущества. Поэтому важно держать браузерную логику за границей 'use client', рендерить стабильные серверные baseline и проверять гидратацию в production-условиях до того, как ошибку найдут пользователи.</p><blockquote>Hydration errors should be fixed, not ignored — официальная позиция React.</blockquote><p><b>Источник:</b> <a href="https://blog.logrocket.com/how-fix-rsc-hydration-mismatches-next-js/" rel="noopener noreferrer">LogRocket Blog — How to fix RSC hydration mismatches in Next.js</a>.</p><p>Проверьте свои критичные маршруты на production-сборке, настройте телеметрию и не давайте hydration-ошибкам копиться в консоли.</p>]]></content:encoded>
    </item>
    <item>
      <title>«Почему стоит перестать деструктурировать всё в JavaScript»</title>
      <link>https://tproger.ru/articles/pochemu-ya-perestal-destrukturirovat-vsyo-v-javascript</link>
      <comments>https://tproger.ru/articles/pochemu-ya-perestal-destrukturirovat-vsyo-v-javascript?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/pochemu-ya-perestal-destrukturirovat-vsyo-v-javascript</guid>
      <description><![CDATA[<p>Разбираем, когда деструктуризация объектов в JS и React упрощает код, а когда делает его труднее для чтения. Практические правила от Мэтта Смита.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/pochemu-ya-perestal-destrukturirovat-vsyo-v-javascript">«Почему стоит перестать деструктурировать всё в JavaScript»</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 20 Jul 2026 05:40:11 GMT</pubDate>
      <content:encoded><![CDATA[<p>Если вы пишете на JavaScript, скорее всего, деструктуризация — один из первых паттернов, который вы используете каждый день. Но что, если автоматическая деструктуризация делает код не короче, а труднее для чтения?</p><p>В своей статье разработчик Мэтт Смит объясняет, почему перестал раскладывать объекты на переменные по умолчанию и как это изменило его подход к читаемости кода.</p><p><b>Деструктуризация — инструмент, а не норма.</b> Её стоит применять там, где она правда упрощает код, а не просто экономит символы.</p><p><b>Объект хранит контекст.</b> project.status понятнее, чем голая переменная status, особенно в больших функциях.</p><p><b>Вложенные объекты раскрывайте поэтапно.</b> Сначала доберитесь до нужного уровня, а потом уже извлекайте поля.</p><p><b>Деструктурируйте позже, а не раньше.</b> Сохраняйте исходный объект до тех пор, пока он действительно не понадобится в разобранном виде.</p><p><b>Каждая новая переменная — когнитивная цена.</b> Если имя не добавляет смысла, лучше обратиться к свойству объекта напрямую.</p><h2>Деструктуризация — не религия</h2><p>Несколько лет назад Мэтт Смит деструктурировал почти всё: объекты, пропсы, параметры, возвращаемые значения. Если встречался объект — он его раскладывал. Это перестало быть осознанным решением и превратилось в привычку: так пишет «современный JavaScript».</p><p>Сейчас он всё ещё использует деструктуризацию, но уже не автоматически. Причина простая: возвращаясь к старому коду, Смит тратит больше времени, чем ожидает, чтобы понять, откуда взялась та или иная переменная. Ему приходится мысленно собирать исходный объект обратно, прежде чем разобраться, что происходит.</p><p>В какой-то момент до него дошло: он оптимизировал процесс написания, а не чтения. Экономия нескольких нажатий клавиш сегодня оборачивалась дополнительными минутами разбора завтра.</p><h2>Не бойтесь повторов</h2><p>Один из самых распространённых паттернов — вынесть поля из объекта, а потом передать их как пропсы в компонент:</p><p>С этим ничего не случилось. Но сегодня автор с большей вероятностью напишет так:</p><p>Да, здесь повторяется post. Но когда он вернётся к этому коду через месяц, ему не придётся вспоминать, откуда взялись title или author. Контекст остаётся на виду.</p><h2>Объект несёт контекст</h2><p>Это особенно заметно в длинных функциях. Представьте, что в начале файла вы написали:</p><p>А сто строк ниже встретили такой код:</p><p>Моментальная пауза: «archived»… что именно? Сравните с вариантом, где объект сохраняет свою форму:</p><p>Объект по-прежнему несёт полезный контекст. Лишние символы редко замедляют чтение. А вот необходимость помнить, к какой сущности относится переменная, замедляет гораздо сильнее.</p><h2>Вложенность лучше раскрывать поэтапно</h2><p>Раньше автор считал вложенную деструктуризацию элегантной. Сейчас она часто кажется попыткой понять всю структуру объекта ещё до того, как начал решать задачу.</p><p>Автор предпочитает писать иначе:</p><p>Так лучше отражается мышление о данных: сначала интересует профиль, а уже потом, если нужно, из него извлекают конкретные поля.</p><h2>Деструктурируйте позже, а не раньше</h2><p>С параметрами компонентов ситуация похожа. Для маленьких компонентов деструктуризация пропсов отлично работает:</p><p>Но по мере роста компонента автор чаще пишет так:</p><p>Ему нравится держать исходный объект под рукой до тех пор, пока он действительно не понадобится в разобранном виде. Это также упрощает понимание того, что получил компонент.</p><h2>Каждая переменная — цена для читателя</h2><p><b>Каждая локальная переменная просит читателя запомнить ещё одно имя.</b> Иногда это стоит того, иногда — нет.</p><p>Если новая переменная обозначает осмысленную концепцию, автор с удовольствием её вводит. Имя вроде billingAddress становится частью словаря функции.</p><p>Но если автор просто превращает project.status в status, уверенности, что код стал читабельнее, нет. Полезное правило большого пальца: если деструктуризация даёт коду лучший словарь — использует её. Если она только экономит несколько символов — обычно нет.</p><h2>Когда деструктуризация всё ещё уместна</h2><p>Всё вышесказанное — не аргумент против деструктуризации. Автор по-прежнему применяет её постоянно.</p><p>Эти случаи локальны, сфокусированы и убирают шум. Есть и другие исключения. При маппинге массива я спокойно пишу:</p><p>Объект существует всего несколько строк, поэтому автор не чувствует, что теряет контекст. Иногда имеет смысл даже переименовать извлечённое свойство: const { status: projectStatus } = project;.</p><p>Такое имя сохраняет больше контекста, чем просто status. Но если автор всё равно несёт имя объекта в переменную, часто оказывается, что project.status читается естественнее. Не нужно придумывать новое имя, а связь с объектом остаётся очевидной.</p><p>Разница в том, что автор больше не деструктурирует просто потому, что объект существует.</p><h2>Главный вопрос</h2><p>Автор всё ещё любит деструктуризацию. Есть множество мест, где она заметно очищает код. Просто он больше не хватается за неё автоматически.</p><p>Перед тем как убрать объект, он спрашивает себя: удаление объекта действительно облегчает понимание или просто делает код короче?</p><blockquote>Если деструктуризация даёт коду лучший словарь — автор её использует. Если она только экономит несколько символов — обычно нет.</blockquote><h2>Выводы</h2><p>Деструктуризация остаётся одним из самых полезных синтаксических улучшений JavaScript. Но удобство записи не должно превращаться в удобство только для автора. Читаемость кода измеряется не количеством символов, а скоростью, с которой человек понимает, что происходит.</p><p>Сохраняйте объекты там, где они несут контекст. Раскрывайте вложенность поэтапно. Вводите переменные, только если они добавляют смысла. И не забывайте главный вопрос: вы делаете код понятнее или просто короче?</p><p><b>Источник:</b> <a href="https://allthingssmitty.com/2026/07/13/i-stopped-destructuring-everything/">Matt Smith — I stopped destructuring everything</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Разработчик уходит, инженер остаётся: как AI-экосистема меняет работу команды разработки</title>
      <link>https://tproger.ru/articles/razrabotchik-uhodit-inzhener-ostayotsya-kak-ai-ekosistema-menyaet-r</link>
      <comments>https://tproger.ru/articles/razrabotchik-uhodit-inzhener-ostayotsya-kak-ai-ekosistema-menyaet-r?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Ислам Виндижев]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/razrabotchik-uhodit-inzhener-ostayotsya-kak-ai-ekosistema-menyaet-r</guid>
      <description><![CDATA[<p>Александр Сахаров (Диасофт) — о том, почему чисто агентский подход к разработке устарел, чем опасен вендорлок на LLM и как устроена AI-driven Digital Q.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/razrabotchik-uhodit-inzhener-ostayotsya-kak-ai-ekosistema-menyaet-r">Разработчик уходит, инженер остаётся: как AI-экосистема меняет работу команды разработки</a>»</p>]]></description>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Аналитика]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 16 Jul 2026 14:16:47 GMT</pubDate>
      <content:encoded><![CDATA[<p><i>Александр Сахаров — член правления и директор по работе с партнёрами Диасофт — на партнёрском дне 29го мая 2026 года вёл программу и показывал обновлённый процесс разработки на платформе</i> <i>Digital Q.</i></p><figure><img src="https://media.tproger.ru/user-uploads/133609/2026-07-15/20558e56-1e70-4f4c-9cf9-952891070b29.webp" alt="" /></figure><p>AI продолжает плотно внедряться в процессы самых разных компаний. Строятся пайплайны и цепочки агентов, жгутся токены, генерируются тонны кода и строятся целые AI-экосистемы для разработки. Это обсуждают практически на всех отраслевых конференциях, ищут способы внедрения и оптимизации процессов.</p><p>Редакция Tproger недавно была нескольких таких ивентах и на партнёрском дне Диасофт пообщалась с членом правления Диасофт и директором по работе с партнёрами Александром Сахаровым. Мы поговорили о том, почему агентская разработка в её нынешнем виде — тупик, как строить эффективные AI-процессы разработки, почему фреймворк теперь важнее модели и что нового в AI-обновлении <a href="https://q.diasoft.ru/" rel="nofollow">платформы Digital Q</a>.</p><p><a href="https://q.diasoft.ru/">Digital Q</a> — российская low-code экосистема разработки от «Диасофт» с готовым «заводом» инструментов для сборки корпоративных приложений: от проектирования бэкенда, дизайна интерфейсов до DevOps. В мае 2026 года вышла AI-driven версия, где искусственный интеллект встроен в саму платформу — он проектирует архитектуру, генерирует код, фронтенд и бизнес-процессы по человекочитаемой спецификации, оставляя разработчику работу с замыслом, а не с рутиной.</p><h2>AI добрался до фундамента</h2><p><b>— Александр, начну с прямого вопроса. ИИ обсуждают на каждом углу. Как вы считаете, что действительно изменилось, стало главным сдвигом, а что просто шум?</b></p><p>— Главный сдвиг — это то, что AI добрался до вещей, которые казались незыблемыми. ERP-системы — это же фундамент крупного предприятия. И мы своими глазами видим, как крупные компании переходят на вайб-кодинг ERP. Звучит страшновато, но это факт, это происходит не в стартапах, а в очень больших организациях. Банки, промышленность, энергетика — везде одно и то же.</p><p>А шум — это вера, что AI всё решит сам по себе. Что можно купить лицензии Copilot, посадить за них разработчиков и они вам начнут производить продукты в десять раз быстрее. Нет, не начнут. Точнее, начнут, но счета вас очень неприятно удивят.</p><h2>От агентов к AI-native платформе</h2><blockquote>Агентская разработка как самостоятельный подход не работает. Не масштабируется. Подход должен быть AI-native</blockquote><p><b>— Вы на сцене показывали, как обновился Digital Q с декабря. Что конкретно поменялось за эти полгода?</b></p><p>— В декабре, на зимнем партнёрском дне, мы представили платформу Digital Q.GPT — на ней можно реализовывать агентский workflow. Интеграция со всеми LLM-моделями, экосистема построения агентов, мультиагентные системы. На тот момент это было супер актуально.</p><p>К маю выяснилось, что этого недостаточно. За последние шесть месяцев все — Anthropic, Google, Gartner, Amazon, Сбер на ЦИПР — пришли к одному и тому же выводу: агентская разработка как самостоятельный подход не работает. Не масштабируется. Подход должен быть AI-native, то есть AI вшит в саму экосистему разработки, а не прикручен сбоку отдельными агентами.</p><p><b>— А что плохого в агентах?</b></p><p>— С агентами ничего плохого, они нужны. Плохо, когда вся разработка строится только вокруг них. Если кто-то хочет писать агенты — пожалуйста, в Digital Q.GPT весь функционал остался: workflow, мультиагентные системы, всё это работает. Но это уже не центральная история. Центральная история теперь — единая экосистема, в которую AI встроен на каждом этапе процесса.</p><h2>Три способа потерять деньги на AI</h2><blockquote>Сегодня становится очевидно, что фреймворк важнее модели. Весь контекст, знания и артефакты разработки должны находиться внутри собственной экосистемы компании, а не зависеть от поставщика LLM. Это позволяет управлять стоимостью разработки, сохранять независимость и обеспечивать масштабирование решений.</blockquote><p><b>— Давайте про антипаттерны. Вы на сцене перечислили целый список — что точно делать не надо. Какой из них самый болезненный?</b></p><p>— Самый болезненный — вендорлок на конкретную LLM. Если вчера вы платили 20 долларов на разработчика в месяц, завтра это 100, послезавтра 200. Скоро будет дороже, чем один разработчик в месяц. И весь ваш контекст — спецификации, история, наработки — лежит у этой модели. Вы заложник. Они вам говорят: «не парьтесь, весь контекст у нас, всё будет хорошо». Хорошо у них будет, а у вас потом будут проблемы.</p><p>Второй болезненный — зоопарк инструментов. Если у вас разработчики накодили чего-то в пяти разных средах, потом вы это нормально не соедините. Получится лоскутное одеяло, только сделанное в десять раз быстрее, чем раньше.</p><p>Третий — использовать AI только в кодировании. Это путь в галлюцинации и в бесконечные ошибки, которые вы потом просто не отследите.</p><p><b>— Как можно решить эти проблемы?</b></p><p>— Главный тезис: фреймворк важнее модели. Они это называют harness, мы называем экосистема разработки. Есть термины IDP — Integrated Development Platform, IDE — Integrated Development Environment. Суть одна. Ваш фреймворк должен быть локально у вас, весь контекст — локально у вас, модели должны быть взаимозаменяемые. Тогда вы можете переключаться между ними и управлять стоимостью.</p><p>Простой Copilot, кстати, не работает. Слишком большой технический долг возникает. Это не моя позиция, это уже общее наблюдение крупных игроков.</p><h2>Как теперь устроена разработка</h2><p><b>— Вы говорили про два контура разработки. Объясните для тех, кто услышит об этом впервые.</b></p><p>— Раньше был один контур: ТЗ — постановка — кодирование — тестирование — релиз. Долго, последовательно. Цифровая трансформация это ускорила: годы превратились в кварталы и месяцы. Но всё равно один линейный процесс.</p><p>Сейчас он распадается на два. Первый — контур замысла, или, как у Сбера говорят, контур намерений. Здесь работает человек. Описывает на естественном языке, что хочет получить. Агенты помогают разложить это на артефакты — процессы, формы, справочники, архитектуру. Человек видит результат визуально, проверяет, правит, опять же голосом или текстом.</p><p>Второй контур — контур реализации. Здесь уже всё на агентах и моделях. Это фактически чёрный ящик под замыслом. Человек его контролирует только по результату. Не нравится — возвращается в контур замысла, правит спецификацию, перезапускает.</p><p>И самое важное между ними — экосистема, которая держит все артефакты и весь контекст. Если этой экосистемы нет — у вас ничего не получится развивать. Сгенерили код, отдали в продакшен, а через полгода вы уже не понимаете, как туда внести изменение.</p><p><b>— Это та же мысль, что и про вендорлок, по сути?</b></p><p>— Та же. Если экосистема не у вас, контекст не у вас, спецификации не у вас — вы теряете возможность развивать продукт. Останется только сгенерированный код, а к коду без замысла осмысленных изменений уже не приделать. После какого-то уровня сложности — точно.</p><p><b>— Вернёмся к Digital Q. Как она теперь устроена? Если разобрать на компоненты — что там лежит?</b></p><p>— Если коротко — то, во что крупные компании годами вкладываются, чтобы отстроить правильный процесс разработки. Независимость от модели — это базовое. Полный SDLC: как правильно писать, какие артефакты должны быть. Репозиторий справочников, репозиторий процессов, репозиторий потоков. Работа с данными. Поддержка двухконтурной модели. Единые репозитории инструкций для разного типа агентов. Полностью DevOps. Полностью процесс тестирования.</p><p>На самом деле там на двухчасовой разговор материала. Но главная мысль одна: только такая штука обеспечивает вам контроль по затратам, нормальный процесс и независимость от иностранных LLM или дорогих российских моделей.</p><blockquote>Разработчик всегда идёт на самую дорогую модель — она же лучшая. И запускает её сто раз в день. Ему кажется, что это бесплатно. Извините, не бесплатно.</blockquote><p><b>— Почему вы так настойчиво возвращаетесь к теме денег? Ведь все маркетинговые материалы AI-вендоров обещают именно экономию.</b></p><p>— Потому что это самая опасная иллюзия сейчас. Uber, пытаясь сэкономить на разработчиках, потратил больше трёх миллиардов долларов на AI-генерацию кода. Японская компания за несколько месяцев потратила 500 миллионов долларов вместо тех людей, которых сократили. Долларов, не рублей. И это уже не теория, это свежие кейсы 2025–2026 годов.</p><p>Почему так получается? Потому что разработчик, если его не ограничивать, всегда идёт на самую дорогую модель — она же лучшая. И запускает её сто раз в день. Увидел маленькое расхождение в результате — поправил формулировку — перегенерил всё. Ему же кажется, что это бесплатно. Это так красиво, так удобно — нажал кнопку, всё пересоздалось. Извините, не бесплатно. Это огромные деньги. Свобода такая, что разоряет.</p><p><b>— И как вы с этим боретесь технически?</b></p><p>— Лимиты в самой экосистеме. Разработчикам автоматически предлагаются более дешёвые модели для простых задач, иногда вообще бесплатные. Жёстко зашиваем: при изменениях перегенерация только изменённых частей, не модуля целиком. Если в модуле 50 тысяч строк кода, и вы поправили одну спецификацию — не должны перегенериваться все 50 тысяч.</p><p>И главное — переиспользование. Когда мы даём задание на исполнение, первый шаг — найти весь код в репозитории, который можно встроить. Если компонент уже есть — мы его не генерим, мы его подключаем. Ни одного токена сюда не тратится. Половину нового модуля у нас собирается из готового кода. К модели обращаемся только за тем, чего ещё нет.</p><p><b>— Расскажите про демо с CRM. Вы показывали, как из 400-страничного ТЗ получается работающее приложение. Это правда один день двух человек, или там есть нюансы?</b></p><p>— Один день двух человек — это правда. Нюансы есть, конечно. Главный: это не black box, который сгенерил вам что-то непонятное. Это полностью оснащённый артефактами IT-проект. Можно пойти и сдать любому госзаказчику по ГОСТу. Полная документация — техническая, пользовательская, финансовая. Полный набор описанных бизнес-процессов. Полный набор тестов, включая тесты на уязвимости.</p><p>Что происходит по шагам? Загружаем ТЗ в основной контекст платформы. Она начинает читать, находит нестыковки, раскладывает по полочкам — где процесс, где поток, где архитектура. Задаёт уточняющие вопросы заказчику. Можно ответить, можно сказать «работаем как есть» — тогда она дальше креативит по тому, что есть.</p><p>Дальше прорисовывает архитектуру бэкенда. Здесь критически важный момент: она смотрит на репозиторий и решает, что писать с нуля, а что переиспользовать. У неё в инструкциях жёстко зашито: инфобез не писать, использовать готовый. Логирование не писать. Справочники, типовые штуки — не переписывать. Только то, что реально новое.</p><p><b>— А фронтенд?</b></p><p>— Полностью автогенерация. Мастер: меню справа, меню слева, нужна аналитика — не нужна, нажал галочки — получил весь фронт. Документированный, открытый, лежит в гите. Дальше можно дорабатывать голосом — буквально говоришь в микрофон «добавь форму жалобы на робота», и она лезет в MCP, смотрит схему дизайна, добавляет форму, обновляет версии, выпускает изменение. Современные разработчики уже на клавиатуре ничего не пишут — у них микрофон.</p><p>Потом бизнес-процессы. Та же AI-машина смотрит на ТЗ и генерит BPMN-процесс — уже машиночитаемый, его можно сразу выполнять. Но она же его и критикует: смотрит со стороны и говорит — у вас тут проблема, тут проблема, ТЗ было неполным, давайте решать. И человек уже работает с агентом, который ему подсвечивает дыры.</p><p>И финал — DevOps-сборка, докер-образы, юнит-тесты, интеграционные, регрессионные, тесты на уязвимости. Половина этих тестов сгенерилась автоматически по нашим стандартам ещё на этапе подготовки.</p><p><b>— Вы говорили, что AI-агенты теперь работают не только в коде, но во всех ролях — от аналитика до девопса. Как это устроено?</b></p><p>— У каждой роли — аналитик, архитектор, фронтенд-разработчик, бэкенд-разработчик, девопс-инженер — теперь свой набор агентов. И не только в IT-ролях. Продавцы, юристы, логисты, кадровики — у всех появляются свои агенты. На некоторых российских предприятиях речь идёт уже не о сотнях, а о тысячах агентов, которые работают параллельно и автоматизируют не только разработку, но и все процессы внутри организации.</p><p>Фишка нашей платформы в том, что мы все роли оснастили всеми агентами из коробки. Не надо ничего собирать самому. Скачали Digital Q, поставили, производите ПО.</p><h2>Что доступно прямо сейчас</h2><blockquote>С июля начинаем публиковать обновлённую версию. Можно скачать, развернуть, запускать.</blockquote><p><b>— И эта экосистема действительно доступна партнёрам?</b></p><p>— Да, мы её отдаём рынку. С июля начинаем публиковать обновлённую версию для партнёров. Можно скачать, развернуть, запускать. Правда, нужно знать, что такое Kubernetes и Kafka — это не магический инсталлер для гуманитариев. Но если знаете — берёте и работаете.</p><p>У нас уже сейчас несколько десятков компаний создали свои продукты на этой экосистеме. Кто-то с большим успехом, крупные компании тоже распробовали и начали работать.</p><p><b>— Возвращаясь к началу разговора. Вы фактически заявляете, что Диасофт — единственный, кто отдаёт такую экосистему рынку. Это правда так, или маркетинг?</b></p><p>— Это так. Давайте честно: на российском рынке такие экосистемы делают несколько компаний. Сбер, ВТБ, Тинькофф — для себя. Это им и нужно, у них колоссальные команды разработки, они это могут себе позволить. Кто-то из телекома делает для своих больших разработок. Иногда они пробуют что-то предложить рынку, но по большому счёту — это всё «для себя».</p><p>Диасофт делает экосистему и для себя, и для рынка. Сегодня в рынок такую экосистему — уже трансформированную под AI — фактически продолжаем отдавать только мы. Это наш бизнес, это наша история. Сбер и другие крупные игроки сейчас взяли паузу с публикацией для рынка, на два-три года минимум. После этого цикла, может быть, появится альтернатива. Сейчас её нет.</p><blockquote>Если такого человека нет — никакая AI-генерация вас не спасёт. Будет только дороже и хуже.</blockquote><p><b>— Какой главный совет тем, кто только сейчас задумывается о собственной AI-трансформации разработки?</b></p><p>— Не повторяйте чужих ошибок. Не садитесь на одну модель — это вендорлок, и он дорого стоит. Не пытайтесь решить всё через агентов поверх существующего бардака — масштабироваться не будет. Не верьте, что AI сам по себе сэкономит вам деньги — без управляющей экосистемы он их сожрёт быстрее, чем вы успеете уволить разработчиков.</p><p>И ещё одно. Команды теперь строятся вокруг продуктового инженера. Это новая ключевая роль. Раньше ценностью был код. Сейчас ценность — бизнес-компетенция, способность правильно поставить задачу. Если у вас есть человек, который понимает бизнес и умеет это сформулировать — код появится быстро. Если такого человека нет — никакая AI-генерация вас не спасёт. Будет только дороже и хуже.</p><h2>Бонус: чек-лист «AI-разработка без иллюзий»</h2><p>Разговор получился интересный, и мы собрали для вас короткий чек-лист, который пригодится и разработчикам, и бизнесу.</p><p><b>Чего точно не стоит делать:</b></p><p>— Сажать команду на одну LLM-модель — это вендорлок, и он будет дорожать;</p><p>— Разрешать разработчикам неограниченно гонять самую дорогую модель;</p><p>— Использовать AI только в кодировании, без интеграции в остальной процесс;</p><p>— Накупить разных инструментов и надеяться, что они потом «как-нибудь соберутся»;</p><p>— Сокращать разработчиков в расчёте на «бесплатные» токены.</p><p><b>Что стоит сделать:</b></p><p>— Держать экосистему разработки и весь контекст локально;</p><p>— Зашить в платформу переиспользование кода — половину нового модуля собирать из готового;</p><p>— Настроить лимиты: дешёвые модели для простых задач, перегенерация только изменённых частей;</p><p>— Разделить процесс на два контура — замысла (где работает человек) и исполнения (где работают агенты);</p><p>— Растить продуктовых инженеров — людей, умеющих формулировать задачу, а не только писать код.</p><p>Реклама. Рекламодатель: ООО «Диасофт», ИНН 7715560268, erid: 2W5zFJRM88q</p>]]></content:encoded>
    </item>
    <item>
      <title>Кнопка «наверх» в Django: почему в проде это уже не три строки JavaScript</title>
      <link>https://tproger.ru/articles/knopka-naverh-v-django-pochemu-v-prode-eto-uzhe-ne-tri-stroki-j</link>
      <comments>https://tproger.ru/articles/knopka-naverh-v-django-pochemu-v-prode-eto-uzhe-ne-tri-stroki-j?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Фёдор Малков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/knopka-naverh-v-django-pochemu-v-prode-eto-uzhe-ne-tri-stroki-j</guid>
      <description><![CDATA[<p>Как добавить кнопку «наверх» в Django-сайт и Django Admin: настройка, CSP, доступность, мобильная версия и работа рядом с cookie-баннерами.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/knopka-naverh-v-django-pochemu-v-prode-eto-uzhe-ne-tri-stroki-j">Кнопка «наверх» в Django: почему в проде это уже не три строки JavaScript</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[CSS]]></category>
      <category><![CDATA[jQuery]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Django]]></category>
      <category><![CDATA[MIT]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Дизайн]]></category>
      <category><![CDATA[CDN]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 01 Jul 2026 13:01:06 GMT</pubDate>
      <content:encoded><![CDATA[<p>Как сделать scroll-to-top для сайта и Django Admin, не забыв про мобильные устройства, CSP, доступность, плавающие виджеты и нормальную настройку без правки шаблонов.</p><p>На первый взгляд кнопка «наверх» — задача на пять минут. Добавил<i> position: fixed</i>, обработчик window.scrollTo()  — готово.</p><p>Но стоит этой кнопке появиться в живом проекте, как выясняется, что она пересекается с cookie-баннером, мешает чату поддержки, выглядит иначе в мобильной версии, не дружит со строгим CSP или пропадает из Django Admin.</p><p>В итоге маленькая UI-деталь начинает обрастать условиями. Я решил собрать их в отдельный Django-пакет — django-scroll-to-top</p><figure><img src="https://media.tproger.ru/user-uploads/139342/2026-06-29/000bf08b-be8e-4252-82ce-dbef3556426e.webp" alt="Пример кнопки &quot;Наверх&quot; на демо сайте" /><figcaption>Пример кнопки "Наверх" на демо сайте</figcaption></figure><h2>Когда трёх строк JavaScript достаточно</h2><p>Для небольшого сайта, где нет сложной верстки, админки, CSP и требований к повторному использованию, самый простой вариант действительно выглядит примерно так:</p><p>Это нормальное решение. Не всегда стоит тянуть пакет ради одной кнопки.</p><p>Но в реальном Django-проекте быстро появляются дополнительные вопросы:</p><ul><li>когда именно показывать кнопку: после 300 пикселей, одного экрана или только при прокрутке вверх;</li><li>что делать на коротких страницах;</li><li>как не перекрыть cookie-баннер, чат, toast-уведомления или нижнюю мобильную навигацию;</li><li>как дать пользователю закрыть кнопку;</li><li>как не сломать клавиатурную навигацию и режим reduced motion;</li><li>как сделать отдельное оформление для сайта и Django Admin;</li><li>как не заставлять проект добавлять unsafe-inline в Content Security Policy;</li><li>как позволить редактору или администратору изменить цвет, положение и иконку без нового деплоя.</li></ul><p>Именно в этот момент «три строки JavaScript» превращаются в отдельный компонент.</p><h2>Что я хотел получить</h2><p>Цель была не в том, чтобы сделать ещё одну стрелку в правом нижнем углу. Хотелось собрать переиспользуемый компонент со следующими свойствами:</p><ol><li>Подключение сайта одной template-тегом.</li><li>Отдельная поддержка обычных страниц и стандартного Django Admin.</li><li>Настройка внешнего вида через админку, а не через постоянную правку CSS.</li><li>Без jQuery, CDN, фронтенд-фреймворка и обязательной сборки.</li><li>Безопасная работа при строгой CSP.</li><li>Прогрессивное улучшение: без JavaScript остаётся обычная ссылка в начало страницы.</li><li>Возможность жить рядом с другими фиксированными элементами интерфейса.</li></ol><p>Пакет в итоге хранит обычные настройки установки в settings.py, а визуальное поведение — в базе данных. Это позволяет менять кнопку через Django Admin, публиковать новую версию настроек и при необходимости откатываться на предыдущую. В проекте есть отдельные профили для публичного сайта и Django Admin, а ревизии могут быть черновыми, опубликованными или архивными.</p><h2>Быстрое подключение</h2><p>Базовый сценарий начинается с установки:</p><p>В settings.py добавляем приложение. Если нужна поддержка стандартной админки, пакет должен идти раньше django.contrib.admin:</p><p>Включаем области, где должна работать кнопка:</p><p>Для публичной части добавляем URLConf пакета:</p><p>А в общий шаблон сайта — один тег:</p><p>На стандартном Django Admin ничего дополнительно вставлять не нужно: пакет использует обычный механизм разрешения шаблонов Django. Если же в проекте переопределён admin/base_site.html  тег можно добавить вручную в блок footer</p><h2>Настройка без превращения админки в редактор CSS</h2><p>Мне не хотелось хранить в базе шаблоны, произвольный CSS или JavaScript. Это неудобно для сопровождения и создаёт лишнюю поверхность для ошибок.</p><p>Поэтому визуальная часть собрана из контролируемых вариантов:</p><ul><li>круг, квадрат, скруглённый квадрат или pill;</li><li>заливка solid, outline, soft, ghost, glass или gradient;</li><li>положение в любом углу экрана;</li><li>отдельные размеры для desktop и mobile;</li><li>светлая и тёмная тема;</li><li>встроенные иконки, иконки от разработчика или загружаемые SVG;</li><li>настройки тени, границы, opacity и focus ring.</li></ul><figure><img src="https://media.tproger.ru/user-uploads/139342/2026-06-29/90107109-2271-460a-9dea-815592d468e7.webp" alt="Настройки кнопки" /><figcaption>Настройки кнопки</figcaption></figure><h2>Что происходит, когда рядом есть cookie-баннер или чат</h2><p>Нижний правый угол страницы редко бывает свободен. Там часто живут:</p><ul><li>cookie-баннер;</li><li>компактная кнопка после закрытия баннера;</li><li>чат поддержки;</li><li>кнопка обратного звонка;</li><li>мобильная навигация;</li><li>toast-уведомления.</li></ul><p>Пакет умеет рассматривать такие элементы как препятствия. Для этого можно пометить элемент атрибутом:</p><p>Дальше для кнопки можно выбрать поведение: игнорировать препятствия, сдвинуться вдоль края, попробовать другой угол или скрыться, если безопасного места не осталось.</p><p>Для сложных виджетов есть отдельный адаптер: он может отслеживать появление и исчезновение элементов, например компактного launcher после закрытия cookie-баннера. При этом ни cookie-пакет, ни чат не становятся зависимостями  django-scroll-to-top</p><h2>Доступность — не отдельная галочка в конце</h2><p>У кнопки есть понятное имя для screen reader, поддержка клавиатуры, видимый focus-visible, минимальный размер области нажатия и режим prefers-reduced-motion.</p><p>Если пользователь отключил анимации на уровне системы, плавная прокрутка не будет навязываться. Если JavaScript не загрузился, кнопка остаётся обычной ссылкой на начало документа.</p><p>Полный независимый аудит WCAG 2.2 AA и тестирование масштабирования 200% и 400% пока находятся в roadmap, поэтому называть компонент полностью сертифицированным по WCAG было бы неправильно. Но структурные требования — клавиатурная доступность, фокус, reduced motion, forced-colors и безопасная работа без JavaScript — уже заложены в компонент и покрываются тестами.</p><h2>CSP и загружаемые SVG</h2><p>В корпоративных проектах часто нельзя просто добавить inline-скрипт и включить unsafe-inline ради одной кнопки.</p><p>По умолчанию компонент использует same-origin CSS и JavaScript. Для него подходит политика такого вида:</p><p>Настраиваемые цвета и размеры отдаются не через inline-стили, а через версионированный stylesheet endpoint. Это позволяет сохранить простой контракт с одним template-тегом и не ослаблять CSP.</p><p>Отдельно пришлось подумать о загружаемых SVG. Админ не рендерит исходный файл как есть: SVG проходит санитарную обработку. Скрипты, обработчики событий, внешние ресурсы, встроенные документы и небезопасные namespace отклоняются. Для загружаемых иконок также хранится информация об авторе, источнике и лицензии.</p><h2>Ревизии, публикация и откат</h2><p>Одна из самых полезных вещей в пакете — не сама кнопка, а жизненный цикл её настроек.</p><p>Можно создать черновик, посмотреть результат в live preview, опубликовать изменения или вернуться к предыдущей версии. Это особенно удобно, когда кнопку настраивает не разработчик, а контент-менеджер или дизайнер.</p><figure><img src="https://media.tproger.ru/user-uploads/139342/2026-06-29/c9840966-4e32-4506-807a-ac78830fecfa.webp" alt="Живой предпросмотр" /><figcaption>Живой предпросмотр</figcaption></figure><p>У ревизий есть три состояния:</p><ul><li>draft — редактируемый черновик;</li><li>published — текущая активная конфигурация;</li><li>archived — сохранённая версия для отката.</li></ul><figure><img src="https://media.tproger.ru/user-uploads/139342/2026-06-29/2fcf0cfc-b29e-4ce1-b1de-9c07aac1fce0.webp" alt="настройки ревизий профиля кнопки" /><figcaption>настройки ревизий профиля кнопки</figcaption></figure><h2>Где пакет уместен, а где нет</h2><p>django-scroll-to-top имеет смысл, когда кнопка нужна в нескольких проектах, должна работать в Django Admin, настраиваться без деплоя или жить в окружении со строгими требованиями к CSP и интерфейсу.</p><p>Для лендинга на одну страницу проще и правильнее написать несколько строк самостоятельно. Это будет быстрее, понятнее и дешевле в сопровождении.</p><p>Но если такая маленькая деталь начинает повторяться в нескольких продуктах, появляется необходимость поддерживать мобильную версию, доступность, независимые настройки для сайтов и админки, то отдельный компонент уже перестаёт быть избыточным.</p><p>Сейчас пакет выпущен как beta-версия 0.2.0, требует Python 3.10+ и поддерживает Django 4.2 LTS, 5.x и 6.0. Лицензия — MIT.</p><p>Исходный код, документация и примеры использования доступны в GitHub-репозитории проекта.</p><p>Пакет опубликован в PyPI под именем django-scroll-to-top.</p><p>Обратная связь, баг-репорты и предложения по интеграции с кастомными Django Admin-темами приветствуются в Issues.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как сделать 3D-вращение изображений при скролле: разбираем эффект от Codrops</title>
      <link>https://tproger.ru/articles/kak-sdelat-3d-vrashhenie-izobrazhenij-pri-skrolle-razbiraem-effek</link>
      <comments>https://tproger.ru/articles/kak-sdelat-3d-vrashhenie-izobrazhenij-pri-skrolle-razbiraem-effek?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-sdelat-3d-vrashhenie-izobrazhenij-pri-skrolle-razbiraem-effek</guid>
      <description><![CDATA[<p>Разбираем, как устроен эффект 3D-вращения картинок из свежей статьи Codrops. Примеры кода на GSAP, Lenis и CSS-трансформации.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-sdelat-3d-vrashhenie-izobrazhenij-pri-skrolle-razbiraem-effek">Как сделать 3D-вращение изображений при скролле: разбираем эффект от Codrops</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[CSS]]></category>
      <category><![CDATA[Дизайн интерфейсов и UX]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 19 Jun 2026 08:09:13 GMT</pubDate>
      <content:encoded><![CDATA[<p>Хотите, чтобы лендинг или портфолио запомнили с первого взгляда? Попробуйте добавить изображениям объёмное вращение при скролле. Эффект выглядит дорого и кинематографично, но под капотом — обычные CSS 3D-трансформации и немного JavaScript.</p><p>В начале июня команда Codrops опубликовала небольшую, но наглядную демонстрацию: галерея фотографий проезжает через вьюпорт, пока каждая картинка медленно кувыркается в трёхмерном пространстве. Идея позаимствована у аниматора Jason Booth, а код выложен на GitHub вместе с пятью готовыми вариациями.</p><p>В этой статье разберёмся, как устроен эффект, из чего состоит математика и как быстро повторить его у себя — без WebGL, Canvas и тяжёлых библиотек.</p><p>Эффект строится на CSS-свойствах perspective и transform-style: preserve-3d, а анимация крутит rotationX/Y/Z и translateZ по прогрессу скролла.</p><p>Для синхронизации с прокруткой используется GSAP ScrollTrigger с параметром scrub: true; плавность даёт библиотека Lenis.</p><p>Codrops предлагает пять вариаций: от мягкого волнообразного движения до агрессивного разворота с blur и изменением яркости.</p><p>Всего нужно три ингредиента: разметка с фоновыми изображениями, CSS для 3D-контекста и 30—40 строк JS, которые связывают скролл с трансформациями.</p><h2>Как устроен базовый эффект</h2><p>В основе лежит простая мысль: каждая картинка — это не плоский прямоугольник, а объект в 3D-пространстве. Пока пользователь скроллит страницу, объект проходит перед «камерой» и меняет ориентацию. Входная точка анимации начинается, когда элемент появляется снизу экрана, а заканчивается, когда уходит вверх.</p><p>Для реализации используется связка GSAP + ScrollTrigger. Параметр scrub: true привязывает анимацию напрямую к позиции скролла: чем дальше прокручено, тем сильнее трансформация. Библиотека Lenis отвечает за плавность: без неё колёсико мыши на Windows или трекпад на macOS могут давать рваное движение, и вся магия растворится.</p><h3>Разметка и CSS</h3><p>HTML минимален: контейнер .gallery и набор .gallery__item с фоновыми картинками. Главное — обернуть каждый item дополнительным .gallery__item-wrap и задать ему perspective. Именно обёртка создаёт 3D-контекст, внутри которого вращается сама картинка.</p><h3>Плавный скролл и триггеры</h3><p>Перед запуском анимации инициализируем Lenis и связываем её с GSAP. Это стандартный «боеприпас» для большинства современных сайтов с анимацией по скроллу.</p><h3>Математика вращения</h3><p>Каждой картинке случайно задаётся начальная ориентация по трём осям. Затем GSAP анимирует от этих значений до противоположных, создавая эффект «переворота» на 180°. В обработчике onUpdate вычисляется смещение по оси Z: чем ближе элемент к центру экрана, тем глубже он «погружается» в пространство.</p><p><b>Совет:</b> если вы убираете плавный скролл, протестируйте эффект на мобильном устройстве. Нативный скролл на iOS и Android может дать менее плавную картинку, и тогда имеет смысл оставить Lenis или добавить @media (prefers-reduced-motion) для доступности.</p><h2>Пять вариаций одной идеи</h2><p>Codrops не ограничивается одной анимацией: в репозитории пять HTML-файлов, каждый из которых демонстрирует, как одно и то же ядро превращается в разное настроение. Вот краткая карта отличий.</p><ul><li><b>Вариант 1.</b> Мягкое волнообразное расположение картинок по горизонтали, случайные углы rotationX 70—120° и небольшой зазор по Z (−50 px). Универсальная, спокойная подача.</li><li><b>Вариант 2.</b> Больший размах по rotationX (240—290°) и усиленная глубина до −300 px. Картинки буквально переворачиваются перед глазами.</li><li><b>Вариант 3.</b> Триггер вычисляет поворот через cos(progress * π), добавляет сдвиг по Y (yPercent) и фильтры saturate/brightness. Получается «подводное» движение.</li><li><b>Вариант 4.</b> Акцент на скорости: в обработчике Lenis отслеживается velocity, и чем быстрее скролл, тем сильнее blur и ниже насыщенность. Динамично и спортивно.</li><li><b>Вариант 5.</b> Агрессивное искажение масштаба: scaleX и scaleY меняются в противофазе, картинки растягиваются и сжимаются, проходя через центр экрана.</li></ul><h2>Мини-руководство: повторяем у себя</h2><p>Чтобы не копировать всю демку целиком, можно взять только схему и адаптировать под свой проект. Ниже — самый короткий путь от макета до рабочей анимации.</p><h2>FAQ</h2><h2>Выводы</h2><p>3D-анимации по скроллу — это способ сделать обычную галерею запоминающейся без тяжёлых WebGL-сцен. Хватает CSS-свойств perspective и transform-style, пары строк GSAP и библиотеки Lenis для плавности.</p><p>Главное, что предлагает Codrops, — не готовый плагин, а отправная точка. Пять вариаций показывают, как одну и ту же идею можно растянуть от спокойного волнообразного движения до агрессивного искажения с blur. Возьмите базовую схему, подберите углы и фильтры под свои картинки — и получите эффект, который будет выглядеть так, будто над ним работала целая команда аниматоров.</p><blockquote>Пользователь не запоминает интерфейс, который просто красив. Он запоминает тот, который отзывается на его действия.</blockquote><p>Источники: оригинальная статья <a href="https://tympanus.net/codrops/2026/06/18/exploring-3d-image-rotations-on-scroll/">Codrops</a>, демо <a href="https://tympanus.net/Development/RotatingOnScrollAnimations/">Rotating On-Scroll Animations</a> и исходный код на <a href="https://github.com/codrops/RotatingOnScrollAnimations">GitHub</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Фреймворк-независимые дизайн-системы: практический подход к веб-компонентам</title>
      <link>https://tproger.ru/translations/frejmvork-nezavisimye-dizajn-sistemy-prakticheskij-podhod-k-veb-2</link>
      <comments>https://tproger.ru/translations/frejmvork-nezavisimye-dizajn-sistemy-prakticheskij-podhod-k-veb-2?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Картофельный Повелитель]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/frejmvork-nezavisimye-dizajn-sistemy-prakticheskij-podhod-k-veb-2</guid>
      <description><![CDATA[<p>Как построить дизайн-систему без привязки к фреймворку, используя веб-стандарты и веб-компоненты. Пошаговое руководство с примерами кода и документацией. Разбираем на практике.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/frejmvork-nezavisimye-dizajn-sistemy-prakticheskij-podhod-k-veb-2">Фреймворк-независимые дизайн-системы: практический подход к веб-компонентам</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[CSS]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[Дизайн интерфейсов и UX]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Дизайн]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 14 Jun 2026 07:00:20 GMT</pubDate>
      <content:encoded><![CDATA[<p>Перевод статьи Scott Riley (Piccalilli), оригинал: https://piccalil.li/blog/framework-agnostic-design-systems-part-1/<br /><br />Прежде чем мы начнём, небольшое примечание: это практическое руководство, которое охватывает управление, создание и упаковку компонентов дизайн-системы. Невозможно углубляться в каждый шаг до мельчайших деталей, не превратив материал в полноценный курс. Предполагается наличие некоторых базовых знаний:</p><ul><li>Базовые знания HTML и CSS</li><li>Базовое понимание веб-компонентов</li><li>Установленные Node.js и npm</li><li>Умение работать в терминале на уровне, достаточном для установки пакетов</li><li>Базовые знания конфигурационных файлов и JSON</li><li>Понимание революционной идеи о том, что &lt;button&gt; — это не &lt;div&gt;</li></ul><p>Наконец, это довольно длинный пост. Считайте каждый h2 приглашением сделать перерыв на чай и подышать свежим воздухом.</p><p><a href="https://www.youtube.com/watch?v=AWM5ZNdWlqw">Okayyyyylet’sgo</a>.</p><h2>Фреймворк-независимые компоненты</h2><p>Из всех недавних хайпов/пузырей/назовите их как хотите в мире технологий тот, что одновременно волновал и ставил в тупик меня в равной степени, — это бум дизайн-систем. Общая концепция определённо фантастическая, и почти любая команда или проект могут извлечь пользу из какой-либо формы централизованного хранилища дизайнерских решений. Но, как и любой другой бум, он породил много <i>странностей</i>. Люди сошлись на определённых способах восприятия дизайна в «эпоху дизайн-систем», слайды <a href="https://atomicdesign.bradfrost.com/chapter-2/">Atomic Design</a> в каждой конференц-презентации стали мемом, а дизайн-токены стали целой личностью для некоторых.</p><p>Этот пост — не обо всех странностях, но нам нужно опереться на что-то более конкретное, чем <i>крутая технология — это круто</i>. И одна из моих наименее любимых странностей из курса «Дизайн-системы: странности 101» довольно специфична, но при этом является источником настоящей физической боли для меня: <i>библиотеки компонентов, привязанные к конкретному фреймворку</i>.</p><p>Идея о том, что наши дизайн-системы могут, и даже должны, работать на компонентах, написанных под конкретный фреймворк, кажется мне дикой. Дизайн-системы, по крайней мере частично, должны быть про универсальность, компонуемость и переносимость. Встраивание привязки к фреймворку в уравнение с самого первого дня абсолютно нелепо.</p><p>Я понимаю, что веб-стандарты немного отставали на заре дизайн-систем, а веб-компоненты и кастомные элементы отставали от всех тех приятных возможностей, которые предлагают реактивные фреймворки с управлением состоянием. К счастью для нас, это больше не так, и существует ряд замечательных инструментов, построенных вокруг создания и потребления стандартных веб-компонентов.</p><p>На самом деле, я бы даже сказал, что на момент написания этого поста веб-компоненты — <i>единственно лучший подход</i> к созданию библиотеки компонентов. Они переносимы, используют веб-стандарты, и любой фреймворк, который не является полным бардаком (и многие, которые являются, смотрю на тебя, React), будет поддерживать их либо напрямую, либо с минимальной конфигурацией.</p><p>Отвлечения в сторону, этот пост будет максимально практичным введением в создание веб-компонентов с использованием веб-стандартов, современного CSS и некоторых удобных инструментов, которые помогут нам ускориться. Он также будет весьма субъективным и сильно опираться на идею, что мы должны поставлять нашу библиотеку вместе с документацией в одном репозитории. Вы не <i>обязаны</i> заниматься всеми этими штуками с документацией, если не хотите, но я настоятельно рекомендую попробовать. Весь код здесь для вас, так почему бы и нет!</p><h2>Принципы</h2><p>Сначала рассмотрим несколько принципов. Если они вам близки — читайте дальше; если нет — можете закрыть вкладку, заварить чай и заняться своими делами.</p><h3>Минимально возможный уровень</h3><p>Хотя существует масса инструментов, которые превращают компоненты для конкретного фреймворка (давайте будем честны — почти всегда это React) в веб-компоненты, я не думаю, что такой подход соответствует тому, что мы <i>говорим</i>, что хотим от наших библиотек компонентов и паттернов по духу.</p><p>Когда мы создаём компоненты и проектируем API компонентов, мы разрабатываем некоторые из самых атомарных элементов дизайн-системы. В таком сценарии, на мой взгляд, есть явная, ощутимая польза от работы максимально близко к платформе доставки. Для веб-продуктов это означает работу непосредственно с веб-стандартами.</p><p>На уровне компонентов я гораздо более настроен на удаление слоёв абстракции и работу ближе к веб-стандартам. Вместо того чтобы сразу прыгать в модный фреймворк, я гораздо больше предпочитаю работать с инструментами сборки и лёгкими обёртками. Это означает, что вы всегда находитесь в «режиме веб-стандартов», идёте прямым путём. Горжусь вами.</p><h3>Максимально простые компоненты</h3><p>Компоненты должны быть максимально примитивными. Даже самый, казалось бы, сложный компонент можно представить как очень простую конечную машину состояний. Мне ещё не встречался компонент, который нельзя было бы выразить таким образом, и вам не нужно по умолчанию обращаться к раздутому фреймворку для простых вариантов компонентов и изолированного состояния.</p><p>Я бы даже сказал, что многие реактивные компоненты — это антипаттерн. Реактивность обычно означает логику, и очень часто это приводит нас в область «бизнес-логики» и общего состояния на уровне контейнера или приложения. Простая реактивность на уровне компонента часто необходима — представьте кнопку, которая показывает спиннер загрузки, пока что-то обрабатывается, и возвращается в исходное состояние, когда всё готово, — но добавление тонн состояний и реактивности в изолированном коде компонента всегда <i>кажется</i> мне красным флагом.</p><p>По моему опыту, компоненты наиболее полезны, когда им явно сообщают, какое состояние они должны отражать и какой контент содержать. Они намеренно ограничены и явно декларативны. Обработка сложного состояния и реактивности в вашем приложении, даже если это означает комбинирование нескольких примитивов в паттерн, специфичный для приложения, гораздо более разумна, чем попытка централизовать сложный громадный компонент, который пытается слишком многое обрабатывать.</p><h3>Максимально устойчиво к будущему</h3><p>Устоявшиеся фреймворки со временем становятся устаревшими технологиями. Учитывая всю работу по «переписыванию Angular-проектов на React», на которой некоторые из нас спокойно прожили целых два года, мы должны это понимать. Сам React становится (можно спорить, <a href="https://adactio.com/journal/20618">уже стал</a>) устаревшей технологией, а «переписывание нашего React-приложения на Solid/Svelte» — теперь обычное дело. Я вполне ожидаю, что это будет повторяться до тошноты.</p><p>Веб-стандарты — хотя, признаюсь, они развиваются медленнее и поддерживаются утомительными, своеобразными процессами выпуска — всегда будут с нами. Веб-стандарты выдержали проверку времени и последовательно доказывают, что они заметно более надёжны, чем ваш проблемный любимый, переусложнённый фреймворк.</p><p>Фреймворки тоже по-настоящему замечательны, когда используются правильно. Говоря по опыту, попытка написать состоятельные, реактивные приложения на ванильном HTML, CSS и JS — закаляющая, но в конечном счёте неразумная задача. Однако примитивные компоненты — это не сложные, состоятельные, реактивные веб-приложения. Это маленькие куски атомарного веб-кода, и создавать их со всеми накладными расходами и своеобразиями полноценного фреймворка — это просто приглашение к будущему устареванию.</p><p>Создавая <i>непосредственно с помощью веб-стандартов</i>, мы получаем более низкоуровневое понимание того, как работают наши компоненты, встроенную защиту от будущего, избегая модного фреймворка, и по сути более прогрессивную, доступную (или, по крайней мере, более легко делаемую доступной) и нативную для веба библиотеку компонентов.</p><p>Разделяя ваши атомарные компоненты дизайн-системы от ваших <i>компонентов приложения</i>, вы получаете лучшее из обоих миров: переносимые, примитивные компоненты на уровне системы; сложные и реактивные компоненты и обёртки на уровне приложения.</p><p>Таким образом, когда вам действительно понадобится переписать приложение на Solid/Svelte, вам хотя бы не придётся переписывать всю библиотеку компонентов вместе с ним.</p><h3>Принимать решения в коде</h3><p>Я абсолютно готов стоять насмерт на этой позиции. Инструменты для дизайна — <i>ужасные</i> места для принятия решений по <i>дизайн-системе</i>. Это отчасти потому, насколько оторваны такие инструменты, как Figma, от того, как на самом деле работают дизайн-системы, вплоть до откровенно катастрофического несоответствия словаря и концепций.</p><p>Как человек, который по сути больше дизайнер, чем разработчик, я создал и работал с более чем дюжиной «дизайн-систем» в Figma. Как человек, который также проводит гораздо больше времени в коде, чем в инструментах дизайна, я считаю себя вправе сказать, что ни одна из них не отражала того, чем должна быть хорошая системная основа. Это не укол в сторону дизайнеров, которые не пишут код, скорее просто показывает, насколько сложной <i>сами инструменты</i> делают эту часть нашей работы.</p><p>Инструменты для дизайна — это места для быстрого тестирования разных идей и экспериментов со стилем и компоновкой. Они абсолютно ужасны для кодификации системных решений, отчасти из-за своей самой природы: они предоставляют очень маленькое, проприетарное подмножество возможностей нашего реального носителя — браузера.</p><blockquote>Так же и браузер, но я рискую укрепиться на том самом холме.</blockquote><p>Окончательные системные дизайнерские решения должны приниматься в браузере. Токены цвета могут использовать современные цветовые пространства. Токены размеров и отступов должны выражаться в относительных единицах, где это возможно. Почти каждый тип токена может выиграть от какой-либо математики, включая логарифмические шкалы для типографики или программные сдвиги оттенка и светлоты для цветов. API компонентов также следует строить с помощью надёжных, хорошо типизированных определений. Инструменты дизайна могут предложить лишь подобие этих концепций.</p><p>Если вы начинаете с Figma — это вполне нормально, но это ужасный источник истины. Воспринимайте свой инструмент дизайна как точный инструмент прототипирования, а не как конечную цель для дизайнерских решений.</p><h3>Документировать по ходу разработки</h3><p>Опираясь на последний принцип, если лучшее место для принятия решений — код, то лучшее время для документирования этих решений — фаза сборки, пока они свежи в вашей голове. Разрабатываете props? Ну посмотрите-ка, у вас уже есть прекрасный набор определений типов для этих props, неплохо было бы добавить туда маленький комментарий <a href="https://jsdoc.app/">JSDoc</a> и заняться своими делами.</p><p>Мне нравится идти дальше и разворачивать библиотеку компонентов прямо в документирующем фреймворке вроде <a href="https://vitepress.dev/">VitePress</a>, активно создавая человекочитаемую документацию параллельно с разработкой самих компонентов. Это не только в итоге станет «официальной» документацией дизайн-системы, но и позволит проверить, насколько переносимы ваши компоненты.</p><p>Это делает мой мозг счастливым, потому что полное кодовое представление моих дизайн-систем (что абсолютно, всегда включает фактическую документацию) живёт в одном репозитории. Всю систему можно развернуть, не жонглируя зависимостями, и это заставляет меня относиться к документации как к необходимому шагу к релизу.</p><h2>Давайте создадим (и задокументируем)</h2><p>Ладно, хватит болтать, давайте на самом деле создадим что-то практичное. Мы соберём основы для централизованной, независимой от фреймворка библиотеки компонентов. Мы будем прорабатывать документацию по мере создания компонентов, что даст нам действительно чистый тестовый стенд для самих компонентов. Настоящий порочный круг, если таковой вообще был.</p><p>Вот что у нас будет в конце этой статьи:</p><ul><li>Основа для нашей гибридной библиотеки компонентов/документации «всё-в-одном» дизайн-системы</li><li>Стильная, хорошо задокументированная кнопка как веб-компонент</li><li>Развёртываемый сайт документации, который показывает, как замечательна наша кнопка</li><li>Готовая к продакшену библиотека компонентов, которую можно опубликовать в вашем любимом пакетном менеджере</li></ul><p>Нам действительно нужно беспокоиться только о двух инструментах: <a href="https://elenajs.com/">Elena</a> для сборки и распространения нашей библиотеки компонентов и <a href="https://vitepress.dev/">VitePress</a> для создания нашей документации.</p><h3>Elena</h3><p>Клей для всего этого проекта — Elena. Фантастическая библиотека от непобедимого <a href="https://arielsalminen.com/">Ariel Salminen</a> для создания прогрессивных веб-компонентов. Я не буду углубляться в философию того, что означает «прогрессивный» в этом контексте, потому что это уже <a href="https://arielsalminen.com/2026/progressive-web-components/">исключительно хорошо задокументировано</a> самим Ariel.</p><p>Elena — это крошечная библиотека, которая делает Just Enough Abstraction™ поверх стандартных веб-компонентов. Мы получаем такие вещи, как props (отражаемые как пользовательские атрибуты), изолированную реактивность, методы жизненного цикла и даже классные штуки вроде миксинов для компонуемости. Мы не будем углубляться <i>слишком</i> сильно в Elena, но следите за ходом мысли и, если вам понравятся основы, я очень рекомендую погрузиться во всё, что она предлагает. Это круто.</p><p>Цитата из <a href="https://elenajs.com/#why-should-i-use-elena">документации Elena</a>:</p><blockquote>[Elena] берёт на себя межфреймворковую сложность (синхронизация prop/атрибута, делегирование событий, совместимость с фреймворками), чтобы вы могли сосредоточиться на создании компонентов, а не на инфраструктуре.</blockquote><p>Именно этого я и хочу от такого инструмента: позвольте мне писать код, не абстрагируйте веб-стандарты, разберитесь со всей странной ерундой, которую я не хочу трогать.</p><h3>VitePress</h3><p>Я не буду тратить много времени на VitePress, потому что, честно говоря, это просто самое удобное готовое решение для документации, которое не называется Storybook. Пара npm install — и у нас есть надёжное, основанное на Markdown решение для документации, готовое к работе.</p><p>Позже мы сделаем несколько классных штук с VitePress, JSDoc и нашим сгенерированным Elena манифестом пользовательских элементов, что поможет ускорить процесс документирования, но, честно говоря, иметь <i>где-то</i> документировать гораздо важнее, чем то, <i>во что</i> мы документируем.</p><h3>Структура проекта</h3><p>Здесь всё может изначально показаться немного странным. Хотя нам нужно собирать и распространять наши компоненты как отдельную библиотеку, нам также нужно их видеть и тестировать. Самый простой способ — это слепить статический сайт и просто свалить все компоненты на одну страницу. Это <i>вполне нормально,</i> и, по сути, я бы поощрил это, если вы просто экспериментируете с Elena, но по причинам, изложенным выше, я считаю, что имеет большой смысл создавать <i>внутри</i> нашей документации.</p><p>У нас по сути будет что-то вроде монорепозитория: Elena будет делать своё дело на уровне компонентов, а сам сайт документации будет статически генерироваться с помощью VitePress.</p><h2>Создание каркаса проекта</h2><p>Здесь довольно много движущихся частей, поэтому вместо того, чтобы просто кидать вам дикую цепочку склеенных npm install, давайте разберём настройку шаг за шагом.</p><p>Для начала создадим папку проекта:</p><p>Замените my-ds на любое название, которое хотите дать своему проекту.</p><p>Затем инициализируем npm:</p><p>Команда npm init -y создаст файл package.json в корне проекта. Эта корневая папка напрямую ничего не будет делать — она просто склеивает наши компоненты и документацию вместе в монорепозитории.</p><p>Приведём в порядок наш package.json:</p><p>Здесь происходит кое-что, что пока не имеет особого смысла (и даже не будет работать) — это станет понятно чуть позже. Настройка workspaces позволит нам обращаться со сборкой библиотеки компонентов как с пакетом, не публикуя его, а скрипты dev, а также различные watch и build позволят нам отслеживать и собирать либо документацию, либо компоненты (либо оба варианта одновременно с помощью команды dev).</p><p>Кстати, давайте установим пару штук:</p><p>Это установит concurrently, который позволит нам запускать команду watch Elena и команду dev VitePress одновременно. Мы будем держать её запущенной, пока работаем. Также установится VitePress и его тема по умолчанию. Если хотите заморочиться — можете использовать другую тему.</p><h3>Настройка VitePress</h3><p>Настроим документацию. Для начала создадим папку docs:</p><p>Затем создайте docs/.vitepress/config.mjs:</p><p>Проверьте расширение!Обратите внимание: мы используем .mjs, а не .js — это заставляет Node трактовать файл как ESM. Это необходимо, потому что мы импортируем из vitepress. Вам не обязательно знать, что это значит. Честно говоря, я не уверен, что сам это понимаю. Просто убедитесь, что используете .mjs. Ладно, спасибо.</p><p>Здесь мы используем postIsolateStyles, чтобы ограничить область действия встроенных стилей .vp-doc VitePress и не дать им просочиться в наши примеры компонентов. Без этого встроенные стили VitePress <i>могут</i> переопределять стили ваших компонентов (включая инкапсулированные сбросы) из-за того, как Vite внедряет таблицы стилей во время выполнения.</p><p>Далее создайте минимальный docs/index.md, чтобы у VitePress была домашняя страница:</p><p>Сейчас хороший момент, чтобы проверить, всё ли работает:</p><p>Вы должны увидеть очень простой локальный сайт на VitePress! По умолчанию он будет доступен по адресу <a href="http://localhost:5173/">http://localhost:5173/</a>.</p><h3>Настройка Elena</h3><p>Теперь, для MVP нашей дизайн-системы, давайте установим Elena. Мы будем использовать Elena для создания компонентов и в конечном итоге распространять их в виде пакета. Именно здесь некоторые вещи из корневого package.json начинают обретать смысл.</p><p>Начнём с создания папки компонентов и инициализации npm для нашего пакета компонентов:</p><p>Далее отредактируйте packages/components/package.json:</p><p>Затем установите Elena:</p><p>Это установит Elena, её бандлер и CLI-инструмент.</p><p>Мы будем использовать CLI-инструмент Elena для создания каркаса наших компонентов. По сути, он проведёт нас через создание компонента, позволяя запустить команду, которая генерирует нужную папку и создаёт js- и css-файлы для любого компонента, который мы захотим создать. Подробнее об этом позже!</p><p>Пока что нам нужно настроить Elena. Во многих случаях можно пропустить этот шаг и просто использовать настройки по умолчанию. Однако мы ведём себя как глупые гуси и совмещаем документацию и компоненты в одном проекте, так что, возможно, придётся кое-что подкрутить. Плюс я люблю, когда конфиги явные, а не невидимые.</p><p>Создайте конфиг Elena по пути packages/components/elena.config.mjs:</p><p>Это говорит Elena, где искать наши компоненты (src), куда выводить собранные компоненты (dist) и где искать точку входа нашей библиотеки (src/index.js). Обратите внимание: все эти пути относительны директории packages/components, <b>а не</b> корня проекта. Наши инструменты Elena и библиотека компонентов самодостаточны.</p><p>Эта точка входа важна, если мы хотим импортировать все наши веб-компоненты через bundle.js, который генерирует Elena. Пока что создадим пустую.</p><p>Создайте packages/components/src/index.js. Пока что он может быть просто пустым или содержать комментарий-заглушку:</p><p>По мере создания компонентов мы сможем добавлять соответствующие export в этот файл, чтобы они попадали в наш production-бандл.</p><p>Убедитесь, что Elena работает: перейдите в корень проекта и выполните:</p><p>К сведениюЕсли вы запускаете это на Mac с Apple Silicon, то, скорее всего, столкнётесь с ошибкой. По моему опыту, это из-за зависимости Elena (lightningcss), которая немного кривая (простите за такую техническую терминологию). Если при попытке сборки вы получаете ошибку 'MODULE_NOT_FOUND', выполните следующее из корня проекта: Code languagebashCopy to clipboard rm -rf node_modules packages/components/node_modules package-lock.json &amp;&amp; npm install Это уничтожит папку node_modules и переустановит зависимости, разложив всё по своим местам. Если эта ошибка случилась однажды, то, скорее всего, придётся запускать это каждый раз при установке новой зависимости. Мне жаль. Управление пакетами — как всегда, Очень Приятное Занятие.</p><h2>И выдохнем…</h2><p>Отойдём на шаг назад, поставим чайник и посмотрим, что у нас есть. Ваша структура проекта должна выглядеть так:</p><p>Наша корневая папка по сути просто контейнер, так что особо беспокоиться о ней не стоит.</p><p>Наша папка docs — это место, где будет жить всё, связанное с VitePress. В конечном итоге это станет полноценной документацией дизайн-системы, и мы будем использовать её для предпросмотра и документирования наших компонентов по мере их создания.</p><p>Наша папка packages/components — это место, где мы будем работать со всем, связанным с компонентами. Папка packages/components/src — это место, где мы будем создавать компоненты, а index.js в ней — точка входа нашей библиотеки, где мы просто будем export'ировать любые компоненты, которые хотим включить в бандл.</p><p>Наша папка dist в packages/components — это место, где будут храниться собранная библиотека компонентов и манифест кастомных элементов. Затем мы сможем импортировать отсюда в наш проект VitePress так, будто это установленный пакет.</p><p>Однако чтобы дойти до этого, нам нужны какие-то реальные компоненты для распространения.</p><h2>Создаём наш первый компонент</h2><p>Теперь, когда всё настроено, мы наконец-то можем начать создавать компоненты! В этой статье мы будем держать всё просто и сосредоточимся на, возможно, самом распространённом компоненте: прекрасной кнопке.</p><p>По невероятному стечению обстоятельств ваш собственный веб-мастер Piccalilli, <a href="https://piccalil.li/author/andy-bell/">Andy Bell</a>, уже написал <i>великолепную</i> статью о <a href="https://piccalil.li/blog/how-i-build-a-button-component/">создании компонентов кнопок</a> на стандартном HTML и CSS. Мы будем опираться на эти принципы здесь, с небольшими изменениями, чтобы получить максимум от нашей настройки веб-компонентов.</p><p>Статья Andy отлично объясняет <i>почему</i> стоят за многими семантическими и структурными решениями, касающимися самих кнопок, поэтому я не буду углубляться в это слишком сильно. Andy прошёл путь, чтобы мы могли бежать. Какой человек.</p><h3>Композитные, примитивные и декларативные компоненты</h3><p>В основе концепции Elena «прогрессивные веб-компоненты» лежит разделение компонентов на три основные категории: <a href="https://elenajs.com/components/overview#_1-composite">композитные</a>, <a href="https://elenajs.com/components/overview#_2-primitive">примитивные</a> и <a href="https://elenajs.com/components/overview#_3-declarative">декларативные</a>. Документация Elena прекрасно объясняет различия подробно, но важно помнить, <i>что все это всё ещё просто веб-компоненты.</i> Нас не заставляют принимать нестандартные концепции или методы, скорее нас поощряют <i>думать</i> о наших компонентах в этих терминах.</p><p>Я позволю документации Elena сделать основную работу с этими определениями, но вот основные моменты:</p><ul><li><b>Композитные</b> компоненты оборачивают и расширяют свой внутренний HTML. Они отлично подходят для таких вещей, как слайдеры, аккордеоны, карточки и многослойные макеты — там, где вы чаще всего позволяете HTML и CSS делать основную работу и расширяете возможности с помощью JS в нужной области. Композитные компоненты также отлично подходят для <i>паттернов</i>, где мы можем захотеть объединить примитивные компоненты и HTML в переиспользуемые <i>«макро»</i> компоненты с определённым поведением. Подумайте о таких вещах, как диалоги, fieldsets и баннеры уведомлений — там, где структура и поведение фиксированы, но содержимое внутри остаётся гибким и определяется потребителем.</li><li><b>Примитивные</b> компоненты объявляют и рендерят свой собственный HTML и поставляются с собственной функцией render(). Это, вероятно, самые распространённые компоненты, которые мы будем использовать в дизайн-системе — подумайте о таких вещах, как кнопки, поля ввода, индикаторы загрузки, бейджи и т.д.</li><li><b>Декларативные</b> компоненты — это комбинация обоих типов и могут объединять Light DOM и декларативный Shadow DOM. Если мы не знаем, что нам <i>действительно</i> нужна инкапсуляция с Shadow DOM, мы можем практически игнорировать его для библиотек компонентов. Я не углублялся <i>слишком</i> сильно в это, но мои первые мысли таковы, что декларативные компоненты были бы отличны для полностью инкапсулированных компонентов, таких как веб-редакторы контента или блоки кода с подсветкой синтаксиса/редакторы, где инкапсуляция и изоляция часто критичны.</li></ul><p>На этот раз мы строим примитивный компонент. Наша кнопка будет объявлять и рендерить свой собственный HTML, и мы будем стилизовать её с помощью CSS в ограниченной области.</p><h3>Создаём каркас компонента</h3><p>Мы будем использовать CLI-помощник Elena для генерации папки и файлов, которые нам нужны для нашего компонента.</p><p>Пространства имён компонентов и пользовательские элементыМы используем сугубо учебный префикс my- для нашей кнопки, но зачем вообще нужен префикс? Это возвращает нас к тому, как пользовательские элементы требуют наличия - в имени тега, чтобы избежать конфликтов с нативными HTML-элементами. Если бы у нас был полный контроль, и мы создали компонент &lt;button&gt;, мы бы конфликтовали с настоящим HTML-элементом &lt;button&gt;, и у нас было бы Очень Плохое Время. Поэтому мы просто не можем этого делать — все наши пользовательские элементы должны быть в формате &lt;{prefix}-{component}&gt;.Жёсткого требования, чтобы наши файлы тоже были с дефисом, нет, но лично мне нравится аккуратность, когда имена файлов и папок совпадают с нашим фактическим элементом. Так что выберите префикс и придерживайтесь его. Для моей дизайн-системы Mindful Design я использую префикс md- — так что все мои пользовательские элементы выглядят примерно как &lt;md-button&gt;, &lt;md-card&gt; и т.д. Web Awesome использует wa-. Вы можете использовать всё, что пожелает ваше сердце. Главное — будьте последовательны.</p><p>Из папки packages/components выполните:</p><p>Затем вам будет предложено выбрать, какие функции и язык вы хотите. Для нашей кнопки нужно выбрать:</p><ul><li>Props</li><li>CSS-переменные</li><li>CSS-инкапсуляция</li><li>Комментарии в коде</li></ul><p>Нажмите Enter, затем выберите JavaScript в качестве языка.</p><p>Установите выходную директорию в src/. По умолчанию Elena использует src/components/, но нам не нужен такой уровень вложенности.</p><p>Это создаст каркас наших файлов с несколькими примерными значениями и комментариями, так что мы не будем смотреть на пустые файлы. Нажмите Enter после выбора функций, языка и директории, и Elena сгенерирует папку my-button с соответствующими JS и CSS файлами. О стилизации мы позаботимся позже, сейчас мы хотим спроектировать API нашего компонента.</p><p>Откройте следующий файл:</p><p>Здесь происходит много всего для простого boilerplate, но мы разберём каждый раздел по мере продвижения!</p><h3>Добавление props</h3><p>Компонентные <a href="https://elenajs.com/components/props">props</a> позволят нам управлять стилизацией и поведением компонента декларативным образом. Затем мы можем использовать эти props для создания вариантов наших компонентов. Для нашей кнопки давайте упростим и используем следующие props:</p><ul><li>variant: стилевой вариант нашей кнопки, например «primary», «danger»</li><li>disabled: отключена ли кнопка или нет</li><li>href: куда должна вести кнопка, также определяет, будет ли кнопка рендериться как ссылка или как кнопка</li></ul><p>Это небольшое подмножество props, которые потребуются кнопке в продакшене, но этого достаточно, чтобы двигаться дальше. Если после этого вы почувствуете себя уверенно, можете вернуться и добавить больше props — size или icon prop были бы отличной отправной точкой!</p><p>Давайте добавим эти props в наш компонент кнопки:</p><p>Объявление static props позволяет нам определить конечный массив props, которые будет принимать наш компонент. По умолчанию все эти props будут отражаться на нашем отрендеренном компоненте как HTML-атрибуты. Вам почти всегда нужно, чтобы это было так, особенно если вы используете нестандартные атрибуты вроде disabled, download и т.д.</p><p>Прямо под этим массивом вы найдёте заготовленные значения props по умолчанию, каждое с небольшим комментарием сверху. Давайте последуем примеру Elena и установим значения по умолчанию для добавленных нами props:</p><p>Комментарии над каждым определением — это JSDoc-комментарии. Они могут выглядеть немного непривычно, но позволяют документировать наши компоненты и props и могут служить источником истины для документирования API наших компонентов. Это также даёт нам немного «мягкой типизации» без необходимости использовать TypeScript. Большинство IDE будут подсвечивать или предупреждать вас, если вы установите prop в значение/тип, не указанный в синтаксисе JSDoc.</p><p>В приведённом выше примере мы определяем наш prop variant, задаём ему значение по умолчанию «default» и мягко типизируем его с помощью определения @type. В данном случае мы принимаем только одно из четырёх перечисленных значений.</p><p>На этом этапе это может показаться немного бессмысленным, но следите за своими JSDoc-комментариями по мере создания компонентов. Мы будем использовать их позже. Пока мы на этом, мы могли бы также задать более точное описание для нашего компонента.</p><p>Измените верхний комментарий в следующем файле:</p><p>Мы также удалили определения @cssprop из этого комментария. Они были сгенерированы, потому что мы выбрали «CSS Variables» при создании нашего компонента, и позволяют нам раскрыть кастомные свойства, используемые для стилизации наших компонентов. Если вы работаете над темизируемой или headless библиотекой компонентов, вы, возможно, захотите оставить их, в противном случае я предпочитаю пропускать определение этих свойств и не раскрывать их в своей документации.</p><p>Давайте взглянем на нашу функцию render():</p><p>Если у вас нет тяжёлого случая React Brain, вы, возможно, заметите хотя бы одну из пары проблем: во-первых, button — это не div. Дико, правда? Это не вина Elena, мы просто создали базовый компонент, и div — это, безусловно, самый распространённый HTML-элемент. Нам нужно самим отрендерить правильную, семантическую, доступную разметку.</p><p>Во-вторых, мы только что добавили href как prop, а это атрибут a, а не button. Нам нужно условно рендерить <i>либо</i> a, <i>либо</i> button в зависимости от того, установлен ли href.</p><h3>Условный рендеринг</h3><p>Дискуссия «должны ли ссылки когда-либо стилизоваться как кнопки?» старше, чем бородка вашего отчима, и точно так же как-то ещё сохраняется сквозь века. Я слишком стар и устал, чтобы беспокоиться об этом, а реальность такова, что кнопки-ссылки CTA — одна из самых распространённых вещей, которые вы увидите на сайте, в конкуренции только с баннерами cookie и плохой доступностью в своей повсеместности.</p><p>Так что вы будете делать это, нравится нам это или нет, и вам лучше делать это правильно.</p><p>Самый чистый подход к этому — абстрагировать наш рендеринг, добавив две новые функции:</p><p>Затем мы можем заменить функцию render() нашего компонента:</p><p>Супер просто: если href присутствует, это ссылка, если нет — это кнопка. Нам не нужно добавлять новые props, просто используем тот, что у нас уже есть.</p><p>Мы используем nothing в этой функции, и если вы попробуете собрать/запустить watch прямо сейчас, вы получите ошибку. Это потому, что nothing — это помощник Elena для безопасного рендеринга, ну, <i>ничего</i>.</p><p>Давайте импортируем его в начало нашей кнопки. Отредактируйте первую строку следующего файла:</p><p>Теперь давайте соберём нашу библиотеку компонентов, чтобы включить нашу новую кнопку в продакшенный bundle.js. Отредактируйте packages/components/src/index.js:</p><p>Затем из корня проекта выполните:</p><p>Если повезёт, сборка пройдёт без проблем, и мы наконец-то сможем встроить нашу кнопку в документацию.</p><h3>Предпросмотр нашей кнопки</h3><p>На данный момент у нас есть всё необходимое, чтобы отрендерить нашу кнопку и увидеть её на странице. Потребовалось немного настроек, чтобы дойти до этого, но мы сделали это!</p><p>Благодаря тому, как наш проект настроен, мы теперь можем подключать наши собранные компоненты так, как будто они являются отдельным пакетом. Нам просто нужно настроить VitePress для импорта бандла, который генерирует Elena, и сказать ему обрабатывать наши импортированные компоненты как веб-компоненты (по умолчанию VitePress ожидает Vue-компоненты).</p><p>Создайте docs/.vitepress/theme/index.js:</p><p>Это говорит нашей теме VitePress импортировать файлы бандла, которые сгенерировала Elena. @my-ds/components загружается асинхронно, так как это клиентская часть, а VitePress по умолчанию использует серверный рендеринг. @my-ds/components/dist/bundle.css импортируется напрямую в начале нашего файла, потому что это просто старый добрый CSS.</p><p>Примечание о серверном рендеринге (SSR)Если вы знаете, что вам нужен SSR, есть несколько способов включить его с Elena. В зависимости от вашего фреймворка/генератора сайта на выбор, вам, возможно, потребуется выполнить несколько дополнительных шагов конфигурации. Обратитесь к документации Elena за советами по SSR и на страницу интеграций с фреймворками для более продвинутых интеграций.</p><p>Далее обновите docs/.vitepress/config.mjs:</p><p>Это немного хакерский способ, но по сути он говорит VitePress рассматривать любой тег с - как пользовательский элемент вместо Vue-компонента. Учитывая, что пользовательские элементы требуют -, чтобы избежать конфликтов с нативными HTML-элементами, этого достаточно для наших целей.</p><p>Теперь давайте соберём нашу фактическую документацию по кнопке. Создайте docs/components/button.md:</p><p>Это должно дать нам всё необходимое для предпросмотра нашей кнопки! Запустите процесс разработки, если вы ещё этого не сделали:</p><p>Это запустит документацию VitePress в режиме разработки и одновременно запустит скрипт watch Elena, давая нам довольно удобный опыт live-reload. Перейдите на <a href="http://localhost:5173/components/button.html">http://localhost:5173/components/button.html</a>, и вы должны увидеть свою прекрасную кнопку!</p><p>Держите сервер разработки запущеннымКоманда npm run dev запустит ваш dev-сервер документации и будет держать Elena в фоне, отслеживая изменения компонентов. Вы будете получать live reloads всякий раз, когда вносите изменения, и теперь вы можете плавно вносить и тестировать изменения компонентов и документации.</p><p>Если вы откроете инспектор браузера и посмотрите на отрендеренную кнопку, вы увидите что-то вроде этого:</p><p>Наш хост-элемент &lt;my-button&gt; оборачивает разметку из своей функции render(), и мы имеем наш первый веб-компонент, отрендеренный в браузере! Я знаю, я знаю. Это выглядит совсем не круто, но оно там есть! Давайте придадим ему стиль.</p><h2>Стилизация нашей кнопки</h2><p>Если вы дошли до этого места, то, возможно, заметили явное отсутствие дискуссий о дизайн-токенах. Не потому, что они неважны, а потому что управление токенами и их распространение — это крайне объёмная тема, а эта статья и без того получается очень уж длинной. Скорее всего, мы разберём рабочие процессы с токенами в отдельном посте!</p><p>Пока что мы будем придерживаться простого подхода и использовать стили с ограниченной областью видимости Elena. Это позволяет нам частично нейтрализовать каскад в CSS и гарантировать, что стили не выйдут за пределы оформления отдельного компонента.</p><p>Мы также сделаем кое-что, чего я <b>не рекомендую</b> для production-компонентов, особенно если вы хотите строить темизируемые дизайн-системы, наследующие разумные глобальные стили (спойлер: вы хотите), — а именно, сбросим стили компонента перед применением собственных. В итоге мы получаем компонент, который не пропускает стили наружу (благодаря ограниченной области видимости) и не позволяет глобальным стилям проникать внутрь (благодаря сбросу на уровне компонента).</p><h3>Стили с ограниченной областью видимости</h3><p>Откройте следующий файл:</p><p>По умолчанию Elena генерирует at-правило @scope для любого создаваемого компонента. Вы <i>не обязаны</i> использовать стили с ограниченной областью видимости. Важно помнить: это <b>всё обычный CSS</b>. Мы не делаем ничего дикого или хрупкого вроде CSS-in-JS, мы просто используем конкретную стандартную возможность CSS. Вы с таким же успехом можете писать неограниченный CSS с пространствами имён и получить в целом те же результаты.</p><p>Более того, если вам нужно поддерживать браузеры, которые не поддерживают @scope, то использование пространств имён может быть тем самым подходом, который вам нужен. Для этого примера (и для моей собственной production-работы) меня вполне устраивает @scope — я считаю его гораздо более чистым способом стилизации компонентов.</p><p>Поскольку при создании компонента мы выбрали «CSS Encapsulation», вы видите, что Elena сгенерировала следующее:</p><p>По сути это означает, что наш компонент не будет наследовать стили из более высоких уровней каскада. В зависимости от вашего подхода к стилизации в дизайн-системе, это может быть как тем, что нужно, так и нет. Для <i>этого конкретного сценария</i> это самый простой способ гарантировать полный контроль над каждым компонентом. Однако во многих реальных сценариях вам действительно стоит <i>хотеть</i> некоторой степени наследования или стилей по умолчанию в компонентах.</p><p>Примечание об инкапсулированном сбросеИспользование all: unset и display: revert сбросит любые стили, определённые до тех пор, пока эти правила не встретятся. Это не предотвратит применение дальнейших неограниченных стилей в файлах или тегах </p>]]></content:encoded>
    </item>
    <item>
      <title>Пора прощаться с ESLint? Как Oxlint меняет правила игры в JavaScript-разработке</title>
      <link>https://tproger.ru/articles/pora-proshhatsya-s-eslint-kak-oxlint-menyaet-pravila-igry-v-javasc</link>
      <comments>https://tproger.ru/articles/pora-proshhatsya-s-eslint-kak-oxlint-menyaet-pravila-igry-v-javasc?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/pora-proshhatsya-s-eslint-kak-oxlint-menyaet-pravila-igry-v-javasc</guid>
      <description><![CDATA[<p>Oxlint на Rust обгоняет ESLint в 50–100 раз по скорости и требует минимальной настройки. Разбираем бенчмарки и сценарии миграции.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/pora-proshhatsya-s-eslint-kak-oxlint-menyaet-pravila-igry-v-javasc">Пора прощаться с ESLint? Как Oxlint меняет правила игры в JavaScript-разработке</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 04 Jun 2026 12:05:14 GMT</pubDate>
      <content:encoded><![CDATA[<p>Линтер <b>Oxlint</b>, написанный на Rust, в 50–100 раз быстрее привычного ESLint и работает сразу после установки. Разбираем, когда миграция оправдана, а когда лучше подождать.</p><p><b>ESLint</b> — это де-факто стандарт статического анализа JavaScript-кода. Инструмент работает поверх Node.js и V8, поддерживает сотни плагинов и позволяет настраивать правила под любой проект. По данным опроса State of JavaScript 2025, ESLint остаётся самым популярным вспомогательным инструментом среди фронтенд-разработчиков.</p><p>Новый проект развивается в рамках экосистемы <b>Oxc</b>, поддерживаемой командой <b>VoidZero</b>.</p><p>Oxlint на Rust обгоняет ESLint в 50–100 раз на крупных репозиториях вроде Vue Core и React Router.</p><p>Из коробки включено 107 правил, тогда как ESLint требует ручной настройки даже для базовых сценариев.</p><p>Поддержка ESLint-плагинов экспериментальная, но список доступных правил постоянно растёт.</p><p>Миграция возможна постепенно: оба линтера можно запускать параллельно.</p><p>Если ваш проект завязан на редкие плагины или пользовательские правила — спешить не стоит.</p><h2>Почему ESLint начинает раздражать</h2><p>Несмотря на зрелость экосистемы, у ESLint накопился приличный багаж архитектурных ограничений:</p><ul><li>Производительность. Код ESLint выполняется в однопоточном режиме поверх JavaScript-движка. В небольших проектах это незаметно, но в монорепозиториях с сотнями тысяч строк проверка легко растягивается на две минуты и больше.</li><li>Конфигурационный ад. Новичкам приходится разбираться в иерархии конфигов, flat config, shared presets и compatibility layers. Документация исчерпывающая, но порог входа остаётся высоким.</li><li>Минимум из коробки. Базовая установка ESLint практически ничего не проверяет. Для получения хоть какой-то пользы нужно ставить плагины, изучать правила и собирать конфигурацию с нуля — в отличие от Prettier или Biome, которые работают сразу после установки.</li></ul><h2>Чем Oxlint лучше привычного линтера</h2><h3>Скорость, которую можно измерить</h3><p>Главное преимущество Oxlint — скорость. В тестах на репозитории <b>Vue Core</b> с type-aware правилами Oxlint справляется за <b>1,3 секунды</b>, тогда как ESLint с typescript-eslint тратит <b>133,8 секунды</b>. Это почти в 100 раз быстрее. На репозитории <b>React Router</b> разрыв меньше, но всё равно впечатляет: <b>435 мс</b> против <b>29,5 с</b> — ускорение в 68 раз.</p><h3>Type-aware линтинг без тормозов</h3><p>ESLint для type-aware правил использует typescript-eslint, который перед проверкой запускает полный анализ через tsc. Это наследует все накладные расходы компилятора TypeScript. Oxlint делает это иначе: type-aware функциональность реализована через oxlint-tsgolint на Go, который в связке с TypeScript 7 и компилятором tsgo работает в 20–40 раз быстрее привычного пайплайна.</p><h3>Настройка за минуту, а не за час</h3><p>После установки Oxlint сразу активирует 107 правил. Конфигурация проще, документация понятнее, а сообщения об ошибках структурированы так, что и человек, и LLM-ассистент разберутся с первого взгляда.</p><h3>Постепенная миграция без боли</h3><p>Oxlint не требует выбросить ESLint в один день. Инструменты можно запускать параллельно: Oxlint берёт быструю проверку на pre-commit, а ESLint остаётся в CI до полного перехода. Экспериментальная поддержка JavaScript-плагинов ESLint уже работает, хотя и не покрывает всю экосистему.</p><h2>Реальные цифры: бенчмарки на популярных репозиториях</h2><p>Автор оригинального материала воспроизвёл тесты на ноутбуке HP EliteBook 1040 G7 (16 ГБ ОЗУ, 4 физических ядра, 8 потоков). Результаты для Vue Core с type-aware правилами:</p><p>Результаты для React Router (без type-aware правил):</p><p>Цифры подтверждают заявленные разработчиками 50–100-кратное ускорение. Для разработчика это разница между «пойду за кофе, пока линтер работает» и «результат на экране мгновенно».</p><h2>Когда ESLint всё ещё нужен</h2><p>Несмотря на впечатляющие цифры, спешить со сносом ESLint не всегда разумно. Вот сценарии, где старый инструмент остаётся предпочтительнее:</p><ul><li>Редкие плагины и пользовательские правила. Если ваш проект завязан на специфические ESLint-плагины, которых ещё нет в Oxlint, миграция потребует дополнительной работы.</li><li>Малые проекты. В репозиториях до 10–20 тысяч строк разница между 1 секундой и 30 секундами линтинга не критична.</li><li>Сложные рабочие процессы. Глубокая интеграция ESLint в CI/CD, пользовательские форматтеры и специфические пайплайны могут быть дорого переносить.</li><li>Сообщество и экосистема. ESLint остаётся доминирующим линтером. Вокруг него больше обучающих материалов, примеров конфигураций и поддержки со стороны LLM-ассистентов.</li></ul><h2>Как мигрировать с ESLint на Oxlint</h2><p>Команда Oxlint подготовила утилиту @oxlint/migrate, которая автоматически преобразует конфигурацию ESLint в формат Oxlint. Выбор пути зависит от текущего состояния проекта:</p><ol><li>Для ESLint v9/v10+ с flat config: запустите npx @oxlint/migrate — утилита преобразует поддерживаемые правила и сообщит о несовместимых.</li><li>Для ESLint v8 и старше (в v10 поддержка legacy-конфигов полностью удалена): сначала мигрируйте на flat config через npx @eslint/migrate-config, затем примените @oxlint/migrate.</li><li>Если нужны type-aware правила: добавьте флаг --type-aware к команде npx @oxlint/migrate и установите oxlint-tsgolint.</li><li>Для экспериментальной поддержки JS-плагинов: используйте флаг --js-plugins в команде npx @oxlint/migrate.</li><li>Не уверены в безопасности? Запустите оба линтера параллельно на несколько недель и сравните результаты.</li></ol><p><b>Совет:</b><br />Начните миграцию с новых модулей или микрофронтендов, а не с устаревшего кода, где линтер и так давно отключён.</p><h2>Выводы</h2><p>ESLint не умер, но его эпоха безраздельного господства подходит к концу. Oxlint демонстрирует, что статический анализ JavaScript может быть быстрым, простым в настройке и дружелюбным к разработчику. Для большинства современных проектов переход уже оправдан экономикой времени: сэкономленные минуты на каждом коммите за год превращаются в десятки часов продуктивной работы.</p><blockquote>Для большинства современных проектов Oxlint — это уже не перспективная альтернатива, а вполне зрелый инструмент по умолчанию.</blockquote><p>Источник: <a href="https://blog.logrocket.com/retire-eslint-migrate-oxlint/" rel="noopener noreferrer">LogRocket — Retire ESLint: How (and why) to migrate to Oxlint</a></p><p>Репозиторий проекта: <a href="https://github.com/oxc-project/oxc" rel="noopener noreferrer">github.com/oxc-project/oxc</a>. Документация: <a href="https://oxc.rs" rel="noopener noreferrer">oxc.rs</a>.</p><p>Попробуйте запустить npx @oxlint/migrate на своём проекте и сравните цифры. Возможно, вы больше никогда не захотите ждать, пока закончится npm run lint.</p>]]></content:encoded>
    </item>
    <item>
      <title>Скрытый сбой идемпотентности в финтех-системе: разбор инцидента</title>
      <link>https://tproger.ru/articles/skrytyj-sboj-idempotentnosti-v-finteh-sisteme-razbor-incidenta</link>
      <comments>https://tproger.ru/articles/skrytyj-sboj-idempotentnosti-v-finteh-sisteme-razbor-incidenta?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Дмитрий Москалюк]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/skrytyj-sboj-idempotentnosti-v-finteh-sisteme-razbor-incidenta</guid>
      <description><![CDATA[<p>Разбор реального production-инцидента в финтех-системе: почему ошибка HTTP 500 не остановила операцию создания карты и как сбой идемпотентности в API Gateway вызвал массовые дубликаты. Практический кейс о микросервисной архитектуре, distributed systems, request-id, API idempotency и техническом долге.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/skrytyj-sboj-idempotentnosti-v-finteh-sisteme-razbor-incidenta">Скрытый сбой идемпотентности в финтех-системе: разбор инцидента</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Рефакторинг]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Финтех]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[микро]]></category>
      <category><![CDATA[faq]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 18 May 2026 04:55:17 GMT</pubDate>
      <content:encoded><![CDATA[<h2>Как все началось</h2><p>Всё началось с безобидного, почти рутинного тикета в саппорт:</p><p><i>«У меня тут несколько одинаковых карт создалось. Я вроде один раз нажимал, а их штук пять висит в приложении». </i></p><p>Для финтеха подобная фраза — не мелкая UI-аномалия, а сигнал тревоги высшего уровня. Когда речь идёт о платёжных инструментах, дубль сущности мгновенно переходит из разряда «странностей» в категорию «полноценный инцидент».</p><p>Поначалу казалось, что это просто один случай. Но на самом деле, проблема уже какое-то время была, хоть и скрытно: люди получали дубликаты своих банковских карт, но массово на это никто не жаловался. На уровне первой линии поддержки это ошибочно классифицировали как пользовательские ошибки</p><p>Настоящий шум поднялся не внутри компании, а уже в соцсетях. Один из клиентов выложил пост. Там была фотография посылки, а в ней — примерно сотня одинаковых карт. Пост очень быстро стал популярным, и вот тогда-то и возникли проблемы с репутацией, а команда разработчиков только тогда и узнала о случившемся. И особенно тревожно это звучало на фоне того, что мы считали что таких проблем быть не может - ведь считалось, что у  нас глобальная идемпотентность на все запросы.</p><p>Мы начали разбираться. Стандартный мониторинг показывал норму: дашборды зелёные, в логах тихо, метрики CPU и памяти без отклонений. При этом в базе обнаруживались дубликаты, которых быть не должно. И только тогда, когда мы внимательно посмотрели на коммунальный API Gateway, то поняли что одно изменение от другой команды поменяло идемпотентность работы endpoint-а.</p><p>Проблема была структурно невидима для тех, кто находился ближе всего к ней. Отсутствие видимой проблемы не равно отсутствию риска — система просто ждала подходящего момента.</p><h2>Что произошло: хронология инцидента</h2><p>Архитектура была классической: Клиент → API Gateway → микросервисы,.</p><p>Сценарий развивался почти незаметно для стандартных средств наблюдения:</p><p>1. Фронтенд: Пользователь нажимает кнопку «Выпустить карту».</p><p>2. Gateway: Запрос начинает обрабатываться в API Gateway.</p><p>3. Микросервис по созданию карт: честно выполняет работу: создаёт запись в БД и возвращает `200 OK` в Gateway.</p><p>4. Новый микросервис: API Gateway вызывает новый микросервис и получает HTTP 500 в ответ от него. Исключение возникает уже после успешного вызова нашего микросервиса, и это ключевая точка разрыва: Gateway считает весь запрос неудавшимся, а ответ нашего микросервиса теряется.</p><p>5. Клиент: получает HTTP 500</p><p>6. Реакция: Пользователь видит красную плашку ошибки и логично решает: «Не сработало, пробую снова». Более того, с точки зрения протокола HTTP - запросы, в ответ на которые пришла ошибка HTTP 500, можно пытаться отправлять опять.</p><p>7. Петля: Микросервис, ничего не зная о судьбе предыдущих ответов, послушно создавал карту за картой.</p><p>Круг замкнулся. Эпидемия началась.</p><p>В компании такого уровня это не было предусмотрено. И это такая обидная ошибка.</p><h2>Как так получилось?</h2><p>Вскрылось ошибочное предположение:</p><p><i>«В API Gateway вызов микросервиса создания карт всегда идет последним». </i></p><p>Таким образом идемпотентность достигалась «формально» - ведь если создание карты завершалось с ошибкой - это точно означало что и вызов API Gateway тоже завершится с ошибкой. Сработало ложное чувство безопасности.</p><p>Ответ на вопрос “почему так было сделано?” очень простой - это было осознанное упрощение на старте. Все знали об этом, но задача на фикс потерялась в недрах бэклога на очень долгое время. Это классический пример того, как архитектурное допущение и отложенный рефакторинг годами живут в проде, пока их не вскрывает редкая последовательность отказов.-</p><h2>Что потребовалось изменить</h2><p>Пришлось в срочном порядке внедрять полноценный механизм идемпотентности по request-id, который не зависел бы от порядка вызова downstream-сервисов. И это было достаточно тяжело, потому что окно для легкого внедрения закрывается в первый день продакшена: до этого момента нет ни живых пользователей, ни накопленных данных, ни клиентов старых версий, с которыми нужно сохранять обратную совместимость. Ниже — ответы на вопросы, которые мы получили от коллег, когда разбирали этот инцидент.</p><h2>FAQ: Часто задаваемые вопросы</h2><p><b>1. Почему нельзя просто заблокировать кнопку на фронте?</b></p><p>Блокировка кнопки решает проблему только при стабильной сети. Если запрос ушёл, сервер создал сущность, но ответ потерялся — кнопка разблокируется по таймауту, и пользователь нажмёт снова. Это не устраняет корневую причину, а лишь слегка снижает вероятность дубля.</p><p><b>2. Чем идемпотентность отличается от дедупликации в БД?</b></p><p>Дедупликация через уникальные индексы защищает от дублей в хранилище, но не решает проблему сайд-эффектов: повторный запрос всё равно вызовет отправку SMS, печать банковской карты, генерацию событий в шине или списание средств. Идемпотентность гарантирует, что вся цепочка выполнится ровно один раз — включая все внешние вызовы и побочные действия.</p><p><b>3. Как долго хранить ключи идемпотентности?</b></p><p>На практике мы хранили ключи в основной базе данных без ограничения срока — затраты на хранение UUID по всем сущностям оказались небольшими. В общем случае минимальный срок зависит от конкретных сценариев использования — кому-то хватит и  часа, а кому-то нужна неделя. В любом случае, окна должно быть достаточно, чтобы покрыть сценарии, когда пользователь возвращается к повтору запроса, например, на следующий день или когда клиентское приложение автоматически перезапускает отложенные запросы после восстановления сети. Бессрочное хранение не обязательно, но слишком короткий TTL создаёт риск дублей при длительных сетевых проблемах.</p><p><b>4. Что делать со старыми клиентами, которые не шлют request_id?</b></p><p>Мы сделали несколько версий API для создания карт — под разные версии приложения. Для новых клиентов работала полноценная идемпотентность с клиентским ключом. Для старых версий приходилось принимать риски и генерировать request_id на стороне сервера. Альтернативой может быть хэширование payload запроса, но это менее надежно и сложнее: таймстемпы и случайные поля могут отличаться от вызова к вызову. Поэтому мы выбрали  подход с генерацией ключа на сервере для устаревших клиентов: риски дублей на переходный период оказались меньше, чем сложность поддержки двух схем валидации одновременно.</p><p><b>5. Обязательно ли делать идемпотентность для всех методов API?</b></p><p>Идемпотентность требуется только для методов, которые изменяют состояние системы — POST, PUT, PATCH и иногда DELETE. Методы чтения (GET, HEAD, OPTIONS) не изменяют данные, поэтому считаются идемпотентными по умолчанию.</p><p><b>6. Как понять, что в вашей системе уже есть скрытая проблема с дублями?</b></p><p>Лучший способ — ввести метрики превентивно, не дожидаясь жалоб пользователей. Отслеживайте количество повторных вызовов с одинаковым ключом идемпотентности и сравнивайте его с общим числом запросов. Если метрики уже показывают ненулевое значение — проблема есть, даже если внешне всё работает незаметно.</p><p>Если метрик ещё нет, вот три косвенных признака, которые помогут заподозрить неладное:</p><ul><li>В базе данных периодически появляются записи с одинаковым содержимым, созданные с разницей в несколько секунд.</li><li>Пользователи жалуются на дубликаты карт, заказов или платежей, но вы не можете воспроизвести проблему локально, списываете на то, что пользователи что-то делают не так</li><li>В логах API Gateway периодически всплывают HTTP 500 ошибки, но downstream-сервисы при этом отрабатывают успешно.</li></ul><p>Если заметили хотя бы один из этих симптомов — простого решения уже не будет. Однако остаётся возможность исправить ситуацию до того, как проблему заметят пользователи. В нашем случае дубли проявлялись редко и стали массовыми только при повышении нагрузки. Если отложить решение, скрытая проблема перейдет на уровень, где её последствия станут заметны снаружи и потребуют значительно больших усилий.</p><h2>Итог</h2><p>Главный урок, который мы вынесли: идемпотентность — это общая ответственность всех команд разработки, и поломать её может быть проще, чем кажется. А добавить в уже работающую систему быстро и дёшево — почти невозможно.</p><p>Метрик на всплески повторных запросов у нас не было. А зря — это самый дешёвый способ увидеть проблему до того, как она обрушит продакшен. Системы, спроектированные на 10% нагрузки, ломаются на 60% — и обычно это становится неожиданностью для команды.</p><h2>Практический чек-лист: что проверить в своей системе уже сегодня</h2><ul><li>Убедитесь, что все критические мутирующие эндпоинты поддерживают ключ идемпотентности.</li><li>Настройте алерты на аномальное количество запросов на создание сущностей от одного пользователя за короткий промежуток времени.</li><li>Проверьте, как ваш API Gateway обрабатывает ошибки — не теряет ли он ответы downstream-сервисов.</li><li>Убедитесь, что фронтенд корректно обрабатывает не только 200, но и 500, 502, 504, не провоцируя пользователя на повторные клики без необходимости.</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>Отказ от Tailwind: как структурировать CSS без фреймворка</title>
      <link>https://tproger.ru/translations/otkaz-ot-tailwind-kak-strukturirovat-css-bez-frejmvorka</link>
      <comments>https://tproger.ru/translations/otkaz-ot-tailwind-kak-strukturirovat-css-bez-frejmvorka?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/otkaz-ot-tailwind-kak-strukturirovat-css-bez-frejmvorka</guid>
      <description><![CDATA[<p>Опыт перехода с Tailwind v2 на ванильный CSS: компонентный подход, CSS custom properties, Grid без media queries и esbuild. Разбираем систему — берите за основу.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/otkaz-ot-tailwind-kak-strukturirovat-css-bez-frejmvorka">Отказ от Tailwind: как структурировать CSS без фреймворка</a>»</p>]]></description>
      <category><![CDATA[CSS]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 17 May 2026 08:39:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Восемь лет назад Джулия Эванс <a href="https://jvns.ca/blog/2026/05/15/moving-away-from-tailwind--and-learning-to-structure-my-css-/">открыла для себя Tailwind</a> и была в восторге. Теперь она провела неделю, переводя несколько сайтов обратно на семантический HTML и ванильный CSS — и делится практической системой из девяти составных частей: reset, компоненты, цвета, размеры шрифтов, утилиты, базовые стили, отступы, адаптивный Grid и сборка через esbuild.</p><p>Tailwind обучает системам: reset, цветовая палитра, шкала размеров — всё это переносится в CSS custom properties без зависимостей.</p><p>Компонентный подход (один класс — один CSS-файл) резко снижает когнитивную нагрузку: 100 строк компонента — это только 100 строк.</p><p>CSS Grid с auto-fit и minmax() создаёт гибкие сетки без единого media query.</p><p>В dev-режиме сборщик не нужен: браузер понимает нативные @import и вложенные селекторы. Для production — одна команда esbuild.</p><p>Tailwind v2 без сборщика весит 2,8 МБ (270 КБ gzip) в каждом проекте — и это один из аргументов для миграции.</p><h2>Зачем уходить с Tailwind</h2><p>Прежде чем разбирать систему, — почему вообще стоит её строить, если Tailwind под рукой.</p><ul><li><b>Build-система стала обязательной.</b> Tailwind v3+ требует JIT-компилятора. Без сборщика вы застряли на v2 — а это <b>2,8 МБ CSS</b> (270 КБ gzip) в каждом проекте.</li><li><b>Смесь стилей неудобна.</b> Когда в одном проекте живут и ванильный CSS, и Tailwind — сопровождение становится болезненным.</li><li><b>Tailwind ограничивает.</b> grid-template-areas технически работает через arbitrary values, но синтаксис настолько громоздкий, что на практике им никто не пользуется. Container queries, @layer, @scope — туда же.</li><li><b>Накопленный опыт.</b> После нескольких лет работы ванильный CSS уже не пугает.</li><li><b>Ценность CSS-экспертизы.</b> Джулия упоминает эссе «Tailwind and the Femininity of CSS»: Tailwind косвенно транслирует идею, что CSS — не настоящее программирование. Она больше не хочет поддерживать этот нарратив.</li></ul><p>При этом Tailwind честно обучал хорошим системам. Миграция — не отказ от этих систем, а их присвоение в виде нативного CSS.</p><h2>Что Tailwind успел дать</h2><p>Приступая к миграции, Джулия поняла: у неё уже есть многое из нужного. Любая CSS-кодовая база состоит из нескольких слоёв — раскладка, шрифты, цвета, переиспользуемые компоненты. Для каждого нужна система, иначе хаос. Tailwind эти системы давал: reset-стили, цветовую палитру, шкалу размеров шрифтов. Переход — это не изобретение колеса заново, а перенос уже понятых систем в нативный CSS.</p><h2>Девять аспектов структуры CSS</h2><p>Как Джулия организует свою CSS-кодовую базу сегодня.</p><h3>1. Reset-стили</h3><p>Простейшее решение — скопировать первые ~200 строк Tailwind Preflight из tailwind.css. За годы работы привыкаешь к box-sizing: border-box и line-height: 1.5 как к умолчаниям. Перенос preflight сохраняет привычное поведение без npm-зависимости.</p><h3>2. Компоненты</h3><p>Это ядро подхода. Идея та же, что в Vue или React-компонентах — но без JavaScript. Три правила:</p><ul><li>У каждого компонента — уникальный CSS-класс.</li><li>CSS одного компонента никогда не перекрывает стили другого.</li><li>Каждый компонент живёт в собственном CSS-файле.</li></ul><p>При редактировании ста строк компонента нужно думать только о ста строках. Нативные вложенные CSS-селекторы (поддерживаются всеми браузерами с 2023 года) делают код компактным:</p><h3>3. Цвета</h3><p>Одно правило: все цвета сайта объявляются в colours.css через <a href="https://developer.mozilla.org/ru/docs/Web/CSS/Using_CSS_custom_properties">CSS custom properties</a> — никакого хардкода в компонентах.</p><h3>4. Размеры шрифтов</h3><p>Вместо классов text-lg — переменные, взятые из Tailwind. Не нужно помнить, в каких единицах задавать размер (em, px или rem):</p><h3>5. Утилитарные классы</h3><p>Небольшой файл для вещей, которые встречаются в разных компонентах — кнопки, .sr-only для скринридеров и т.п. Держится маленьким намеренно.</p><h3>6. Базовые стили</h3><p>Стили, применяемые ко всему сайту. Джулия намеренно ограничивает этот файл двумя правилами — и планирует пополнять его снизу вверх, когда паттерн из компонентов повторяется несколько раз:</p><h3>7. Отступы</h3><p>Наименее завершённая часть системы. Основной принцип: за внешние отступы отвечает родительский контейнер, а не сами компоненты. Паттерн «owl selector» (или «lobotomized owl» — селектор вида * + *) даёт отступ между любыми соседними дочерними элементами, не трогая первый:</p><p>Дополняет это принцип «no outer margin»: компоненты не задают собственные внешние отступы — ими управляет исключительно родитель. Это предотвращает коллизии при вставке компонента в разные контексты.</p><h3>8. Адаптивный дизайн: больше Grid</h3><p>Вместо Tailwind-классов вида md:text-xl — гибкие сетки <a href="https://developer.mozilla.org/ru/docs/Web/CSS/CSS_grid_layout">CSS Grid</a>, которые сами адаптируются без брейкпоинтов. auto-fit — директива Grid, которая создаёт столько колонок, сколько умещается в контейнер (может быть 4, 3, 2 или 1 — в зависимости от ширины):</p><p>Ещё одна возможность, неудобная в Tailwind, — grid-template-areas (именованные зоны сетки): в Tailwind её можно задать через arbitrary values, но синтаксис настолько громоздкий, что в реальных проектах это нечитаемо. В ванильном CSS это просто:</p><h3>9. Система сборки: esbuild</h3><p>В dev-режиме сборщик не нужен совсем: современный CSS поддерживает нативные @import и вложенные селекторы в браузере без препроцессоров.</p><p>Для production-бандла Джулия использует <a href="https://esbuild.github.io/">esbuild</a> — сборщик на Go, распространяемый как нативный бинарник (без Node.js в runtime), который работает в десятки раз быстрее webpack:</p><h2>Возможности CSS, которые стоит изучить</h2><p>В процессе миграции Джулия наткнулась на несколько возможностей CSS, которые пока не использовала:</p><ul><li><a href="https://developer.mozilla.org/ru/docs/Web/CSS/@layer">@layer</a> — каскадные слои для управления приоритетом стилей без повышения специфичности.</li><li><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@scope">@scope</a> — ограничение области действия CSS-правил конкретным поддеревом DOM.</li><li>Container queries — медиазапросы относительно размера родительского контейнера, а не viewport.</li><li>Subgrid — вложенные сетки, наследующие треки родительской Grid.</li></ul><h2>Итог</h2><p>Главный вывод: Tailwind — это не магия, а набор систем. Reset-стили, цветовая палитра, шкала размеров шрифтов — всё это существует в нативном CSS как custom properties. Компонентный подход решает те же задачи изоляции. CSS Grid делает большинство media queries ненужными. А esbuild заменяет тяжёлый toolchain одним бинарником.</p><p>Начать можно с трёх шагов: скопировать Preflight → добавить custom properties для цветов и размеров → разбить стили по файлам-компонентам. Оригинальная статья Джулии Эванс доступна на <a href="https://jvns.ca/blog/2026/05/15/moving-away-from-tailwind--and-learning-to-structure-my-css-/">jvns.ca</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>sizes='auto' закрывает 14 лет страданий с адаптивными картинками</title>
      <link>https://tproger.ru/translations/sizes-auto-zakryvaet-14-let-ada-s-responsive-images-esse-mat</link>
      <comments>https://tproger.ru/translations/sizes-auto-zakryvaet-14-let-ada-s-responsive-images-esse-mat?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/sizes-auto-zakryvaet-14-let-ada-s-responsive-images-esse-mat</guid>
      <description><![CDATA[<p>Mat Marquis о том, как одно слово sizes='auto' закрывает 14-летнюю боль responsive images. Поддержка теперь и в Gecko, и в WebKit, разбор перевода с Piccalilli.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/sizes-auto-zakryvaet-14-let-ada-s-responsive-images-esse-mat">sizes='auto' закрывает 14 лет страданий с адаптивными картинками</a>»</p>]]></description>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 07 May 2026 11:30:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Если у вас в шаблоне есть img loading="lazy" с длинным sizes-выражением через media query — теперь его можно заменить на одно слово sizes="auto". Браузер сам померит размер картинки в макете и выберет нужный source. В апреле 2026 поддержка приехала и в Gecko, и в WebKit; раньше так умел только Blink. По этому поводу Mat Marquis — бывший председатель RICG (Responsive Images Community Group, группа стандартизации srcset/sizes в HTML) и человек, который 14 лет защищал нынешний синтаксис, — написал исповедальное эссе на Piccalilli. Перевели его целиком, потому что оно одновременно история стандартизации и практический разбор.</p><p>Прежде чем нырять в текст автора — короткая выжимка, ради чего стоит поменять разметку прямо сегодня.</p><ul><li><b>Что изменилось:</b> Mozilla и Apple наконец смержили патчи (авторы — Simon Pieters в Gecko и Yoav Weiss в WebKit), и sizes="auto" работает во всех движках. Раньше фича жила только в Blink (Chrome, Edge). Конкретные номера версий Firefox и Safari, в которых оказалась поддержка, лучше сверять по <a href="https://caniuse.com/mdn-html_elements_img_sizes_auto" rel="noopener">caniuse</a>.</li><li><b>Как использовать:</b> только на изображениях с loading="lazy". К img добавляете sizes="auto" — браузер берёт реальный размер элемента из layout и выбирает source из srcset.</li><li><b>Когда не работает:</b> hero-картинки и LCP-кандидаты (Largest Contentful Paint — самый крупный визуальный элемент в первом экране, ключевая метрика Core Web Vitals), у которых нет loading="lazy" (их браузер запрашивает до того, как знает layout). Им по-прежнему нужен явный sizes — но это редкие исключения, а не правило.</li><li><b>Безопасность миграции:</b> sizes — descriptive-атрибут (описывает факт, а не команду). Браузеры без поддержки auto просто проигнорируют ключевое слово и откатятся к запасному значению — например, sizes="auto, (min-width: 1040px) 650px, 100vw".</li><li><b>Уже в продакшене:</b> WordPress использует этот подход после патча от Joe McGill — выходца из RICG (Responsive Images Community Group).</li></ul><h2>Четырнадцать лет ожидания</h2><p>Я ждал четырнадцать лет, чтобы написать эту статью. Четырнадцать лет, чтобы рассказать вам про одно относительно недавнее дополнение к тому, как картинки работают в вебе. Для вас — буквально пара символов в разметке, которая улучшит фундаментальную эргономику работы с изображениями. Для пользователей — невидимое, бесшовное и потенциально огромное улучшение фронтенд-производительности, навсегда вшитое в ткань веба. А для меня — наконец-то время признаться в зловещих махинациях; признание, которое зрело почти полтора десятилетия.</p><p>Тогда, четырнадцать лет назад, я был достопочтенным председателем RICG (Responsive Images Community Group) — пиратской радиостанции среди web standards bodies, ответственной за то, чтобы привести в платформу разметку для responsive images. Кто-то из вас помнит. Кто-то был там, на заре responsive web design, и помогал находить новые сценарии, в которых веб-платформа не справлялась — когда сборная команда фронтенд-специалистов сплотилась, организовалась и врезалась лбом в процесс веб-стандартов, который не был ей рад. Мы требовали место за столом наряду с производителями браузеров и представляли интересы веб-дизайнеров, разработчиков и тех пользователей, которым мы служили. Нас были сотни. После лет итераций, бесчисленных черновиков спецификаций и прототипов, бесконечных споров, превращавшихся в консенсус через древние мейл-листы и IRC-каналы, мы вместе с вендорами браузеров наконец пришли к рабочему синтаксису. И сделали его реальностью — собрали деньги в коммьюнити, чтобы оплатить независимые реализации в браузерах, написали полифиллы для разгона adoption, прикрутили это всё к крупным CMS, написали статьи, выступили с докладами и распространили — позвольте сказать — лучшие футболки в истории веб-стандартов.</p><p>Я понимаю, что многие из вас при всём при этом отсутствовали — это древняя история по меркам веб-разработки. Для вас разметка для responsive images существовала всё то время, что вы делали сайты: плотный, непрозрачный, неотвратимый и неизбежный аспект платформы, замысловатый синтаксис и постоянный источник фрустрации.</p><p>Если вы из второй группы — позвольте представиться: это всё я. Прямо здесь — я.</p><p>Каждый раз, когда вы безуспешно пытались понять, почему браузер выбирает конкретный source из srcset, — это я вас мучил. Каждый раз, когда приходилось затаскивать огромную third-party библиотеку, чтобы справиться с синтаксисом, который явно не задумывался для написания человеком, — я был причиной; чёрт, я даже мог его соавторствовать. Когда вы запускали bookmarklet, который ломал ваш workflow, в надежде, что он сгенерирует значение sizes, более-менее совпадающее с реальностью ваших layouts. Когда становилось слишком много, и вы опускали руки — сдавались — и в итоге грузили на пользователей огромные оригиналы, от которых те никогда не получат никакой практической пользы, но заплатят всю цену в производительности. Это всё было не вашей виной. Это было моей. Я не только не остановил эти синтаксисы от стандартизации — я был их знаменосцем. Я зубами рвал за разметку, которую вы прокляли.</p><p>Ох. И как будто этого мало — вот часть, от которой вы по-настоящему разозлитесь: я её тоже терпеть не могу.</p><p>Каждый доклад, который я делал, и каждая статья, которую я писал по теме, — курс про изображения, целая книга про изображения — всё это было сквозь стиснутые зубы. В этом синтаксисе есть части, которые я ненавижу с момента, когда впервые их увидел, — то есть с того же момента, как стал их главным заступником. И мне не жаль. Я бы повторил.</p><h2>Зверь, которого нужно было приручить</h2><p>Поймите меня правильно — я не ненавижу <b>сами</b> responsive images. Проблему нужно было решать, никаких сомнений. Тогда, как и сейчас, подавляющая часть transfer size сайта приходится на изображения. Гибкая картинка требует source, достаточно большого, чтобы покрыть максимальный размер, который она занимает в layout — без responsive images картинку, которая занимает в макете, скажем, две тысячи пикселей в ширину, пришлось бы отдавать каждому пользователю в оригинальных 2000 px. Уменьшить её в CSS — тривиально, но запрос-то тот же. Пользователь несёт все издержки трафика, ничего за это не получая.</p><p>Не забывайте, что проблема родом из эпохи, когда соединения медленнее 3G были нормой. Не было надёжного способа подстроить эти запросы под контекст пользователя так, чтобы сохранить браузерные оптимизации. И решения, к которым мы пришли, эффективны, и они сэкономили пользователям непостижимые объёмы трафика. Responsive images как концепция — потрясающее дополнение к платформе. Я горжусь, что сыграл в этом маленькую роль.</p><p>А вот picture — это отдельная история. picture мне нравится с самого начала. Что не любить-то? Кому не нужен такой уровень контроля? К тому же picture позволил ответственно отдавать новые форматы изображений с быстрым и надёжным механизмом отката между браузерами — открыл двери невероятным успехам в кодировании и сжатии, причём без единой строчки JavaScript. Синтаксис читается осмысленно, он даёт нам шаблон для стандартизации более умных решений вокруг любых медиа-запросов и становится мощнее с каждым добавленным media query. picture крутой, мне нравится picture, всем нравится picture. Мы здесь не про picture.</p><p>picture принципиально отличается от srcset и sizes — последние представляют собой <b>descriptive-синтаксис</b>. Чтобы было сразу понятно: <i>descriptive</i> — это «описательный»: вы описываете факт (какие источники у картинки и какого размера она в layout), а решение принимает браузер. <i>Prescriptive</i> — «предписывающий»: вы прямо говорите, что делать. srcset вы используете, чтобы дать браузеру информацию про набор источников, идентичных везде кроме разрешения; sizes — чтобы дать информацию о том, каких размеров изображение будет отрендерено. Ни один из этих атрибутов не говорит браузеру, <b>что</b> делать. Получив эту информацию, браузер делает ровно одну, очень сложную, вещь: определяет источник, наилучшим образом подходящий под контекст пользователя. Визуально источник, выбранный из srcset, неважен — все они выглядят одинаково. Но выбранный кандидат лучше всего подходит под условия пользователя. Вы не получаете никакого контроля над тем, как принимается это решение. Более того — вы даже не имеете права знать, как оно принимается. By design — то есть так задумано: это намеренно вырезано в HTML-спецификации:</p><blockquote>Реализация сама определяет, как — выбрав один источник из набора кандидатов. <i>(In an implementation-defined manner, choose one image source from sourceSet.)</i></blockquote><p>Как вам такое? «Тогда браузер», в строгих технических терминах, <i>просто делает что захочет</i>. Этот формально кодифицированный недостаток контроля не <b>случился сам</b>: ответственность могла остановиться на мне — но не остановилась. Я лично проголосовал «за» за решение, что у вас не должно быть права голоса в том, как работают srcset/sizes — что вы даже не можете знать, как они работают. Сейчас, после всех этих лет, при разоблачении меня как злодея этой истории, я наконец могу рассказать почему. И вам это тоже не понравится. Потому что я знал — вы бы сделали неправильно.</p><h2>Это работа не для человека</h2><p>Не воспринимайте это слишком лично — я бы тоже сделал неправильно. Чёрт возьми, я и <b>делал</b> неправильно, через десятки предложений и прототипов, в поисках решения, которое можно было стандартизировать. Все делали неправильно. В итоге все эти итерации только доказали: никто не мог сделать эту часть правильно. Та «одна вещь», которую делают srcset/sizes — определение источника, наилучшим образом подходящего под контекст пользователя, включая размер viewport, плотность дисплея, пользовательские настройки, пропускную способность и бесчисленное количество других потенциально непознаваемых факторов? В этих факторах есть вещи, которые мы знать не можем, и столько же — которых нам знать не следует.</p><p>Например, мы не можем подстраивать выдачу под скорость соединения пользователя — кажется, что жаль. Но представим на секунду, что могли бы — что мы могли бы сказать «выше этой скорости — этот source, ниже — тот». Теперь это решение ваше. Какие пороги скорости вы бы выставили для своих картинок, и какие я — для своих? Они будут разные. То есть для одной и той же скорости пользователь получит на одном сайте красивые, но забивающие канал картинки, а на следующем — сильно сжатые, но эффективные. <i>Какие из них</i> пользователь хочет? Вопрос с подвохом — все хотят разное. А чего хочет ваша компания? Уф. Все смотрят на вас — на вас, с открытыми тикетами, митингом через полчаса и всем этим контролем, который вам в руки сунула спецификация. Почему сайт ощущается так медленно? Почему наши картинки теперь выглядят хуже, чем у конкурентов? Почему сайт <i>опять</i> ощущается так медленно? Даже когда мы рассматриваем только скорость соединения, цена нашего контроля — это утрата контроля у пользователя. А ведь мы ещё ничего не сказали про остальные факторы.</p><p>Я не хотел этого. Я не хотел этого для тех, кто строит веб, не хотел этого для тех, кто пользуется вебом, и точно не хотел смотреть, как сам веб трещит под весом миллиона огромных картинок и сотни тысяч тикетов «надо когда-нибудь подробно расписать нашу политику работы с responsive images», похороненных в трекерах навечно.</p><p>У браузера доступа к информации куда больше, чем у нас, — точно больше, чем нам разумно бы хотелось. Поэтому он может принимать решения о размере экрана, плотности дисплея, пропускной способности, пользовательских настройках и любых будущих факторах, о которых мы пока даже не догадываемся, — не делая ничего из этого нашей проблемой. Браузер может тонко настраивать детали — например, избегать ненужных запросов, оставляя крупный source, если он уже в кеше, вместо запроса меньшего, функционально идентичного. Я бы не хотел владеть этой логикой. Браузер может опрашивать пользовательские настройки — давая человеку контроль над этими решениями и стабильность опыта от сайта к сайту.</p><p>В итоге нам не нужен контроль, когда речь о выборе источника. Нам нужны просто <b>быстрые картинки</b> — и srcset с sizes закрывают этот use case прекрасно. Лучше, чем кто-то из нас способен был бы лично, если бы пришлось. Было бы кошмаром, если бы пришлось. Descriptive-синтаксис избавляет нас от всего этого ужаса и позволяет браузеру делать то, что он умеет лучше всего: использовать информацию, которая у него уже есть, чтобы сделать один эффективный запрос за источником. Нам остаётся только дать ему ту небольшую часть информации, которой у него нет.</p><p>Честно говоря, srcset даже не так уж плох, всё взвесив! Любая CMS, статический генератор или build-tool в мире легко выплюнет список сгенерированных источников и их ширин через запятую. Чем больше значений вы туда положите, тем эффективнее и точнее будут запросы. Никаких страданий, никаких user-facing издержек, кроме нескольких лишних байт разметки. Аккуратный синтаксис, если приглядеться. srcset — норм.</p><p>Responsive images — не проблема. picture — не проблема. srcset — даже не проблема.</p><p>Мы оба знаем, в чём проблема.</p><h2>Дилемма sizes</h2><p>Браузер не может знать, сколько места займёт изображение в макете, потому что принимает решения по запросам картинок задолго до того, как у него будет информация для рендера layout — там просто пока нечего измерять. Размер viewport в этот момент уже доступен — но это ужасный proxy для размера реально отрендеренного изображения. Веб не сделан из full-bleed «hero»-картинок; он сделан из колонок и гридов, сайдбаров и «карточек» и кучи маленьких круглых аватарок. Допущение, что source никогда не будет больше viewport, — неплохое начало (поэтому пропущенный sizes, формально невалидный, работает как sizes="100vw"). Но этого недостаточно. И вот мы с вами вынуждены описывать все размеры, которые элемент примет на всех breakpoints и контейнерных запросах, единой строкой в HTML-атрибуте. Какая мерзость.</p><p>Именно потому, что для sizes нужна информация об окружающем layout, его невозможно автоматизировать. Сборочный процесс не может узнать, сколько места займёт картинка в разных макетах без огромных накладных расходов — вроде «собрать всё, отрендерить весь сайт, замерить каждое изображение на каждой странице, сгенерировать sizes для всех, и только потом продолжить сборку». Поэтому мы пишем эти описания вручную — и за исключением совсем простых случаев это нельзя сделать без инструментария. Описание размеров гибкой картинки требует слишком многих вычислений между breakpoints. Вот пример из относительно простого макета:</p><p>Никто не должен быть способен это написать. В смысле — как? Изменяя размер браузера и щурясь? <b>Гадая?</b> sizes — один из немногих паттернов разметки, которые буквально требуют инструментария, что максимально далеко от веб-этоса «открой текстовый редактор и собери сайт» — этоса, который я очень ценю. Чёрт, даже если бы вы умудрились описать всё через media query — то есть использовать прескриптивный синтаксис как дескриптивный, говоря «выше такого размера <b>вот это произойдёт</b>» вместо «выше такого размера <b>сделай вот это</b>» — мне делается дурно. Я ненавижу sizes. Я всегда ненавидел sizes.</p><p>Поэтому я здесь. Поэтому я наконец об этом пишу. Я не извиняюсь за sizes. Я здесь, чтобы помочь его <b>похоронить</b>.</p><h2>Начало и конец</h2><p>Несколько недель назад в Gecko и WebKit залендили патчи — авторы Simon Pieters и Yoav Weiss, два лучших участника RICG. Эти патчи влились тихо, выровняв Gecko и WebKit с Blink — поддержка значения auto в атрибуте sizes. Автоматический sizes — потенциальные размеры отрендеренного изображения, которые браузер определяет сам, наряду со всеми остальными факторами. Полностью автоматические responsive images. Передаёте список кандидатов через srcset, прикручиваете sizes="auto" — и браузер делает остальное.</p><p>Как? Центральная проблема srcset/sizes была в тайминге: браузер принимает решения по запросам картинок задолго до того, как у него есть информация о макете страницы, поэтому мы должны были давать ему информацию о layout сами. Это допущение больше <b>не строго истинно</b>. Это всё ещё дефолтное поведение: если в разметке есть img, запрос за ним уйдёт задолго до того, как layout будет известен, — <b>если только</b> картинка не использует атрибут loading="lazy" (исключительно частая лучшая практика для всех картинок, кроме тех, что почти наверняка попадут в viewport при первой загрузке страницы). Добавление loading="lazy" к img меняет всё уравнение: теперь эти изображения запрашиваются в момент пользовательского взаимодействия, гораздо позже момента, когда у браузера уже есть вся информация о размерах будущего рендера. Браузеру больше не нужны мы — и в мире всё стало хорошо.</p><p>Готов поспорить, вы ждёте подвоха. Не ждите. Если переживаете за поддержку браузеров — не стоит: встретив строку «auto» в начале sizes, любой браузер с поддержкой скажет «понял, дальше я сам», выкинет остальную часть sizes и продолжит. Браузер без поддержки выбросит auto как бессмысленное и продолжит читать атрибут как обычно. Это значит, что начать использовать можно прямо сейчас — без затрат и накладных расходов, кроме набора слова auto, в начале sizes:</p><p>Не первое матерное слово, на которое меня сподвиг sizes, но точно с самым позитивным результатом.</p><p>Этот подход — ровно то, что теперь использует WordPress.</p><h2>Когда sizes ещё нужен</h2><p>Конечно, это не конец абсолютно — описательные значения sizes вам всё ещё иногда понадобятся. Картинка, которая, скорее всего, попадёт в viewport при первой загрузке, — это сценарий, в котором вы <b>не хотели</b> бы использовать loading="lazy" (а sizes="auto" работает только с ленивыми изображениями). Но такие картинки — исключения, не правило.</p><p>Эти редкие исключения — изображения, почти наверняка попадающие в viewport в самом верху страницы, ваши вероятные Largest Contentful Paint элементы (LCP — самый крупный визуальный элемент в первом экране, ключевая метрика Core Web Vitals; лениво грузить такое нельзя — у него слишком ранний дедлайн), которым плохо живётся под loading="lazy"? Ну, вы только что представили их в голове, верно? Большая «hero»-картинка, тип изображения, который, скажем, занимает всю ширину viewport-а или близко к этому. Их относительно легко описать через breakpoints. Может быть, что-то в районе — ну, вытащу значение из воздуха — sizes="100vw". Все остальные картинки — те, что раскиданы по колонкам, гридам, сайдбарам, «карточкам» и кучкам маленьких круглых аватарок, из которых на самом деле и сделан веб? loading="lazy" sizes="auto". Готово. Поздравляю.</p><p>Я не буду скучать по всем этим вручную выкованным sizes. У меня к ним любви и не было. Я никогда не испытаю ни проблеска ностальгии по тому, что я помог сделать реальным и неотделимо связал со своим именем. Синтаксис никогда не был целью; целью всегда был <b>механизм</b>. На тот момент платформа не давала браузерам способа принимать более умные решения о том, какой источник запросить и когда — никакие сценарии или markup-трюки никогда не дадут request настолько же быстрый и эффективный, как тот, что делает сам браузер. Мы получили этот механизм — и я заставил всех нас оплатить его стоимость, ради пользователей и ради здоровья веба.</p><p>Так что любой из вас, дизайнеров и разработчиков, кто боролся с атрибутами sizes в прошлом, — давайте, нарисуйте мой портрет, какого хотите размера, распечатайте и приклейте к ближайшей дартс-доске. Я держу голову высоко и не приношу извинений. Я был прав. Мы были правы. Я по-прежнему стою за необходимость декларативного синтаксиса. Стою за это ровно настолько же, насколько жалею, что он не мог быть лучше — и ровно настолько же, насколько знаю, что в то время не мог. Конечно, я ёжусь от идеи отдать контроль не меньше, чем любой разработчик, но когда речь о высокопроизводительных изображениях — у нас никогда не могло быть контроля <b>по-настоящему</b>. Было бы самонадеянно даже пытаться. И как бы фрустрирующе это ни было — отказаться от контроля — владеть responsive images было бы бременем; <b>проклятием</b>.</p><p>Спросите меня, откуда я знаю.</p><h2>Что делать сегодня</h2><p>Поправка к шаблонам короткая. У всех img с loading="lazy" в проекте — поставить sizes="auto" (можно с запасным значением auto, … для старых браузеров). Hero-картинки и явные LCP-кандидаты оставить как есть. Сборку и pre-render это не ломает: auto — расширение существующего descriptive-синтаксиса, не замена. Если вы пишете на современном WordPress — вероятно, вам уже ничего делать не нужно.</p><p>Оригинал статьи Mat Marquis — на <a href="https://piccalil.li/blog/the-end-of-responsive-images/" rel="noopener">Piccalilli</a>. Спецификация атрибута sizes с поддержкой auto — в <a href="https://html.spec.whatwg.org/multipage/images.html#sizes-attributes" rel="noopener">WHATWG HTML</a>. Совместимость по версиям браузеров — на <a href="https://caniuse.com/mdn-html_elements_img_sizes_auto" rel="noopener">caniuse</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>WebGL-портфолио Susurrus: акварельный 3D-мир на Three.js и Kuwahara-шейдере</title>
      <link>https://tproger.ru/translations/webgl-portfolio-susurrus-akvarelnyj-3d-mir-na-three-js-i-kuwah</link>
      <comments>https://tproger.ru/translations/webgl-portfolio-susurrus-akvarelnyj-3d-mir-na-three-js-i-kuwah?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/webgl-portfolio-susurrus-akvarelnyj-3d-mir-na-three-js-i-kuwah</guid>
      <description><![CDATA[<p>Перевод case-study Wei Xianyao о Susurrus — WebGL-сцене на React Three Fiber, построенной вокруг Kuwahara-шейдера. Отражающая вода, ScrollControls, физика.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/webgl-portfolio-susurrus-akvarelnyj-3d-mir-na-three-js-i-kuwah">WebGL-портфолио Susurrus: акварельный 3D-мир на Three.js и Kuwahara-шейдере</a>»</p>]]></description>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[OpenGL]]></category>
      <category><![CDATA[Компьютерная графика]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 06 May 2026 05:59:52 GMT</pubDate>
      <content:encoded><![CDATA[<p>Чем это могло бы быть, если бы 3D-сцена в браузере вела себя как акварельный рисунок — текучая, отзывчивая, интерактивная? Дизайнер Wei Xianyao (Weisdevice) <a href="https://tympanus.net/codrops/2026/04/24/susurrus-crafting-a-cozy-watercolor-world-with-three-js-and-shaders/">опубликовал case-study</a> на Codrops о проекте <b>Susurrus</b>: WebGL-сцена, целиком построенная вокруг одного Kuwahara-шейдера в постпроцессинге, с отражающей водой, физикой и звуком. Перевод материала.</p><p>Главный приём — Kuwahara-фильтр как единственный пасс постпроцессинга. Всё остальное (отражения, частицы, реакция на скролл, физика появления хлеба по клику) встроено вокруг него и подгоняется под его эстетику.</p><p><b>Концепция.</b> Забытая мельница на воде, рендерится как акварель, но полноценно 3D и интерактивна. Вода, ветер, сцена — единое атмосферное пространство. Под мирным фасадом скрыт сюрреалистический намёк: подводная мельница бесконечно производит хлеб, хотя зерно давно ушло.</p><p><b>Стек.</b> React, React Three Fiber, Drei, React Three Rapier, Howler.js, TypeScript, WebGL, HTML/SCSS.</p><p><b>Главный приём — Kuwahara-шейдер.</b> Несмотря на сильно обработанный вид, это единственный пасс постпроцессинга. Сцена строится вокруг него, в том числе на этапе моделей в Blender — чтобы видеть итоговый эффект сразу.</p><p><b>Отражающая вода — три шага.</b> MeshReflectorMaterial в низком разрешении (для производительности), кастомный шейдер сверху для деталей и анимации воды, тюнинг освещения.</p><p><b>Reveal Effect.</b> ScrollControls контролирует параметр uProgress, шейдер применён к ScreenQuad. Это компактный способ реализовать разворачивающуюся при скролле интро-сцену.</p><h2>Концепция: уют, которого не бывает</h2><p>Wei работает в свободном режиме: не использует Figma и подобные инструменты на личных проектах, идёт от концепта в голове. Susurrus родился как «эхо в сознании»: дом, плавающий на отражающей воде, с Kuwahara-шейдером, наложенным как пост-процессинг — чтобы получить «3D-веб-впечатление как картина».</p><p>Интерфейс при этом намеренно прост — фокус на 3D-контенте. В сцене присутствуют два поэта, но смысловое ядро — атмосфера и эмоция, переданные через визуал и звук. Само слово «susurrus» (шёпот, шорох) задаёт тон: слова намеренно невнятны, важнее — настроение.</p><p>При ближнем рассмотрении сцена становится тревожной: подводная мельница бесконечно производит хлеб, хотя зерна давно нет. Это тихая метафора несуществующего комфорта — то, что выглядит решённым, но к чему присматриваться не стоит.</p><h2>Kuwahara-шейдер: ядро всего проекта</h2><p>Весь визуальный стиль Susurrus построен на Kuwahara-фильтре. Это единственный пасс постпроцессинга — всё остальное собрано вокруг него. Wei поставил его на этап раньше, чем закончил 3D-модели в Blender: так можно видеть итоговый эффект и подгонять модели под шейдер, а не получить сюрприз в финале.</p><p>При исследовании автор нашёл несколько подходов, опираясь в основном на разбор Maxime Heckel о Kuwahara-фильтре и painterly-шейдинге. На основе этих референсов Wei сделал упрощённую реализацию:</p><ul><li>Не использовал TensorPass, чтобы пасс остался простым (хотя он усиливает детализацию).</li><li>Использовал отличающийся подход на vertex-стадии, по сравнению со стандартными реализациями.</li></ul><p>Стандартный vertex для Kuwahara обычно выглядит так:</p><p>Версия Wei проще:</p><p>Wei не применяет полную модель-вью-проекционную матрицу (MVP), чтобы немного ускорить вычисления. Цена компромисса — эффект слабее, когда камера подходит близко, но в Susurrus камера не приближается к моделям анимацией, поэтому это ОК.</p><h2>Отражающая вода в три шага</h2><p>Авторская «грязная» реализация воды:</p><ul><li>MeshReflectorMaterial в акварельном стиле. Из-за визуальной обработки разрешение можно ставить очень низким — это сохраняет производительность на мобильных и десктопе.</li><li>Кастомный шейдер на отдельной плоскости поверх MeshReflectorMaterial — добавляет детали и анимацию воды.</li><li>Освещение подкручено так, чтобы вода казалась живее, не плоской и не скучной.</li></ul><h2>Reveal Effect для интро-сцены</h2><p>Wei использовал ScrollControls для контроля параметра uProgress, который подаётся в reveal-шейдер. Шейдер применён к ScreenQuad — это удобный способ реализовать эффект «открытия» сцены при скролле.</p><h2>Звук, физика и адаптивность</h2><p><b>Звуковые эффекты.</b> Через react-howler: разные звуковые взаимодействия по hover/click. Эффекты интегрированы с фоновой музыкой, чтобы получился lo-fi-стиль — «картина, которая может петь».</p><p><b>Физика.</b> Главный интерактивный элемент Susurrus — Spawning Bread on Click: щелчок порождает физический объект (хлеб), который падает в сцену. На реализации стоит React Three Rapier.</p><p><b>Адаптивность.</b> Стандартная для автора цель — мобильная совместимость и плавная производительность на mobile и более старых устройствах.</p><h2>Выводы</h2><p>Susurrus — пример того, как один точно выбранный шейдер может задать стиль всему проекту: от моделей в Blender до анимации воды и интерактивности. Идея Wei — начать с Kuwahara-фильтра ещё до финальных моделей — практичная: видишь итоговый эффект сразу и не тратишь время на проработку деталей, которые шейдер всё равно сгладит.</p><p>Для тех, кто работает с Three.js / React Three Fiber, в случае Susurrus есть три прямых заимствования: компактный паттерн ScrollControls + ScreenQuad для reveal-сцен, дешёвая реализация отражающей воды через MeshReflectorMaterial низкого разрешения + кастомный шейдер сверху, и выбор пасса постпроцессинга на старте проекта, а не в финале.</p><p>Источник: <a href="https://tympanus.net/codrops/2026/04/24/susurrus-crafting-a-cozy-watercolor-world-with-three-js-and-shaders/">Susurrus: Crafting a Cozy Watercolor World with Three.js and Shaders — Codrops</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Inline-пропсы в React тихо обнуляют memo: разбор на 200 строк, как чинить</title>
      <link>https://tproger.ru/translations/inline-propsy-v-react-tiho-obnulyayut-memo-razbor-na-200-strok-k</link>
      <comments>https://tproger.ru/translations/inline-propsy-v-react-tiho-obnulyayut-memo-razbor-na-200-strok-k?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/inline-propsy-v-react-tiho-obnulyayut-memo-razbor-na-200-strok-k</guid>
      <description><![CDATA[<p>Контролируемый эксперимент LogRocket: 200 memoized React-строк, inline объекты в JSX делают коммит 244 мс на нажатие. Простой фикс снижает до 6 мс. Разбор.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/inline-propsy-v-react-tiho-obnulyayut-memo-razbor-na-200-strok-k">Inline-пропсы в React тихо обнуляют memo: разбор на 200 строк, как чинить</a>»</p>]]></description>
      <category><![CDATA[Оптимизация]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 05 May 2026 11:30:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Совет по производительности React обычно сводится к набору рецептов: оборачиваем дорогие дочерние компоненты в React.memo, добавляем useCallback к обработчикам, useMemo к вычислениям — и идём дальше. На практике эти инструменты работают только тогда, когда передаваемые через них значения действительно стабильны. Если родитель пересоздаёт объект или функцию на каждом рендере, React видит новую ссылку и memoization-граница перестаёт делать полезную работу.</p><p>В <a href="https://blog.logrocket.com/react-pattern-everyone-uses-kills-performance/">материале на блоге LogRocket</a> разобран один из самых частых React-паттернов, который в неподходящем контексте оказывается одним из самых дорогих, — передача inline-объектов, массивов и колбэков прямо в месте вызова компонента. Контролируемый эксперимент с 200 memoized строк показывает, как это превращает один keystroke в коммит на 243,9 мс — и как простой рефактор возвращает время до 6 мс.</p><p><b>React.memo сравнивает по ссылке.</b> Внутри React работает Object.is: {padding:16} и {padding:16} — это разные ссылки, значит «изменилось».</p><p><b>Inline-объекты в JSX обнуляют memo.</b> Каждый рендер родителя создаёт новый объект/функцию, мемоизированный дочерний компонент видит «новые пропсы» и перерисовывается заново. Оптимизация, которую вы планировали, не срабатывает.</p><p><b>Цена в живом коде.</b> Эксперимент: 200 memoized строк, поиск, inline style и onAddToCart. После 6 нажатий — счётчик рендеров каждой строки = 14, на keystroke коммит 243,9 мс.</p><p><b>Фикс простой.</b> Статичный объект — в module scope. Динамический колбэк — в useCallback с пустыми зависимостями. После: коммит 6 мс, счётчик рендеров = 2, Why Did You Render молчит.</p><p><b>React Compiler не отменяет понимания.</b> Он автоматизирует много memoization, но useMemo/useCallback остаются escape hatch для случаев, когда нужен точный контроль (например, dependency для Effect).</p><h2>Как работает bailout у React</h2><p>React.memo оборачивает компонент в memoization-границу. Когда родитель ререндерится, React не пропускает дочерний автоматически только потому, что он мемоизирован. Вместо этого сравниваются новые пропсы со старыми. Если каждый пропс считается равным — bail out, переиспользуем предыдущий результат. Если хотя бы один не равен — рендер. По умолчанию React сравнивает попропсово через Object.is.</p><p>Эта деталь критична, потому что для объектов и функций Object.is — это, по сути, проверка по ссылке:</p><p>Содержимое выглядит идентичным, но ссылки разные. React поэтому считает их изменёнными. Именно по этой причине inline-объекты и колбэки оказываются скрытой причиной того, что мемоизированный дочерний компонент продолжает ререндериться.</p><p>Та же логика объясняет, зачем нужны useCallback и useMemo. По <a href="https://react.dev/reference/react/useCallback">документации React</a>, useCallback кеширует определение функции между рендерами, а useMemo — результат вычисления. Оба помогают только тогда, когда зависимости остаются достаточно стабильными, чтобы React переиспользовал предыдущее значение. Если положить в массив зависимостей нестабильный объект, React видит новую зависимость на каждом рендере и пересчитывает заново.</p><p>Это и объясняет, почему баг ощущается запутанным в реальном приложении. Значения «выглядят» неизменными для человека: у style-объекта те же ключи, тело колбэка идентично, config всё ещё говорит то же самое. Но React не сравнивает намерение или структуру — он сравнивает идентичность.</p><h2>Когда inline-пропсы реально становятся проблемой</h2><p>Стоит провести границу между теоретической и практической ценой. Inline-колбэк сам по себе — не баг производительности. Если ребёнок дешёвый, частота рендера низкая и memoization-границы вокруг нет, измеримого отрицательного эффекта может вообще не быть. И в документации React, и в гайдах LogRocket по производительности — общее место: оптимизация работает там, где есть реальные узкие места, а не гипотетические.</p><p>Проблема начинается, когда сходятся три условия одновременно:</p><ul><li>Родитель ререндерится часто (поиск, скролл, фильтры, анимация, live data).</li><li>Дочерний компонент или поддерево большое — лишняя работа заметна.</li><li>Вы уже добавили memoization и ждёте, что React пропустит работу, когда «ничего важного не изменилось».</li></ul><p>В такой связке нестабильные inline-ссылки не просто добавляют немного оверхеда — они <b>обнуляют ту оптимизацию, которую вы намеренно ввели</b>. И этот паттерн коварен в продакшене: он не объявляет себя багом. UI работает, исключений нет, предупреждений нет, и без профилировщика часто нет очевидного запаха. Цена проявляется иначе: тормозящая фильтрация списков, лаг ввода, шумные flame-графы и компонентные деревья, которые продолжают перерисовываться, даже когда осмысленные данные не менялись.</p><h2>Контролируемый эксперимент: 200 memoized строк</h2><p>Чтобы не спорить «плохо или нормально», автор поста собрал контролируемый тест: поисковый список товаров с 200 memoized строками, где каждая строка получает одинаковые логические значения, но новые ссылки на объект и функцию на каждом рендере родителя. Это позволяет напрямую увидеть, делает ли React.memo bail out или всё поддерево ререндерится на каждое нажатие клавиши.</p><p>Представьте storefront UI с 200 memoized ProductRow. Родитель — ProductList — хранит searchTerm в state. Каждое нажатие апдейтит state, ререндерит ProductList и снова прогоняет JSX, который мапает отфильтрованные товары. В эксперименте каждая ProductRow обёрнута в memo и помечена whyDidYouRender = true, но получает два inline-пропса в месте вызова:</p><p>Это ровно тот случай, о котором React предупреждает при передаче функций в memoized-компоненты: свежая функция или объект, созданные во время рендера, не пройдут сравнение пропсов, если ссылку не стабилизировать.</p><p>В эксперименте эффект становится виден почти мгновенно. Объект style и колбэк onAddToCart пересоздаются каждый раз, когда ререндерится ProductList, поэтому memo-обёртка видит изменённые пропсы для каждой строки на каждом нажатии. Счётчик рендеров делает это конкретным: после шести нажатий каждая видимая строка показывает <b>Renders: 14</b>. React Profiler затем показывает рантайм-цену ошибки: одно нажатие порождает коммит, в котором ProductList занимает <b>243,9 мс</b> и все 200 row-fibers светятся в flame-графе.</p><p>Здесь React Developer Tools отрабатывают по полной. По официальной документации, React DevTools позволяют инспектировать компоненты, редактировать пропсы и state, а также находить проблемы производительности. Профайлер также доступен программно через &lt;Profiler&gt;, но интерактивный вид DevTools обычно используется командами для отладки.</p><p><a href="https://github.com/welldone-software/why-did-you-render">Why Did You Render</a> делает корневую причину ещё нагляднее. Пакет модифицирует React и сообщает о потенциально избегаемых ререндерах. В этом примере он рапортует props.style как «different objects that are equal by value» и props.onAddToCart как «different functions with the same name» — ровно тот референциальный мисматч, который мы и ожидаем. Это диагностический инструмент только для разработки, не для прода, но крайне эффективный для выявления этого класса багов.</p><h2>Рефакторинг, который реально решает проблему</h2><p>Чтобы остановить каскад рендеров, нужны стабильные ссылки. Концептуально фикс прост: значения, которые не меняются, не должны пересоздаваться во время рендера; колбэки, которым нужно жить через рендеры, должны быть memoized, когда ребёнок зависит от референциальной стабильности.</p><p>Вынос ROW_STYLE в module scope решает проблему на самом дешёвом уровне: React никогда не видит новую ссылку на объект, потому что он создаётся один раз вне компонента. Использование useCallback для handleAddToCart даёт ребёнку стабильную ссылку на функцию между рендерами, пока массив зависимостей не меняется. Это и есть тот случай, для которого React документирует useCallback при передаче функций в мемоизированных детей.</p><p>В эксперименте стабилизация ссылок восстанавливает bail-out. Измеренный результат впечатляет: ProductList падает с 243,9 мс до <b>6 мс</b>, бейджи рендеров остаются на <b>2</b> сколько ни печатай, и Why Did You Render замолкает — избегаемых референциальных мисматчей больше нет.</p><h2>Когда стабилизировать ссылки, а когда — нет</h2><p>Это часть, которая часто теряется в дискуссиях про производительность. Урок не «никогда не используй inline-объекты» и не «оборачивай всё в useCallback». Урок: <b>memoization — это контракт</b>. Если ребёнок полагается на референциальное равенство, чтобы пропустить работу, родитель обязан этот контракт уважать и передавать стабильные ссылки.</p><p>Но это не значит, что каждому компоненту нужна агрессивная мемоизация. Современные рекомендации React всё ещё трактуют memoization как точечную оптимизацию, а не дефолтный стиль. Если рендер дешёвый, поддерево маленькое или ребёнок не memoized, стабилизация ссылок может добавить сложности без реальной выгоды. Поэтому большинство гайдов по React performance, включая обзоры LogRocket, акцентируют профилировку прежде, чем механически оптимизировать.</p><p>Полезное правило большого пальца: <b>сначала перенеси, потом мемоизируй</b>. Если значение статично — вынеси его за пределы тела компонента, прежде чем тянуться к хукам. Это даёт референциальную стабильность почти без когнитивной или рантайм-нагрузки. useCallback и useMemo — только когда значение реально динамическое и ребёнок выигрывает от стабильной идентичности.</p><h2>Меняет ли это React Compiler</h2><p>Один актуальный нюанс — <a href="https://react.dev/learn/react-compiler">React Compiler</a>. Документация описывает его как стабильный билд-тайм инструмент, который автоматически оптимизирует React-приложения и по умолчанию мемоизирует код на основе анализа и эвристик. Это уменьшает потребность в ручных useMemo, useCallback и React.memo, особенно в новом коде.</p><p>Но это не делает референциальную стабильность нерелевантной. Документация также отмечает, что useMemo и useCallback остаются полезными как escape hatch для случаев, когда разработчику нужен точный контроль — например, чтобы держать memoized-значение стабильным как зависимость для Effect. Так что даже в кодовых базах, переходящих на React Compiler, всё равно полезно понимать, как нестабильные ссылки влияют на ререндеры, результаты профайлера и кейсы, где ручной контроль ещё нужен.</p><h2>Итог</h2><p>Inline-объекты и inline-колбэки — не плохой React-код по умолчанию. Чаще всего это просто обычные JavaScript-выражения внутри JSX. Проблема появляется, когда они пересекают memoization-границу и вы ждёте, что React воспримет «то же значение» как «тот же пропс». По умолчанию React сравнивает пропсы и зависимости хуков через Object.is, поэтому для объектов и функций новой ссылки достаточно, чтобы React счёл значение изменившимся.</p><p>Этот паттерн заслуживает большего внимания, чем обычно получает. Это не пустяковая микрооптимизация. Это один из самых простых способов случайно обнулить React.memo — особенно в фильтруемых списках, дашбордах, search-heavy UI и компонентных деревьях с дорогими потомками. Код выглядит чистым, приложение работает, но оптимизация, на которую вы рассчитывали, исчезает.</p><p>Практический вывод для команд, строящих быстрые React-интерфейсы: <b>профилируй сначала</b>. Если memoized поддерево всё ещё ререндерится слишком часто — проверь пропсы прежде, чем винить React. Перенеси статичные объекты из render-пути. Мемоизируйте колбэки только тогда, когда ребёнок реально выигрывает. Используй React DevTools и Why Did You Render, чтобы подтвердить, что именно изменилось и почему. Делай это последовательно — и React.memo перестанет быть декоративным куском кода и начнёт делать свою работу.</p><p>Источник: <a href="https://blog.logrocket.com/react-pattern-everyone-uses-kills-performance/">The React pattern everyone uses that quietly kills performance — LogRocket Blog</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Bring Back Idiomatic Design: почему мы скучаем по интерфейсам Windows 95 — перевод эссе Джона Лёбера</title>
      <link>https://tproger.ru/translations/bring-back-idiomatic-design-pochemu-my-skuchaem-po-interfejsam-wi</link>
      <comments>https://tproger.ru/translations/bring-back-idiomatic-design-pochemu-my-skuchaem-po-interfejsam-wi?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/bring-back-idiomatic-design-pochemu-my-skuchaem-po-interfejsam-wi</guid>
      <description><![CDATA[<p>Почему в Windows 95 каждое приложение было предсказуемым, а сегодня каждый сайт — угадайка? Разбираемся с идиомами дизайна и что делать прямо сейчас.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/bring-back-idiomatic-design-pochemu-my-skuchaem-po-interfejsam-wi">Bring Back Idiomatic Design: почему мы скучаем по интерфейсам Windows 95 — перевод эссе Джона Лёбера</a>»</p>]]></description>
      <category><![CDATA[Веб-дизайн]]></category>
      <category><![CDATA[Дизайн интерфейсов и UX]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 13 Apr 2026 15:30:04 GMT</pubDate>
      <content:encoded><![CDATA[<p>Каждый раз, когда вы не можете найти кнопку «Назад», не уверены, кликабелен ли элемент или это просто текст, и проводите минуту в выпадающем календаре, чтобы выбрать дату — это не случайность. Это следствие того, что веб разучился быть консистентным. Перевод эссе <a href="https://essays.johnloeber.com/p/4-bring-back-idiomatic-design">«Bring Back Idiomatic Design»</a> Джона Лёбера 2023 года — про то, как мы это потеряли и что делать продуктовому разработчику прямо сейчас.</p><p>Я из поколения десктоп-софта. От Windows 95 до Windows 7 я рос на преимущественно офлайн-приложениях, которые управлялись мышью и клавиатурой — задолго до планшетов и смартфонов. В последнее время я скучаю по одной конкретной части той эпохи: по консистентности дизайна. В этом эссе я хочу рассказать про идиоматический дизайн, подчеркнуть важность гомогенных интерфейсов и предложить мысль, что мы потеряли что-то важное.</p><ul><li>Идиоматический дизайн — это набор настолько распространённых решений, что и пользователи, и разработчики применяют их «не задумываясь». Чекбокс «Запомнить меня» — каноничный пример: никто не делает выпадающий список или текстовое поле для этого вопроса.</li><li>Десктоп-эра (Windows 95–7) держалась на гомогенных интерфейсах: File / Edit / View, подчёркнутые буквы для шорткатов вроде Alt + F, статус-бар с состоянием, слова вместо иконок. Идиомы диктовали ОС и её GUI-библиотеки.</li><li>Веб-эра — это эра гетерогенных интерфейсов. Figma и Linear — два лучших энтерпрайз-инструмента сегодня — не разделяют ни одной иконки и ни одного шортката. Даже внутри Google: Gmail, GSuites и Google Docs — три разных опыта.</li><li>Причины разрушения идиом: переход на мобильные (паттерны для тач-экрана пришлось переизобретать), и то, что современный фронтенд пишут не на голом HTML, а на React + npm-пакетах, где идиомы теряются на каждой итерации.</li><li>Apple — главный выживший пример идиоматического дизайна в наше время. Эффект «it just works» строится на том, что iOS навязывает третьим приложениям свои шрифты, кнопки, жесты. То же делает Substack для авторов: ноль настроек, всегда выглядит одинаково.</li><li>Практический вывод для разработчика: следовать HTML/CSS-идиомам, не переизобретать `` через React, не ломать back-button браузера, предпочитать слова иконкам, и понятность — красоте.</li></ul><h2>Идиомы дизайна</h2><p>Допустим, вы заходите на сайт, и он спрашивает: «вы хотите остаться залогиненным?». Есть множество способов задать этот вопрос: текстовое поле, в которое можно ввести «да» или «нет»; выпадающий список с вариантами «Запомнить меня» и «Выйти при закрытии окна». Но в реальности это всегда чекбокс. Почему?</p><p>Чекбокс — это <i>идиома дизайна</i>. Это настолько распространённое решение, что вы как пользователь умеете им пользоваться, не задумываясь, а если бы делали сайт сами, тоже бы поставили чекбокс, не задумываясь. И для тех, кто строит, и для тех, кто пользуется, это стандартный паттерн, на который все полагаются.</p><h2>Гомогенные интерфейсы</h2><p>Чекбокс — это ещё и часть <i>интерфейса</i>. Через него вы взаимодействуете с системой и вводите данные. Интерфейс тем лучше, чем меньше думанья он требует: будь то руль автомобиля или онлайн-форма — если на разбирательство уходит хоть какое-то время, это плохо. Когда вы взаимодействуете со множеством вещей, вы хотите гомогенных интерфейсов с консистентным опытом. Если вы выучили, что Cmd + C — это «копировать», вы хотите, чтобы это работало везде. Никто не хочет помнить, что в одних случаях нужно Ctrl + Shift + C, а в других правый клик → «копировать».</p><p>Но мы пришли именно к этому. Софт ушёл в интернет, и интерфейсы перестали быть гомогенными вообще. Сотни способов выбрать дату, ввести номер банковской карты, сделать любую банальную операцию. Шорткаты в каждом приложении свои. Способов взаимодействия столько, что их нельзя ни запомнить, ни выучить. Использование веб-приложений в 2023-м — это бесконечное упражнение «где у этой штуки то, что мне нужно?».</p><h2>Эра десктоп-софта</h2><p>Для контраста: одной из сильных сторон десктоп-эры была высокая консистентность интерфейсов через идиомы дизайна. Посмотрите на типичный скриншот из Windows 2000 — Microsoft Word.</p><p>Визуально это слегка уродливо и устарело: всё прямоугольное, шрифт так себе, цвета тусклые. Но интерфейс делает несколько вещей по-настоящему правильно.</p><ul><li>Структура меню «Файл / Правка / Вид…» была стандартной. В Adobe Photoshop или Microsoft Excel — без разницы, вы знали, что «Сохранить» лежит в «Файле», «Отменить» в «Правке», «Полный экран» в «Виде» и так далее.</li><li>Меню навигируется с клавиатуры. У каждого пункта есть подчёркнутая буква: <b>F</b> в File, <b>N</b> в New. Это шорткаты. Нажимаете Alt + F, открывается меню «Файл», нажимаете N — создаётся новый файл. И мощным пользователям удобно, и шорткаты легко учить.</li><li>Статус-бар внизу показывает всё про текущее состояние: страницу, столбец, количество слов, идёт ли запись правок, в каком вы режиме (вставки или замены) и так далее.</li><li>Пункты меню подписаны словами. Слова, не иконки, — основной интерфейс к действиям. Иконки используются только там, где смысл очевиден. Весь интерфейс не оставляет места для воображения. На скриншоте нет «интересно, а что эта кнопка делает?» — вы знаете, как этим пользоваться, даже если никогда раньше не пользовались.</li></ul><p>Возможно, вы не знаете, что значат метки <b>REC</b>, <b>TRK</b>, <b>OVR</b> в статус-баре. Тогда вам помог бы ещё один стандартный паттерн: всплывающие подсказки при наведении мыши, которые объясняют, что эта штука делает.</p><p>Что критично — эти идиомы дизайна использовались не только в Microsoft Word, а вообще во всей экосистеме Windows. Посмотрите на экран выхода из Windows XP. Каждая кнопка визуально явно кнопка и подписана прямо тем, что она делает. У каждой подчёркнутая буква для шортката. Разве не приятно?</p><p>Эра десктоп-софта была эрой гомогенных интерфейсов — возможно потому, что операционная система и её GUI-библиотеки диктовали огромные пласты дизайна, и эти ограничения подталкивали разработчиков к конформным паттернам.</p><p>Стоит упомянуть, что последние десятилетия Microsoft вместе с релизами Windows публиковала несколько-сотен-страничные жёстко предписывающие гайды по тому, как делать идиоматические приложения. Один из недавних примеров — <a href="https://learn.microsoft.com/en-us/windows/apps/design/">Windows Apps Design</a>.</p><h2>Эра браузерного софта</h2><p>Эра браузерного софта — это эра гетерогенных интерфейсов. Возьмите два моих любимых веб-приложения: Figma и Linear.</p><p>Я намеренно беру утилитарный энтерпрайз-софт и не сравниваю его с Facebook, Twitter и подобными — это были бы яблоки и апельсины.</p><p>Это, пожалуй, два лучших куска энтерпрайз-софта на сегодня. И хотя у них масса общих фич — настройки команд, абстрактные иерархии элементов, коллаборативные комментарии и так далее — у них нет ни одной общей иконки. У них нет ни одной общей идиомы дизайна. У них разные шорткаты. Оба отлично сделаны <i>с нуля по первым принципам</i>, но не конформны ни к одному другому интерфейсу, который пользователь мог видеть раньше.</p><p>Мы в эпохе индивидуально хорошо сделанных и полезных веб-приложений, и все они уникальны. Даже в продуктах одной и той же компании опыт гетерогенный: пользоваться Gmail — это совсем не то же самое, что пользоваться GSuites, и совсем не то же самое, что Google Docs. В сумме это очень фрустрирует. Отсутствие гомогенных интерфейсов означает, что я провожу большую часть своего цифрового времени не в продуктивном потоке, а тыкая по экрану и спрашивая себя: «можно ли по этому кликнуть? откроется ли это в новой вкладке? сработает ли кнопка „назад" в браузере?». Жуть.</p><p>Эта негомогенность — по двум причинам.</p><h3>Переход на мобильные</h3><p>Все паттерны, придуманные для приложений с мышью и клавиатурой, пришлось переизобретать с появлением тач-экрана. Большинство веб-приложений вынуждены поддерживать оба опыта — мобильный и десктопный — а они радикально разные. В результате большинство пользовательских опытов застряло в неловкой середине: например, гамбургер-меню, придуманные для мобильных, стали использоваться и для десктопа.</p><p>Современный фронтенд-разработчик живёт в культуре копирования и переиспользования модульных компонентов, поэтому копировать-вставлять плохие паттерны и закреплять их — очень легко. После 10+ лет такого подхода поколение за поколением фронтендеров деградировало качество UI/UX-дизайна.</p><h3>Недостаточно идиом за пределами HTML</h3><p>Если бы все следовали одним и тем же идиомам, интерфейсы бы выглядели довольно консистентно. В ранние годы интернета сильные идиомы были: гиперссылки на другие страницы — синие подчёркнутые, фиолетовые если уже посещали. Прекрасно. Сегодня каждый сайт — это собственная угадайка о том, как стилизованы элементы интерфейса. Это ссылка? Может быть.</p><p>Может удивлять, что современный веб-дизайн настолько неидиоматичен — ведь стандарты HTML/CSS очень предписывающие. Проблема в том, что хотя стандарты для написания HTML существуют, его никто не пишет. Все пишут React в TypeScript или последний фреймворк. Импортируют бесчисленные npm-пакеты. Всё это проходит через сложный билд-процесс и выдаёт что-то, что бежит в браузере.</p><p>Большая ирония в том, что модульные компоненты должны были <i>обеспечить</i> идиоматический дизайн. Дайте сообществу разработать кучу датапикеров, и пусть лучший победит. Разработчики смогут легко интегрировать самые удачные модули. Так в теории. В реальности — сотни конкурирующих дизайн-библиотек и ни одной окончательной рекомендации, которая выжила бы долгосрочно.</p><p>Фронтенд-разработчики не делают ничего неправильного. Браузеры сегодня очень мощные и предлагают универсальные API, которые позволяют делать почти всё, если подходить креативно. Например, Figma не следует ни одной HTML-идиоме, потому что в ней нет HTML. Она написана на WebAssembly; команда на cutting edge-реализации десктоп-стиля софта в браузере. Конечно, это ломает HTML-as-document-модель веб-страницы. Кнопка «назад» в браузере, шорткаты и так далее идут лесом, пока заново выстраивается парадигма взаимодействия человека и компьютера.</p><p>Короче, веб-идиом дизайна мало, потому что фронтенд-разработка движется слишком быстро. Инженеры заняты тем, что <i>возможно</i>, а не вопросами полировки — и правильно. Многопользовательская коллаборация в реальном времени гораздо ценнее шорткатов для опытных пользователей. А поскольку существует бесконечное количество и фронтенд-пакетов, и форматов взаимодействия, навязывать единые идиомы на такое большое пространство очень тяжело. Должно пройти время, чтобы передний край остыл, чтобы лучшие паттерны проявились и стали идиоматическими.</p><p>Хуже того: даже на техническом уровне правильные идиомы часто пропускают разработчики, которые гонят к финишной черте. Я видел в open source-кодовых базах &lt;span&gt; с обработчиком onclick вместо тега &lt;a&gt;. Это хаос, и это ломает скрин-ридеры и другие средства доступности.</p><h2>Успех идиоматического дизайна</h2><p>И всё же некоторые из самых успешных продуктовых организаций сегодня агрессивно навязывают свои идиомы дизайна и достигают какой-то гомогенности интерфейсов.</p><p>Apple — отличный пример. Мы говорили про Microsoft прошлого, но Apple сегодня двигает резко бескомпромиссную дизайн-систему. Общая библиотека шрифтов, кнопок, цветов и её консистентность через все нативные приложения и устройства Apple создали мощный эффект подражания для сторонних приложений. Даже когда вы пользуетесь сторонним приложением на iPhone, взаимодействие через клавиатуру, pinch-to-zoom и так далее контролируется iOS. Это большая часть эффекта Apple «оно просто работает». Сильный, со вкусом сделанный, идиоматический дизайн — в ядре успеха Apple.</p><p>Что интересно про «оно просто работает»-эффект — он заставляет пользователей доверять дефолтам и избегать кастомизации. Похожая динамика на платформах вроде Substack, где у меня как у автора нет возможности выбрать шрифт или даже подчеркнуть текст. Но ограничивающие дефолты выставлены со вкусом, и это отлично работает. Дизайн-принципы Substack и Apple набирают распространение по мере успеха этих продуктов: дизайнеры смотрят на них как на удачные примеры. Эти решения становятся идиомами через две вещи: (1) люди сходятся на них как на хорошем дизайне, и (2) частоту использования в сообществе.</p><h2>Что с этим делать</h2><p>Если вы строите продукт, вы хотите следовать идиомам дизайна так близко, как это практически возможно — это делает софт легче в использовании и максимизирует совместимость на разных устройствах и в разных браузерах. Я следую этим правилам и нарушаю их только редко.</p><ol><li>Изучайте и следуйте идиомам HTML/CSS, когда возможно. Например, ссылка должна быть подчёркнутой, цветной, с курсором-пальцем при наведении и написана как тег &lt;a&gt;.</li><li>Избегайте JavaScript-переизобретений базовых HTML-элементов: например, React-компонент Button вместо стилизованного &lt;button&gt;.</li><li>Изучайте и следуйте идиомам браузера, когда возможно. Кнопка «назад» должна всегда работать. Копирование-вставка URL должны приводить пользователя к тому же интерфейсу. Ctrl+Click по навигационному элементу должен открывать его в новой вкладке.</li><li>Если отклоняетесь от общих идиом — убедитесь, что ваш дизайн полностью внутренне консистентен и хотя бы «идиоматичен» внутри вашей организации.</li><li>Предпочитайте слова иконкам. Используйте только иконки, понятные универсально.</li><li>Если сомневаетесь — делайте визуальные элементы <i>очевидными</i>. Никогда не должно возникать вопроса, кнопка это или таб.</li><li>Предпочитайте то, что легко понять, тому, что визуально красиво.</li><li>Если зашли в тупик — обратитесь к двум типам ресурсов: лучшим сайтам с дизайном, которые вы знаете, и книгам по интерфейсному дизайну прошлых десятилетий. Большинство проблем интерфейсного дизайна сегодня — не новые, а повторы исторических, у которых есть решённые аналоги в прошлом.</li></ol><p>Я мечтаю о дне, когда каждый датапикер или форма ввода банковской карты в интернете будут абсолютно одинаковыми — когда после 30 лет итеративной разработки и миллионов попыток мы наконец сойдёмся на лучшей. Я мечтаю о будущем, в котором в каждом веб-приложении Ctrl+Click будет открывать ссылку в новой вкладке. Это было бы хорошо.</p><h2>От переводчика</h2><p>Эссе написано в 2023 году, но за два с половиной года консистентности в вебе не прибавилось — скорее наоборот. ИИ-сгенерированные интерфейсы и v0/Cursor-style фронтенд-генерация только увеличили число способов сделать одно и то же: каждый промпт даёт чуть новый &lt;Button&gt; с уникальным API.</p><p>Из практически применимого для российских команд: совет «следуйте HTML-идиомам» снижает не только риск сломать UX, но и число npm-зависимостей — а значит, и риск supply-chain атак, и порог входа для новых разработчиков. Особенно ценно, когда команда меняется быстрее, чем проект.</p><p>Оригинал эссе: <a href="https://essays.johnloeber.com/p/4-bring-back-idiomatic-design">essays.johnloeber.com</a>. Сайт автора: <a href="https://www.johnloeber.com">johnloeber.com</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>CSS Studio: визуальный редактор, который правит ваш код руками ИИ-агента</title>
      <link>https://tproger.ru/news/css-studio-vizualnyj-redaktor-kotoryj-pravit-vaw-kod-rukami-i</link>
      <comments>https://tproger.ru/news/css-studio-vizualnyj-redaktor-kotoryj-pravit-vaw-kod-rukami-i?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/css-studio-vizualnyj-redaktor-kotoryj-pravit-vaw-kod-rukami-i</guid>
      <description><![CDATA[<p>Автор Motion выпустил CSS Studio — визуальный редактор стилей в dev-сборке. Правите CSS руками, изменения через MCP уходят в Claude Code или Cursor.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/css-studio-vizualnyj-redaktor-kotoryj-pravit-vaw-kod-rukami-i">CSS Studio: визуальный редактор, который правит ваш код руками ИИ-агента</a>»</p>]]></description>
      <category><![CDATA[Open Source]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[CSS]]></category>
      <category><![CDATA[Дизайн интерфейсов и UX]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 10 Apr 2026 17:15:04 GMT</pubDate>
      <content:encoded><![CDATA[<p>Если вы регулярно объясняете <a href="https://claude.com/claude-code">Claude Code</a> или <a href="https://cursor.com">Cursor</a> текстом, какой именно padding вам нужен, — вот инструмент, который делает это за вас руками. Мэтт Перри, автор библиотеки <a href="https://motion.dev">Motion</a> (бывший Framer Motion), выпустил <a href="https://cssstudio.ai/">CSS Studio</a> — визуальный редактор стилей, который живёт прямо в вашей dev-сборке и шлёт изменения в ваш ИИ-агент через MCP. Запуск вылетел в топ Show HN.</p><ul><li>CSS Studio — визуальный WYSIWYG-редактор, который встраивается в ваш dev-сайт через npm-пакет.</li><li>Вы двигаете padding, шрифты, отступы, анимации руками; изменения через MCP-сервер уходят в Claude Code, Cursor или любой другой агент с MCP-поддержкой.</li><li>Агент правит код по месту: классы в Tailwind-проектах, объект стилей в CSS-in-JS, селектор в стайлшитах. Специальной поддержки Tailwind-токенов пока нет — token-режим в планах.</li><li>Цена: $99 за одно место.</li></ul><h2>Что это и зачем</h2><p>Сейчас типичный ИИ-воркфлоу для фронтенда выглядит так: вы открываете сайт в браузере, замечаете кривой отступ, идёте в чат агента и пишете «сделай padding у кнопки-подписки на два пикселя меньше и выровняй по базовой линии». Агент угадывает, какой компонент вы имели в виду, промахивается, вы поправляете. Через десять сообщений нужный padding наконец встал куда надо.</p><p>CSS Studio заменяет эту итерацию прямым редактированием. Вы добавляете npm-пакет в dev-сборку, запускаете её, в углу страницы появляется панель редактора. Кликаете на элемент, двигаете ползунки или тянете за точки — padding меняется в реальном времени в браузере. Когда результат нравится, нажимаете «Apply» (или включаете auto-apply). В этот момент подключённый ИИ-агент через MCP получает JSON-патч с описанием изменений и дописывает реальные файлы.</p><p>То есть вы получаете WYSIWYG-редактор, но результат приземляется в ваш настоящий код. Что с Tailwind — отдельный вопрос. Специальной интеграции с ним пока нет: визуальная панель показывает вычисленные CSS-значения, а агент уже сам догадывается, как их вернуть в исходник, — вслепую, без понимания Tailwind-токенов. Перри пообещал token/strict-режим с распознаванием Tailwind-классов и CSS-переменных, но это пока план. С CSS-in-JS и обычными стайлшитами проще: агент дотягивается до объекта стилей в компоненте или до нужного селектора в файле.</p><h2>Как это работает технически</h2><p>Всё завязано на <a href="https://modelcontextprotocol.io/">Model Context Protocol</a> — стандарт от Anthropic, который позволяет агентам подключаться к локальным инструментам (файлы, БД, сервисы) как к плагинам, без кастомной интеграции под каждый. CSS Studio поднимает локальный MCP-сервер рядом с вашим dev-сервером (подружиться с Vite получилось сразу, судя по отзыву разработчика mpeg на HN).</p><p>В Claude Code или Cursor вы запускаете команду /studio — и агент начинает слушать MCP-сервер. Когда вы в браузере двигаете слайдер padding, CSS Studio стримит агенту JSON вида «компонент такой-то, свойство такое-то, новое значение — вот такое, плюс информация о viewport и URL». Агент видит текущий контекст проекта, находит нужный файл и вносит правку по правилам кодовой базы.</p><p>Перри также упоминает, что для низкой задержки MCP-сервер может использовать Claude Channels — малоизвестную фичу Claude Code для стриминга. В обычном режиме агент периодически опрашивает MCP-сервер; Claude Channels снимают эту задержку.</p><h2>Что умеет</h2><ul><li><b>Стили</b> — padding, margin, цвета, шрифты, тени, бордеры, flex/grid-настройки через визуальные контролы.</li><li><b>Текст и контент</b> — прямое редактирование содержимого элементов без захода в файлы.</li><li><b>Лейаут</b> — добавление и удаление элементов, перестановка.</li><li><b>Анимации</b> — таймлайн-редактор для motion-эффектов (что логично от автора Motion).</li><li><b>Breakpoints</b> — редактор понимает, в каком брейкпоинте вы сейчас правите; canvas-режим для параллельного просмотра нескольких вьюпортов Перри дорабатывает прямо сейчас.</li><li><b>Рисование</b> — инструмент для набросков новых блоков на странице, потом отдаёте агенту на реализацию.</li></ul><h2>Кому полезно</h2><p>Первый очевидный сценарий — фронтендеры, которые уже сидят на ИИ-агентах для написания кода и устали от словесных описаний CSS-правок. Второй — дизайнеры и продакт-менеджеры, у которых нет доступа к репозиторию, но им нужно быстро подкрутить что-то на лендинге. Раньше они писали тикет, теперь — двигают слайдеры сами, агент пишет изменения в файлы.</p><p>Третий — QA и владельцы агентств, которые собирают десятки маркетинговых сайтов: визуальные правки через браузер с автоматической синхронизацией в код ускоряют финальную полировку. В комментариях на HN несколько человек отдельно отметили, что до этого сами писали похожие инструменты «на коленке» — значит потребность назрела.</p><h2>Что не так</h2><p>Цена — $99 за одно место, и комьюнити на HN это обсуждает активно. Сравнивают с Figma (около $160 за место) и с Cursor (те же $20 в месяц). Для команды из пяти человек выходит $495 в год. Перри в комментариях пообещал подумать над ценообразованием, а пока рассчитывает на ранних энтузиастов.</p><p>Второе — лендинг. Несколько комментаторов заметили, что сайт продукта для дизайна выглядит «как сгенерированный LLM» — слишком много фиолетового, шаблонная композиция, анимации fade-in. Для инструмента, который продаёт дизайн, это, мягко говоря, неловко. Перри признал и пообещал переделать.</p><p>Третье — зависимость от ИИ-агента с MCP. Если вы не сидите на Claude Code / Cursor / Windsurf и не планируете, CSS Studio для вас пока бесполезен: он не генерирует код самостоятельно, а только командует вашим агентом. Отдельная боль для российских разработчиков — оплата: Stripe из РФ не работает, нужна зарубежная карта или сервис-посредник. Зато живое демо на сайте cssstudio.ai доступно без регистрации, попробовать можно.</p><h2>Что это значит</h2><p>CSS Studio — один из первых публичных примеров того, как MCP превращается в инструмент «человек рисует, агент кодирует». До этого WYSIWYG-редакторы либо жили в отдельной вселенной (как Figma и Webflow), либо редактировали код напрямую, но теряли контекст проекта. MCP даёт третий путь: визуальный фронтенд + реальный агент с доступом к вашей кодовой базе.</p><p>Если такой подход взлетит, ждите аналогичных инструментов для других доменов: визуальный редактор схемы базы данных → агент правит миграции, визуальный редактор API → агент правит OpenAPI и генерирует клиент, визуальный редактор Grafana-дашбордов → агент правит Terraform. Базовая механика одна и та же.</p><p>Источники: <a href="https://cssstudio.ai/">cssstudio.ai</a>, <a href="https://news.ycombinator.com/item?id=47702196">обсуждение на Hacker News</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>TanStack съедает экосистему React, и никто об этом не говорит</title>
      <link>https://tproger.ru/translations/tanstack-sedaet-ekosistemu-react-i-nikto-ob-etom-ne-govorit</link>
      <comments>https://tproger.ru/translations/tanstack-sedaet-ekosistemu-react-i-nikto-ob-etom-ne-govorit?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/tanstack-sedaet-ekosistemu-react-i-nikto-ob-etom-ne-govorit</guid>
      <description><![CDATA[<p>Перевод колонки разработчика: как TanStack за два года из одной библиотеки (Query) превратился в полную платформу из восьми библиотек, которая вытесняет Next.js, Redux и React Router.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/tanstack-sedaet-ekosistemu-react-i-nikto-ob-etom-ne-govorit">TanStack съедает экосистему React, и никто об этом не говорит</a>»</p>]]></description>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 10 Apr 2026 11:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Если вы пишете на React и давно не пересматривали свой стек — загляните в package.json. Велика вероятность, что половина ваших зависимостей уже из семейства TanStack, а вы этого не планировали. Публикуем перевод <a href="https://dev.to/harsh2644/tanstack-is-eating-reacts-ecosystem-and-nobody-is-talking-about-it-10n0">колонки разработчика Harsh с dev.to</a> о том, как за два года TanStack превратился из одной библиотеки в полноценную платформу, которая вытесняет Next.js, Redux и React Router.</p><p>Полгода назад я бы посмеялся над таким заголовком. TanStack? Это же ребята, которые делают React Query. Съедают экосистему? Я много лет пользовался React Query, любил его, рекомендовал всем — но воспринимал TanStack как одну библиотеку. Отличную библиотеку, не больше.</p><p>Потом я обновил проект в прошлом месяце и заметил кое-что. Я уже использовал TanStack Query, TanStack Router и TanStack Table. TanStack Form начал заменять React Hook Form в новых проектах. А TanStack Start полностью вытеснил мой Next.js-сетап. Я открыл package.json — и почувствовал странное: половина моего стека оказалась TanStack. Не потому что я так планировал, а потому что по одной библиотеке за раз, месяц за месяцем, TanStack просто становился лучшим выбором. И я шёл за лучшим выбором, не задумываясь, куда это меня ведёт.</p><ul><li>TanStack превратился из одной библиотеки (Query) в полноценную платформу из восьми взаимосвязанных продуктов: Query, Router, Table, Form, Start, Store, DB и AI</li><li>По State of React 2026 (~3700 разработчиков) у TanStack Query 68% использования и всего 1% негатива, у Next.js — те же ~80% охвата, но в 17 раз больше негатива</li><li>Главное отличие философии: все библиотеки TanStack headless — они делают логику, а UI и рендеринг остаются за вами</li><li>TanStack Router и TanStack Start дают сквозную типизацию по всему приложению — от search params до server functions</li><li>Реальность: TanStack Start ещё RC, TanStack DB — в бете, TanStack AI — в альфе. На прод сейчас безопасно только Query/Router/Table/Form/Store</li><li>Рекомендация автора: Query ставьте уже сегодня, Router — на новом greenfield-проекте, Start — пока наблюдайте</li></ul><h2>Что сейчас вообще такое TanStack</h2><p>Два года назад TanStack означал одно: React Query — лучшая библиотека для фетчинга данных в экосистеме React. Простая, мощная, решала реальную проблему. Сегодня TanStack — это восемь взаимосвязанных библиотек, которые вместе образуют полноценную фронтенд-платформу.</p><ul><li><a href="https://tanstack.com/query"><b>TanStack Query</b></a> — заменяет ручной fetch + useEffect. Стабильна, 68% использования</li><li><a href="https://tanstack.com/router"><b>TanStack Router</b></a> — заменяет React Router и роутинг Next.js. Стабильна</li><li><a href="https://tanstack.com/table"><b>TanStack Table</b></a> — заменяет все табличные библиотеки сразу. Стабильна</li><li><a href="https://tanstack.com/form"><b>TanStack Form</b></a> — заменяет React Hook Form. Стабильна</li><li><a href="https://tanstack.com/start"><b>TanStack Start</b></a> — заменяет Next.js и Remix. RC, активно растёт</li><li><a href="https://tanstack.com/store"><b>TanStack Store</b></a> — заменяет Zustand и Redux. Стабильна</li><li><a href="https://tanstack.com/db"><b>TanStack DB</b></a> — заменяет Firebase и Supabase-клиенты. Бета</li><li><b>TanStack AI</b> — заменяет AI SDK других вендоров. Альфа</li></ul><p>Два года назад — одна библиотека. Сегодня — целая платформа, которая может заменить ваш фреймворк. И почему-то большинство разработчиков до сих пор спят.</p><h2>Момент, который всё изменил</h2><p>Восемь месяцев назад я дебажил проблему с роутингом в проекте на Next.js. Конкретно — URL search params. Это когда фильтры, пагинация и сортировка живут в URL, чтобы пользователи могли делиться ссылками, а кнопка «Назад» работала правильно.</p><p>В Next.js для этого нужно жонглировать тремя хуками:</p><p>Работало. Но многословно. И не типобезопасно: searchParams.get('category') возвращает string | null, и TypeScript не знает, какие значения валидны. А потом я увидел, как коллега делает ровно то же самое через TanStack Router:</p><p>TypeScript точно знал, какого типа category и page. Он упал бы при компиляции, если бы я попытался установить невалидное значение. Состояние URL и типы TypeScript были в идеальной синхронизации. Я долго смотрел на этот код, потом открыл новую ветку и начал миграцию.</p><h2>Цифры — State of React 2026</h2><p>Здесь история перестаёт быть моей личной и становится чем-то большим. Опрос <a href="https://2026.stateofreact.com/">State of React 2026</a> — более 3700 разработчиков, опубликован в феврале 2026 — дал показательные результаты.</p><p>Next.js, который когда-то казался стандартом для фулстек-React, широко используется, но не особо любим: 80% респондентов им пользовались, у 17% — негативное отношение, основные жалобы на избыточную сложность и слишком тесную интеграцию с главным спонсором (Vercel).</p><p>А вот цифры по TanStack Query: 68% использования, 42% позитивного отношения, <b>1% негативного</b>. Один процент негатива у библиотеки, которой пользуется 68% React-разработчиков. Это ненормально хорошие цифры. Для сравнения: у Next.js в 17 раз больше негатива при примерно том же охвате. Экосистема говорит. Большинство просто пока не слушает.</p><h2>Почему TanStack выигрывает</h2><p>После нескольких месяцев размышлений я для себя так это сформулировал: TanStack выигрывает потому, что у него есть философия — и эта философия лучше той, которую он заменяет.</p><p>Философия звучит так: <b>владей своим кодом, а не фреймворком</b>. Каждая библиотека TanStack — headless by design, то есть без встроенного UI: она занимается логикой, а вёрстку и стили делаете вы. Нет никакого готового TanStack-компонента, который нужно подгонять под свой дизайн. Нет TanStack-стилей, с которыми нужно воевать. Нет мнения TanStack о том, как должно выглядеть ваше приложение.</p><p>Сравните это с Next.js — там ваши &lt;Image&gt;, шрифты, роутинг и серверное поведение контролируются фреймворком. Вы получаете мощь, но платите вендор-лок-ином. «Vendor lock-in, сложные API и слишком много шума в экосистеме Next.js — для меня это no-go», — так сформулировал один из респондентов опроса. Ответ TanStack на эту жалобу — архитектурный: это не фреймворк, а набор строительных блоков. Код — ваш, решения — ваши, а TanStack просто берёт на себя сложные части.</p><h2>Ключевые библиотеки, которые стоит знать прямо сейчас</h2><h3>1. TanStack Query — вы наверняка уже им пользуетесь</h3><p>Если вы ещё не используете <a href="https://tanstack.com/query">TanStack Query</a> — остановитесь и поставьте его прямо сейчас: npm i @tanstack/react-query плюс обернуть приложение в QueryClientProvider. Я подожду.</p><p>Кеширование, фоновые рефетчи, stale-while-revalidate (показываем старые данные, пока подгружаются свежие), оптимистичные обновления, бесконечный скролл, devtools — всё в комплекте. Это точка входа в экосистему TanStack — именно с Query начинают большинство.</p><h3>2. TanStack Router — тот, который удивит больше всего</h3><p>Это библиотека, которая окончательно перетянула меня на сторону TanStack. Полная сквозная типизация по всему слою роутинга — не только пути, но и search params, контекст маршрута, данные лоадеров — всё типизируется от маршрута до компонента.</p><p>Если у вас хоть раз был баг из-за того, что useParams() вернул undefined, а TypeScript не предупредил — TanStack Router и есть ответ.</p><h3>3. TanStack Form — наследник React Hook Form</h3><p>React Hook Form — отличная библиотека. TanStack Form — это то, чем был бы React Hook Form, если бы его писали сегодня, с TypeScript-first подходом. Никаких строковых register('email') — все имена полей проверяются типами.</p><h3>4. TanStack Start — альтернатива Next.js, которую никто не ждал</h3><p>Это самое новое и самое спорное пополнение. TanStack Start — это меньше магии и больше контроля: вы сами решаете, как грузятся данные, где они запускаются и что рендерится. Типобезопасность отличная, и Start прекрасно дружит со всей остальной экосистемой TanStack. Полноценный fullstack-фреймворк поверх TanStack Router — SSR, стриминг, server functions, всё как в Next.js, но без привязки к Vercel и с end-to-end типизацией.</p><p>Больше не нужно гадать, что возвращает ваш API: типы текут от базы данных до компонента без единой ручной аннотации.</p><h3>5. TanStack DB и AI — будущее, которое строится прямо сейчас</h3><p>У TanStack есть несколько проектов на ранних стадиях: помимо стабильных Query/Router/Table/Form/Store, в бете — TanStack DB, в альфе — TanStack AI, а ещё есть TanStack CLI со встроенным MCP-сервером (Model Context Protocol) для работы с ИИ-агентами.</p><p>TanStack DB — реактивное клиентское хранилище данных: что-то вроде Firebase, но без привязки к вендору. TanStack AI — унифицированный интерфейс к разным ИИ-провайдерам: один и тот же API, независимо от того, дёргаете ли вы Claude, GPT-4 или Gemini. И то, и другое пока не прод — но они показывают, куда движется TanStack. Это уже не библиотеки, это платформа.</p><h2>Честный контраргумент</h2><p>Я выставил TanStack серебряной пулей. Это не так. Если ваша команда хорошо знает Redux и React Router, потеря продуктивности на изучение новых инструментов может не окупиться. У Next.js годы боевой эксплуатации на проде. Redux-разработчиков на рынке больше, чем TanStack-разработчиков, — это важно для найма. Если вам нужна скучная и предсказуемая технология, оставайтесь на привычном стеке.</p><p>Ещё один момент: если вам нужны React Server Components с полной прод-поддержкой уже сегодня — Next.js всё ещё ответ. И если ваша команда глубоко в Redux, а переход на новое означает месяцы переобучения, — цена, возможно, не оправдана. TanStack — отличный инструмент, но не всегда правильный выбор. Используйте его, когда его сильные стороны совпадают с вашими задачами.</p><h2>Так стоит ли переходить</h2><p>Честная рекомендация после шести месяцев жизни в экосистеме TanStack:</p><ul><li><b>Ставьте Query уже сегодня.</b> Если вы ещё не пользуетесь — это самое выгодное по ROI изменение, которое можно сделать в React-кодбазе. Минимум риска, моментальный эффект, плюс это ворота в понимание философии TanStack</li><li><b>Попробуйте Router на следующем greenfield-проекте</b> (то есть новом, с чистого листа). Не мигрируйте существующее приложение — ценность яснее всего видна, когда вы стартуете с типобезопасности с первого дня</li><li><b>Наблюдайте за Start.</b> Он ещё не так стабилен, как Next.js. Но траектория понятна: разработчики, которые изучат его сейчас, получат заметное преимущество, когда он дойдёт до 1.0</li><li><b>Следите за DB и AI.</b> Оба слишком ранние для прода. Но они показывают амбиции команды TanStack — и, судя по её послужному списку, получатся отлично, когда будут готовы</li></ul><h2>Что всё это значит</h2><p>TanStack выигрывает не потому, что маркетит себя лучше Next.js, и не благодаря виральным твитам или докладам на конференциях. Он выигрывает, потому что решает проблему, которая реально болит у React-разработчиков в 2026 году: слишком много магии, слишком много вендор-лок-ина, слишком много сложности, которая живёт не в вашем коде, а в фреймворке.</p><p>TanStack возвращает вам контроль. Полную типобезопасность. Никакого скрытого поведения. Никакой зависимости от вендора. Просто хорошо спроектированные примитивы, которые делают ровно то, что написано на коробке. В эпоху, когда ИИ пишет всё больше кода за нас, эта ясность важнее, чем когда-либо: ИИ-инструменты работают лучше с явным типизированным кодом, чем с магическими конвенциями фреймворков. TanStack не планировал съесть экосистему React. Он просто построил инструменты получше — и разработчики пошли за лучшими инструментами. Так экосистемы и меняются на самом деле — не анонсами, а пул-реквестами.</p><p>Источник: колонка <a href="https://dev.to/harsh2644/tanstack-is-eating-reacts-ecosystem-and-nobody-is-talking-about-it-10n0">TanStack is eating React's ecosystem and nobody is talking about it</a> на dev.to. Автор: разработчик <a href="https://dev.to/harsh2644">harsh2644</a>. Перевод сокращён и адаптирован, авторские мнения сохранены.</p>]]></content:encoded>
    </item>
    <item>
      <title>Railway ушёл с Next.js — время сборки сократилось с 10 минут до 2</title>
      <link>https://tproger.ru/news/railway-uwyol-s-next-js-vremya-sborki-sokratilos-s-10-minut-do</link>
      <comments>https://tproger.ru/news/railway-uwyol-s-next-js-vremya-sborki-sokratilos-s-10-minut-do?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/railway-uwyol-s-next-js-vremya-sborki-sokratilos-s-10-minut-do</guid>
      <description><![CDATA[<p>Облачная платформа Railway перевела весь фронтенд с Next.js на Vite + TanStack Start и ускорила сборку в 5 раз. Разбираем причины и тренд ухода с Next.js.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/railway-uwyol-s-next-js-vremya-sborki-sokratilos-s-10-minut-do">Railway ушёл с Next.js — время сборки сократилось с 10 минут до 2</a>»</p>]]></description>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 09 Apr 2026 12:00:04 GMT</pubDate>
      <content:encoded><![CDATA[<p>Если ваш фронтенд собирается дольше 10 минут — возможно, дело не в коде, а во фреймворке. Облачная платформа <a href="https://railway.com">Railway</a> перевела свой фронтенд с Next.js на Vite + TanStack Start — и сократила время сборки с 10+ минут до менее 2.</p><p><a href="https://railway.com">Railway</a> — облачная PaaS-платформа (аналог Heroku), которую используют десятки тысяч разработчиков для деплоя приложений. Их собственный фронтенд — дашборд, документация, маркетинговые страницы — работал на Next.js.</p><ul><li>Railway перевёл весь фронтенд с Next.js на Vite + TanStack Start</li><li>Время сборки сократилось с 10+ минут до менее 2 минут</li><li>Это часть тренда: крупные проекты всё чаще уходят с Next.js из-за сложности сборки и несоответствия App Router их архитектуре</li><li>Railway — не первые: с Next.js публично уходили Kent C. Dodds и другие команды</li></ul><h2>Почему ушли с Next.js</h2><p>По словам команды Railway, основные проблемы были связаны с временем сборки и сложностью инфраструктуры. Next.js-приложение Railway разрослось до такого масштаба, что каждый билд занимал более 10 минут — это тормозило CI/CD-пайплайн и замедляло итерации.</p><p>Дополнительные факторы:</p><ul><li>Несоответствие App Router модели Railway — у них client-first продукт, а App Router ориентирован на server-first подход</li><li>Сложность конфигурации Next.js для нестандартных кейсов — когда приложение выходит за рамки «блога на Vercel», настройка становится нетривиальной</li><li>Размер бандла и время cold start при серверном рендеринге</li></ul><h2>Что получили</h2><p>После миграции время сборки упало с 10+ минут до менее 2 — ускорение более чем в 5 раз. Для команды, которая деплоит десятки раз в день, это означает экономию часов ежедневно.</p><p>Публикация <a href="https://railway.com/blog">вызвала</a> бурное обсуждение на Hacker News (206 очков, 188 комментариев). Мнения разделились: одни поддержали решение, другие указали, что проблема не в Next.js, а в архитектуре конкретного приложения.</p><h2>Часть тренда</h2><p>Railway — не первые, кто публично уходит с Next.js. За последний год аналогичные решения приняли:</p><ul><li><a href="https://kentcdodds.com">Kent C. Dodds</a> — публично отказался от Next.js в пользу Remix, который позже влился в React Router 7</li><li>Многие команды переходят на Vite + React или SvelteKit для ускорения сборки</li></ul><p>Общая тенденция: Next.js отлично подходит для проектов, которые деплоятся на Vercel и укладываются в стандартные паттерны. Для крупных client-first приложений с нестандартной инфраструктурой издержки фреймворка начинают перевешивать преимущества.</p><p>Для фронтенд-разработчиков это повод задуматься: фреймворк — инструмент, а не религия. Если сборка тормозит, DX деградирует, а большая часть фич фреймворка не используется — возможно, пора пересмотреть стек.</p>]]></content:encoded>
    </item>
    <item>
      <title>React vs Vue в 2026 году: какой фреймворк выбрать</title>
      <link>https://tproger.ru/articles/react-vs-vue-v-2026-godu--kakoj-frejmvork-vybrat</link>
      <comments>https://tproger.ru/articles/react-vs-vue-v-2026-godu--kakoj-frejmvork-vybrat?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Алексей Михайлишин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/react-vs-vue-v-2026-godu--kakoj-frejmvork-vybrat</guid>
      <description><![CDATA[<p>Сравниваем React и Vue в 2026 году по производительности, экосистеме, рынку вакансий и порогу входа. Актуальные данные и рекомендации по выбору фреймворка.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/react-vs-vue-v-2026-godu--kakoj-frejmvork-vybrat">React vs Vue в 2026 году: какой фреймворк выбрать</a>»</p>]]></description>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Vue]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sat, 28 Mar 2026 15:32:22 GMT</pubDate>
      <content:encoded><![CDATA[<p>React или Vue — вечный спор среди фронтенд-разработчиков. Одни клянутся гибкостью React и его экосистемой, другие ценят элегантность Vue и низкий порог входа. Но в 2026 году оба фреймворка серьёзно изменились: React получил Server Components и Compiler, Vue готовит революционный Vapor Mode. Разберёмся на актуальных данных, какой инструмент подойдёт именно вам.</p><p><b>React</b> — JavaScript-библиотека для создания пользовательских интерфейсов, разработанная Meta (ранее Facebook). <b>Vue.js</b> — прогрессивный фреймворк для создания UI, созданный Эваном Ю (Evan You). Оба инструмента используют компонентный подход и виртуальный DOM, но различаются в философии, синтаксисе и экосистеме.</p><p>— React лидирует по npm-загрузкам (429 млн/мес против 47 млн у Vue) и рынку вакансий</p><p>— Vue проще в освоении и имеет более целостную экосистему «из коробки»</p><p>— React 19.2 принёс Activity, Performance Tracks и useEffectEvent</p><p>— Vue Vapor Mode обещает производительность без виртуального DOM</p><p>— Для крупных корпоративных проектов React остаётся безопасным выбором</p><p>— Для быстрого старта и небольших команд Vue даёт преимущество в скорости разработки</p><h2>React в 2026 — что нового</h2><p>React продолжает эволюционировать. В 2025–2026 годах произошло несколько значимых событий, которые определили направление развития библиотеки.</p><h3>React 19 и Server Components</h3><p>React 19 стал самым масштабным обновлением со времён хуков. <b>Server Components (RSC)</b> — компоненты, которые рендерятся на сервере и не увеличивают клиентский бандл — перешли из экспериментального статуса в стабильный. Это позволяет снизить объём JavaScript, отправляемого клиенту, на 30–50% в типичных приложениях.</p><p>Ключевые нововведения React 19:</p><ul><li><b>Actions</b> — встроенная обработка форм с серверными и клиентскими экшенами</li><li><b>useOptimistic</b> — хук для оптимистичных обновлений UI</li><li><b>use()</b> — новый хук для чтения промисов и контекста в рендере</li><li><b>Нативная поддержка метаданных</b> — title, meta, link можно рендерить прямо в компонентах</li><li><b>Улучшенная поддержка Web Components</b> — полная интеграция с кастомными элементами</li></ul><h3>React 19.2 и Compiler v1.0</h3><p>Вышедший в 2026 году React 19.2 добавил экспериментальные фичи: <b>Activity</b> (управление жизненным циклом скрытых компонентов), <b>React Performance Tracks</b> (интеграция с DevTools для профилирования) и <b>useEffectEvent</b>.</p><p>Отдельное событие — выход <b>React Compiler v1.0</b>. Компилятор автоматически мемоизирует компоненты, устраняя необходимость ручного использования useMemo, useCallback и React.memo. По данным Meta, это сократило количество ре-рендеров в их приложениях на 40%.</p><h3>React Foundation и Linux Foundation</h3><p>В 2025 году React перешёл под управление <a href="https://react.dev/blog">React Foundation</a> при Linux Foundation. Это означает более открытое управление проектом и снижение зависимости от одной компании. Для разработчиков это сигнал долгосрочной стабильности.</p><h2>Vue в 2026 — что нового</h2><p>Vue тоже не стоит на месте. Хотя темп обновлений ниже, чем у React, каждый релиз Vue приносит продуманные и обратно совместимые улучшения.</p><h3>Vue 3.5 — стабильность и производительность</h3><p>Вышедший в сентябре 2024 года Vue 3.5 ("Tengen Toppa Gurren Lagann") сфокусирован на внутренних улучшениях производительности. Реактивная система была оптимизирована для более точного отслеживания зависимостей, а потребление памяти снижено на 56% по данным бенчмарков команды Vue.</p><p>Ключевые улучшения Vue 3.5:</p><ul><li><b>useTemplateRef()</b> — типобезопасные ссылки на элементы</li><li><b>Deferred Teleport</b> — телепортация контента с отложенным рендерингом</li><li><b>Lazy Hydration</b> — ленивая гидратация для SSR-приложений</li><li><b>useId()</b> — генерация стабильных уникальных ID для SSR</li><li><b>Улучшенный watch</b> — deep watch с поддержкой паузы и возобновления</li></ul><h3>Vapor Mode — будущее без виртуального DOM</h3><p><b>Vapor Mode</b> — экспериментальный режим компиляции Vue, который генерирует код без виртуального DOM. Вместо создания виртуального дерева и его сравнения (diffing) Vapor Mode компилирует шаблоны в прямые DOM-операции. Это аналог подхода <a href="https://svelte.dev/">Svelte</a>, но с сохранением API Vue.</p><p>По предварительным бенчмаркам, Vapor Mode показывает прирост производительности в 2–3 раза на операциях обновления. Проект находится в активной разработке на <a href="https://github.com/vuejs/core-vapor">GitHub</a> (2400+ звёзд), но пока не рекомендован для продакшена.</p><h3>Nuxt 4 — полная переработка</h3><p><b>Nuxt 4</b> вышел в 2025 году и уже добрался до версии 4.4. Это полная переработка мета-фреймворка для Vue с улучшенной архитектурой, нативной поддержкой серверных компонентов и обновлённым Nuxt UI v4. Для Vue-экосистемы Nuxt 4 — это то же, что Next.js для React.</p><h2>Сравнение по критериям</h2><p>Рассмотрим ключевые метрики, которые помогут сделать осознанный выбор. Все данные актуальны на март 2026 года.</p><p><b>Критерий / React / Vue</b></p><h3>Производительность</h3><p>В стандартных бенчмарках (js-framework-benchmark) React и Vue показывают сопоставимые результаты. React с Compiler v1.0 автоматически оптимизирует ре-рендеры, Vue 3.5 имеет более эффективную реактивную систему. На практике разница в производительности редко становится решающим фактором — оба фреймворка достаточно быстры для подавляющего большинства задач.</p><p>Реальная разница появляется в экстремальных сценариях: Vue Vapor Mode (когда выйдет из эксперимента) обещает преимущество за счёт отказа от виртуального DOM, а React Server Components снижают нагрузку на клиент, перенося логику на сервер.</p><h3>Порог входа</h3><p>Vue традиционно считается более дружелюбным к новичкам. Однокомпонентные файлы (SFC) с секциями &lt;template&gt;, &lt;script&gt; и &lt;style&gt; интуитивно понятны. Документация Vue — одна из лучших в индустрии.</p><p>React требует понимания JSX, хуков и однонаправленного потока данных. С приходом Server Components и Compiler порог входа вырос — нужно разбираться, какие компоненты серверные, а какие клиентские. По данным State of JS 2024, React назвали "избыточно сложным" чаще других фреймворков.</p><h3>Экосистема</h3><p>React обладает самой большой экосистемой в мире фронтенда. <b>Next.js</b>, <b>Remix</b>, <b>React Native</b>, тысячи UI-библиотек (Material UI, Ant Design, Chakra UI, shadcn/ui) — для любой задачи найдётся готовое решение. Обратная сторона — проблема выбора: для одной задачи существует десяток конкурирующих библиотек.</p><p>Vue предлагает более целостный подход. Официальные решения покрывают большинство потребностей: <b>Vue Router</b>, <b>Pinia</b> (стейт-менеджмент), <b>Nuxt</b> (SSR/SSG), <b>Vuetify</b> и <b>PrimeVue</b> (UI). Меньше выбора, но меньше и головной боли.</p><h3>Рынок вакансий</h3><p>По данным npm, React скачивают <b>429 млн раз в месяц</b> против <b>47 млн у Vue</b> — разрыв примерно в 9 раз. На GitHub суммарно у React <b>244 000</b> звёзд, у Vue — <b>263 000</b> (с учётом Vue 2 и Vue 3 репозиториев). Однако звёзды на GitHub не отражают реальное использование в продакшене.</p><p>На рынке труда React доминирует. По данным <a href="https://survey.stackoverflow.co/2024">Stack Overflow Developer Survey 2024</a>, React используют на работе значительно чаще, чем Vue. На hh.ru и LinkedIn вакансий с React в 3–4 раза больше, чем с Vue. Это важно для тех, кто строит карьеру.</p><h3>Размер бандла</h3><p>Минифицированный и сжатый (gzip) размер:</p><ul><li><b>React</b> (react + react-dom): ~44 КБ</li><li><b>Vue 3</b>: ~33 КБ</li></ul><p>Vue компактнее на ~25%. С React Server Components часть кода не попадает в клиентский бандл вовсе, что может нивелировать эту разницу. Vue Vapor Mode в будущем обещает ещё меньший размер за счёт tree-shaking рантайма виртуального DOM.</p><h3>Поддержка TypeScript</h3><p>Оба фреймворка отлично работают с TypeScript, но подходы различаются.</p><p>Vue 3 написан на TypeScript и предоставляет первоклассную типизацию «из коробки». &lt;script setup lang="ts"&gt; в SFC — лаконичный и типобезопасный способ писать компоненты. IDE-поддержка через Volar (теперь часть Vue Language Tools) значительно улучшилась.</p><p>React исторически использует .tsx файлы и имеет зрелую систему типов через @types/react. Типизация хуков и контекста может быть многословной, но хорошо документирована. React Compiler v1.0 полностью поддерживает TypeScript.</p><h2>Когда выбрать React</h2><p>React — оптимальный выбор в следующих ситуациях:</p><ul><li><b>Крупный корпоративный проект</b> — максимальная экосистема, проще найти разработчиков</li><li><b>Нужен React Native</b> — единая кодовая база для веб и мобильных приложений</li><li><b>Server-side rendering</b> — Next.js с React Server Components даёт лучший в классе SSR</li><li><b>Большая команда</b> — огромное сообщество, много документации и готовых решений</li><li><b>Карьерные перспективы</b> — React-вакансий на рынке в 3–4 раза больше</li><li><b>Сложные интерактивные интерфейсы</b> — дашборды, real-time приложения, графические редакторы</li></ul><p>React подходит тем, кто готов инвестировать время в изучение экосистемы и не боится "усталости от выбора" (framework fatigue). Если команда уже знает React — смена на Vue ради смены не имеет смысла.</p><h2>Когда выбрать Vue</h2><p>Vue — лучший выбор, когда:</p><ul><li><b>Быстрый старт проекта</b> — от идеи до прототипа за минимальное время</li><li><b>Небольшая команда</b> — целостная экосистема снижает время на принятие решений</li><li><b>Постепенная миграция</b> — Vue можно внедрять по частям в существующий проект</li><li><b>Обучение фронтенду</b> — низкий порог входа, отличная документация</li><li><b>Проекты на Laravel/Django/Rails</b> — Vue традиционно хорошо интегрируется с серверными фреймворками</li><li><b>Китайский рынок</b> — Vue крайне популярен в Китае (Alibaba, Baidu, Xiaomi используют его)</li></ul><p>Vue идеально подходит для команд, которые ценят прагматичность и хотят сфокусироваться на продукте, а не на выборе инструментов. Если проект не требует React Native или React-специфичных библиотек — Vue даст результат быстрее.</p><h2>Выводы</h2><p>В 2026 году и React, и Vue — зрелые, стабильные инструменты с активным развитием. Спор «что лучше» не имеет универсального ответа — выбор зависит от контекста проекта, команды и задач.</p><blockquote>React и Vue решают одну задачу разными способами. Важен не фреймворк, а то, как вы его используете. Выбирайте инструмент под задачу, а не задачу под инструмент.</blockquote><p><b>Выбирайте React</b>, если вам нужна максимальная экосистема, React Native, Server Components или вы ориентируетесь на рынок труда. <b>Выбирайте Vue</b>, если цените скорость разработки, целостный developer experience и низкий порог входа.</p><p>Оба фреймворка продолжают развиваться: React движется в сторону серверного рендеринга и компиляции, Vue — в сторону максимальной производительности через Vapor Mode. Следите за обновлениями обоих проектов и выбирайте то, что делает вашу команду продуктивнее.</p>]]></content:encoded>
    </item>
    <item>
      <title>Ваш debounce вас обманывает — и вот почему</title>
      <link>https://tproger.ru/translations/vaw-debounce-vas-obmanyvaet---i-vot-pochemu</link>
      <comments>https://tproger.ru/translations/vaw-debounce-vas-obmanyvaet---i-vot-pochemu?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Алексей Михайлишин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/vaw-debounce-vas-obmanyvaet---i-vot-pochemu</guid>
      <description><![CDATA[<p>Debounce снижает частоту вызовов, но не контролирует сетевые запросы. Разбираем race conditions и ошибки, исправляем через AbortController и retry.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/vaw-debounce-vas-obmanyvaet---i-vot-pochemu">Ваш debounce вас обманывает — и вот почему</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Лучшая практика]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sat, 28 Mar 2026 14:02:07 GMT</pubDate>
      <content:encoded><![CDATA[<p><a href="https://www.geeksforgeeks.org/javascript/debouncing-in-javascript/">Debounce</a> — один из тех паттернов, которые фронтенд-разработчик узнаёт в самом начале карьеры и использует всю оставшуюся жизнь.</p><p>По сути debounce делает одну простую вещь: собирает серию вызовов и превращает их в один вызов после паузы. Отлично подходит для «шумных» UI-событий.</p><p>Самый типичный пример — автодополнение в поиске. Но тот же паттерн работает для обработки resize, scroll, live-валидации, фильтров и хуков аналитики.</p><p>Классическая реализация выглядит так:</p><p>Выглядит дисциплинированно. Ощущается эффективно. Быстро доезжает до прода.</p><p>И вот тут начинается обман.</p><p>Проблема не в самом debounce. Проблема в связке «debounce + fetch», когда в уравнение входит реальная сеть.</p><p>Debounce создаёт ощущение, что запросы «под контролем». Но он не контролирует жизненный цикл запроса: порядок ответов, отмену устаревших запросов, поведение при ошибках.</p><p>Именно поэтому в продакшене debounce «врёт»: UI выглядит плавно, а сетевой слой по-прежнему хрупкий.</p><p>В этой статье мы оставим debounce для того, в чём он хорош (сглаживание UI), и укрепим сетевой слой отменой запросов, повторными попытками и корректной обработкой ошибок.</p><blockquote><b>Ключевые выводы:</b><br />— Debounce — это паттерн UI, а не паттерн работы с сетью<br />— Он гарантирует только одно: «я не буду вызывать функцию слишком часто»<br />— Порядок ответов, отмена устаревших запросов и обработка ошибок — это то, что вам придётся решать отдельно<br />— AbortController отменяет устаревшие запросы на уровне сети<br />— Повторные попытки с экспоненциальной задержкой спасают от транзиентных ошибок сервера</blockquote><h2>Проблема 1 — гонка запросов (race conditions)</h2><p>На локальной машине всё летает. Но в продакшене сеть непредсказуема: запросы могут приходить с разной задержкой, и нет никакой гарантии, что ответы придут в том же порядке, в каком были отправлены.</p><p>Представьте: пользователь печатает 12345678. Debounce пропускает запросы для 1234567 и 12345678. Ответ на 1234567 задерживается на сервере и приходит <i>после</i> ответа на 12345678. UI обновляется последним пришедшим ответом — и показывает устаревшие данные.</p><p>Это классическая гонка запросов, и debounce сам по себе её не предотвращает.</p><h3>Решение — AbortController</h3><p>Нам нужно гарантировать, что обрабатывается только ответ на последний запрос, а все предыдущие — отменяются. <a href="https://developer.mozilla.org/en-US/docs/Web/API/AbortController">AbortController</a> — это браузерный API, который позволяет отменять fetch-запросы. Создаём контроллер, передаём его signal в fetch, и вызываем abort(), когда нужно отменить запрос.</p><p>Что изменилось:</p><ul><li>Перед каждым запросом мы отменяем предыдущий через abort() и создаём новый контроллер</li><li>В блоке catch проверяем, является ли ошибка AbortError — это ожидаемое поведение, а не реальный сбой</li></ul><p>Результат: в обычном потоке только последний запрос из серии нажатий доходит до конца. Предыдущие отменяются на уровне сети, а не просто игнорируются после получения ответа.</p><h2>Проблема 2 — сетевые ошибки</h2><p>Сеть непредсказуема не только по задержкам, но и по надёжности. Иногда запрос, который мог бы пройти при повторной попытке, просто падает. Причины: кратковременная перегрузка сервера, пики нагрузки, таймауты базы данных.</p><h3>fetch не бросает исключение при HTTP-ошибках</h3><p>Это одна из главных ловушек нативного fetch: он отклоняет промис только при сетевых сбоях (нет соединения). Коды 4xx и 5xx — это «успешные» ответы с точки зрения fetch. Если сервер вернёт 500, ваш код радостно вызовет response.json() и получит undefined вместо данных.</p><p>Исправляем проверкой response.ok:</p><p>Теперь 500-я ошибка выбрасывает исключение до того, как мы пытаемся разобрать тело ответа. Блок catch обработает её корректно.</p><h3>Повторные попытки с экспоненциальной задержкой</h3><p>Но простая проверка — это только начало. В реальном приложении стоит добавить автоматические повторные попытки для транзиентных ошибок. Если запрос упал из-за временной проблемы, лучше попробовать ещё раз с нарастающей задержкой, чем сразу показывать ошибку пользователю.</p><p>Писать логику повторов вручную — это циклы, счётчики попыток, тайминги, и всё это должно корректно работать с отменой. Нетривиально и неинтересно. Воспользуемся библиотекой <a href="https://github.com/nickersoft/fetchkit">@fetchkit/ffetch</a> — это тонкая обёртка над fetch, которая решает именно эту задачу.</p><p>Есть и альтернативы: <a href="https://github.com/sindresorhus/ky">ky</a>, <a href="https://github.com/axios/axios">axios</a> или собственная обёртка. ffetch выбран за совместимый с fetch API и корректную работу с AbortController при повторных попытках.</p><p>Что нам это даёт:</p><ul><li>retries: 3 — при 500-й ошибке библиотека повторяет запрос до 3 раз</li><li>shouldRetry — повторяем только при 5xx; всё остальное (сетевая ошибка, отмена) пробрасывается сразу</li><li>throwOnHttpError: true — автоматически бросает исключение на HTTP-ошибки, не нужна ручная проверка response.ok</li><li>Задержка между повторами учитывает AbortController — если abort() вызван во время ожидания, повтор немедленно прекращается</li></ul><p>Последний пункт особенно важен. Без этого отмена запроса в середине серии повторов убила бы текущий fetch, но оставила бы таймер — и следующая попытка сразу бы упала с AbortError.</p><h2>Полное решение</h2><p>Собираем всё вместе: debounce для UI-сглаживания, AbortController для отмены устаревших запросов, ffetch для повторных попыток и автоматической обработки HTTP-ошибок.</p><p>Каждый слой отвечает за своё: debounce снижает частоту вызовов, AbortController гарантирует, что обрабатывается только актуальный запрос, а ffetch добавляет устойчивость к транзиентным сбоям.</p><h2>Частые вопросы</h2><h3>Зачем AbortController, если debounce и так снижает количество запросов?</h3><p>Debounce снижает <i>частоту</i> вызовов, но не контролирует, что происходит с уже отправленными запросами. Если два запроса ушли один за другим, более ранний может вернуться позже — и перезаписать актуальные данные. AbortController отменяет устаревший запрос на уровне сети, а не просто игнорирует ответ.</p><h3>Можно ли обойтись без сторонней библиотеки для повторов?</h3><p>Да, можно написать retry-логику вручную. Но это циклы, счётчики, экспоненциальная задержка и корректная обработка отмены. В продакшен-коде проще использовать готовое решение — ffetch, ky или axios — чтобы не изобретать велосипед и не допускать ошибок в edge-кейсах.</p><h3>Работает ли этот подход с React / Vue / Angular?</h3><p>Да. AbortController и retry-логика — это чистый JavaScript, независимый от фреймворка. В React, например, AbortController часто используется в useEffect для отмены запросов при размонтировании компонента. Принцип тот же: debounce для UI, отмена и повторы для сетевого слоя.</p><h2>Выводы</h2><p>Debounce — не проблема. Проблема — считать его полным решением для управления сетевыми запросами, когда он контролирует только одно измерение: частоту вызовов.</p><p>Debounce — это паттерн UI, а не паттерн работы с сетью. Чтобы построить надёжное приложение, нужно дополнить его управлением жизненным циклом запросов:</p><ul><li>Отмена устаревших запросов через AbortController</li><li>Повторные попытки с экспоненциальной задержкой для транзиентных сбоев</li><li>Корректная обработка HTTP-ошибок (проверка response.ok или автоматический проброс через библиотеку)</li></ul><p>Тогда UI будет не только отзывчивым, но и точным — даже при непредсказуемых сетевых условиях.</p><p><i>Адаптированный перевод статьи <a href="https://blog.gaborkoos.com/posts/2026-03-28-Your-Debounce-Is-Lying-to-You/">Your Debounce Is Lying to You</a> Габора Кооша (Gabor Koos).</i></p>]]></content:encoded>
    </item>
    <item>
      <title>CSS counters в подходе Atomic CSS - часть 2</title>
      <link>https://tproger.ru/articles/css-counters-v-podhode-atomic-css---chast-2</link>
      <comments>https://tproger.ru/articles/css-counters-v-podhode-atomic-css---chast-2?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Рамазан Максютов]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/css-counters-v-podhode-atomic-css---chast-2</guid>
      <description><![CDATA[<p>В этом посте мы более глубоко погрузимся в то, как работать с CSS Counters в Atomic CSS. В частности, мы разберемся в процессе наследования счётчиков и их значений, а также увидим как отличается отображение счётчиков в разных браузерах. Будет интересно!</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/css-counters-v-podhode-atomic-css---chast-2">CSS counters в подходе Atomic CSS - часть 2</a>»</p>]]></description>
      <category><![CDATA[CSS]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 25 Jan 2026 03:42:49 GMT</pubDate>
      <content:encoded><![CDATA[<p>Всем привет, друзья!</p><p>В <a href="https://tproger.ru/articles/css-counters-v-podhode-atomic-css---chast-1">первой статье</a> про CSS counters мы с вами разобрались, как с ними работать на базовом уровне. Мы изучили основные CSS свойства и функции для работы с ними, а также привели базовые примеры с помощью фреймворка <a href="https://mlut.style/">mlut</a>.</p><p>В этой статье мы углубим наши познания в области кастомных CSS счётчиков, опираясь на <a href="https://www.w3.org/TR/css-lists-3/#auto-numbering">спеки</a> и <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Counter_styles/Using_counters">обзор </a>в MDN. Если конкретнее, то мы изучим принципы наследования счётчиков и их значений, а также разберём парочку примеров. А бонусом мы посмотрим на небольшое расхождение в том, как ведут себя кастомные счётчики в разных браузерах.</p><p>Ну что, поехали!</p><h2>Базово про вложенность</h2><h3>Наивный путь</h3><p>Думаю, вы хотя бы раз в жизни сталкивались с ситуациями, когда вам приходилось верстать многоуровневые списки. CSS counters позволяют создавать такие списки – давайте научимся этому.</p><p>На базовом уровне для этого можно создать новый счётчик с новым именем внутри элемента, где уже задан “родительский счётчик”. Например, если на родительском &lt;ol&gt; мы зададим счётчик parent-counter, то на дочернем `&lt;ol&gt;` можем задать счётчик `child-counter`. Выглядеть это будет так:</p><p>А вот такие стили сгенерирует mlut:</p><p>А так будет выглядеть результат – в принципе, как мы и ожидали:</p><figure><img src="https://media.tproger.ru/user-uploads/134620/2026-01-21/3a5fc372-d4b7-4b9d-91e9-6329989a07cd.png" alt="" /><figcaption>Простейший вложенный список</figcaption></figure><h3>Продвинутый путь</h3><p>Но возможности кастомных счётчиков позволяют уменьшить количество утилит почти вдвое.</p><p>Существует такое правило:</p><p>Если мы создаём счётчик с каким-то именем (далее – дочерний счётчик или вложенный) на данном элементе, а он наследует счётчик с точно таким же именем от родителя (далее – родительский счётчик), то новый счётчик будет вложен в родительский. Тогда функция counter() будет возвращать значение последнего вложенного счётчика с данным именем, а counters() значения всех вложенных счётчиков с таким именем в области видимости элемента.</p><p>Про область видимости и правила наследования счётчиков поговорим чуть попозже, а пока давайте проиллюстрируем данное выше правило следующей разметкой:</p><p>А результат мы получим абсолютно такой же! Благодаря тому, что мы возпользовались возможностью создавать вложенные счётчики, мы значительно сократили количество атомарных классов. Кроме того, мы уменьшили количество сущностей (счётчиков), которые нам нужно держать в голове при разработке.</p><p>Кроме того, мы можем обратить внимание на несколько тонкостей:</p><p>– функция counters() действительно отображает значения всех уровней счётчика nested с указанным разделителем;</p><p>– свойство `counter-increment` инкрементирует значение наиболее глубоко вложенного счётчика с данным именем, который может видеть наш элемент.</p><h2>Вложенность и наследование</h2><p>В этом разделе мы подробно разберём процесс наследования кастомных счётчиков и посмотрим на примерах, как это работает.</p><h3>Область видимости</h3><p>Когда мы инициализируем счётчик на каком-то из элементов нашей страницы, он становится видимым сразу для некоторого числа других элементов. Это множество элементов называется областью видимости счётчика. В него входят:</p><p>– все потомки того элемента, в котором этот счётчик был создан;</p><p>– все последующие соседи того элемента, в котором счётчик был создан, а также все потомки этих соседей;</p><p>– наследование счётчика прерывается на первом элементе-соседе, на котором создаётся счётчик с таким же именем с помощью counter-reset.</p><p>Давайте проиллюстрируем эти правила следующим примером:</p><p>CSS:</p><p>А результат получится такой:</p><figure><img src="https://media.tproger.ru/user-uploads/134620/2026-01-21/6ca18933-fb37-404b-8bc9-68db60cb7852.png" alt="" /><figcaption>Наследование счётчика</figcaption></figure><p>Мы видим, что счётчик inherited был создан на первом элементе &lt;div&gt;, а его дочерние элементы &lt;p&gt; унаследовали его. Также его унаследовали следующие два соседа нашего &lt;div&gt;, но на последнем из них счётчик inherited был переопределён на новый, так что последний &lt;div&gt; из области видимости первого счётчика выпал. Итого, в область видимости счётчика, созданного на первом &lt;div&gt; входят:</p><p>– первый и второй элементы &lt;div&gt;;</p><p>– дочерние параграфы &lt;p&gt; первого элемента &lt;div&gt;;</p><p>– дочерние параграфы второго элемента &lt;div&gt;.</p><h3>Правила наследования счётчиков</h3><p>В прошлом пункте мы с вами узнали, что у каждого счётчика есть область видимости  – набор элементов, которые видят наш счётчик и могут обращаться к его значению. Оказывается, и у каждого HTML-элемента есть множество счётчиков, к которым этот он может обращаться.</p><p>Счётчики могут попасть в это множество двумя путями:</p><p>– через механизм наследования;</p><p>– посредством создания прямо в этом элементе.</p><p>Второй путь мы изучили уже вдоль и поперёк, поэтому сейчас сосредоточимся на первом – наследовании. Как мы уже знаем, счётчик может передаваться дочерним элементам и последующим соседям. Сформулируем ниже более строгие правила, которые в принципе покрывают все возможные случаи наследования счётчиков.</p><ol><li>Текущий элемент наследует любой счётчик, который определён ранее на любом родительском элементе.</li><li>Предположим, что на предыдущем элементе-соседе есть счётчик. Прежде, чем текущий элемент унаследует этот счётчик от соседа, произойдёт проверка: нет ли уже в текущем элементе счётчика с таким именем? Если такого нет, то копия счётчика из предыдущего элемента унаследуется текущим. Если же есть такой, то этого не произойдёт.</li></ol><p>А как же наследуется значение? Здесь немного всё интереснее. Значение счётчика наследуется от самого ближайшего предшествующего элемента в DOM-дереве. А именно, если сами счётчики наследуются только от родителя или соседа, то их значения могут передаваться ещё и от самого последнего дочернего элемента, находящегося внутри предыдущего соседа.</p><p>Всё это мы видим на приведённом выше примере. Давайте я ещё раз покажу его:</p><figure><img src="https://media.tproger.ru/user-uploads/134620/2026-01-21/b86868e0-8193-4c31-af8f-ffa4a4e53d8f.png" alt="" /><figcaption>Наследование значения счётчика</figcaption></figure><p>Здесь:</p><ol><li>Div 1 не наследует никакие счётчики.</li><li>Все &lt;p&gt; внутри Div 1 получили в наследство от своего родителя счётчик, который затем на них инкрементируется и отображается;</li><li>Div 2 унаследовал счётчик как сосед Div 1, а параграфы &lt;p&gt; внутри Div 2 – как дочерние элементы Div 2;</li><li>Мы также видим, как наследуется значение счётчика на всех этапах. В частности, из интересного стоит отметить, как Div 1 передаёт значение первому вложенному параграфу &lt;p&gt;, тот передаёт следующему, а вот последний параграф &lt;p&gt; внутри Div 1 передаёт значение уже Div 2. И это всё идеально соответствует правилу, которое гласит, что значение счётчика передаётся от последнего предшествующего соседа в DOM-дереве.</li></ol><p>Вот и всё, казалось бы: мы разобрали правила наследования и вложения счётчиков, изучили примеры – что же ещё можно здесь рассказать? Но, оказывается, у описанного поведения есть тонкости, которые мы рассмотрим выше.</p><h2>Тонкости поведения браузеров</h2><p>Давайте попробуем создать вложенный список несколько более простым способом, чем мы это делали раньше. Мы попробуем сэкономить целых два уровня вложенности.</p><p>CSS:</p><p>Я этот пример придумал, когда хотел сделать вложенный список проще, чем тот, что описан выше и в спецификациях. И вот моя задумка:</p><ol><li>создаём в первом элементе &lt;div&gt; счётчик curious с начальным значением 1 и с помощью counters() отображаем значения всех счётчиков c этим именем, которые присутствуют в этом элементе (он только один в данном случае);</li><li>этот же счётчик наследуется дочерними &lt;p&gt; и следующим соседом &lt;div&gt;.</li><li>на первом вложенном &lt;p&gt; в каждой из &lt;div&gt; создаётся вложенный счётчик с тем же именем curious.</li></ol><p>Теперь вопрос, что здесь будет?</p><p><b>Вариант А:</b> получится правильный вложенный список, где нумерация будет идти следующим образом (1 1.1 1.2 2 2.1 2.2). То есть созданный на первом &lt;p&gt; вложенный счётчик будет наследоваться следующим его соседом, как на картинке ниже:</p><figure><img src="https://media.tproger.ru/user-uploads/134620/2026-01-21/8825e951-9f45-4119-bb76-aefe77a6037d.png" alt="" /><figcaption>Вариант А</figcaption></figure><p><b>Вариант Б</b>: получится некорректный вложенный список, где нумерация будет такой (1 1.1 2 3 3.1 4). То есть созданный в первом &lt;p&gt; вложенный счётчик не наследуется его соседями. Здесь можно сослаться на то, что счётчик наследуется от предыдущего соседа только тогда, когда на текущем элементе счётчика с таким именем нет. А на втором &lt;p&gt; уже может быть унаследованный от родителя счётчик curious. Тогда результат должен быть таким:</p><figure><img src="https://media.tproger.ru/user-uploads/134620/2026-01-21/994570e3-2a11-445b-af76-284e8d09397b.png" alt="" /><figcaption>Вариант Б</figcaption></figure><p><b>Вариант В</b>: получится вообще не понятно, что. Ну, например такая нумерация (1 1.1 2 3 3.1 3.2). То есть в первой `` вложенный счётчик из первого `` не унаследуется его соседом, а во второй `` – унаследуется. Совершенно маловероятный вариант, но пусть будет.</p><figure><img src="https://media.tproger.ru/user-uploads/134620/2026-01-21/1a3401c2-dc07-4e65-af0e-2d06bea523de.png" alt="" /><figcaption>Вариант В</figcaption></figure><p>Ну что, каков ваш ответ?</p><p>А ответ таков: вариант А будет работать в браузерах Firefox и Safari, а вариант Б ни в каких браузерах не реализуется! И что же получается, что для Chromium браузеров остаётся самый удивительный вариант В? Да, так и есть, по крайней мере в версии 143 (в версии 144 это уже исправлено). Можете проверить аналогичную <a href="https://jsfiddle.net/46yns3vh/">иллюстрацию</a>.</p><p>Вот такая вот тонкость имеется в поведении CSS Counters в разных браузерах.</p><h3>Как это можно объяснить?</h3><p>Safari и Firefox в данном случае идут вразрез со спецификациями, хотя их поведение более интуитивно понятно для пользователей. На самом деле реализоваться должен вариант Б. Дело в том, что от родительского элемента счётчик наследуют все дочерние, а счётчик, созданный на первом дочернем элементе, наследуется соседями только тогда, когда у них нет счётчика с таким именем.</p><p>А вот команда Chromium стремилась реализовать вариант Б, но допустила небольшой <a href="https://issues.chromium.org/issues/458409068">баг</a>, который уже исправлен в версии 144.</p><h2>Заключение</h2><p>Ну вот мы и разобрались в основных концепциях кастомных CSS счётчиков. Надеюсь, эта статья была для вас познавательной и интересной. К счастью, веб-технологии активно развиваются и нам всегда будет, чему учиться. А я постараюсь делать это вместе с вами в будущих статьях!</p><p>Успехов вам в увлекательном пути Frontend-разработки!</p>]]></content:encoded>
    </item>
    <item>
      <title>Пузырь 2021–2022 годов лопнул: эксперты составили прогноз рынка на 2026 год</title>
      <link>https://tproger.ru/news/puzyr-2021-2022-godov-lopnul--eksperty-sostavili-prognoz-rynka-na-2026-god</link>
      <comments>https://tproger.ru/news/puzyr-2021-2022-godov-lopnul--eksperty-sostavili-prognoz-rynka-na-2026-god?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/puzyr-2021-2022-godov-lopnul--eksperty-sostavili-prognoz-rynka-na-2026-god</guid>
      <description><![CDATA[<p>После пузыря 2021–2022 ИТ-рынок стабилизируется: в 2026 ждут низкий найм, меньше джунов и рост спроса на сильных инженеров</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/puzyr-2021-2022-godov-lopnul--eksperty-sostavili-prognoz-rynka-na-2026-god">Пузырь 2021–2022 годов лопнул: эксперты составили прогноз рынка на 2026 год</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[Навыки]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Fullstack]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 30 Dec 2025 11:01:55 GMT</pubDate>
      <content:encoded><![CDATA[<p>IT-рынок пережил болезненную коррекцию после бума и перегрева 2021–2022 годов.</p><p>Тогда компании нанимали инженеров с запасом, под давлением цифровизации, дешевых денег и страха «остаться позади». По данным Indeed и FRED, пик вакансий пришелся на середину 2022 года. После чего последовал резкий спад, так и не вернувшись до прежнего уровня.</p><h2>Почему ИИ — удобный, но не главный виновник</h2><p>ИИ стал публичным оправданием сокращений. Заявление «мы заменяем людей на ИИ» хорошо смотрится в отчетах и перед инвесторами.</p><p>На практике же компании сокращали издержки, выравнивали штат и параллельно активнее нанимали за пределами США и Европы, где инженеры стоят дешевле.</p><p>Исследования показывают, что ИИ пока не делает разработчиков быстрее в реальной работе. Напротив, опытные инженеры иногда теряют в продуктивности из-за необходимости проверять и исправлять сгенерированный код.</p><h2>Как будет выглядеть рынок в 2026 году</h2><p>Эксперты <a href="https://www.finalroundai.com/blog/software-engineering-job-market-2026">сходятся</a> во мнении: 2026 год пройдет в режиме «низкого найма — низких увольнений». Массовых сокращений не ожидается, но и бурного роста вакансий не будет. Так выглядит стабилизация рынка.</p><p>При этом спрос смещается — универсальных «кодеров» нужно меньше. А вот инженеры, которые умеют проектировать системы, работать с производительностью, безопасностью и сложной интеграцией, наоборот будут все чаще находить вакансии под себя.</p><p>По прогнозу Бюро статистики труда США, число вакансий для разработчиков продолжит расти примерно на 15%. Это медленнее, чем ожидалось раньше, но все еще быстрее большинства профессий.</p><figure><img src="https://media.tproger.ru/user-uploads/111041/2025-12-30/3a3ad90f-f354-48b3-83bd-8857158de8e8.jpeg" alt="" /></figure><h2>Почему джунам повезло меньше всего</h2><p>Самое слабое место рынка — начальные позиции. Количество вакансий для junior-разработчиков упало примерно на 40% по сравнению с допандемийным уровнем.</p><p>Компании больше не готовы вкладываться в длительное обучение: им нужны люди, которые могут приносить пользу почти сразу.</p><p>Но это также создает отложенную проблему — без притока новичков рушится кадровый «конвейер».</p><h2>Какие навыки реально востребованы</h2><p>В 2026 году ценятся не языки сами по себе, а связки «язык + область».</p><p>Тот же Python чаще всего нужен при работе с ИИ и данными. JavaScript и TypeScript — для фронтенда и fullstack. Go — для бэкенда и инфраструктуры. Java — для enterprise-систем.</p><p>Параллельно растет спрос на ИИ- и дата-инженеров, а также специалистов по ИИ-инфраструктуре.</p>]]></content:encoded>
    </item>
    <item>
      <title>Создание сайта на информатике в 9 классе: просто, быстро, на «отлично»!</title>
      <link>https://tproger.ru/articles/sozdanie-sajta-na-informatike-v-9-klasse--prosto--bystro--na--otlichno--</link>
      <comments>https://tproger.ru/articles/sozdanie-sajta-na-informatike-v-9-klasse--prosto--bystro--na--otlichno--?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Блог Школа программирования Пиксель]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/sozdanie-sajta-na-informatike-v-9-klasse--prosto--bystro--na--otlichno--</guid>
      <description><![CDATA[<p>Создание сайта в 9 классе больше не проблема! В статье — две простые инструкции, сделать сайт с ними сможет любой школьник!</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/sozdanie-sajta-na-informatike-v-9-klasse--prosto--bystro--na--otlichno--">Создание сайта на информатике в 9 классе: просто, быстро, на «отлично»!</a>»</p>]]></description>
      <category><![CDATA[Партнёрский материал]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Для начинающих]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 25 Dec 2025 09:10:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>Привет! Ищешь, как быстро создать сайт к уроку информатики в 9 классе, да такой, который по-настоящему удивит и учителя, и одноклассников?</p><p>Тогда наша инструкция для тебя. С ней ты превратишь создание сайта из «скучного школьного задания» в первый реальный цифровой проект, который можно будет показать друзьям и который даст тебе полезный практический навык на годы вперед.</p><p>Умение создавать сайты — одино из самых востребованных в современном мире. Причем неважно, гуманитарий ты или технарь — сайт может сделать любой. Кроме того, работая над проектом, ты прокачаешь свои знания по информатике. Зачем? Все просто: на ЕГЭ по информатике легче всего получить высокий балл, а значит — серьезно поднять средний балл аттестата и поступить в лучший вуз.</p><p>В этой статье мы разберем два способа создать первый сайт, каждый — с пошаговыми инструкциями. Ты можешь выбрать способ, который ближе тебе по духу: самостоятельно написать код (для тех, кто любит логику, контроль и хочет понять, как все устроено изнутри) или создать сайт в конструкторе Tilda (для дизайнеров, гуманитариев или тех, кто хочет сделать и быстро, и красиво). Поехали!</p><h2>Подготовка инструментов и окружения</h2><p>Прежде чем приступить к созданию сайта, нужно подготовить инструменты (так веб-разработчики и программисты в целом называют программы, которыми пользуются) и рабочее окружение. Нам понадобятся:</p><p><b>Браузер</b>. Используй Google Chrome или Mozilla Firefox. Эти браузеры имеют полнофункциональные «Инструменты разработчика». Чтобы открыть их, нажми клавишу F12 на клавиатуре. «Инструменты разработчика» позволяют просматривать HTML-код и CSS-стили открытой страницы — функция, полезная не только для отладки своего сайта, но и во время обучения: ты сможешь легко подсмотреть, как устроен фронтенд любого сайта в Интернете.</p><p>Для ручной верстки нужен <b>редактор кода VS Code</b> — программа, в которой ты будешь писать и редактировать HTML и CSS. Чтобы установить ее, перейди на официальный сайт <a href="http://code.visualstudio.com">code.visualstudio.com</a>. Скачай версию для твоей операционной системы (Windows, macOS, Linux):</p><figure><img src="https://media.tproger.ru/user-uploads/134865/2025-12-19/91b27489-e70b-4f02-aaed-5facf0587ee1.png" alt="Главная страница сайта VS Code" /></figure><p>Запусти установочный файл и следуй инструкциям мастера установки. Можно оставить все параметры по умолчанию.</p><p>Чтобы кодить было проще, установим несколько полезных расширений. Для этого запусти VS Code и нажми на иконку «Extensions» на левой панели или используй сочетание клавиш Ctrl+Shift+X:</p><figure><img src="https://media.tproger.ru/user-uploads/134865/2025-12-19/0185c53a-9862-4f44-875f-ef8531904eed.png" alt="Интерфейс VS Code" /></figure><p>В поисковой строке введи название расширения, нажми «Install» и перезагрузи редактор после установки.</p><p>Обязательные расширения:</p><p>• Live Server от Ritwick Dey. Это расширение запускает локальный сервер и автоматически перезагружает страницу в браузере при сохранении кода. Чтобы использовать его, после написания кода щелкни правой кнопкой мыши по html-файлу и выбери «Open with Live Server».</p><p>• Russian Language Pack — для русификации интерфейса.</p><p>• Auto Rename Tag. Когда ты меняешь название открывающего HTML-тега, расширение автоматически меняет и закрывающий.</p><p>Для верстки вручную важно <b>правильно организовать файлы</b>. Создай новую папку под проект, дай ей понятное имя, например, <b>Проект создание сайта 9 класс</b>. Внутри этой папки создай:</p><p>• папку <b>images</b> — для хранения всех изображений сайта;</p><p>• папку <b>styles</b> — для хранения файлов со стилями (CSS);</p><p>• файл <b>index.html</b> — это главный файл, который браузер открывает по умолчанию; его можно создать и позже, прямо из редактора.</p><p>Такая структура является стандартной — она позволяет легко находить нужные файлы и избегать ошибок в путях к ним.</p><p>Если для своего проекта по информатике ты выбираешь создание сайта на конструкторе, то зарегистрируйся на сайте <a href="http://tilda.cc">Тильда</a>:</p><figure><img src="https://media.tproger.ru/user-uploads/134865/2025-12-19/b0a4a5ac-88af-47ff-bf07-aeda80d95b67.png" alt="Главная страница сайта Тильда" /></figure><p>Для регистрации нужна электронная почта. После входа ты попадешь в «Личный кабинет»: здесь будут видны все твои проекты. Чтобы создать новый сайт, нажми кнопку «Создать новый сайт».</p><p>Для создания сайта на информатике достаточно бесплатного тарифа. Хотя у него есть ограничения: одна страница и адрес сайта вида your-site.tilda.ws — этого полностью хватит для выполнения школьного проекта.</p><h2>Создание сайта в 9 классе: верстка вручную</h2><p>Если ты выбираешь верстать сайт вручную, то эта инструкция для тебя. В противном случае — можешь смело пропустить ее и сразу перейти к созданию сайта в Тильде.</p><h3>Шаг 1: Создаем структуру сайта (HTML)</h3><p>Открой папку проекта в VS Code, для этого в меню выбери File → Open Folder, найди и открой созданную ранее папку проекта:</p><figure><img src="https://media.tproger.ru/user-uploads/134865/2025-12-19/ea9288f0-d6c5-4c97-849c-f5c1fd46984a.png" alt="Папка &quot;Создание сайта на информатике&quot; открыта в VS Code" /></figure><p>Создай файл <b>index.html</b>. В левой панели проводника щелкни правой кнопкой мыши по пустому месту, выбери «New File» и введи название <b>index.html</b>:</p><figure><img src="https://media.tproger.ru/user-uploads/134865/2025-12-19/63e3d5e0-6312-4fd0-ad17-44aaf70aed80.png" alt="Создание индексного файла" /></figure><p>Открой index.html и создай базовую HTML-структуру. Для этого достаточно ввести ! (восклицательный знак) и нажать Tab — VS Code автоматически создаст базовый шаблон HTML5:</p><figure><img src="https://media.tproger.ru/user-uploads/134865/2025-12-19/ae22d641-fb1e-419a-b436-57f0e53dc206.png" alt="Шаблон HTML-файла для создания сайта в 9 классе" /></figure><p>Основные элементы HTML-файла::</p><ul><li>&lt;!DOCTYPE html&gt; — объявление типа документа.</li><li>&lt;html lang="en"&gt; и &lt;/html&gt; — между этими тегами находится весь html-код страницы. lang="en" показывает браузеру, что страница на английском, сейчас для нас это не важно, поэтому можешь оставить, как есть.</li><li>&lt;head&gt; и &lt;/head&gt; — внутри этих тегов служебная информация.</li><li>&lt;meta charset="UTF-8"&gt; — объявление кодировки UTF-8, нужно, чтобы браузер правильно отображал символы на странице.</li><li>&lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt; — показывает, как масштабировать страницу на устройствах с разными экранами.</li><li>&lt;title&gt; и &lt;/title&gt; —между этими тегами заголовок вкладки, он же — название твоего проекта.</li><li>&lt;body&gt; и &lt;/body&gt; — между этими тегами находится контент, который видят пользователи.</li></ul><p>Добавь контент в тег &lt;body&gt;, например, так:</p><p>Вот как это выглядит в редакторе:</p><figure><img src="https://media.tproger.ru/user-uploads/134865/2025-12-19/56de7fab-97f6-42ce-a7a2-3a73c583dac6.png" alt="Файл index.html в редакторе кода" /></figure><p>И в браузере (двойной клик по <b>index.html</b>):</p><figure><img src="https://media.tproger.ru/user-uploads/134865/2025-12-19/6d67fcf5-c47c-4b51-a2a3-c9b557290cba.png" alt="Сайт, открытый в браузере" /></figure><p>В этом примере есть комментарии. Они находятся между сочетаниями символов &lt;!-- и --&gt;. Браузер не отображает закомментированный текст — это удобно, если нужно оставить в коде пометки на будущее.</p><h3>Шаг 2: Добавляем стили (CSS)</h3><p>Создай файл стилей <b>style.css</b> в папке <b>styles</b>.</p><p>Подключи стили к HTML — для этого в раздел &lt;head&gt; файла <b>index.html</b> добавь строку кода:</p><p>&lt;link rel="stylesheet" href="styles/style.css"&gt;</p><p>После этого добавь базовые стили в <b>style.css</b>:</p><p>Как видишь, в css-файлах тоже есть комментарии, но они находятся между сочетаниями символов /* и */.</p><p>Вот как это выглядит в редакторе кода:</p><figure><img src="https://media.tproger.ru/user-uploads/134865/2025-12-19/d479bc07-ad46-4325-8dd4-bbfc9d6d8804.png" alt="CSS-файл сайта по информатике в редакторе VS Code" /></figure><p>Если кликнуть на маленький квадратик с цветом в css-файле в VS Code, то откроется палитра — как в фоторедакторах.</p><h3>Шаг 3: Тестируем веб-сайт</h3><p>На этом этапе у тебя уже есть работающий статичный сайт. Открой его в браузере и проверь, все ли выглядит, как надо. После добавления стилей его внешний вид немного изменился:</p><figure><img src="https://media.tproger.ru/user-uploads/134865/2025-12-19/5d67871b-ef9b-44a1-afc7-0315d8f2bf28.png" alt="Создание сайта в 9 классе на информатике: проверяем, что стили применились и внешний вид изменился" /></figure><p>Кстати, ты можешь зайти в «Инструменты разработчика» и менять содержимое страницы и стили. Все изменения будут отображаться на странице в реальном времени, но не сохранятся в файлах.</p><p>Также можно использовать расширение Live Server в VS Code: щелкни правой кнопкой мыши на <b>index.html</b> и выбери «Open with Live Server». Сайт откроется на локальном сервере с автоматической перезагрузкой при сохранении изменений.</p><p>Для школьного проекта статичного одностраничного веб-сайта достаточно. Чтобы добавить дополнительную страницу, создай HTML-файл в папке проекта и размести на него ссылку в <b>index.html</b>.</p><p>Если хочешь создать более сложный сайт — посмотри видеоуроки по ссылке:</p><p><a href="https://youtube.com/playlist?list=PLdzeMLV8u_l406gFs_XAR36XmX8N2SouY&amp;si=6oh4OQG8XwkuiaYn">Бесплатный онлайн-курс «Уроки веб-программирования для детей</a></p><p>За 7 уроков ты изучишь основы HTML, CSS и даже JavaScript, узнаешь, как создать небольшой интернет-магазин и пользоваться библиотекой jQuery. Такой, более продвинутый, сайт ты сможешь не только представить в качестве школьного задания, но и добавить в резюме, если решишь связать свою жизнь с диджитал-сферой.</p><h3>Шаг 4: Публикация созданного веб-сайта в Интернете</h3><p>Если ты хочешь поделиться сайтом в интернете, то мы рекомендуем GitHub Pages. Создай аккаунт на <a href="http://github.com">github.com</a>, затем создай новый репозиторий с названием username.github.io (здесь username — твой логин). Загрузи все файлы проекта в репозиторий. Через 5-10 минут сайт будет доступен по адресу https://username.github.io, этой ссылкой ты можешь поделиться с учителем или добавить ее в презентацию проекта.</p><h2>Создание веб-сайта на Tilda</h2><p>Теперь перейдем ко второму способу создать сайт для проекта по информатике — с помощью визуального конструктора Tilda. Это метод не требует знаний программирования, главное в нем — скорость и простота реализации.</p><h3>Шаг 1: Старт и выбор стратегии</h3><p>В личном кабинете Tilda нажми кнопку «Создать новый сайт», введи любое название, затем выбери «Создать новую страницу». Теперь выбери метод создания сайта для проекта. Есть два варианта — «Пустая страница» и готовые шаблоны:</p><figure><img src="https://media.tproger.ru/user-uploads/134865/2025-12-19/f9848d1a-facd-46af-ab35-0da9ed598862.png" alt="Создание сайта в 9 классе в конструкторе Тильда" /></figure><p>Если времени в запасе достаточно для экспериментов, то мы рекомендуем начинать с чистого листа. Этот метод дает полную свободу в расположении элементов, а дизайн сайта, созданного с нуля, будет по-настоящему уникальным.</p><p>Альтернативный вариант — готовые шаблоны. Используй их, если сайт был нужен «уже вчера». Шаблоны можно изменять и настраивать под свои задачи.</p><h3>Шаг 2: Сборка страницы из блоков</h3><p>В левой панели интерфейса расположены все доступные блоки. Для добавления блока перетащи его в рабочую область.</p><p>Основные типы блоков: заголовок, текст, изображение, кнопка.</p><p>Заголовок:</p><figure><img src="https://media.tproger.ru/user-uploads/134865/2025-12-19/83598f8c-0525-4541-8234-c07d7a945de7.png" alt="Как вставить блок &quot;Заголовок&quot; при создании сайта в 9 классе" /></figure><p>Изменить текст можно двойным щелчком мыши, а настроить шрифт, размер и цвет — в панели параметров справа.</p><p>Текст:</p><figure><img src="https://media.tproger.ru/user-uploads/134865/2025-12-19/ea86ff89-0063-4dee-9f15-d2ecfd09540e.png" alt="Добавление блока &quot;Текст&quot; в Тильда при создании сайта на информатике в 9 классе" /></figure><p>Доступные настройки для текстовых блоков: выравнивание, межстрочный интервал, отступы.</p><p>Изображение:</p><figure><img src="https://media.tproger.ru/user-uploads/134865/2025-12-19/c3fcfcaa-bb4d-450d-b9df-7b7c2cdb30c2.png" alt="Как добавить изображение в Тильда при создании сайта на информатике в 9 классе" /></figure><p>Кнопка:</p><figure><img src="https://media.tproger.ru/user-uploads/134865/2025-12-19/1bd1ea16-5c7b-4248-8877-e06e583703b9.png" alt="Добавление кнопки в Тильда при создании сайта на информатике в 9 классе" /></figure><p>Для кнопки нужно задать текст на ней, указать ссылку, настроить внешний вид: цвет, форму и размер.</p><h3>Шаг 3: Настройка единого стиля</h3><p>В верхней панели управления нажми на «Мой проект» и затем на «Настройки сайта». Что нужно сделать:</p><p>• выбери основные шрифты для заголовков и текста;</p><p>• определи цветовую палитру: основные цвета текста и фона, дополнительные цвета.</p><p>Эти настройки нужны, чтобы дизайн всех элементов сайта был единообразным.</p><h3>Шаг 4: Публикация сайта</h3><p>Нажми оранжевую кнопку «Опубликовать» в правом верхнем углу страницы. Сайт станет доступен в Интернете сразу после публикации. Ссылку можно отправлять учителю и одноклассникам для просмотра проекта.</p><p>Кстати, сайт <a href="https://pixel.study/?utm_source=tproger.ru&amp;utm_medium=article&amp;utm_campaign=sozdanie-sayta-na-informatike-v-9-klasse-prosto-bystro-na-otlichno">школы программирования «Пиксель»</a> тоже сделан на Tilda. Как видишь, даже для серьезного коммерческого проекта не обязательно писать код — часто достаточно простого конструктора.</p><h2>А что дальше? От школьного проекта — к уровню PRO</h2><p>Итак, твой сайт готов. Это важный первый шаг. Но возможности веб-дизайна и веб-разработки гораздо шире. Посмотри, какие проекты создают другие школьники! Может быть они вдохновят тебя на более детальную работу над своим сайтом ;)</p><ul><li><a href="https://rutube.ru/video/8a94032fea008a448982c7e6d20f540e/?playlist=388242">Сайт интернет-магазина</a>. Это полнофункциональный сайт с возможностью регистрации, личным кабинетом, каталогом товаров и корзиной.</li></ul><ul><li><a href="https://rutube.ru/video/4ede61fd3a6086708706df49201a61f9/?playlist=388242">Адаптивный сайт-органайзер</a> со встроенными офисными функциями: блокнот, калькулятор, напоминания.</li></ul><ul><li><a href="https://rutube.ru/video/25fe2b50e7dacecc347b81bb812508b7/?playlist=388242">Веб-сайт магазина музыкальных пластинок</a>.</li></ul><p>Эти проекты объединяет одно — при создании сайтов ребята использовали профессиональные технологии и подходы:</p><ul><li>JavaScript — для интерактивных элементов;</li><li>фреймворки — для разработки сложных интерфейсов;</li><li>backend-разработка — для работы с данными и пользователями,</li><li>базы данных — для хранения информации,</li><li>API — для интеграции с внешними сервисами.</li></ul><p>Хочешь выйти на профессиональный уровень? Тогда тебе на курсы программирования и веб-разработки. На них ты:</p><ul><li>научишься создавать динамические веб-приложения, а не статичные сайты;</li><li>разберешься в полном цикле разработки — от интерфейса до серверной части;</li><li>освоишь технологии, которые действительно востребованы на рынке труда;</li><li>и — превратишь хобби в перспективную профессию!</li></ul><p>А здесь лучшие курсы, которые тебе помогут:</p><ul><li><a href="https://pixel.study/htmlcss?utm_source=tproger.ru&amp;utm_medium=article&amp;utm_campaign=sozdanie-sayta-na-informatike-v-9-klasse-prosto-bystro-na-otlichno">Создание сайтов на языках HTML, CSS, JavaScript</a></li><li><a href="https://pixel.study/traektoria-razrabotchik-sajtov-i-prilozhenij?utm_source=tproger.ru&amp;utm_medium=article&amp;utm_campaign=sozdanie-sayta-na-informatike-v-9-klasse-prosto-bystro-na-otlichno">Fullstack-разработчик для подростков 14-17 лет</a></li></ul><h2>Подведем итоги: вопрос-ответ</h2><ul><li>Смогу ли я создать сайт в 9 классе, если не разбираюсь в информатике?</li></ul><p>Да, конечно. Конструктор Tilda создан специально для тех, у кого нет технической подготовки. А если ты выберешь путь программирования — многие курсы рассчитаны на обучение с абсолютного нуля: ты начнешь с основ и будешь изучать веб-разработку шаг за шагом.</p><ul><li>Сколько времени нужно, чтобы сделать свой сайт без подготовки и специальных знаний?</li></ul><p>Создать сайт можно очень быстро. Например, верстка простого сайта на HTML/CSS может занять 2-3 вечера, а проект на Tilda — 4-6 часов интенсивной работы.</p><p>Этого достаточно для качественного проекта, соответствующего требованиям школьной программы. Но не забудь, что тебе нужно не только создать сайт для проекта, но и продумать, как ты опишешь этапы работы учителю и продемонстрируешь результат, а на это тоже нужно время.</p><ul><li>Что делать, если я запутался в коде?</li></ul><p>Это стандартная ситуация в разработке. Используй ее для развития:</p><ul><li>поищи описания ошибок в поисковиках  — большинство проблем уже решены другими разработчиками;</li><li>зарегистрируйся на платформе Stack Overflow — это сообщество разработчиков, где можно найти ответы на конкретные вопросы;</li><li>изучай документацию MDN Web Docs — авторитетный источник по HTML и CSS.</li><li>если ты уже занимаешься на курсах программирования — попроси помощи у преподавателя или других учеников: в нашей школе царит дружелюбная атмосфера и все помогают друг другу!</li></ul><p><i>Реклама. Рекламодатель ООО «Пиксель.Стади», ИНН 5074078988, erid: 2W5zFHGg7r8</i></p>]]></content:encoded>
    </item>
    <item>
      <title>Промпты для поиска работы: от прокачки навыков до резюме</title>
      <link>https://tproger.ru/articles/prompty-dlya-poiska-raboty--ot-prokachki-navykov-do-rezyume</link>
      <comments>https://tproger.ru/articles/prompty-dlya-poiska-raboty--ot-prokachki-navykov-do-rezyume?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Валерия Турчак]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/prompty-dlya-poiska-raboty--ot-prokachki-navykov-do-rezyume</guid>
      <description><![CDATA[<p>Подборка рабочих промптов для ChatGPT — от улучшения резюме до настройки ментора по фронтенду и управления продуктивностью.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/prompty-dlya-poiska-raboty--ot-prokachki-navykov-do-rezyume">Промпты для поиска работы: от прокачки навыков до резюме</a>»</p>]]></description>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Навыки]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 04 Dec 2025 14:20:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>Искать работу или прокачивать скиллы можно по-разному — кто-то читает документацию, кто-то смотрит видео, а кто-то использует нейросети как персонального ассистента. ChatGPT и подобные инструменты помогают структурировать обучение, улучшить резюме или разобраться в незнакомых технологиях — если правильно их спросить.</p><p>Ниже — несколько промптов, которые можно адаптировать под свои задачи: от менторства по фронтенду до создания резюме, которое не отфильтруют автоматические системы. Каждый промпт можно дополнить деталями о вашем опыте, целях или текущих проектах, чтобы получить более персонализированный результат.</p><h2>Ментор для фронтендеров</h2><p>Промпт помогает быстрее изучать незнакомые темы и прокачивать знания через общение с нейросетью как с техническим наставником.</p><p>В квадратных скобках можно подставить свой опыт, уровень языка и технологии, которые изучаете сейчас.</p><h2>Продуктивность и тайм-менеджмент</h2><p>Набор промптов для работы с личной эффективностью: от постановки целей до борьбы с прокрастинацией. Рекомендуется адаптировать под конкретную профессию и распорядок дня.</p><h4>Постановка целей по SMART</h4><h4>Коучинг по модели GROW</h4><h4>Оптимизация рабочих процессов</h4><h4>Приоритизация по Эйзенхауэру</h4><h4>Техника Помидора</h4><h4>Борьба с прокрастинацией</h4><h4>Еженедельная рефлексия</h4><h2>Работа с резюме</h2><p>Восемь промптов для улучшения резюме: от поиска слабых мест до адаптации под конкретную вакансию. Нейросеть выступает в роли рекрутера и помогает переформулировать достижения с акцентом на результаты.</p><h4>Поиск слабых мест</h4><h4>Акцент на достижениях</h4><h4>Вступление</h4><h4>Усиление опыта</h4><h4>Оформление для ATS</h4><h4>Адаптация под вакансию</h4><h4>Сопроводительное письмо</h4><h4>Сравнение с топами</h4><h3>Обход ATS-систем</h3><p>Метод для прохождения автоматических анализаторов резюме. Текст уменьшается и подгоняется под цвет фона, чтобы остаться невидимым для человека, но читаемым для системы.</p><p>Этот фрагмент нужно вставить в резюме с уменьшенным размером шрифта и цветом, совпадающим с фоном документа.</p><h2>Вместо вывода</h2><p>Промпты работают тем эффективнее, чем больше контекста вы добавляете: опишите текущую должность, стек технологий, конкретные проблемы или цели. Нейросеть не заменит живого ментора или рекрутера, но помогает быстрее структурировать мысли, найти слабые места и отработать подход к задаче. Адаптируйте шаблоны под себя — и они станут полезным дополнением к работе над карьерой и продуктивностью.</p>]]></content:encoded>
    </item>
    <item>
      <title>Самое нужное для фронтендера в 2025: честный взгляд изнутри индустрии</title>
      <link>https://tproger.ru/articles/samoe-nuzhnoe-dlya-frontendera-v-2025--chestnyj-vzglyad-iznutri-industrii</link>
      <comments>https://tproger.ru/articles/samoe-nuzhnoe-dlya-frontendera-v-2025--chestnyj-vzglyad-iznutri-industrii?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[MCN Telecom]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/samoe-nuzhnoe-dlya-frontendera-v-2025--chestnyj-vzglyad-iznutri-industrii</guid>
      <description><![CDATA[<p>За последние пару лет роль фронтенд-разработчика заметно изменилась. То, что раньше считалось “плюсом”, теперь стало обязательной базой, а сами интерфейсы окончательно превратились в сложные приложения, которые порой работают быстрее десктопных программ.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/samoe-nuzhnoe-dlya-frontendera-v-2025--chestnyj-vzglyad-iznutri-industrii">Самое нужное для фронтендера в 2025: честный взгляд изнутри индустрии</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 03 Dec 2025 10:20:04 GMT</pubDate>
      <content:encoded><![CDATA[<p>За последние пару лет роль фронтенд-разработчика заметно изменилась. То, что раньше считалось “плюсом”, теперь стало обязательной базой, а сами интерфейсы окончательно превратились в сложные приложения, которые порой работают быстрее десктопных программ.</p><p>2025 год особенно интересен: требования растут, стек стремительно обновляется, а вокруг — десятки новых инструментов, которые одновременно и вдохновляют, и заставляют чувствовать себя не в своей тарелке. Так что давайте спокойно и по-человечески разберёмся, что сегодня действительно важно, а что можно смело откладывать.</p><h2>Как изменилась профессия и что теперь требуют от фронтендера</h2><p>Если лет пять назад от вас ждали уверенную верстку, JavaScript и один фреймворк, то сегодня к этому прибавились архитектура, серверные рендеринги, работа с AI-инструментами и понимание, как всё это уживается на проде. Современный фронтенд стал более инженерным: теперь вы не просто “собираете интерфейс”, а участвуете в создании части системы.</p><p>Эта эволюция кажется пугающей только на первый взгляд. На самом деле она отражает главный тренд — интерфейсы стали критически важными для пользователей и бизнеса. А значит, и навыки разработчиков должны подтягиваться до нового уровня.</p><h2>Стек, который в 2025 уже обязателен</h2><p>Начнём с основы — технологий, без которых трудно представить работу фронтендера.</p><p>TypeScript окончательно стал стандартом. Это уже не “приятное дополнение”, а часть культуры. Большие команды без типизации работать не могут — слишком дорого обходятся ошибки и непредсказуемые зависимости.</p><p>JavaScript тоже не стоит на месте: ежегодно появляются полезные нововведения, которые упрощают работу с асинхронностью, структурами данных и синтаксисом. Те, кто следят за ECMAScript, всегда ощущают себя увереннее остальных: код становится чище, а решения — элегантнее.</p><p>Во фронтенде всё больше внимания уделяется браузерным API. WebGPU, новые возможности Storage, нативные анимации — всё это сильно снижает потребность в тяжёлых библиотеках и позволяет делать вещи, которые раньше были попросту невозможны. Чем лучше вы понимаете браузер, тем реже сталкиваетесь с ограничениями.</p><h2>Фреймворки: что происходит, и куда всё движется</h2><p>React по-прежнему доминирует, но теперь уже невозможно говорить о React в отрыве от Next.js или серверных компонентов. Это целая новая парадигма, где часть логики уезжает на сервер, а приложение начинает работать быстрее и экономнее. Для многих разработчиков переход на RSC становится точкой, где React ощущается как совершенно другой инструмент.</p><p>Параллельно растет популярность SvelteKit. Он проще, легче и зачастую приятнее в работе, особенно в небольших командах и стартапах, где важна скорость разработки. Vue 3 остается стабильным и очень комфортным выбором — его любят команды, которые ценят предсказуемость и мягкий порог входа.</p><p>Angular в 2025 году остаётся выбором крупных компаний и проектов, где важны строгая структура и предсказуемость. Благодаря встроенному DI, мощному CLI и единому стилю разработки он помогает быстрее масштабировать команды и поддерживать большие приложения.</p><h2>Архитектура: что фронтендер обязан понимать в 2025</h2><p>Современная разработка уже не обходится без SSR, SSG или ISR. Рендеринг стал частью оптимизации, а значит нужно понимать, почему одни страницы стоит отдавать с сервера, а другие — генерировать заранее.</p><p>Edge-функции — еще одно направление, которое стремительно набирает обороты. Когда код выполняется ближе к пользователю, интерфейс работает быстрее, а логика становится гибче. Если раньше подобные вещи интересовали только backend-разработчиков, то теперь это важный элемент фронтенд-экосистемы.</p><p>Микрофронтенды остаются актуальными для крупных команд. Они не всегда нужны, но если продукт растет, а структура усложняется, этот подход заметно снижает хаос.</p><h2>Как AI меняет работу разработчика</h2><p>AI перестал быть экспериментом — он стал полноценным участником рабочего процесса. Хорошие специалисты уже воспринимают его не как угрозу, а как инструмент.</p><p>Он помогает быстрее проектировать, находить ошибки, генерировать тесты и даже анализировать архитектуру. Но чтобы это работало эффективно, приходится учиться формулировать точные запросы, проверять ответы и комбинировать идеи модели со своим опытом.</p><p>Компании в 2025 году всё чаще спрашивают не “умеете ли вы пользоваться AI”, а “как именно он встроен в ваш рабочий процесс”.</p><h2>Ключевые навыки, без которых сейчас не обойтись</h2><p>Первое — производительность. Пользователи стали очень нетерпеливыми: если интерфейс притормаживает, они просто уходят. Поэтому важно понимать, как распределяется нагрузка, почему лишний ререндер может быть дорогим и что делать, чтобы сайт оставался быстрым даже на слабых устройствах.</p><p>Второе — доступность. A11y перестала быть “бонусом”. Это требование. Интерфейс должен быть удобен всем пользователям, независимо от их ограничений, и компании всё чаще контролируют этот аспект.</p><p>Третье — автоматизация. CI/CD, базовая работа с пайплайнами, понимание, как собирается и проверяется код — всё это экономит время и снижает число ошибок. Чем сильнее разработчик в автоматизации, тем надёжнее продукт.</p><h2>Софт-скиллы, о которых всё чаще говорят</h2><p>Поскольку команды становятся более распределенными, важным навыком стала коммуникация — умение четко формулировать свои мысли, обсуждать решения и объяснять сложные вещи так, чтобы вас понимали.</p><p>Еще одна ключевая компетенция — умение учиться. Обновления приходят настолько быстро, что способность адаптироваться становится не менее важной, чем знание фреймворков.</p><p>И, конечно, продуктовое мышление. Хороший фронтендер давно перестал цениться только за чистый код. Намного важнее, когда вы понимаете, какие решения действительно улучшают продукт, а какие — лишь выглядят технологично.</p><h2>Заключение</h2><p>2025 год стал переломным для фронтенда. Порог входа вырос, но вместе с этим вырос и потенциал — теперь разработчик может влиять на продукт намного сильнее. “Самое нужное для фронтендера в 2025” — это не столько конкретный стек, сколько способность мыслить шире: понимать архитектуру, разбираться в инструментах, не бояться AI и постоянно развиваться.</p><p>Если смотреть на профессию не как на бесконечный список требований, а как на путь, то изменения перестают пугать. Они открывают новые возможности — и именно это делает работу фронтенд-разработчика такой захватывающей.</p>]]></content:encoded>
    </item>
    <item>
      <title>В сеть слили исходники App Store — Apple сама допустила утечку</title>
      <link>https://tproger.ru/news/v-set-slili-ishodniki-app-store---apple-sama-dopustila-utechku</link>
      <comments>https://tproger.ru/news/v-set-slili-ishodniki-app-store---apple-sama-dopustila-utechku?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/v-set-slili-ishodniki-app-store---apple-sama-dopustila-utechku</guid>
      <description><![CDATA[<p>Apple допустила утечку исходников App Store: из-за включённых sourcemaps в сеть попал фронтенд на Svelte, TypeScript и модули API</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/v-set-slili-ishodniki-app-store---apple-sama-dopustila-utechku">В сеть слили исходники App Store — Apple сама допустила утечку</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Apple]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[App Store]]></category>
      <category><![CDATA[iPhone]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 06 Nov 2025 03:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Разработчик под ником <b>rxliuli</b> <a href="https://github.com/rxliuli/apps.apple.com">выложил</a> на GitHub полный фронтенд-код веб-версии App Store.</p><p>Оказалось, что <b>утечка произошла из-за самой Apple</b> — компания просто забыла отключить sourcemaps в продакшн-сборке сайта.</p><h2>Что именно утекло</h2><p>В открытый доступ попали:</p><ul><li>компоненты интерфейса на <b>Svelte</b> и <b>TypeScript</b>,</li><li>исходники модулей API,</li><li>конфиги, константы и хранилища состояния,</li><li>а также логика маршрутизации и региональные страницы (us/iphone/ и др.).</li></ul><p>Проект был загружен на GitHub как <b>apps.apple.com</b>, получил тысячи звезд и форков, прежде чем его удалили по жалобе правообладателя — то есть Apple.</p><figure><img src="https://media.tproger.ru/user-uploads/111041/2025-11-06/ac44ba50-9ae2-4cca-85c4-f0e9aa3fb110.jpeg" alt="" /></figure><h2>Почему это важно</h2><p>Apple обычно тщательно охраняет исходный код своих сервисов, поэтому такой случай — редкость. По сути, <b>вся фронтенд-структура App Store</b> на несколько дней оказалась в открытом доступе «по вине одного флажка в настройках».</p><p>В README автор честно указал, что репозиторий создан «в образовательных целях» и весь код принадлежит Apple Inc. Правда, в конечном итоге это не уберегло его от сноса.</p>]]></content:encoded>
    </item>
    <item>
      <title>5 вещей, которые должен знать фронтенд-разработчик про Docker</title>
      <link>https://tproger.ru/articles/5-veshhej--kotorye-dolzhen-znat-frontend-razrabotchik-pro-docker</link>
      <comments>https://tproger.ru/articles/5-veshhej--kotorye-dolzhen-znat-frontend-razrabotchik-pro-docker?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Дима Державин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/5-veshhej--kotorye-dolzhen-znat-frontend-razrabotchik-pro-docker</guid>
      <description><![CDATA[<p>Зачем фронтенд-разработчику Docker? Практическое руководство: основные команды, создание Dockerfile, подключение к бэкенду, работа с реестрами и запуск в продакшене. Повысите свой уровень с Middle до Senior.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/5-veshhej--kotorye-dolzhen-znat-frontend-razrabotchik-pro-docker">5 вещей, которые должен знать фронтенд-разработчик про Docker</a>»</p>]]></description>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Инфраструктура]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 30 Oct 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Каждый день граница между фронтендом и бэкендом размывается, поэтому компании всё чаще ищут универсальных разработчиков, способных не только написать код, но и обеспечить стабильную работу приложения на каждом этапе релизного цикла, вплоть до запуска в продакшене.</p><p><i>Много кто пропустил момент, когда Docker стал стандартом в индустрии, а контейнеризация перестала быть приятным опциональным бонусом при найме опытного разработчика.</i></p><p>Сегодня причислять себя к Senior-грейду без знания основ контейнеризации — неоправданно.</p><p>Не будем лукавить — также компании любят экономить на сотрудниках, размывая отвественность из смежных областей на фронтенд-разработчика, который находится где-то посредине релизного цикла.</p><p>Давайте разбираться, что должен знать фронтенд-разработчик про Docker.</p><h2>Что такое Docker?</h2><p><i>Docker</i> — это программа для создания, развёртывания и управления приложениями в контейнерах. Контейнер создаётся на основе образа, который описан в <i>Dockerfile</i>.</p><p><i>Dockerfile</i> — по сути, инструкция для создания контейнера. В нём описывается окружение, зависимости и команды для запуска приложений внутри, например, прокси-сервера или микросервиса авторизации.</p><h3>Какие проблемы решает Docker во фронтенде?</h3><p>В небольшом проекте работа с web-приложением сводится к использованию четырёх команд: start, build, test, deploy.</p><p>А вот запуск веб-приложения в большом и устоявшемся коммерческом проекте выглядит так:</p><ul><li>Запусти Nginx, чтобы отдать клиент.</li><li>Подними (а перед этим установи) бекенд на Go и кэш на Redis, чтобы заработало API.</li><li>Запусти БД, чтобы были данные.</li><li>Запусти вспомогательные сервисы для API, например, аутентификацию или backoffice.</li></ul><p>Без контейнеризации запуск сложного приложения превращается в филиал ада: разработчики тратят время на запуск инфраструктуры, у пользователей MacOS не работает то, что работает у пользователей Ubuntu, а порты Postgres конфликтуют с портами локально поднятого почтового сервера.</p><p>Так ноутбук начинает выполнять функцию обогревателя для помещения площадью 40 квадратных метров 🙂</p><h3>Для решения каких задач фронтенд-разработчики выбирают Docker чаще всего?</h3><p>На стороне фронтенда Docker чаще всего используют для:</p><ul><li>Запуска и работы web-приложения.</li><li>Запуска инфраструктуры для web-приложения.</li><li>Запуска тестов (создание скриншотов, e2e-тесты).</li><li>Сборка приложения на CI.</li></ul><h2>Что же должен знать фронтенд-разработчик про Docker?</h2><h3>Основные команды для работы с Docker</h3><p>Без знания основных команд вы не сможете ни запустить контейнер, ни отладить, ни понять, что же с ним происходит.</p><p>Базовое управление контейнерами также доступно через интуитивно понятный Docker UI.</p><p><b>Важно:</b> все основные команды имеют полезные аргументы. Полный список аргументов вы можете найти в документации.</p><h3>Как создать базовый Docker-образ для веб-приложения?</h3><p>Прежде чем запустить контейнер, нужно описать его содержимое, а также выбрать порядок выполнения команд.</p><p>Образ стандартного web-приложения выглядит примерно так:</p><p>При создании Dockerfile рекомендуем следовать минимальному набору лучших практик:</p><ul><li>Использовать базовые образы, чтобы не нагружать образ лишними модулями.</li><li>Добавлять <i>.dockerignore</i>, чтобы исключать лишние файлы из сборки.</li><li>Не запускать контейнер от root, чтобы снизить риски для безопасности.</li><li>Проверять сторонние образы с помощью docker scan, опять же, чтобы снизить риски для безопасности.</li></ul><h3>Как отправить образ в Container Registry?</h3><p><i>Container Registry</i> — это хранилище для Docker-образов.</p><p>Container Registry можно сравнить с Github, только вместо репозиториев — готовые для развёртывания образы.</p><p>Для работы с Container Registry есть несколько основных команд:</p><p>По тегу latest вы всегда можете получить последнюю версию вашего контейнера.</p><p>Популярные Container Registry:</p><ul><li>Docker Hub (публичный, простой и бесплатный для открытых проектов);</li><li>GitHub Container Registry (платный, интегрирован с GitHub);</li><li>Google Container Registry (платный);</li><li>Yandex Container Registry (платный).</li></ul><p>Важно: старайтесь подбирать Container Registry под экосистему, в которой будет работать ваше приложение. Это сэкономит много сил и времени.</p><h2>Как запустить Docker-контейнер локально и на сервере?</h2><p>Для локального запуска контейнера потребуется пройти простой пайплайн:</p><p>Если вы хотите запустить контейнер на удалённом сервере с установленным Docker, то вам потребуется пройти пайплайн посложнее:</p><p>Важно: в данном примере мы используем в качестве Container Registry — Docker Hub.</p><h2>Как подключить фронтенд к бэкенду внутри Docker?</h2><p>Чтобы не настраивать общение клиента и сервера через порты, хорошая практика — объединять сервисы в рамках единой Docker-сети.</p><p>Обычно этой задачей занимается файл-оркестратор docker-compose.yml:</p><p>Чтобы поднять весь стэк, нам понадобятся команды:</p><p>Ключевые моменты:</p><ul><li>Сервисы в одной сети могут общаться по имени (в примере фронтенд обращается к бэкенду по http://backend:5000);</li><li>depends_on гарантирует порядок запуска, но не ждёт готовности сервиса;</li><li>Для продакшена можно разделить конфигурации на docker-compose.yml и docker-compose.prod.yml.</li></ul><h2>Бонус: Как управлять контейнерами через UI?</h2><p>В случае отсутствия опыта контейнеризации у команды разработки, управление контейнерами можно осуществлять через UI (вместо терминала) при помощи <i>Portainer</i>.</p><p>Portainer — это легковесная панель управления Docker-контейнерами. Через удобный графический интерфейс он позволяет выполнять операции, которые обычно отправляются через терминал (docker run, docker ps, docker compose up).</p><figure><img src="https://media.tproger.ru/user-uploads/113154/2025-10-16/4ff13bab-77e8-4d2f-b78d-2695dc106945.png" alt="Админ панель Portainer.IO для управления контейнерами и их образами" /><figcaption>Админ панель Portainer.IO для управления контейнерами и их образами</figcaption></figure><p>Portainer делает управление докер-контейнерами доступным для широкого круга пользователей: от разработчиков и тестировщиков до системных администраторов.</p><p>Portainer не заменяет необходимость знания Docker, но значительно ускоряет и упрощает такие рутинные операции, как развёртывание и мониторинг.</p><h2>Когда Docker необходим, а когда можно обойтись?</h2><p>Используйте Docker когда:</p><ul><li>работаете в команде с разными ОС;</li><li>проект имеет сложные внутренние и внешние зависимости;</li><li>нужно обеспечить идентичность разных сред: разработки, тестирования, продакшена;</li><li>работаете с full-stack приложениями, где фронтенд тесно связан с бэкендом.</li></ul><p>Без Docker можно обойтись когда:</p><ul><li>работаете над небольшим проектом;</li><li>вся команда использует одинаковое железо и ОС;</li><li>проект не имеет сложных зависимостей;</li><li>нет необходимости в изоляции окружений.</li></ul><h2>Заключение</h2><p>В последние годы Docker прочно вошёл в арсенал фронтенд-разработчиков, перестав быть инструментом исключительно для бэкенда и DevOps.</p><p>Основная ценность Docker для фронтенд разработчика заключается в решении двух ключевых задач: быстрый запуск сложной рабочей среды приложения и обеспечение стабильности на протяжении релизного цикла.</p><p>Поэтому даже базовое знание Docker поможет выделиться на фоне других разработчиков, ведь вы сможете не просто создать приложение, но и провести его через полный релизный цикл.</p><p>В своём <a href="https://t.me/+2OPggty992w5YTY6">телеграмм-канале</a> я делюсь практическим опытом разработки, честно рассказываю о трудностях в работе, а также показываю кейсы проектов, которыми занимаюсь в свободное время!</p><p>Буду рад каждому, кто подписался  ✨</p><h2>Возможно, вам будет интересно:</h2><p>Делитесь своими находками и полезными командами для работы с Docker в комментариях!</p>]]></content:encoded>
    </item>
    <item>
      <title>COBOL в Японии: почему цифровое прошлое до сих пор определяет настоящее</title>
      <link>https://tproger.ru/articles/cobol-v-yaponii--pochemu-cifrovoe-prowloe-do-sih-por-opredelyaet-nastoyashhee</link>
      <comments>https://tproger.ru/articles/cobol-v-yaponii--pochemu-cifrovoe-prowloe-do-sih-por-opredelyaet-nastoyashhee?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Ислам Виндижев]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/cobol-v-yaponii--pochemu-cifrovoe-prowloe-do-sih-por-opredelyaet-nastoyashhee</guid>
      <description><![CDATA[<p>Узнайте, почему в Японии COBOL до сих пор основа экономики, на нём всё ещё учатся программировать и к чему привело использование такого старого языка.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/cobol-v-yaponii--pochemu-cifrovoe-prowloe-do-sih-por-opredelyaet-nastoyashhee">COBOL в Японии: почему цифровое прошлое до сих пор определяет настоящее</a>»</p>]]></description>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Языки программирования]]></category>
      <category><![CDATA[Организация разработки]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 29 Oct 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>В мире IT, где технологии устаревают за несколько лет, судьба COBOL — настоящая аномалия. Этот язык, созданный в 1959 году, должен был исчезнуть вместе с мейнфреймами. Но в Японии — стране высоких технологий — COBOL не просто жив. Он остаётся «невидимым скелетом» всей экономики. Почему? Всё дело в уникальной комбинации истории, экономики и культуры.</p><figure><img src="https://media.tproger.ru/user-uploads/133609/2025-10-08/0636793c-acd1-42e1-a595-a64f38e8dd74.jpeg" alt="Самурай и COBOL" /></figure><h2>История: золотой век мейнфреймов и становление цифровой инфраструктуры</h2><p>В 1960-80-е годы, во время «экономического чуда», Япония массово внедряла компьютеры. Стандартом стали мейнфреймы IBM, а COBOL — идеальным языком для них.</p><figure><img src="https://media.tproger.ru/user-uploads/133609/2025-10-08/38868fd4-c43c-4974-b30b-ee964a6141fc.jpg" alt="Мейнфрейм IBM System/370, был выпущен в 70-е" /><figcaption>Мейнфрейм IBM System/370, был выпущен в 70-е</figcaption></figure><figure><img src="https://media.tproger.ru/user-uploads/133609/2025-10-08/92ea0127-597f-41e6-821c-15660b5bc9f8.jpg" alt="Терминал IBM 3277" /><figcaption>Терминал IBM 3277</figcaption></figure><p>На COBOL переписали все ключевые процессы: обработку банковских транзакций, расчёт заработных плат, управление счетами, логистику, оформление страховых полисов. Так, за два десятилетия была создана цифровая ДНК японской экономики — миллиарды строк кода, которые стали критически важны для бизнеса.</p><h3>Принцип «Работает — не трогай»</h3><p>Из истории вытекает первая и главная причина живучести COBOL — эффект <b>path dependency</b> (зависимость от предшествующего развития).</p><p>Зависимость от предшествующего развития — это когда прошлые решения ограничивают будущие возможности и пути развития системы, отрасли или даже страны.</p><p>Из-за этого эффекта инженеры были ограничены в своём выборе. При этом каждый программист знает, что не стоит трогать legacy, которое работает. А чем дольше его не трогать — тем старше и больше оно становится. Чем старше и больше — тем страшнее, дороже и рискованнее его изменять.</p><figure><img src="https://media.tproger.ru/user-uploads/133609/2025-10-08/7ca1727c-57e9-4a9f-bd15-b070cc3b2be0.jpeg" alt="" /></figure><p>Представьте себе системы, которые работали десятилетиями в такой консервативной сфере, как финансы, где ошибка в одну запятую может стоить миллионов. Здесь стабильность и предсказуемость ценятся превыше всего. А в процессе миграции можно столкнуться с ошибками, потерями данных или простоями, которые парализуют бизнес и приносят огромные финансовые и репутационные потери.</p><p>Ещё один риск — скрытая логика. За годы эксплуатации исходный код обрастает тысячами правок и нюансов, которые не отражены в документации. Перенести эту сложную бизнес-логику без потерь практически невозможно.</p><p>Конечно же, переписывать системы такого размера ещё и очень долго. И чем старше становится система, тем больше миграция будет отставать от темпов развития бизнеса.</p><p>Так японские компании пришли к рациональному выводу: проще и безопаснее поддерживать работающую систему, чем пытаться заменить её целиком.</p><h2>Экономика: стоимость замены против стоимости поддержки</h2><p>Японский бизнес предпочитает поддержку старых решений не только руководствуясь простой логикой. Конечно, в дело вступили жёсткие расчёты, финансы и экономика.</p><p>Помимо прямых затрат на разработку, нужно учесть стоимость новых лицензий на ПО, обучение всего персонала, параллельное ведение старых и новых систем на время перехода и колоссальные затраты на тестирование.</p><p>Следующий вопрос — экономическая выгода. Руководство компаний справедливо задаётся вопросом: «Какую прибыль принесет нам этот переход?». Чаще всего ответ — «Никакой, мы просто получим систему, которая делает то же самое, но на другом языке». С точки зрения ROI (возврата инвестиций) проекты миграции или модернизации выглядят крайне непривлекательно.</p><figure><img src="https://media.tproger.ru/user-uploads/133609/2025-10-08/8cb5b998-d3b9-4ec6-aebc-673590bdd6e5.jpeg" alt="Японские феодалы делят золото" /></figure><p>В итоге, инвестиции в поддержку legacy-систем, какими бы большими они ни были, почти всегда оказывались ниже запредельной стоимости и рисков полной замены систем на COBOL.</p><h2>Культура: японский консерватизм и системный подход</h2><p>Экономическая рациональность не существует сама по себе. Она подкрепляется и японской культурой, которая символизирует надёжность, стабильность, долговечность и лояльность.</p><p>Японская бизнес-культура, особенно в крупных корпорациях и госсекторе, обычно против рисков и характеризуется консерватизмом. Излишний риск не считается оправданным.</p><p>Ещё одна особенность — система пожизненного найма.</p><p>В любой сфере человек мог проработать в компании всю жизнь до пенсии. Эта практика была популярна в послевоенный период, но сейчас менее распространена. От неё отступают в сторону ротации для большей гибкости и эффективности.</p><p>Такая традиция создала уникальную среду: инженеры, начавшие работать с COBOL в 1980-х, оставались в компаниях до пенсии, накапливая и передавая бесценные знания. Это создавало внутреннюю стабильную экосистему экспертизы.</p><p>Можно подумать, что такая ситуация создаёт дефицит специалистов, которые могут продолжать поддерживать и развивать кодовые базы на COBOL. Это не совсем так.</p><h2>Решение кадрового кризиса: не вопреки, а благодаря</h2><p>Самое большое заблуждение — считать, что Япония столкнулась с кадровым голодом и ничего не делает. Напротив, она выстроила целую индустрию по управлению этим COBOL-наследием.</p><p>Основная масса ключевых экспертов действительно люди предпенсионного возраста. При этом молодые специалисты приходят в эту сферу на условиях лучших, чем в среднем по рынку.</p><figure><img src="https://media.tproger.ru/user-uploads/133609/2025-10-08/fcced980-8cb6-4908-b75f-38385288aef4.jpeg" alt="Старый самурай передаёт знания молодому" /></figure><p>Крупные корпорации передают поддержку COBOL-систем специализированным IT-гигантам, таким как Fujitsu, NEC, NTT Data, IBM Japan. Внутри этих компаний существуют целые департаменты, которые:</p><p>1.  Целенаправленно нанимают и обучают молодых инженеров работе с COBOL и мейнфреймами.</p><p>2.  Предлагают им стабильную карьеру с высокой (из-за низкой конкуренции) зарплатой и социальными гарантиями.</p><p>3.  Разрабатывают инструменты модернизации: транспайлеры (конвертирующие COBOL в Java, <a href="https://www.ibm.com/docs/en/watsonx/watsonx-code-assistant-4z/1.x?topic=transform-transforming-cobol-java-by-using-generative-ai">в том числе на базе AI</a>), <a href="https://www.ibm.com/products/cobol-compiler-linux-x86">эмуляторы</a> и <a href="https://cobolcloud.io/">платформы</a> для запуска legacy-кода в облаке.</p><p>Проблема кадров осознана и решается решается разными путями. Но возможно ли и нужно ли поддерживать COBOL бесконечно?</p><h2>Есть ли у COBOL преимущества сегодня?</h2><p>Кажется, что у такой старой технологии нет никаких преимуществ. Но давайте найдём одно — стабильность и надёжность. Системы продолжают работать исправно и пока их удаётся поддерживать. Вряд ли новый проект начнут разрабатывать на COBOL, но поддержка всё ещё продолжается.</p><p>Безусловный минус — стоимость поддержки. К 2025 году затраты на поддержку COBOL-решений могли <a href="https://www.nikkei.com/article/DGXZQOFK052Y70V00C21A2000000/">составить до 12 триллионов йен в год или 80 миллиардов долларов</a>, что уже превышает некоторый психологический барьер. Этому прогнозу уже несколько лет, так что сегодня компании стоят перед сложным выбором: вкладываться в модернизацию или продолжать поддержку.</p><p>В конечном итоге, живучесть COBOL в Японии — это не признак технологической отсталости, а следствие расчёта, уважения к стабильности и долгосрочной стратегии управления legacy. Эти старые системы — всё ещё ядро национальной цифровой инфраструктуры: дорогое в обслуживании, но надёжное.</p><p>Если японские компании и правительство всё-таки примут риски модернизации, то об этом мы с вами узнаем уже в ближайшие несколько лет.</p>]]></content:encoded>
    </item>
    <item>
      <title>Типы языков программирования: от низкоуровневых до высокоуровневых — как выбрать для новичка</title>
      <link>https://tproger.ru/articles/tipy-yazykov-programmirovaniya--ot-nizkourovnevyh-do-vysokourovnevyh---kak-vybrat-dlya-novichka</link>
      <comments>https://tproger.ru/articles/tipy-yazykov-programmirovaniya--ot-nizkourovnevyh-do-vysokourovnevyh---kak-vybrat-dlya-novichka?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/tipy-yazykov-programmirovaniya--ot-nizkourovnevyh-do-vysokourovnevyh---kak-vybrat-dlya-novichka</guid>
      <description><![CDATA[<p>Выбираете первый язык программирования? Узнайте о низкоуровневых (C, C++), среднеуровневых (Java, C#) и высокоуровневых (Python, JavaScript) языках: плюсы, минусы и примеры применения. Чек-лист от экспертов поможет новичкам выбрать язык для веб, мобильной разработки или игр.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/tipy-yazykov-programmirovaniya--ot-nizkourovnevyh-do-vysokourovnevyh---kak-vybrat-dlya-novichka">Типы языков программирования: от низкоуровневых до высокоуровневых — как выбрать для новичка</a>»</p>]]></description>
      <category><![CDATA[Низкоуровневое программирование]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Ruby]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[.NET]]></category>
      <category><![CDATA[Windows]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[Xamarin]]></category>
      <category><![CDATA[Data Science]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Аналитика]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[Dart]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 28 Oct 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Для погружения в программирование нужно всего 3 вещи:</p><ul><li>Решить, с какого языка/технологии вы хотите начать.</li><li>Решить, на каком ресурсе вы хотите обучаться.</li><li>Выделить время на само программирование.</li></ul><p>Звучит просто, однако у вас уйдёт много времени на исследования, чтобы решить, что вам подходит и на каком ресурсе обучаться.</p><p>Некоторые люди начинают с относительно низкоуровневого программирования на C и C++. Другие выбирают более традиционный путь, изучая Java или C#. Есть и те, кто начинает с высокоуровневых или скриптовых языков вроде Python, Ruby или JavaScript.</p><p>Мы классифицируем языки по уровню абстракции. Для новичков: низкоуровневые — как ручная сборка машины (контроль, но сложный); среднеуровневые — как готовый конструктор с инструкцией (сохраняем баланс); высокоуровневые — как приложение на смартфоне (быстро, но меньше контроля). Ниже разберём плюсы и минусы и поможем сделать правильный выбор.</p><h2>Низкоуровневые языки: близко к «железу»</h2><p>Это языки, где вы напрямую работаете с памятью компьютера. Нет автоматической уборки ненужных данных, <b>всё под вашим контролем</b>. Подходят для системного ПО, игр или устройств (например, микроконтроллеров).</p><p>Примеры: C (для ОС вроде Linux), C++ (для игр на движке вроде Unreal Engine), Assembler (для оптимизации критических частей кода).</p><p><b>Плюсы:</b></p><ul><li>Полный контроль: вы решаете, как использовать ресурсы. Так, в C++ можно вручную выделять память для массивов, избегая ненужных копий данных.</li><li>Высокая скорость: прямой доступ к памяти позволяет писать код, который работает быстрее (это важно для работы с играми или серверами).</li><li>Основы основ: такие языки учат, как компьютер работает изнутри, чтобы в будущем ценить удобства других языков. Например, вы узнаёте, почему «утечка памяти» — это проблема.</li><li>Эффективность: низкоуровневые языки мотивируют думать об оптимизации заранее, снижая расход батареи или CPU.</li><li>Компактность: минимальная библиотека, приложения получаются лёгкими (идеально для embedded-систем, как в IoT-устройствах).</li></ul><p>Минусы:</p><ul><li>Всё-таки это сложно: рутинные задачи (например, чтение файла) требуют больше кода и внимания к деталям, рискуя ошибками вроде переполненного буфера.</li><li>Ручное управление памятью: можно легко «забыть» освободить память, вызвав утечки или краши. Например, в C нужно использовать malloc/free, иначе программа съест всю RAM.</li><li>Много копипасты: придётся писать шаблонный код, и делать это часто.</li><li>Платформо-зависимость: код для Windows может не работать на Linux без правок.</li></ul><h2>Среднеуровневые языки: баланс контроля и удобства</h2><p>Эти языки предлагают готовые инструменты, упрощающие работу, но требуют строгой проверки типов данных. Для их запуска нужна специальная программа (среда выполнения). Они идеальны для приложений, серверов и игр.</p><p>Примеры: Java (для Android-приложений), C# (для Unity-игр или .NET-серверов).</p><p>Плюсы:</p><ul><li>Автоматическая память: память очищается автоматически благодаря сборщику мусора, что избавляет от ручной работы и снижает вероятность ошибок, вроде утечек памяти в больших проектах. При этом можно получить доступ к низкоуровневым функциям для особых задач, например, через специальные инструменты в Java.</li><li>Богатые библиотеки: готовые инструменты для сетей, GUI или баз данных. Пример: Java’s Spring для веб-серверов.</li><li>Кроссплатформенность: компиляция в байт-код (JVM для Java) позволяет запускать код везде. Например, пишешь на Windows, запускаешь на Linux.</li><li>Безопасность: язык проверяет типы данных перед запуском программы, помогая заранее найти ошибки. Среда выполнения защищает от опасных сбоев, например, от переполненной памяти.</li><li>Масштабируемость: встроенные инструменты для параллельных вычислений позволяют легко создавать программы, которые одновременно выполняют много задач (серверы для тысяч пользователей и т.п.).</li></ul><p>Минусы:</p><ul><li>Дополнительная нагрузка от рантайма: Среда выполнения и автоматическая очистка памяти создают дополнительную нагрузку. Сборщик мусора может ненадолго останавливать программу, что заметно в играх или при обработке видео.</li><li>Меньше контроля: абстракции скрывают детали памяти, усложняя оптимизацию (например, в Java сложно избежать боксинга примитивов).</li><li>Повторяющийся код, которого много: приходится писать повторяющийся код и тренировать свою усидчивость, например, для доступа к данным объекта. Кстати, инструменты вроде Lombok могут упростить эту задачу.</li><li>Зависимость от среды: для запуска программ нужна специальная среда (например, JVM для Java), что влияет на размер программ и замедляет их старт.</li><li>Сложность интеграции: подключение кода на других языках, например, на C, требует писать специальные обёртки, что усложняет работу и снижает скорость.</li></ul><h2>Высокоуровневые языки: удобство и скорость разработки</h2><p>Эти языки скрывают технические детали, позволяя сосредоточиться на создании <b>логики программы</b>. Подходят для веба, data science или скриптов.</p><p>Примеры: Python (для ML), Ruby (для веб-разработки), JavaScript (для фронтенда).</p><p>Плюсы:</p><ul><li>Простота: сложные задачи решаются в пару строк. Так, в JS async/await упрощает API-запросы.</li><li>Быстрая разработка: динамическая типизация позволяет быстро писать и тестировать код без необходимости его компиляции.</li><li>Богатые экосистемы: есть библиотеки для всего (к примеру, NumPy для данных в Python).</li><li>Гибкость: легко менять код, идеально для прототипов или стартапов.</li></ul><p>Минусы:</p><ul><li>Низкая производительность: абстракции добавляют нагрузки. Например, циклы в Python медленнее, чем в C.</li><li>Ошибки на рантайме: из-за слабой типизации ошибки выявляются только при запуске программы, что усложняет отладку.</li><li>Риск «спагетти-кода»: лёгкость изменений может привести к хаосу без дисциплины.</li><li>Скрытые проблемы: абстракции маскируют баги.</li><li>Зависимость от интерпретатора: программы требуют установленного интерпретатора, что замедляет их запуск и добавляет зависимость от дополнительного ПО.</li></ul><h2>Чек-лист: как выбрать язык программирования для новичка</h2><p>Этот чек-лист основан на советах экспертов, чтобы помочь новичкам выбрать первый язык программирования. Каждый пункт включает конкретные рекомендации.</p><ol><li><b>Определите, что вас вдохновляет, и выберите сферу.</b> Подумайте, что вы хотите создавать: сайты, игры, мобильные приложения или серверы. Разные сферы требуют разных языков. Например, для веб-разработки подойдут JavaScript или Python, для мобильных приложений — Java, Kotlin, Swift или Dart, а для игр — C# или C++. Составьте список идей (например, сайт-визитка, игра, аналитика данных) и найдите, какие языки для них используют. <br />— Аня Жаркова, руководитель мобильной разработки в USETECH</li><li><b>Ищите язык с широким применением.</b> Выбирайте языки, которые используются в разных областях, чтобы легче переключаться между задачами. Например, Kotlin подходит для мобильной разработки, веба и серверов, а C# — для десктоп-приложений, игр (Unity) и бэкенда. Это даёт гибкость и упрощает изучение новых языков в будущем.<br />— Аня Жаркова, руководитель мобильной разработки в USETECH</li><li><b>Проверьте спрос на рынке труда. </b>Если цель — смена профессии, изучите вакансии на HH.ru или LinkedIn. Введите «junior Python», «junior Java» и сравните, где больше предложений и какие требования. Избегайте языков с низким спросом, если хотите быстро найти работу. Например, Java, Kotlin, Python и JavaScript популярны для найма.<br />— Владислав Масунов, Head of Development</li><li><b>Опробуйте языки на практике.</b> Напишите простые программы (например, "Hello World" или калькулятор) на нескольких языках, чтобы понять, какой синтаксис вам ближе. Используйте онлайн-редакторы вроде Replit или CodePen. Например, попробуйте TypeScript для веба (он поддерживает типизацию и разные подходы к программированию) или C++ для понимания работы с памятью. Это поможет почувствовать, к чему лежит душа.<br />— Рома Троицкий, фронтенд-инженер в Сбер B2C, член ПК HolyJS &amp; MoscowCSS; Евгений Антонов, ИТ-консультант, автор тг-канала <a href="https://t.me/general_it_talks">@general_it_talks</a></li><li><b>Выберите язык с хорошей документацией и сообществом.</b> Убедитесь, что у языка много обучающих материалов и активное сообщество. Например, TypeScript имеет богатую документацию и поддержку, что упрощает старт. Проверьте ресурсы вроде LearnPython.org, freeCodeCamp для JavaScript или Telegram-чаты для C++. Это поможет быстрее решать вопросы.<br />— Рома Троицкий, фронтенд-инженер в Сбер B2C, член ПК HolyJS &amp; MoscowCSS</li><li><b>Учитывайте сложность и карьерные цели.</b> Для небольших проектов или быстрого старта берите Python или PHP — они проще и подходят для веб-разработки или скриптов. Для сложных задач с высокой нагрузкой (например, серверы или оптимизация) попробуйте C++ или Go. Если цель — работа в крупных компаниях, Java и Kotlin востребованы и часто используются с ИИ-инструментами. Выбирайте, исходя из сложности и ваших амбиций.<br />— Евгений Антонов, ИТ-консультант, автор тг-канала <a href="https://t.me/general_it_talks">@general_it_talks</a></li><li><b>Смотрите на универсальность и переход к другим языкам. </b>Выбирайте язык, который учит основам программирования и упрощает переход к другим. Например, изучение C# может помочь освоить Java, а затем — Android-разработку. TypeScript учит объектно-ориентированному и функциональному программированию, что полезно для разных задач. Это создаёт базу для дальнейшего роста.<br />— Аня Жаркова, руководитель мобильной разработки в USETECH; Рома Троицкий, фронтенд-инженер в Сбер B2C, член ПК HolyJS &amp; MoscowCSS</li><li><b>Не гонитесь за гилти плежа.</b> Избегайте языков, которые изучают «для удовольствия» без практического применения. Выбирайте те, которые можно применить в реальных проектах или которые востребованы в индустрии. Например, вместо нишевых языков берите Python, Java или Kotlin: они имеют чёткие сценарии использования.<br />— Аня Жаркова, руководитель мобильной разработки в USETECH</li><li><b>Практикуйтесь с ИИ-инструментами.</b> Если хотите работать в крупных компаниях, освойте язык, который хорошо сочетается с ИИ-инструментами (например, Go или Java). Практикуйтесь с ИИ-агентами по типу GitHub Copilot для автоматизации задач — это ценится работодателями.<br />— Евгений Антонов, ИТ-консультант, автор тг-канала <a href="https://t.me/general_it_talks">@general_it_talks</a></li><li><b>Составьте план развития.</b> Создайте roadmap: определите, какие проекты хотите делать через 3-6 месяцев (например, мобильное приложение или веб-сервис), и подберите язык под эти цели. Если выбрали C#, начните с десктоп-приложений, затем попробуйте Xamarin для кроссплатформенной разработки. Постепенно добавляйте новые языки, опираясь на первый.<br />— Аня Жаркова, руководитель мобильной разработки в USETECH</li></ol><p>Если не определились, предлагаем пройти квиз и расставить всё по полочкам:</p>]]></content:encoded>
    </item>
    <item>
      <title>Какие приложения установить на Windows и macOS</title>
      <link>https://tproger.ru/articles/kakie-prilozheniya-ustanovit-na-windows-i-macos</link>
      <comments>https://tproger.ru/articles/kakie-prilozheniya-ustanovit-na-windows-i-macos?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Валерия Турчак]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kakie-prilozheniya-ustanovit-na-windows-i-macos</guid>
      <description><![CDATA[<p>Список разбит по категориям: от браузеров и гейминга до утилит безопасности и инструментов для продуктивности.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kakie-prilozheniya-ustanovit-na-windows-i-macos">Какие приложения установить на Windows и macOS</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Apple]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Практика]]></category>
      <category><![CDATA[Google]]></category>
      <category><![CDATA[.NET]]></category>
      <category><![CDATA[Браузеры]]></category>
      <category><![CDATA[Windows]]></category>
      <category><![CDATA[iOS]]></category>
      <category><![CDATA[Slack]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Microsoft]]></category>
      <category><![CDATA[Tor]]></category>
      <category><![CDATA[Windows 10]]></category>
      <category><![CDATA[Google Chrome]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Управление проектами]]></category>
      <category><![CDATA[Rust]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[VPN]]></category>
      <category><![CDATA[Telegram]]></category>
      <category><![CDATA[Xbox]]></category>
      <category><![CDATA[GitLab]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[macOS]]></category>
      <category><![CDATA[Для продвинутых]]></category>
      <category><![CDATA[Intel]]></category>
      <category><![CDATA[MIT]]></category>
      <category><![CDATA[Adobe]]></category>
      <category><![CDATA[Firefox]]></category>
      <category><![CDATA[IBM]]></category>
      <category><![CDATA[Mozilla]]></category>
      <category><![CDATA[Avast]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[NVIDIA]]></category>
      <category><![CDATA[Маркетинг]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Мессенджер]]></category>
      <category><![CDATA[AMD]]></category>
      <category><![CDATA[YouTube]]></category>
      <category><![CDATA[Epic Games]]></category>
      <category><![CDATA[Игра]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Бета]]></category>
      <category><![CDATA[Safari]]></category>
      <category><![CDATA[Взлом]]></category>
      <category><![CDATA[PlayStation]]></category>
      <category><![CDATA[Microsoft Edge]]></category>
      <category><![CDATA[Discord]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[RPA]]></category>
      <category><![CDATA[Дизайн]]></category>
      <category><![CDATA[Figma]]></category>
      <category><![CDATA[Графы]]></category>
      <category><![CDATA[Markdown]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Notion]]></category>
      <category><![CDATA[Дизайн интерфейсов и UX]]></category>
      <category><![CDATA[Steam]]></category>
      <category><![CDATA[GPU]]></category>
      <category><![CDATA[Hardware]]></category>
      <category><![CDATA[iPhone]]></category>
      <category><![CDATA[MacBook]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 26 Oct 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Итак, вы только что настроили новый компьютер. Операционная система установлена, драйверы обновлены, и теперь пора заняться самым интересным — установкой программ. Но с чего начать? Какие приложения действительно необходимы, а какие просто занимают место?</p><p>Редакция Tproger сделала и адаптировала <a href="https://www.techspot.com/article/2974-desktop-software-essentials/">перевод подборки  программ для Windows и macOS</a>. Здесь вы найдёте проверенные временем решения для работы, развлечений и повседневных задач. Мы сосредоточились на бесплатных и условно-бесплатных приложениях с отличной репутацией, которые решают реальные задачи без навязывания ненужных функций.</p><p>Список разбит по категориям: от браузеров и гейминга до утилит безопасности и инструментов для продуктивности.</p><p>Неважно, опытный вы пользователь или новичок — здесь найдётся что-то полезное для каждого.</p><h2>Браузеры</h2><p>Браузер — это, пожалуй, самое важное приложение на вашем компьютере. Именно через него проходит большая часть вашей цифровой жизни: работа, развлечения, коммуникации. Выбор браузера влияет не только на скорость загрузки страниц, но и на конфиденциальность, безопасность и удобство работы.</p><ul><li><b>Большинство пользователей:</b> Chrome, Edge или Safari</li><li><b>Защита приватности: </b>Firefox, Brave, Ungoogled Chromium</li><li><b>Опытные пользователи:</b> Vivaldi</li><li><b>Максимальная анонимность: </b>Tor Browser</li></ul><h3>Google Chrome</h3><p>Chrome остаётся самым популярным браузером в мире — и не просто так. Он быстрый, стабильный и отлично интегрируется с экосистемой Google. Огромная библиотека расширений из Chrome Web Store позволяет настроить браузер под любые задачи. Синхронизация между устройствами работает безупречно: вкладки, пароли, закладки и история всегда под рукой.</p><p>Минус один, но существенный: Chrome прожорлив. Если у вас открыто больше десятка вкладок, он может съесть несколько гигабайт оперативной памяти. На компьютерах с 8 ГБ RAM и меньше это становится проблемой.</p><h3>Mozilla Firefox</h3><p>Firefox — это выбор тех, кто ценит приватность и открытость. Mozilla не зарабатывает на продаже ваших данных, а сам браузер активно развивается сообществом. Встроенные инструменты защиты от трекинга работают из коробки, блокируя рекламные сети и скрипты слежения.</p><p>По скорости Firefox не уступает Chrome, а по потреблению памяти даже выигрывает. Библиотека расширений чуть меньше, чем у Chrome, но все основные инструменты доступны.</p><h3>Microsoft Edge</h3><p>Edge построен на том же движке Chromium, что и Chrome, но при этом лучше оптимизирован для Windows. Microsoft вложилась в производительность: браузер работает быстро, потребляет меньше ресурсов и отлично интегрируется с системой.</p><p>Особенно приятны функции вроде Collections (коллекции вкладок для организации исследований), режим чтения и встроенный скриншотер. Edge поддерживает все расширения Chrome, так что переход безболезненный.</p><h3>Brave</h3><p>Brave — это Chrome на стероидах приватности. Браузер блокирует рекламу и трекеры по умолчанию, что делает сёрфинг быстрее и безопаснее. При этом он полностью совместим с расширениями Chrome.</p><p>Есть интересная фишка: Brave Rewards позволяет зарабатывать криптовалюту за просмотр приватной рекламы (если захотите её включить). Спорная механика, но как опция — почему нет. Для тех, кто хочет Chrome без Google и с упором на приватность, Brave — отличный выбор.</p><h3>Safari (только macOS)</h3><p>Если у вас Mac, Safari заслуживает внимания. Это самый энергоэффективный браузер для macOS: на MacBook он даёт ощутимо больше автономности по сравнению с Chrome или Firefox. Интеграция с экосистемой Apple безупречна: Handoff, синхронизация через iCloud, Reading List, автозаполнение паролей.</p><p>Safari быстрый, безопасный и не перегружен функциями. Единственный минус — библиотека расширений заметно скромнее, чем у конкурентов. Но для большинства задач базового функционала хватает.</p><h3>Ungoogled Chromium</h3><p>Для ультраосторожных Ungoogled Chromium удаляет всё отслеживание и сервисы Google — но вам придётся настраивать всё самостоятельно, так как в нём нет автообновлений или встроенной синхронизации.</p><p>Для максимально осторожных пользователей — это Chrome, из которого убрали всю телеметрию Google, отслеживание и облачные сервисы. Браузер работает, но требует ручной настройки: отсутствуют автоматические обновления и встроенная синхронизация между устройствами.</p><h3>Tor Browser</h3><p>Выводя приватность на следующий уровень, Tor Browser маршрутизирует ваш трафик через сеть Tor, анонимизируя ваш IP и многократно шифруя соединение. Он медленнее по задумке, но идеален, если ваш приоритет — максимальная анонимность, а не скорость или удобство.</p><h3>Vivaldi</h3><p>Vivaldi — браузер мечты для тех, кто хочет полного контроля. Стекирование вкладок, тайлинг, кастомные горячие клавиши, встроенная почта и календарь, веб-панели — это полноценный десктопный опыт внутри браузера. Хотите боковую панель браузера, открывающую ваши заметки, RSS-ленты или любой нужный сайт? Vivaldi это умеет.</p><h3>Arc</h3><p>Наконец, Arc — когда-то новичок на рынке браузеров, нацеленный на переосмысление UX: замена традиционной панели вкладок на боковую панель, акцент на веб-приложениях, интегрированные разделённые виды и easels для заметок и доски. К сожалению, компания за Arc прекратила разработку, чтобы полностью переключиться на ИИ с новым браузером, который сейчас в закрытой бета-версии.</p><h2>Управление паролями</h2><ul><li><b>Лучший бесплатный выбор:</b> Bitwarden</li><li><b>Также отлично:</b> 1Password, Dashlane, KeePass</li></ul><p>Миллионы людей продолжают использовать одни и те же слабые пароли на всех сайтах — или, что ещё хуже, держатся за классику вроде «123456». Даже сильные пароли мало помогают, если их повторяют или забывают. Конечно, большинство браузеров предлагают встроенные менеджеры паролей, но они ограничены, привязаны к одному браузеру и менее безопасны, чем специализированные решения.</p><p>Также не будем забывать о passkeys (ключах доступа). Если говорить практически, можно сказать, что passkeys объединяют концепцию пароля и двухфакторной аутентификации (2FA) в одно плавное действие, но гораздо безопаснее и гораздо менее раздражающе.</p><h3>Bitwarden</h3><p>Полностью опенсорсный, зашифрованный и щедрый даже в бесплатной версии. Вы получаете неограниченное количество паролей, синхронизацию между устройствами и приложения для всех платформ. Премиум ($10/год) добавляет безопасный обмен файлами и инструменты 2FA. Также есть доступные семейные и командные планы.</p><h3>1Password</h3><p>Премиум-решение с отполированным интерфейсом, сильной кроссплатформенной поддержкой и отличными функциями вроде Travel Mode (режим путешествий) и полной интеграцией passkeys.</p><h3>Dashlane</h3><p>Предлагает мониторинг даркнета, интеграцию VPN и плавный пользовательский опыт. Есть бесплатный тариф с ограниченными функциями, но премиум-версия конкурентоспособна.</p><h3>KeePassXC</h3><p>Отличная оффлайн-альтернатива, если хотите полного контроля и не против ручной синхронизации (или использования чего-то вроде Syncthing или Dropbox для синхронизации базы данных).</p><p>Пропустите LastPass — когда-то фаворит, он упал в немилость после повторных утечек безопасности. Для душевного спокойствия лучше поискать в другом месте.</p><h2>Продвинутые утилиты и дополнения к ОС</h2><ul><li><b>Поиск + лаунчеры:</b> Everything или Wox (Windows), Alfred или Raycast (macOS)</li><li><b>Пакетные менеджеры: </b>WinGet, Homebrew (macOS)</li><li><b>Для пользователей Windows:</b> PowerToys</li><li><b>Для пользователей Mac: </b>Rectangle</li><li><b>История буфера обмена: </b>ClipClip, Flycut (macOS)</li><li><b>Скриншоты + аннотации: </b>Monosnap</li></ul><h3>Winget</h3><p><b></b>Официальный менеджер пакетов Microsoft, встроенный в Windows 10 и 11. Работает похоже на Chocolatey, но разработан и поддерживается Microsoft. Homebrew — самый популярный менеджер пакетов для macOS. Позволяет быстро устанавливать, обновлять и управлять приложениями и CLI-инструментами с помощью команд в терминале.</p><h3>Everything</h3><p>Что касается поиска, Everything остаётся золотым стандартом сверхбыстрого поиска по именам файлов в Windows. Он индексирует диски за секунды и выдаёт почти мгновенные результаты с минимальной нагрузкой на систему. Если нужен функционал шире базового поиска, Wox использует движок Everything и добавляет мощные возможности лаунчера: поиск файлов, запуск приложений, калькулятор, перевод текста и расширения через плагины. Получается более гибкий опыт в духе Spotlight для Windows.</p><h3>Command Palette/Alfred/Raycast</h3><p>В который раз Microsoft не смогла существенно улучшить встроенный поиск Windows, хотя <b>Command Palette</b> в PowerToys даёт неплохой компромисс для тех, кто не хочет ставить сторонние утилиты.</p><p>На macOS <b>Alfred</b> по-прежнему главный лаунчер и утилита поиска. Он быстрый, интуитивный и в бесплатной версии включает историю буфера и настраиваемые поиски; расширенная автоматизация и «воркфлоу» доступны в Powerpack.</p><p>Тем, кто хочет современную облачно-интегрированную альтернативу с готовыми расширениями и встроенной поддержкой Notion, GitHub и Slack, стоит присмотреться к <b>Raycast</b> — это стильный, дружественный к разработчикам вариант, который стремительно набирает популярность.</p><h3>Менеджеры буфера обмена</h3><p>Они позволяют возвращаться к ранее скопированному — тексту, изображениям, ссылкам — и сильно ускоряют рутинные операции.</p><p>В Windows встроенная история буфера (Win + V) кое-как выручает, но продвинутым пользователям обычно хочется большего. В числе бесплатных рекомендаций — <b>ClipClip</b> для Windows и <b>Flycut</b> для macOS.</p><p>Когда речь о скриншотах и аннотациях, штатные инструменты macOS и Windows заметно выросли. Но многим всё равно удобнее сторонние решения. Нам по-прежнему нравится <b>Monosnap</b> за простоту и возможность мгновенно заливать снимки в облако для шаринга (и это бесплатно).</p><p><b>PowerToys</b> — набор полезных утилит от Microsoft для продвинутых пользователей Windows, повышающих продуктивность и упрощающих рабочие процессы. Среди инструментов: FancyZones для продвинутого раскладывания окон, PowerRename для пакетного переименования, Keyboard Manager для ремапинга клавиш, универсальный color picker и другие.</p><p><b>Rectangle</b> и <b>Magnet </b>— два самых популярных приложения на macOS для закрепления окон: быстрые выравнивание и ресайз по хоткеям или перетаскиванием, примерно как по умолчанию в Windows. Пользователям, пришедшим с Windows и скучающим по системному снапингу, одно из них жизненно необходимо.</p><p>Широко используемая альтернатива в Windows — <b>FancyZones</b> (часть PowerToys), предлагающая продвинутое управление окнами: настраиваемые сетки, зоны привязки и поддержку нескольких мониторов — поэтому это фаворит пауэр-пользователей на Windows.</p><h2>Для рутины и создания проектов</h2><ul><li><b>Бесплатные инструменты: </b>FreeOffice, LibreOffice и WPS Office</li><li>Microsoft Office за единовременную плату $49, Office 2024 — $129</li><li><b>Заметки: </b>Notion, OneNote, Obsidian</li><li><b>Бесплатный PDF-редактор: </b>PDFsam</li><li><b>Почтовые клиенты:</b> Thunderbird, eM Client</li></ul><p>Независимо от того, пишете ли вы тексты, планируете проект, кодите или наводите порядок в цифровой жизни, правильные инструменты решают многое. Сегодня выбор топовых приложений для продуктивности и разработки — часто бесплатных — лучше, чем когда-либо.</p><p><b>Microsoft Office</b> остаётся отраслевым стандартом для профессиональной продуктивности. Подписка Microsoft 365 открывает доступ к Word, Excel, PowerPoint, Outlook и включает 1 ТБ облачного хранилища.</p><p>Среди бесплатных альтернатив LibreOffice — мощный open-source комплект с сильным сообществом (хотя интерфейс некоторым кажется старомодным). Если нужна внешне более майкрософтовская альтернатива, попробуйте<b> FreeOffice </b>или <b>WPS Office Free</b> — у них хорошая совместимость.</p><p>На macOS <b>Pages</b>, <b>Numbers</b> и <b>Keynote</b> предустановлены и более чем достаточны для большинства задач, особенно если вы в экосистеме Apple.</p><h3>Знания и ведение заметок</h3><p><b>Notion</b> стал универсальной платформой организации: заметки, базы данных, to-do, управление проектами, создания совместных рабочих пространств. Если нужны более локальные заметки с синхронизацией между устройствами и поддержкой Markdown, <b>Obsidian</b> — любимец студентов и исследователей.</p><p>Для быстрых кроссплатформенных заметок <b>OneNote</b> — крепкий бесплатный вариант от Microsoft. В качестве альтернатив — <b>Simplenote</b> или open-source <b>Joplin</b>.</p><p>Если вы занимаетесь академической работой и научными статьями, <b>Zotero</b> — отличный open-source менеджер источников с интеграцией в браузер и совместными коллекциями. <b>Milanote</b> предлагает визуальный подход к заметкам и планированию — идеально для креативных пользователей.</p><h3>Работа с PDF</h3><p>Хотя Adobe Acrobat остаётся премиальным редактором PDF, бесплатные альтернативы вроде <b>PDFsam</b> позволяют без усилий объединять, разбивать, редактировать и поворачивать страницы.</p><h2>Инструменты для дизайна и создания контента</h2><p>Для дизайна два выделяющихся приложения хорошо дополняют набор продуктивности. <b>Figma Desktop</b> — совместная платформа интерфейс-дизайна, широко используемая UI/UX-дизайнерами и фронтенд-разработчиками. Десктоп-версия работает быстрее, чем браузер, и лучше интегрируется с ОС — это удобно для сложных дизайн-систем и коллаборации в реальном времени.</p><p><b>Canva</b> с интуитивным drag-and-drop превосходно чувствует себя и как десктоп-приложение. Отлично подходит для быстрых графических материалов для соцсетей, маркетинга, постеров и презентаций. Благодаря тысячам шаблонов и совместной работе это фаворит как у профи, так и у новичков.</p><h2>Почтовые клиенты</h2><p>Если вы предпочитаете отдельный почтовый клиент, у <b>eM Client</b> много функций, бесплатный — до двух аккаунтов. <b>Mozilla</b> <b>Thunderbird</b> — мощная open-source альтернатива с удобной настраиваемостью, а <b>Mailbird</b> — вариант с упором на продуктивность для тех, кого не пугает подписка.</p><h2>Инструменты разработчика</h2><ul><li><b>Редакторы кода и текста:</b> VS Code, Cursor, Sublime Text</li><li><b>Система контроля версий:</b> SourceTree, GitHub Desktop</li><li><b>Контейнеры: </b>Docker</li><li><b>Локальные LLM: </b>Ollama</li><li><b>SFTP, загрузка файлов:</b> WinSCP, Forklift</li></ul><p>Для разработчиков <b>Visual Studio Code</b> — безусловный вариант. Бесплатный, лёгкий, но мощный, кроссплатформенный — тысячи расширений покрывают практически любой язык, фреймворк или инструмент. Набирающая популярность альтернатива — <b>Cursor</b>, редактор на базе VS Code с усиленной AI-помощью. Он подходит для связки с LLM: даёт inline-подсказки, генерирует код, рефакторит и позволяет редактировать кодовую базу.</p><p>При этом<b> Sublime Text </b>остаётся для скорости и простоты, а <b>Notepad++</b> — отличный лёгкий редактор для быстрых правок в Windows.</p><p>Для Git графические клиенты <b>SourceTree</b> и <b>SmartGit</b> дают понятный интерфейс для управления репозиториями на GitHub, GitLab и не только. <b>GitHub Desktop</b> раньше был простоват и не слишком хорош, но сейчас существенно прибавил — всё ещё простой для работы, но в хорошем смысле.</p><p>Для локальных окружений, API-тестирования или терминального воркфлоу инструментов — пруд пруди. Например, <b>Docker Desktop</b> стал стандартом для тех, кто собирает и запускает контейнеризированные приложения на разных платформах. Он упрощает настройку окружений и держит систему чистой.</p><p><b>Ollama</b> позволяет запускать большие языковые модели (LLM) локально с минимальной настройкой. Поддерживает модели вроде LLaMA, Mistral и другие open-weight альтернативы GPT, так что можно работать с ИИ прямо на своём компьютере без отправки данных в облако.</p><p>Если вы работаете с облачными хранилищами или SFTP, WinSCP (Windows) и ForkLift (macOS) — отличные клиенты с двухпанельным управлением файлами, синхронизацией и автоматизацией. На Mac также популярны <b>Commander One</b> и <b>Transmit</b> — у них есть встроенные подключения к удалённым и облачным путям.</p><h3>Безопасность</h3><p>И Windows, и macOS сегодня предлагают более чем достойную встроенную защиту. С защитой в реальном времени, интеграцией с файерволом и биометрией вроде <b>Windows Hello</b> и <b>Touch ID</b>. Для обычных пользователей, которые соблюдают гигиену безопасности: не скачивают сомнительное ПО, используют менеджеры паролей и включают 2FA — встроенной защиты часто хватает.</p><p>Для продвинутых пользователей есть дополнительные варианты.</p><p>Отличное первое дополнение — <b>Malwarebytes</b>. Это давний фаворит в обнаружении и удалении malware, adware и руткитов; бесплатная версия по-прежнему хороша для ручных сканов. В платной — защита в реальном времени без ощутимой просадки производительности.</p><p>Если не хочется ставить традиционный антивирус, есть достойные альтернативы. <b>Emsisoft Emergency Kit</b> — мощный портативный сканер, который можно запускать с флешки: идеально для редких глубоких сканов или лечения заражённых систем без установки чего-либо. Просто подключаете, когда нужно.</p><p>Ещё один отличный инструмент — <b>VirusTotal</b>: бесплатный веб-сервис, который проверяет файлы и URL через десятки антивирусных движков. Прежде чем открывать подозрительную загрузку, можно залить файл на VirusTotal.com или использовать их расширение для браузера, чтобы проверять ссылки в реальном времени. Быстро, просто и удобно для осторожных пользователей.</p><p>Мы не поклонники установки антивирусов на каждый компьютер и не полностью в курсе, какие сейчас показывают лучшие результаты. Тем не менее, <b>AV-Tes</b>t давно и регулярно оценивает популярные решения, поэтому советуем смотреть их свежие отчёты. В текущем списке высокооценённых — <b>Avast, BitDefender, ESET </b>и другие; многие из них предлагают бесплатные версии для пробы.</p><h3>Удалённый доступ и вспомогательные утилиты</h3><p><b>RustDesk</b> стал современным, ориентированным на приватность аналогом <b>TeamViewer</b>. Он с открытым исходным кодом, быстрый и работает кроссплатформенно.</p><p>Тем, кому нужны более устоявшиеся коммерческие решения, подойдёт <b>AnyDesk</b>, который остаётся лёгким и надёжным вариантом для личного и командного использования.</p><p>Превращение смартфона в пульт дистанционного управления компьютером бывает невероятно удобно — будь то презентации, потоковое видео или просто навигация с дивана.</p><p><b>Remote Mouse</b> — простой и эффективный способ эмулировать мышь и клавиатуру с телефона. Для более продвинутых сценариев можно использовать приложения вроде <b>Unified Remote.</b></p><h2>Редактирование изображений и видео</h2><ul><li><b>Профессиональный видеомонтаж:</b> DaVinci Resolve</li><li><b>Простой видеомонтаж: </b>CapCut</li><li><b>Редакторы изображений:</b> GIMP, PhotoDemon, Pixelmator Pro</li><li><b>Бесплатное улучшение изображений:</b> Upscayl</li><li><b>RAW-редактирование:</b> RawTherapee</li><li><b>Видеоконвертация:</b> HandBrake</li></ul><p>Если вам нужен бесплатный инструмент для редактирования изображений, <b>GIMP</b> — один из самых мощных вариантов. Он предоставляет профессиональные возможности, такие как слои, маски и настраиваемые плагины, что делает его идеальным для продвинутых пользователей. Если вы ищете более лёгкий редактор с чистым интерфейсом, стоит обратить внимание на <b>PhotoDemon</b>. Он работает как портативное приложение на Windows, поддерживает слои и редактирование — отличный выбор для быстрых правок или ретуши.</p><p>Если вы хотите увеличивать разрешение изображений без потери качества, <b>Upscayl</b> — мощный и бесплатный инструмент для апскейла. Он кроссплатформенный, и по нашим тестам показывает результаты на уровне платных решений вроде Topaz.</p><p>Для векторной графики — логотипы, иллюстрации — <b>Inkscape</b> является достойным open-source вариантом с полной поддержкой редактирования SVG. <b>Krita</b> — ещё один отличный бесплатный инструмент, особенно подходящий для цифровой живописи и художественного творчества.</p><p>Для редактирования RAW-фотографий, <b>Darktable</b> и <b>RawTherapee</b> — два высококлассных open-source аналога Adobe Lightroom. Их широко используют фотографы, которым нужна работа с изображениями без подписки.</p><p>Для простых GIF-анимаций <b>ScreenToGif</b> — удобная утилита, мгновенно записывающая область экрана и экспортирующая в GIF или другие форматы с оверлеями.</p><p>Среди платных фоторедакторов <b>Adobe Photoshop</b> остаётся лидером, но для macOS есть <b>Pixelmator Pro</b> — мощное приложение с разовой оплатой, а <b>Affinity Photo</b> предлагает профессиональные возможности по более доступной цене.</p><h3>Видеомонтаж и конвертация</h3><p><b>DaVinci Resolve</b> считается лучшим бесплатным профессиональным ПО. Его используют и энтузиасты, и профессионалы — от простого тримминга до цветокоррекции и сложного постпродакшена.</p><p><b>Shotcut</b> и <b>Kdenlive</b> — тоже сильные бесплатные варианты, предлагают более простой фукнционал с хорошим набором функций для новичков и продвинутых пользователей. <b>CapCut</b>, изначально мобильное приложение, теперь доступен на десктопе — идеально подходит для быстрых монтажей и роликов для соцсетей.</p><p>Для пользователей macOS <b>iMovie </b>предустановлен и остаётся надёжным вариантом для базовых видео. Если вам нужно просто конвертировать или сжимать видео в современные форматы, <b>HandBrake</b> — проверенное бесплатное решение с поддержкой и вариацией входных и выходных форматов.</p><p>Тем, кто ищет топовый профессиональный монтаж, подойдут <b>Adobe Premiere Pro</b> и<b> Final Cut Pro</b>, но там есть дорогая подписка и более высокий порог входа.</p><h2>Коммуникации и совместная работа</h2><ul><li><b>Для повседневной связи: </b>WhatsApp, Messenger и Zoom, если у вас нет FaceTime</li><li><b>Для приватности: </b>Signal</li><li><b>Для работы:</b> Slack, Teams</li><li><b>Для игр и общения: </b>Discord</li></ul><p>Выбор коммуникационных и мессенджерных приложений в первую очередь зависит от того, с кем вы общаетесь — с семьёй, друзьями, коллегами или игровым сообществом. Вот актуальная картина:</p><p>Для личной переписки <b>WhatsApp</b> и <b>Facebook Messenger</b> остаются самыми массовыми платформами по всему миру. У них есть десктопные клиенты и встроенное сквозное шифрование по умолчанию. <b>Telegram</b> также крайне популярен благодаря синхронизации между устройствами и поддержке крупных чатов. Пользователи Apple продолжают активно использовать <b>iMessage</b> для приватного, шифрованного общения в экосистеме Apple.</p><p>Из видеоконференций <b>Zoom</b> остаётся одним из лидеров для групповых звонков и онлайн-ивентов, предлагая локальные записи, демонстрацию экрана и комнаты (breakout rooms). Однако бесплатный тариф ограничивает 1:1 звонки 40 минутами, если не перейти на платный план. Zoom поддерживает сквозное шифрование, но при включении E2EE отключаются некоторые функции вроде облачной записи и комнат.</p><p><b>Google Meet</b> — отличный браузерный аналог без необходимости установки, который заметно улучшился по качеству и удобству использования. Многие компании применяют Meet в ежедневной работе и гибридных форматах. Если ваша организация использует Microsoft 365, скорее всего, вы работаете в <b>Microsoft Teams</b>, который уже заменил Skype на корпоративном уровне. Teams поддерживает большие созвоны, обмен файлами и глубоко интегрирован с Office. Сквозное шифрование доступно, но только для 1:1 звонков.</p><p><b>FaceTime</b> по-прежнему отличный для пользователей Apple, и благодаря новым обновлениям к звонку теперь могут присоединяться и пользователи Android/Windows по ссылке через браузер.</p><p>Когда приватность критична, <b>Signal</b> — один из лучших вариантов. Разработан некоммерческой организацией, бесплатен, open-source, без рекламы, использует надёжное сквозное шифрование для сообщений и звонков.</p><p>Для рабочих коммуникаций<b> Slack</b> и <b>Teams</b> продолжают использоваться в бизнес-среде. Бесплатный тариф Slack ограничивает историю 90 днями и звонки, но остаётся любимцем стартапов и малых команд благодаря интеграциям и ботам. <b>Cisco Webex</b> — также крепкий вариант, особенно популярен в корпоративной среде.</p><p>Если вы работаете с креативными командами, сообществами или геймерами, <b>Discord</b> стал явным лидером. Изначально созданный для игр, он превратился в полноценную коллаборативную платформу с текстом, голосом и видео, стримингом экрана и ботами для автоматизации. Многие комьюнити — и даже IT-компании — используют Discord как основной рабочий инструмент.</p><p>Для внутриигрового голосового чата <b>TeamSpeak </b>остаётся олдскульным достойным вариантом: можно использовать анонимно и получать полный контроль над сервером. Встроенный чат Steam лучше, чем раньше, и помогает в игровой координации, но большинство всё же выбирает Discord.</p><h2>Гейминг, моддинг и стриминг</h2><ul><li><b>Игровые платформы: </b>Steam, Epic Games, EA App, Ubisoft, GOG</li><li><b>Последние драйверы для GPU:</b> Nvidia GeForce, AMD Radeon, Intel Arc</li><li><b>Стриминг:</b> OBS Studio</li></ul><p><b>Steam</b> остаётся центром PC-игр. Это не только магазин, но и социальная платформа, лаунчер и площадка с модами, облачными сохранениями и встроенным стримингом. Регулярные распродажи, поддержка контроллеров и сообщества делают его обязательным для любого PC-геймера.</p><p>Не менее важно установить Epic <b>Games Store</b>. Хотя библиотека меньше, он регулярно раздаёт бесплатные игры, доступные любому с аккаунтом Epic. Это также must-have, если вы играете в Fortnite.</p><p>Помните: не все издатели размещают игры на Steam или Epic. Для тайтлов EA понадобится <b>EA App (ранее Origin)</b>, для Ubisoft — <b>Ubisoft Connect</b>, для Blizzard/Activision — <b>Battle.net</b>, а GOG Galaxy не только предлагает DRM-free классику, но и может агрегировать игры из других лаунчеров.</p><p>Некоторые сверхпопулярные игры распространяются отдельно: Minecraft (через Minecraft.net или Microsoft Store), Roblox, League of Legends и Valorant (через лаунчер Riot Games). Если вы новичок и ищете что-то лёгкое, можно начать с free-to-play тайтлов или классики вроде <b>Brutal Chess</b> или <b>GZDoom</b>.</p><p>Если вы играете с геймпадом, Windows поддерживает Xbox-контроллеры из коробки. PlayStation-контроллеры теперь тоже отлично работают: Steam через <b>Steam Input </b>поддерживает DualShock 4 и DualSense практически во всех играх. При необходимости глубокой кастомизации можно использовать DS4Windows, но большинству хватает возможностей Steam.</p><p>Если вас интересует моддинг, хороший менеджер модов время в этой жизни:</p><ul><li><b>Mod Organizer 2</b> — лучший для RPG Bethesda (Skyrim, Fallout).</li><li><b>Vortex (от Nexus Mods)</b> — дружелюбный к новичкам и поддерживает широкий перечень игр.</li></ul><p>Для записи геймплея или стриминга <b>Nvidia ShadowPlay</b> и <b>AMD Radeon ReLive</b> подходят для простых задач. Но для стриминга с вебкой, сценами, оверлеями или многосценовым продакшеном <b>OBS Studio</b> — безальтернативный лидер. Он бесплатный, open-source и подходит как новичкам, так и про-стримерам (Twitch, YouTube, Kick и т.д.). <b>SignalRGB</b> помогает синхронизировать весь RGB-зоопарк и задавать динамические эффекты.</p><h2>Мониторинг железа и разгон</h2><ul><li><b>Мониторинг: </b>CPU-Z, HWMonitor, HWiNFO64</li><li><b>Настройка и разгон:</b> Afterburner, FanControl, ThrottleStop, SignalRGB</li></ul><p>Одно из первых дел, которое стоит сделать после сборки ПК — убедиться, что компоненты соответствуют ожиданиям и работают корректно. К счастью, существует много инструментов, позволяющих мониторить, тестировать и настраивать железо.</p><p>Начать стоит с <b>CPU-Z</b> — классического бесплатного инструмента, показывающего информацию о CPU, материнской плате, оперативной памяти и других компонентах. Он также умеет запускать простой стресс-тест и бенчмарк для проверки стабильности.</p><p>Для более широкого мониторинга <b>HWMonitor</b> показывает температуры, напряжения и скорости вентиляторов в реальном времени. Если нужно ещё глубже и с более гибким интерфейсом — <b>HWiNFO64</b> считается одним из лучших: поддерживает логирование датчиков и интеграцию с оверлеями (например, RTSS или Rainmeter).</p><p>Чтобы проверить хранилище, <b>CrystalDiskMark</b> измеряет скорость чтения/записи SSD и HDD — это помогает понять, соответствует ли диск заявленным характеристикам. Глубже оценить здоровье накопителя можно в <b>Hard Disk Sentinel</b>, который анализирует SMART-данные, оценивает срок службы и предлагает ограниченный ремонт.</p><p>С точки зрения охлаждения, всё больше геймеров используют утилиты для настройки вентиляторов. <b>FanControl</b> — актуальный бесплатный фаворит: поддерживает сложные кривые оборотов, привязку к датчикам, и совместим с большинством современных материнских плат. На Mac одной из лучших утилит остаётся<b> Macs Fan Control.</b></p><p>Для настройки видеокарт долгое время стандартом был <b>MSI Afterburner</b> — для разгона, настройки вентиляторов и мониторинга с RTSS-оверлеем. Однако из-за замедления обновлений многие сегодня используют встроенные утилиты от <b>Nvidia (GeForce Experience/Control Panel)</b> и <b>AMD (Adrenalin Software)</b>.</p><p>Если вы меняете видеокарту или подозреваете проблемы с драйверами, обязательно используйте <b>Display Driver Uninstaller</b> (DDU) — он полностью очищает систему от старых драйверов перед переустановкой.</p><p>Если вы играете на ноутбуке или хотите снизить нагрев и повысить автономность, <b>ThrottleStop</b> остаётся одним из лучших инструментов для андервольта CPU и настройки энергопрофилей.</p><p>Тем, кто серьёзно подошёл к разгону CPU и GPU, пригодятся фирменные инструменты вроде <b>Intel XTU (для Intel) и AMD Ryzen Master</b> — они дают контроль над частотами, напряжениями и лимитами мощности.</p><h2>Управление файлами</h2><ul><li><b>Поиск больших файлов:</b> SpaceSniffer, WizTree, Disk Drill (macOS)</li><li><b>Поиск дубликатов: </b>dupeGuru</li><li><b>Архивы и ZIP: </b>PeaZip, The Unarchiver</li><li><b>Очистка: </b>BCUninstaller, CCleaner Portable, AppCleaner (macOS)</li></ul><p>Чтобы грамотно управлять файлами и освобождать место, нужно понимать, что именно занимает пространство. На Windows популярны <b>WinDirStat и WizTree </b>— быстрые бесплатные инструменты для визуализации диска. <b>SpaceSniffer</b> предоставляет динамическую схему.</p><p>На macOS — <b>GrandPerspective и Disk Drill </b>предлагают аналогичный функционал, а <b>DaisyDisk</b> — один из самых красивых платных вариантов с молниеносным сканированием.</p><p>Если дубликаты засоряют диск, <b>dupeGuru</b> (open-source) отлично справляется с поиском повторяющихся изображений и музыки, даже слегка изменённых.</p><p>Для пакетного переименования файлов (например, фоточек с камеры) существует гибкий <b>Bulk Rename Utility</b>. Если нужно что-то попроще: <b>PowerRename</b> из PowerToys (Windows) или встроенный инструмент в <b>Finder</b> (macOS) подходят большинству.</p><p>Встроенный <b>File Explorer</b> в Windows недавно получил вкладки и стал удобнее, но <b>Files</b> (open-source) — современная альтернатива с улучшенным UX. Кто-то ещё пользуется <b>Total Commander</b> или <b>Directory Opus</b>, благодаря расширяемости и скриптам, хотя новичкам они кажутся устаревшими. Для просмотра изображений по-прежнему незаменим <b>IrfanView</b>.</p><p>Для работы с архивами, если не устраивает встроенный ZIP-менеджер Windows, скачайте <b>7-Zip</b> или <b>PeaZip</b>. На Mac лучшим бесплатным инструментом остаётся <b>The Unarchiver</b>.</p><p>Для очистки системы важно выбирать надёжные утилиты. На Windows, <b>BCUninstaller (Bulk Crap Uninstaller)</b> — один из самых проверенных для удаления программ и их хвостов. <b>BleachBit</b> и <b>Wise Disk Cleaner</b> — безопасные альтернативы <b>CCleaner</b> (лучше использовать Portable-версию, так как стационарная испортила репутацию). На Mac <b>AppCleaner</b> всё ещё любим за полное удаление приложений без мусора.</p><p>Если вы организуете большую библиотеку медиа, стоит взглянуть на open-source <b>TagSpaces</b>, позволяющий тегировать файлы локально, без облака.</p><h2>Облачное хранилище и резервное копирование</h2><ul><li><b>Простая синхронизация: </b>Dropbox, Google Drive</li><li><b>Фото между устройствами:</b> Apple iCloud, Google Photos</li><li><b>Приватность: </b>pCloud, Proton Drive, Internxt</li><li><b>Полные бэкапы:</b> Backblaze, IDrive</li></ul><h3>Базовое облачное хранилище</h3><p><b>Dropbox</b> — один из самых простых в использовании, хотя бесплатных 2 ГБ мало.</p><p><b>
Google Drive</b> — 15 ГБ бесплатно, используется Gmail, Docs и Photos. Идеален для Android.</p><p><b>
OneDrive</b> — идёт в комплекте с Windows и Microsoft 365. 1 ТБ включён в большинство Office-планов. Хотя по скорости и интерфейсу уступает Dropbox/Google.</p><p><b>
iCloud Drive</b> — лучший выбор для пользователей Apple, глубокая интеграция с macOS/iOS. Бесплатно 5 ГБ, далее по планам до 2 ТБ.</p><p><b>
Proton Drive</b> — шифрованная альтернатива от создателей ProtonMail.</p><h3>Фото и видео</h3><p>На macOS приложение <b>Photos</b> автоматически создаёт альбомы по людям и локациям, синхронизирует всё через iCloud.</p><p>На Windows мы часто рекомендуем <b>Google Photos</b>, который предлагает аналогичный набор функций и автоматизацию. Для пользователей Android — это стандарт по умолчанию. Да, раньше было безлимитно, теперь фото занимают общее место Google Drive (15 ГБ), которое быстро заканчивается.</p><h3>Полные бэкапы</h3><p>Если требуется сохранять всю систему, терабайты медиа, состояние дисков используйте отдельные сервисы резервного копирования.</p><p><b>Backblaze</b> — топ в этой категории: фиксированная цена (~$8/месяц за устройство), безлимитное хранилище, минимум настроек: установил и забыл.</p><p><b>IDrive</b> — более контролируемый вариант, поддерживает несколько устройств, внешние диски и версионность файлов.</p><p>Простой для не-технарей — <b>Carbonite</b>, с возможностью быстрого восстановления и круглосуточной поддержкой.</p><p>Профессионалам — <b>Acronis Cyber Protect</b>: клон дисков, анти-вымогатель, гибридное облако.</p><h3>Для особо чувствительных данных</h3><p>Если вы храните личные финансовые документы или медицинские сведения, стоит выбрать end-to-end решений.</p><p><b>pCloud</b> предлагает клиентское шифрование (через платный «Crypto»). Даже при взломе аккаунта файлы не расшифруются без ключа.</p><p><b>Proton Drive </b>— аналогичный подход, с прозрачностью open-source.</p><h2>Прочие полезные инструменты, не вошедшие в другие разделы</h2><p><b>Google Earth</b> — для любителей карт и планировки.</p><p><b>qBittorrent</b> — лучший torrent-клиент: чистый, без рекламы, с поиском. Альтернатива — легковесный Transmission или кастомизируемый Deluge.</p><p><b> iMazing</b> — must-have для владельцев iPhone: резервные копии, экспорт медиа, проверка батареи, конвертация HEIC.</p><p><b>AirDroid</b> — аналог для Android: управление файлам, уведомления, SMS с ПК.</p><p><b>Rufus</b> — лидер по созданию загрузочных USB-дисков для Windows/Linux.</p><p><b>Open Shell </b>— возвращает классическое меню «Пуск» в стиле Windows 7.</p><p><b>Stretchly</b> — напоминает делать перерывы — полезно удалёнщикам и фрилансерам.</p><p><b>AutoHotkey</b> — скриптовый движок для Windows: переназначение клавиш, макросы, автоматизация.</p><p><b>VPN: </b>бесплатные — ProtonVPN, Windscribe, TunnelBear (с лимитом). Платные — ProtonVPN, NordVPN.</p><p><b>Calibre</b> — лучшее бесплатное решение для чтения, организации и конвертации e-book (EPUB, MOBI, PDF и др.).</p><h2>Заключение</h2><p>Итак, мы прошлись по основным категориям приложений, которые стоит установить на новый компьютер. Конечно, этот список не исчерпывающий — у каждого свои задачи и предпочтения. Но если вы установите хотя бы половину из перечисленного, ваш компьютер станет гораздо удобнее и функциональнее.</p><p>Несколько советов напоследок:</p><ol><li><b>Не захламляйте систему.</b> Устанавливайте только то, что действительно используете. Чем меньше фоновых процессов — тем быстрее работает компьютер.</li><li><b>Следите за обновлениями.</b> Большинство программ обновляются автоматически, но некоторые требуют ручного апдейта. Свежие версии — это не только новые функции, но и закрытые уязвимости.</li><li><b>Делайте резервные копии.</b> Никакие утилиты не спасут от отказа жёсткого диска. Регулярный бэкап на внешний носитель или в облако — обязательная практика.</li><li><b>Экспериментируйте. </b>Попробуйте несколько браузеров, редакторов, плееров. То, что подходит большинству, может не подойти именно вам.</li><li><b>Читайте отзывы.</b> Перед установкой незнакомого приложения загляните на форумы или Reddit. Сообщество быстро выявляет проблемы и подводные камни.</li></ol><p>Теперь ваш компьютер готов к работе, учёбе, развлечениям — и чему угодно ещё. Главное — не забывайте, что инструменты важны, но ещё важнее то, как вы их используете. Удачи!</p>]]></content:encoded>
    </item>
    <item>
      <title>Безопасные методы работы с массивами в JavaScript</title>
      <link>https://tproger.ru/articles/bezopasnye-metody-raboty-s-massivami-v-javascript</link>
      <comments>https://tproger.ru/articles/bezopasnye-metody-raboty-s-massivami-v-javascript?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Даровская Маша]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/bezopasnye-metody-raboty-s-massivami-v-javascript</guid>
      <description><![CDATA[<p>Безопасные методы работы с массивами в JavaScript: toSorted(), toReversed() и toSpliced() вместо мутирующих sort(), reverse() и splice(). Примеры использования в React, сравнение методов и поддержка браузерами. Как писать чистый код без побочных эффектов.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/bezopasnye-metody-raboty-s-massivami-v-javascript">Безопасные методы работы с массивами в JavaScript</a>»</p>]]></description>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 24 Oct 2025 12:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Это <a href="https://allthingssmitty.com/2025/09/08/finally-safe-array-methods-in-javascript/">перевод статьи</a> Мэта Смитта (<a href="https://allthingssmitty.com/">Matt Smith</a>) — веб-разработчика, фронтенд-инженера и UX-дизайнера.</p><p>Есть веская причина, по которой многие разработчики задумываются, прежде чем использовать в JavaScript методы .sort(), .reverse() или .splice(): эти методы изменяют исходный массив. Такой побочный эффект может привести к скрытым, трудноуловимым ошибкам — особенно в приложениях с общим или реактивным состоянием.</p><p>Хорошая новость в том, что за последние пару лет в JavaScript появились новые методы работы с массивами, которые делают этот процесс более безопасным и чистым, полностью избегая мутаций:</p><ul><li>toSorted()</li><li>toReversed()</li><li>toSpliced()</li></ul><p>Эти методы возвращают копии массивов, вместо того чтобы изменять оригинал. Это небольшое, но важное обновление синтаксиса — особенно для разработчиков на React, где неизменяемость данных (immutability) — ключ к правильному управлению состоянием.</p><h2>Проблема методов, изменяющих массив «на месте»</h2><p>В JavaScript традиционные методы, такие как .sort(), .reverse() и .splice(), модифицируют сам массив, на котором были вызваны:</p><p>В таких фреймворках, как React, это может привести к непредсказуемому поведению при обновлении состояния, поскольку прямое изменение массивов не вызывает повторный рендер.</p><h2>Сравнение старых и новых методов</h2><ul><li>Для сортировки вместо arr.sort(), который изменяет исходный массив, теперь можно использовать arr.toSorted(), возвращающий новый.</li><li>Для обратного порядка вместо arr.reverse() следует применять arr.toReversed(), чтобы сохранить оригинал.</li><li>Для удаления или вставки элементов вместо arr.splice() можно использовать arr.toSpliced(), который создаёт копию массива с изменениями, не трогая исходный.</li></ul><p>Эти новые методы работают так же, как и их «изменяющие» аналоги, но вместо модификации исходного массива возвращают новый.</p><p>⚠️ Важно: это <a href="https://developer.mozilla.org/en-US/docs/Glossary/Shallow_copy">поверхностные копии</a>, поэтому если массив содержит объекты, сами объекты останутся теми же ссылками, а не новыми экземплярами.</p><h2>Решение: безопасные, не изменяющие оригинал методы</h2><p>В стандарте ES2023 появились новые версии привычных методов массивов, которые не изменяют исходный массив:</p><p>toSorted() — создаёт отсортированную копию массива, не затрагивая оригинал.</p><p>Вы также можете передать собственную функцию сравнения — точно так же, как в методе .sort():</p><p>toReversed() — возвращает обратную копию массива, не изменяя исходный порядок элементов в оригинале.</p><p>Отлично подходит для случаев, когда нужно вывести список в обратном порядке, не изменяя исходный массив.</p><p>toSpliced() — это более безопасная альтернатива методу .splice(). Она возвращает новый массив с добавленными или удалёнными элементами, не затрагивая оригинал.</p><p>Напоминание: метод .splice() возвращает удалённые элементы, а .toSpliced() — обновлённый массив.</p><h2>Почему это важно в React</h2><p>В React неизменяемость данных — ключевой принцип, который обеспечивает обновление компонентов и предсказуемость состояния.</p><p>Новые методы позволяют работать с массивами как с неизменяемыми структурами данных, не прибегая к использованию structuredClone() или сложных обходных решений для глубокой копии.</p><h2>Практический пример: сортировка задач в React</h2><p>Вот как можно использовать toSorted() или toReversed() в компоненте, чтобы безопасно отображать динамические списки, не изменяя исходные данные:</p><p>Такой подход избегает изменения массива tasks, что особенно важно, если он передан через props или вычисляется из state — в противном случае могут возникнуть ошибки. Кроме того, использование операторов опциональной цепочки (?.) и объединения с null (??) помогает предотвратить сбои, если tasks окажется undefined.</p><p>И это ещё не всё! Оба этих оператора — опциональная цепочка и nullish coalescing — улучшения синтаксиса, делающие код более надёжным и устойчивым к ошибкам во время выполнения, приближая его к современному стандарту JavaScript.</p><h2>Маленькое изменение в синтаксисе — большое улучшение</h2><p>Эти методы не требуют нового подхода к мышлению — это просто безопасные, неизменяемые версии уже привычных вам инструментов. Если вы работаете в современной среде (или используете сборщики вроде Babel или SWC), вы можете начать применять их уже сегодня.</p><h2>Поддержка браузерами</h2><p>Методы toSorted(), toReversed() и toSpliced() поддерживаются во всех современных средах:</p><p>✅ Chrome / Edge — с версии 110+</p><p>✅ Safari — с версии 16+</p><p>✅ Firefox — с версии 115+</p><p>✅ Node.js — с версии 20+</p><p>Для старых окружений можно использовать полифил, например, из библиотеки <a href="https://www.npmjs.com/package/core-js">core-js</a>.</p><h2>Основные выводы</h2><p>Метод .toSorted() возвращает отсортированную копию массива, не изменяя оригинал. Метод .toReversed() создаёт новый массив в обратном порядке, также без мутаций исходного. Метод .toSpliced() возвращает изменённую копию массива — с добавленными или удалёнными элементами, но оригинальный массив остаётся нетронутым.</p><p>ES2023 принёс не только заметные обновления вроде опциональной цепочки и<a href="https://allthingssmitty.com/2025/06/16/using-await-at-the-top-level-in-es-modules/"> top-level await,</a> но и такие, казалось бы, мелкие улучшения, которые делают код чище, понятнее и безопаснее. Попробуйте использовать новые методы в своих проектах — и вы больше не будете смотреть на .sort() с тем же доверием.</p>]]></content:encoded>
    </item>
    <item>
      <title>JavaScript: как логические операторы присваивания упрощают код и повышают читаемость</title>
      <link>https://tproger.ru/articles/javascript--kak-logicheskie-operatory-prisvaivaniya-uproshhayut-kod-i-povywayut-chitaemost</link>
      <comments>https://tproger.ru/articles/javascript--kak-logicheskie-operatory-prisvaivaniya-uproshhayut-kod-i-povywayut-chitaemost?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Даровская Маша]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/javascript--kak-logicheskie-operatory-prisvaivaniya-uproshhayut-kod-i-povywayut-chitaemost</guid>
      <description><![CDATA[<p>null</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/javascript--kak-logicheskie-operatory-prisvaivaniya-uproshhayut-kod-i-povywayut-chitaemost">JavaScript: как логические операторы присваивания упрощают код и повышают читаемость</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 22 Oct 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Это<a href="https://allthingssmitty.com/2025/07/28/logical-assignment-operators-in-javascript-small-syntax-big-wins/"> перевод статьи Мэта Смитта</a> (<a href="https://allthingssmitty.com/">Matt Smith</a>) — веб-разработчика, фронтенд-инженера и UX-дизайнера.</p><p>В повседневной работе с JavaScript нам часто приходится проверять значение переменной перед тем, как присвоить ей новое. Подобные проверки быстро превращаются в шаблон, особенно если вы работаете с props в компонентах, глобальными настройками или объектами состояния.</p><p>Именно здесь на помощь приходят логические операторы присваивания — компактное нововведение стандарта ES2021, которое позволяет сократить типичные условные конструкции, не меняя при этом саму логику кода.</p><h2>Что такое логические операторы присваивания?</h2><p>Логические операторы присваивания объединяют обычный логический оператор (||, &amp;&amp; или ??) с оператором присваивания (=), создавая короткую и наглядную запись.</p><p>По сути, это синтаксический сахар, позволяющий писать условное присваивание в одну строку. При этом они работают по тому же принципу, что и обычные логические выражения: правая часть вычисляется только в том случае, если левая не проходит логическую проверку — то есть оказывается falsy, truthy или nullish (в зависимости от конкретного оператора).</p><p><b>Примечание: </b>Оператор опциональной последовательности (?.) нельзя использовать в левой части логического присваивания.</p><p>Попытка сделать это приведёт к синтаксической ошибке:</p><p>Если нужно безопасно присвоить значение, используйте обычную проверку или промежуточную переменную:</p><p>Оператор опциональной последовательности (?.) возвращает значение свойства, а не ссылку на само свойство.</p><p>А поскольку в JavaScript присваивание возможно только в том случае, если левая часть выражения является ссылкой (например, переменной или свойством объекта), использование ?. в левой части делает выражение некорректным.</p><h2>Логическое присваивание через OR (||=)</h2><p>Оператор ||= выполняет присваивание только тогда, когда значение слева является ложным (falsy) — то есть false, 0, “”, null, undefined или NaN.</p><p>Присвоить, если значение — falsy.</p><p>Это эквивалент записи:</p><p>Этот оператор удобен, чтобы задать значение по умолчанию, если переменная ещё не инициализирована. Однако он перезаписывает такие значения, как 0, ” или false, даже если они были установлены специально.</p><p>Другой способ задать значения по умолчанию — использовать параметры функций с дефолтными значениями. Подробнее об этом можно прочитать в <a href="https://allthingssmitty.com/2025/06/29/default-parameters-your-code-just-got-smarter/">статье о параметрах по умолчанию</a> в JavaScript.</p><h2>Логическое присваивание через AND (&amp;&amp;=)</h2><p>Присвоить, если значение — truthy:</p><p>Этот оператор полезен, когда нужно обновить значение только при наличии уже существующего truthy значения.</p><p><b>Примечание: </b>при использовании &amp;&amp;= правая часть выражения вычисляется только если левая часть является truthy, и результат этого вычисления присваивается, даже если он окажется falsy.</p><p>Исходное значение (true) играет роль «ворот»: именно оно определяет, выполняется ли присваивание.</p><p>Однако новое значение берётся из результата вызова checkPermissions (или любого выражения справа).</p><p>Важно: оператор &amp;&amp;= не сохраняет старое значение, а заменяет его результатом вычисления правой части.</p><h2>Присваивание через nullish-оператор (??=)</h2><p>Присвоить, если значение — null или undefined:</p><p>Эквивалентно:</p><p>Используйте ??=, когда нужно задать значение только если переменная действительно отсутствует — то есть равна null или undefined, а не просто falsy. В отличие от ||=, этот оператор сохраняет корректные значения, такие как 0, false и ”.</p><p>Подробнее: если хотите глубже разобраться в механике nullish-оператора и принципах работы с дефолтными значениями — посмотрите <a href="https://allthingssmitty.com/2025/04/10/mastering-default-values-in-javascript-with-the-nullish-coalescing-operator/">материал о том, как грамотно использовать значения по умолчанию в JavaScript</a>.</p><h2>Значения по умолчанию для пропсов компонентов</h2><p>Логические операторы присваивания особенно удобны при работе с пропсами в компонентах.</p><p>Например, если часть значений не передана, можно задать дефолты прямо в коде:</p><p>Такой подход:</p><ul><li>делает код компактнее и читаемее,</li><li>избавляет от лишних if или тернарных выражений,</li><li>позволяет контролировать поведение пропсов при разных типах значений (null, undefined, false, ”).</li></ul><p>Идеально подходит для случаев, когда вы хотите задать понятные значения по умолчанию, не ломая текущую логику компонента.</p><h2>Важно учитывать</h2><ul><li>Оператор ||= срабатывает, когда левая часть — falsy-значение (0, ”, false, null, undefined). Это может привести к нежелательному перезаписыванию:</li></ul><ul><li>Используйте ??= если нужно проверять только на null или undefined, сохраняя корректные falsy-значения (0, ”, false).</li><li>Правая часть вычисляется только при необходимости, что сохраняет производительность и предотвращает побочные эффекты:</li></ul><h2>Пример с побочным эффектом</h2><p>В этом примере:</p><ul><li>Изначально obj.val равно 0, что является falsy. Поэтому выражение ++calls вычисляется и присваивается obj.val.</li><li>После первой строки obj.val становится 1 (truthy).</li><li>На второй строке условие уже не выполняется, и ++calls не вызывается.</li></ul><p>В результате значение calls остаётся равным 1, потому что вторая операция не выполняет инкремент.</p><h2>Поддержка браузерами</h2><p>Логические операторы присваивания поддерживаются всеми современными окружениями:</p><p>✅ Chrome 85+, Firefox 79+, Safari 14+, Edge 85+</p><p>✅ Node.js 15+</p><p>❌ Internet Explorer — не поддерживается</p><p>Если нужно обеспечить работу в старых окружениях, используйте транспайлер, например, @babel/preset-env с настройками ES2021.</p><h2>Теперь вы готовы!</h2><p>Логические операторы присваивания — небольшое, но очень полезное дополнение к JavaScript. Они делают код понятнее, уменьшают шаблонные конструкции и упрощают условную логику.</p><p>Особенно полезны они во фронтенд-разработке, например:</p><ul><li>при работе с props и state;</li><li>при задании значений по умолчанию для API;</li><li>при очистке и валидации форм.</li></ul><p>Если вы уже уверенно используете ||, &amp;&amp; и ??, переход на ||=, &amp;&amp;= и ??= будет естественным — здесь всё дело лишь в привычке.</p>]]></content:encoded>
    </item>
    <item>
      <title>Вышел Bun 1.3: full-stack рантайм, поддержка Redis и новый SQL API. Разобрались, что еще нового</title>
      <link>https://tproger.ru/news/vywel-bun-1-3--full-stack-rantajm--podderzhka-redis-i-novyj-sql-api--razobralis--chto-eshhe-novogo</link>
      <comments>https://tproger.ru/news/vywel-bun-1-3--full-stack-rantajm--podderzhka-redis-i-novyj-sql-api--razobralis--chto-eshhe-novogo?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/vywel-bun-1-3--full-stack-rantajm--podderzhka-redis-i-novyj-sql-api--razobralis--chto-eshhe-novogo</guid>
      <description><![CDATA[<p>Bun 1.3 стал full-stack рантаймом с Redis, SQL API, поддержкой MySQL и PostgreSQL, новым тест-раннером и ускорением сборки до 2,5 раз</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/vywel-bun-1-3--full-stack-rantajm--podderzhka-redis-i-novyj-sql-api--razobralis--chto-eshhe-novogo">Вышел Bun 1.3: full-stack рантайм, поддержка Redis и новый SQL API. Разобрались, что еще нового</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 13 Oct 2025 04:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Команда <b>Oven</b> <a href="https://bun.com/blog/bun-v1.3">представила</a> <b>Bun 1.3</b> — крупнейший релиз в истории JavaScript-рантайма.</p><p>Теперь Bun официально позиционируется как <b>full-stack платформа</b> для фронтенда и бэкенда. И она объединяет сервер, сборщик, менеджер пакетов вместе с тест-раннером в одном инструменте.</p><p>В новую версию добавлены десятки ключевых функций: встроенные клиенты для <b>Redis</b>, <b>MySQL</b>, <b>PostgreSQL</b> и <b>SQLite</b>, единый <b>SQL API</b>, улучшенные <b>WebSocket-модули</b>, переработанный <b>тест-раннер</b> и поддержка <b>VSCode Test Explorer</b>.</p><h2>Full-stack по-умному</h2><p>Главное новшество — режим <b>full-stack Bun.serve()</b> с поддержкой роутинга, cookies и WebSockets.</p><p>Теперь фронтенд и бэкенд можно запускать в одном процессе без проблем с CORS, а приложение собрать в <b>единый исполняемый файл</b> с помощью bun build --compile.</p><p>Разработчики могут напрямую импортировать HTML, запускать React-приложения с хот-перезагрузкой и собирать проект одной командой bun init --react. По данным команды, скомпилированные React-приложения в Bun работают <b>до 1,8 раза быстрее, чем через nginx</b>.</p><h2>Новый SQL и встроенный Redis</h2><p>Bun 1.3 представил унифицированный <b>Bun.SQL API</b> — теперь один и тот же код работает с MySQL, PostgreSQL, SQLite и MariaDB. Добавлен хелпер sql.array() для работы с массивами в PostgreSQL, улучшена поддержка JSON и Unix-сокетов.</p><p>Кроме того, в рантайм встроен <b>Redis-клиент</b>, который поддерживает 66 команд, автоматическое переподключение, очереди сообщений и Pub/Sub. По данным разработчиков, он <b>значительно быстрее ioredis</b>, а поддержка кластеров и Lua-скриптов появится в будущих релизах.</p><h2>Новые возможности</h2><p>Среди прочих улучшений — <b>Zstandard-сжатие</b>, нативная поддержка <b>YAML</b>, API для безопасного хранения секретов (<b>Bun.secrets</b>), и серьезный прирост производительности: операции с криптографией ускорены <b>до 400х</b>, установка пакетов — <b>до 2,5х</b>.</p><p>Также обновлен менеджер пакетов с <b>интерактивным bun update</b>, изолированными установками и API для проверки безопасности зависимостей.</p><h2>Почему это важно</h2><p>Bun 1.3 превращает экспериментальный рантайм в <b>полноценную платформу для веб-разработки</b>, способную заменить Node.js, Vite и Redis-CLI одновременно.</p><p>Разработчики называют релиз «началом новой эпохи», цель которой — сделать Bun лучшим способом писать и развертывать JavaScript-приложения.</p>]]></content:encoded>
    </item>
    <item>
      <title>Курсы Vue.js: обучение фреймворку Vue.js</title>
      <link>https://tproger.ru/articles/kursy-vue-js--obuchenie-frejmvorku-vue-js-258494</link>
      <comments>https://tproger.ru/articles/kursy-vue-js--obuchenie-frejmvorku-vue-js-258494?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Анастасия Шишкина]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kursy-vue-js--obuchenie-frejmvorku-vue-js-258494</guid>
      <description><![CDATA[<p>Лучшие курсы по фреймворку Vue.js. Рейтинг вариантов онлайн-обучения бесплатно и платно, обзор обучающей программы и стоимости курсов.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kursy-vue-js--obuchenie-frejmvorku-vue-js-258494">Курсы Vue.js: обучение фреймворку Vue.js</a>»</p>]]></description>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Обучающие курсы]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Vue]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 10 Oct 2025 10:27:21 GMT</pubDate>
      <content:encoded><![CDATA[<p>Выбирая курсы Vue.js, вы делаете осознанный шаг в сторону роста как фронтенд-разработчика. Vue.js занимает особое место среди современных фреймворков: сочетает производительность, сравнимую с React, что позволяет быстро создавать сложные SPA. Прогрессивная архитектура легко внедряется в проекты любого масштаба — от небольших виджетов до enterprise-систем. Начните учиться уже сейчас и применяйте навыки в реальных задачах — как в стартапах, так и в корпоративной разработке.</p><p>Я провела анализ около 70 учебных программ от онлайн-школ. В результате я отобрала 34 наиболее эффективных курса, разбила их на три блока: мой личный топ-10, ещё 16 курсов для углубления в специализацию и 8 бесплатных стартовых уроков для начала обучения.</p><p><b>Чтобы помочь сэкономить на старте, я добавила в описания уникальные промокоды — активируйте их при оплате и получите скидку на обучение.</b></p><h2>ТОП-10 лучших курсов Vue.js в 2026 году</h2><ol><li><a href="https://experts2.ru/vajVEe?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=1">Vue.js</a> от Skillbox — TypeScript и Vue.js через создание трех сложных проектов: каталога фильмов, аудиоплеера и блога с пожизненным доступом к материалам.</li><li><a href="https://experts2.ru/nSDtkb?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=2">Vue.js разработчик</a> от OTUS — профессиональное освоение Vue.js с персональным проектом на выбор: панель управления рассылками или модернизация CRM-системы.</li><li><a href="https://experts2.ru/vgeSGd?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=3">Фронтенд-разработчик</a> от Skillbox — 17 реальных проектов в портфолио, включая задания от Газпромбанк.Тех с гарантией трудоустройства или возвратом средств.</li><li><a href="https://experts2.ru/UczKkf?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=4">Frontend-разработчик с нуля до Middle</a> от GeekBrains — полный стек технологий от HTML до Vue.js с развитием soft skills и стажировкой у партнеров.</li><li><a href="https://experts2.ru/IQcbrf?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=5">Интенсив по программированию</a> от SkillFactory — освоение JavaScript и Vue.js с возможностью очного обучения в Москве и налоговым вычетом.</li><li><a href="https://experts2.ru/ofXFur?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=6">Vue.js</a> от html.academy — интенсивная практика с реальными задачами от IT-компаний и персональной карьерной консультацией.</li><li><a href="https://experts2.ru/RpPkvd?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=7">Vue.js</a> от Loftschool — два готовых проекта в портфолио: таск-менеджер и виртуальная пиццерия с поддержкой учебного центра.</li><li><a href="https://experts2.ru/svrLeW?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=8">Vue.js</a> от Level Up — интенсив с созданием SPA-приложения и персональными воркшопами от преподавателя.</li><li><a href="https://experts2.ru/rcXuYq?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=9">Vue.js</a> от Learn.Javascript — комбинированное изучение Vue.js и Nuxt.js с проектом приложения доставки еды и онлайн-трансляциями.</li><li><a href="https://experts2.ru/EbnZpv?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=10">JavaScript</a> от Специалиста — сертификат на двух языках с еженедельными вебинарами.</li></ol><p>Программы подойдут фронтенд-разработчикам, которые хотят освоить современный стек технологий для создания интерфейсов. Также курсы будут ценны для fullstack-специалистов, стремящихся углубить знания клиентской части приложений. Начинающим айтишникам Vue.js предлагает мягкий вход в профессию благодаря продуманной архитектуре и понятной документации.</p><h2>Онлайн-курсы Vue.js</h2><p><b>1. <a href="https://experts2.ru/vajVEe?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=1">Vue.js</a> | Skillbox</b></p><p><i>Используйте промокод kursfinder, чтобы получить скидку 50%</i></p><p><a href="https://experts2.ru/vajVEe?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=1">Получить скидку &gt;&gt;&gt;</a></p><p>Курс последовательно познакомит вас с TypeScript, а затем с Vue.js. Вы приобретете навыки создания сложных интерактивных веб-приложений и систем, свободных от багов и программных ошибок. В программе — разработка проектов различной сложности: каталоги фильмов, стриминговые сервисы и блог-платформы. Вы освоите написание понятного структурированного кода, что сократит время разработки и тестирования приложений. Полученные знания дополнят вашу базу в верстке и JavaScript, позволив создавать сложные веб-приложения профессионального уровня.</p><figure><img src="https://media.tproger.ru/user-uploads/108137/2025-10-10/f34c7e17-cb5f-431c-b27b-71fd120603c5.jpg" alt="" /></figure><ul><li>Стоимость: 99 672 рубля</li><li>Длительность: 2 месяца</li><li>Формат обучения: видеолекции, практика, тренажеры</li><li>Сертификат: сертификат установленного образца</li></ul><p><b>Кому подойдет: </b></p><ul><li>фронтендерам.</li></ul><p><b>Преимущества:</b></p><ul><li>портфолио с тремя крупными проектами: каталог фильмов, аудиоплеер и блог;</li><li>решение реальных задач от партнеров курса во время практики;</li><li>пожизненный доступ ко всем материалам и будущим обновлениям;</li><li>персональная обратная связь по всем работам;</li><li>мобильная версия платформы с синхронизацией прогресса;</li><li>беспроцентная рассрочка на оплату;</li><li>налоговый вычет до 13% от стоимости обучения.</li></ul><p><b>Недостатки:</b></p><ul><li>ограниченное количество мест на курс.</li></ul><p><b>Программа обучения:</b></p><ul><li>Работа с TypeScript и современными инструментами разработки</li><li>Фундаментальные принципы Vue на практических примерах</li><li>Организация взаимодействия между компонентами</li><li>Управление состоянием страниц и приложений</li><li>Настройка хранилища Pinia для данных</li><li>Методы тестирования Vue-компонентов</li><li>Построение архитектуры и структуры проекта</li><li>Освоение Nuxt и серверного рендеринга</li><li>Анализ различий между Vue 2 и Vue 3</li><li>Дополнительные практические занятия и кейсы</li></ul><p><a href="https://experts2.ru/vajVEe?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=1">Ознакомиться с полной программой &gt;&gt;&gt;</a></p><p><b>2. <a href="https://experts2.ru/nSDtkb?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=2">Vue.js разработчик</a> | OTUS</b></p><p>Курс позволяет освоить Vue.js на профессиональном уровне, уделяя внимание архитектуре компонентов, синтаксису фреймворка и принципам реактивности. По завершении обучения вы сможете самостоятельно разрабатывать масштабируемые веб-приложения с нуля. В рамках программы предусмотрена работа над персональным проектом по выбору: создание панели управления для email-рассылок, модернизация CRM-системы или другие практические задачи. Готовый проект пополнит ваше портфолио и станет весомым аргументом при трудоустройстве в IT-сфере.</p><figure><img src="https://media.tproger.ru/user-uploads/108137/2025-10-10/143107c9-7d57-446c-a89c-70911cf3d922.jpg" alt="" /></figure><ul><li>Стоимость: 71 000 рублей</li><li>Длительность: 3 месяца</li><li>Формат обучения: онлайн-трансляции, домашние задания, проектная работа, общение с экспертами на вебинарах</li><li>Сертификат: сертификат установленного образца</li></ul><p><b>Кому подойдет: </b></p><ul><li>новичкам в Vue-разработке;</li><li>JavaScript-разработчикам с навыками CSS и HTML;</li><li>backend-разработчикам, которые хотят освоить fullstack.</li></ul><p><b>Преимущества:</b></p><ul><li>две онлайн-трансляции в неделю для прямого общения с преподавателями;</li><li>множество заданий и масштабный проект для портфолио;</li><li>детальный анализ кода от профессиональных разработчиков;</li><li>возможность начать карьеру у партнеров площадки еще во время обучения;</li><li>возврат средств при несоответствии содержания курса ожиданиям;</li><li>выбор наиболее интересной темы для проектной работы.</li></ul><p><b>Недостатки:</b></p><ul><li>необходимо ждать начало обучения;</li><li>чтобы поступить на курс, необходимо пройти обязательное тестирование.</li></ul><p><b>Программа обучения:</b></p><ul><li>Работа Vue с GraphQL</li><li>Подключение WebSockets во Vue-приложениях</li><li>Освоение TypeScript</li><li>Создание десктопных приложений на Electron</li><li>Серверный рендеринг с помощью Nuxt</li><li>Работа с библиотеками в экосистеме Nuxt</li><li>Выбор темы и организация проектной работы</li><li>Реализация интерактивных интерфейсов и Web Components</li><li>Организация кода и паттерны проектирования во Vue</li></ul><p><a href="https://experts2.ru/nSDtkb?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=2">Ознакомиться с полной программой &gt;&gt;&gt;</a></p><p><b>3. <a href="https://experts2.ru/vgeSGd?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=3">Фронтенд-разработчик</a> | Skillbox</b></p><p><i>Используйте промокод kursfinder, чтобы получить скидку 60%</i></p><p><a href="https://experts2.ru/vgeSGd?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=3">Получить скидку &gt;&gt;&gt;</a></p><p>Курс построен на практическом подходе, максимально приближенном к реальной работе. Обучение включает изучение теоретических основ с интерактивными материалами и выполнение 17 проектов для портфолио. Вы освоите полный стек технологий для создания сайтов любой сложности: HTML, CSS, Vue.js, TypeScript, JavaScript. Параллельно с техническими навыками развиваются soft skills: работа в команде, планирование задач, решение нестандартных проблем. После завершения программы карьерные консультанты помогут сформировать портфолио и подготовиться к собеседованиям в компаниях-партнерах.</p><figure><img src="https://media.tproger.ru/user-uploads/108137/2025-10-10/e955c991-d26d-435a-b482-75e233cdc626.jpg" alt="" /></figure><ul><li>Стоимость: 152 150 рублей</li><li>Длительность: 7 месяцев</li><li>Формат обучения: видеоуроки, текстовые материалы, тесты, интерактивные тренажеры, проекты</li><li>Сертификат: удостоверение о повышении квалификации</li></ul><p><b>Кому подойдет: </b></p><ul><li>тем, кто хочет построить карьеру в IT;</li><li>тем, кто хочет зарабатывать на фрилансе.</li></ul><p><b>Преимущества:</b></p><ul><li>интеграция ИИ-инструментов в рабочие процессы разработчика;</li><li>реалистичные проектные задания от компаний «Газпромбанк.Тех», WhiteMark и платформы «Маруся»;</li><li>до 17 завершенных проектов с реальными кейсами партнеров;</li><li>гарантированная помощь в поиске работы или возврат оплаты;</li><li>проверка домашних заданий в течение суток;</li><li>годовое обучение английскому для веб-разработчиков.</li></ul><p><b>Недостатки:</b></p><ul><li>не выявлено.</li></ul><p><b>Программа обучения:</b></p><ul><li>Подготовка материалов к публикации</li><li>Верстка интерактивных элементов</li><li>Создание адаптивных стилей</li><li>Верстка адаптивных блоков интерфейса</li><li>Разработка динамических интерфейсных решений</li><li>Подготовка верстки к запуску в продакшен</li><li>Углубленная работа с объектной моделью документа</li><li>Обработка и валидация пользовательского ввода</li></ul><p><a href="https://experts2.ru/vgeSGd?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=3">Ознакомиться с полной программой &gt;&gt;&gt;</a></p><p><b>4. <a href="https://experts2.ru/UczKkf?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=4">Frontend-разработчик с нуля до Middle</a> | GeekBrains</b></p><p><i>Используйте промокод kursfinder, чтобы получить скидку 7%</i></p><p><a href="https://experts2.ru/UczKkf?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=4">Получить скидку &gt;&gt;&gt;</a></p><p>Каждое занятие включает практические задания по ключевым направлениям веб-разработки. Через несколько месяцев обучения вы освоите адаптивную верстку на HTML и CSS, создание интерактивных элементов на JavaScript, проектирование макетов в Figma и работу с фреймворком Vue.js. Курс дополнен реальными задачами от компаний-партнеров — вы сможете выбрать подходящие проекты и расширить портфолио новыми работами.</p><figure><img src="https://media.tproger.ru/user-uploads/108137/2025-10-10/293170bd-c6e2-4734-bbd3-4cd44b9389aa.jpg" alt="" /></figure><ul><li>Стоимость: 142 128 рублей</li><li>Длительность: от 6 месяцев</li><li>Формат обучения: видеоуроки, онлайн-занятия по расписанию, тренажеры, мини-кейсы, персональная обратная связь</li><li>Сертификат: сертификат установленного образца</li></ul><p><b>Кому подойдет: </b></p><ul><li>людям, которые хотят освоить веб-программирование с нуля;</li><li>IT-специалистам из смежных сфер.</li></ul><p><b>Преимущества:</b></p><ul><li>персональная консультация менеджера с дополнительной скидкой;</li><li>помощь в поиске работы и стажировки у компаний-партнеров;</li><li>решение реальных задач от «Газпромбанк.Тех»;</li><li>15+ завершенных проектов с кейсами известных компаний;</li><li>индивидуальные комментарии наставников по домашним заданиям;</li><li>доступ к эксклюзивной базе предложений работы.</li></ul><p><b>Недостатки:</b></p><ul><li>в базовом тарифе нет помощи наставника и содействия в трудоустройстве.</li></ul><p><b>Программа обучения:</b></p><ul><li>Принципы работы компьютера и интернета</li><li>Освоение профессионального окружения разработчика</li><li>Эффективное взаимодействие в команде</li><li>Подготовка материалов к публикации</li><li>Создание контентных блоков и гибких компонентов</li><li>Верстка частей страницы и форм ввода</li><li>Разработка responsive-разделов и анимаций</li><li>Подготовка верстки к промышленной эксплуатации</li><li>Основы верстки в React-окружении</li><li>Реализация бизнес-логики в React-компонентах</li><li>Управление состоянием и информацией в приложении</li></ul><p><a href="https://experts2.ru/UczKkf?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=4">Ознакомиться с полной программой &gt;&gt;&gt;</a></p><p><b>5. <a href="https://experts2.ru/IQcbrf?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=5">Интенсив по программированию</a> | SkillFactory</b></p><p>Курс предоставляет комплексное освоение инструментов фронтенд-разработки с четким разграничением функционала фронтенда и бэкенда. Вы приобретете навыки верстки веб-сайтов и email-рассылок, работы с системой контроля версий и алгоритмами баз данных. А практическое взаимодействие с действующими специалистами отрасли создаст основу для профессионального старта в программировании.</p><figure><img src="https://media.tproger.ru/user-uploads/108137/2025-10-10/b9a7cf82-f60d-4ca6-a077-dd3c25abc2a0.jpg" alt="" /></figure><ul><li>Стоимость: от 104 940 рублей</li><li>Длительность: от 4 месяцев</li><li>Формат обучения: видеоуроки, вебинары, тренажеры</li><li>Сертификат: сертификат и диплом</li></ul><p><b>Кому подойдет: </b></p><ul><li>новичкам без опыта в IT.</li></ul><p><b>Преимущества:</b></p><ul><li>курсы по нейросетям и английскому языку в качестве подарка;</li><li>решение реальных задач от компаний-партнеров;</li><li>от пяти завершенных проектов для вашей коллекции работ;</li><li>возврат средств при отсутствии предложений работы;</li><li>общий чат для общения с другими участниками курса;</li><li>мероприятия и стажировки у партнеров для демонстрации навыков работодателям.</li></ul><p><b>Недостатки:</b></p><ul><li>в базовом тарифе нет курса английского для IT.</li></ul><p><b>Программа обучения:</b></p><ul><li>Создание веб-страниц</li><li>Изучение JavaScript</li><li>Освоение TypeScript и вспомогательных средств разработки</li><li>Разработка приложений на React.js</li><li>Проектирование приложений и основы бэкенда</li><li>Профессиональное ориентирование и подготовка к трудоустройству</li></ul><p><a href="https://experts2.ru/IQcbrf?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=5">Ознакомиться с полной программой &gt;&gt;&gt;</a></p><p><b>6. <a href="https://experts2.ru/ofXFur?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=6">Vue.js</a> | html.academy</b></p><p>Программа для опытных разработчиков, ориентированная на быстрое повышение квалификации. В сжатые сроки вы изучите основные возможности Vue.js и их практическое применение в разработке сайтов, онлайн-магазинов и веб-приложений. Под руководством преподавателей вы выполните два проекта — учебный таск-менеджер и авторскую виртуальную пиццерию. Готовые работы составят основу вашего портфолио для демонстрации потенциальным работодателям.</p><figure><img src="https://media.tproger.ru/user-uploads/108137/2025-10-10/c3e7e237-a710-4c90-8185-868c422520fe.jpg" alt="" /></figure><ul><li>Стоимость: от 53 760 рублей</li><li>Длительность: от 3 месяцев</li><li>Формат обучения: теоретические материалы, практические задания, проектные работы</li><li>Сертификат: нет</li></ul><p><b>Кому подойдет: </b></p><ul><li>IT-специалистам с навыками программирования на JavaScript;</li><li>людям, которые хотят погрузиться в веб-разработку с нуля.</li></ul><p><b>Преимущества:</b></p><ul><li>готовые примеры решения типовых задач;</li><li>два полноценных приложения для портфолио — таск-менеджер и виртуальная пиццерия;</li><li>бесплатная помощь в подборе курса и ответы на вопросы об обучении;</li><li>освоение технологий, востребованных у работодателей;</li><li>оперативные и подробные ответы от учебной службы.</li></ul><p><b>Недостатки:</b></p><ul><li>отсутствие документа об окончании курса;</li><li>нет возможностей для онлайн-взаимодействия с преподавателем.</li></ul><p><b>Программа обучения:</b></p><ul><li>Ключевые особенности фреймворка Vue.js</li><li>Начало работы с Vue.js</li><li>Отображение компонентов в интерфейсе</li><li>Создание компонента счетчика</li><li>Реализация функций компонентов</li><li>Конструкции: условная отрисовка и работа со списками</li><li>Типы и обработка взаимодействий</li><li>Способы связи между компонентами</li><li>Использование слотов и динамического контента</li><li>Организация двустороннего обмена данными</li><li>Обзор Vue Test Utils и Vitest</li><li>Разработка через тестирование</li></ul><p><a href="https://experts2.ru/ofXFur?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=6">Ознакомиться с полной программой &gt;&gt;&gt;</a></p><p><b>7. <a href="https://experts2.ru/RpPkvd?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=7">Vue.js</a> | Loftschool</b></p><p>Шестинедельная программа развивает компетенции веб-программирования и дополняет портфолио авторским SPA-проектом. В рамках курса изучается Vue.js для одностраничных приложений, продвинутый JavaScript, методики End-to-End и Unit-тестирования, технологии внедрения анимации. Еженедельный план содержит групповые сессии по развитию профессиональных и личностных навыков, цикл персональных воркшопов под руководством преподавателя, активную фазу реализации собственного приложения.</p><figure><img src="https://media.tproger.ru/user-uploads/108137/2025-10-10/6afa171a-bc19-4e03-8366-940a2d5f62a3.jpg" alt="" /></figure><ul><li>Стоимость: по запросу</li><li>Длительность: 6 недель</li><li>Формат обучения: теоретические материалы, практические задания, проект, групповая работа с наставниками</li><li>Сертификат: сертификат установленного образца</li></ul><p><b>Кому подойдет: </b></p><ul><li>опытным IT-специалистам.</li></ul><p><b>Преимущества:</b></p><ul><li>насыщенный учебный план с упором на практические задания;</li><li>сопровождение наставника от начала обучения до выпуска;</li><li>готовое SPA-приложение с админ-панелью для портфолио;</li><li>безлимитное использование учебных материалов;</li><li>совместная работа с группой над развитием гибких навыков;</li><li>активность в Telegram-чате с преподавателем и студентами;</li><li>помощь в старте профессионального пути в веб-разработке.</li></ul><p><b>Недостатки:</b></p><ul><li>не указана стоимость.</li></ul><p><b>Программа обучения:</b></p><ul><li>Представление наставника и участников группы</li><li>Создание макета дипломного проекта с использованием webpack</li><li>Размещение работы на GitHub для проверки наставником</li><li>Доработка верстки для разных устройств</li><li>Подключение данных из админ-панели к лендингу</li><li>Проверка компонентов приложения</li><li>Групповая разработка под руководством наставника</li><li>Финальная корректировка проекта</li><li>Сдача работы на итоговую проверку</li><li>Внесение результатов в дипломные документы</li></ul><p><a href="https://experts2.ru/RpPkvd?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=7">Ознакомиться с полной программой &gt;&gt;&gt;</a></p><p><b>8. <a href="https://experts2.ru/svrLeW?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=8">Vue.js</a> | Level Up</b></p><p>Комбинированный курс по Vue.js и Nuxt.js демонстрирует возможности фреймворков для разработки интерфейсов и веб-решений. Вы выполните практикумы, включая проект приложения доставки еды. Доступны онлайн-обучение на платформе или занятия в петербургском образовательном центре. Программа создана специально для начинающих frontend-разработчиков, которые хотят углубить знания в веб-программировании и повысить свою квалификацию.</p><figure><img src="https://media.tproger.ru/user-uploads/108137/2025-10-10/25e70162-4d98-443c-b94d-99e431004ec7.jpg" alt="" /></figure><ul><li>Стоимость: 38 990 рублей</li><li>Длительность: 1,5 месяца</li><li>Формат обучения: очные занятия с преподавателем в Санкт-Петербург или онлайн, практические задания</li><li>Сертификат: нет</li></ul><p><b>Кому подойдет:</b></p><ul><li>новичкам с базовыми знаниями JavaScript;</li><li>IT-разработчикам с опытом.</li></ul><p><b>Преимущества:</b></p><ul><li>интенсивные занятия под руководством преподавателя;</li><li>глубокое освоение расширенного стека современных инструментов;</li><li>три приложения на Vue.js и одно на Next.js;</li><li>несколько дополнительных мини-приложений для пополнения кейсов;</li><li>ведение курса опытным веб-программистом с многолетней практикой;</li><li>детальный разбор всех практических заданий.</li></ul><p><b>Недостатки:</b></p><ul><li>нет сертификата;</li><li>фиксированное расписание.</li></ul><p><b>Программа обучения:</b></p><ul><li>Знакомство с возможностями Vue.js</li><li>Переход к полноценной работе с Vue-cli</li><li>Изучение продвинутых концепций Vue</li><li>Применение роутинга и менеджеров состояний</li><li>Работа с Vuex и Pinia</li><li>Освоение Nuxt.js для production-проектов</li></ul><p><a href="https://experts2.ru/svrLeW?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=8">Ознакомиться с полной программой &gt;&gt;&gt;</a></p><p><b>9. <a href="https://experts2.ru/rcXuYq?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=9">Vue.js</a> | Learn.Javascript</b></p><p>Курс посвящен веб-разработке на Vue 3. Вы изучите функционал фреймворка, освоите различные подходы к решению профессиональных задач и реализуете проект. В работе будут применяться как готовые UI-компоненты с изменяемой конфигурацией, так и созданные самостоятельно. Помимо Vue 3, программа включает JavaScript и TypeScript. Консультации по практическим заданиям проходят на еженедельных вебинарах.</p><figure><img src="https://media.tproger.ru/user-uploads/108137/2025-10-10/bd9a724a-7f1c-4a9a-b25a-269996d62d56.jpg" alt="" /></figure><ul><li>Стоимость: 24 700 рублей</li><li>Длительность: 2 месяца</li><li>Формат обучения: онлайн-занятия, домашние задания, проектные работы</li><li>Сертификат: сертификат на двух языках</li></ul><p><b>Кому подойдет: </b></p><ul><li>IT-разработчикам со знанием основ программирования на JavaScript, CSS и HTML.</li></ul><p><b>Преимущества:</b></p><ul><li>курсовая и итоговая работы для пополнения портфолио;</li><li>документ об окончании на русском и английском языках;</li><li>регулярные онлайн-встречи с преподавателями два раза в неделю;</li><li>обширная база вводных уроков для начинающих;</li><li>групповой чат с возможностью задавать вопросы эксперту;</li><li>рецензирование домашних заданий с обратной связью;</li><li>возврат оплаты при несоответствии курса ожиданиям.</li></ul><p><b>Недостатки:</b></p><ul><li>редкий набор групп на обучение;</li><li>онлайн-трансляции проводятся в фиксированное время.</li></ul><p><b>Программа обучения:</b></p><ul><li>Изучение Vue и создание компонентов</li><li>Современные подходы к веб-программированию</li><li>Знакомство с Composables, библиотеками VueUse и Pinia</li><li>Продвинутые техники разработки на Vue</li><li>Принципы реактивного программирования и рендеринга</li><li>Практическое использование inject и provide</li><li>Применение Vue Test Utils и Vitest для тестирования приложений</li></ul><p><a href="https://experts2.ru/rcXuYq?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=9">Ознакомиться с полной программой &gt;&gt;&gt;</a></p><p><b>10. <a href="https://experts2.ru/EbnZpv?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=10">JavaScript</a> | Специалист</b></p><p>Программа повышает уровень владения JavaScript для разработки реактивных веб-форм, включая применение Vue.js. После обучения вы сможете управлять состоянием приложения, создавать сложные формы, проектировать UI-компоненты и строить сайты на Vue.js. Доступны форматы онлайн-обучения на платформе или очного посещения московского образовательного центра.</p><figure><img src="https://media.tproger.ru/user-uploads/108137/2025-10-10/2d8bb429-f1d9-4f27-a37c-b58dd40371fc.jpg" alt="" /></figure><ul><li>Стоимость: 31 990 рублей</li><li>Длительность: 36 ак.часов</li><li>Формат обучения: очно и онлайн, практика</li><li>Сертификат: сертификат установленного образца</li></ul><p><b>Кому подойдет: </b></p><ul><li>IT-специалистам, обладающим навыками веб-разработки на JavaScript;</li><li>веб-дизайнерам;</li><li>менеджерам frontend-проектов.</li></ul><p><b>Преимущества:</b></p><ul><li>несколько форматов обучения – очно, онлайн или по индивидуальному плану;</li><li>12 академических часов бесплатно для занятий в компьютерных классах образовательного центра;</li><li>дополнительная скидка до 30% при изучении курса в рамках дипломных программ;</li><li>возможность бесплатных занятий в компьютерном классе образовательного центра;</li><li>частый набор групп на очное и онлайн-обучение.</li></ul><p><b>Недостатки:</b></p><ul><li>небольшое количество практических заданий.</li></ul><p><b>Программа обучения:</b></p><ul><li>Основы программирования на Vue.js: компоненты, шаблоны, свойства</li><li>Продвинутая работа с компонентами</li><li>Создание анимаций и переходов</li><li>Разработка веб-сайтов и работа с реактивностью</li></ul><p><a href="https://experts2.ru/EbnZpv?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=10">Ознакомиться с полной программой &gt;&gt;&gt;</a></p><h2>Еще 16 дополнительных курсов Vue.js</h2><p>Погрузиться в мир современной фронтенд-разработки можно с разных сторон. Обучение Vue.js открывает перед разработчиками множество путей для профессионального роста. В подборке собраны программы, которые помогут освоить фреймворк через практику и живые примеры. Каждый найдет подходящий формат — от коротких интенсивов до фундаментальных курсов.</p><ul><li><a href="https://experts2.ru/mhcCbS?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=netop">Vue JS</a> от itProger. Оформив подписку на сайте, вы получите полный доступ к курсу по Vue JS, где научитесь создавать компоненты и собирать из них современные веб-сайты. К каждому заданию школа подготовила подробную методичку решения, готовый проект-пример и ответы для самопроверки — это поможет осваивать материал в комфортном темпе и сразу видеть, как должен выглядеть итоговый результат.</li><li><a href="https://experts2.ru/ekgBzN?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=netop">Игра на Vue.js</a> от Stepik. На курсе вы создадите полноценную игру на Vue.js — от проектирования интерфейса до программирования игровой логики на JavaScript, а затем опубликуете готовое приложение в каталоге ВКонтакте; в процессе работы вы разработаете интерактивное приложение, сгенерируете идею через чат-бот и выполните самостоятельный проект для своего портфолио.</li><li><a href="https://experts2.ru/jQuJqz?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=netop">Фреймворк Vue.JS</a> от Frontendblock. Если ваша цель — за 4 недели разобраться во всех возможностях и опциях третьей версии Vue.js, этот экспресс-курс для вас. Все уроки записаны заранее и построены по принципу «теория + практика». Ваши работы будут проверяться, а кураторы предоставят обратную связь. В процессе вы сделаете два проекта разной сложности, и они автоматически пополнят ваше портфолио. Есть три формата участия: можно учиться самостоятельно, с поддержкой куратора или выбрать полностью индивидуальный план.</li><li><a href="https://experts2.ru/ElfbQn?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=netop">Vue.js 3, Vue Router и Pinia</a> от Stepik. В этом курсе вам предстоит освоить Vue, Vue Router и Pinia на практике, создавая два полноценных приложения. Вы разработаете сервис для отображения прогноза погоды и SaaS-платформу для хранения веб-закладок. Курс идеально подойдет тем, кто уже уверенно чувствует себя в основах HTML, CSS и JavaScript и готов погрузиться в изучение одного из самых востребованных фронтенд-фреймворков — Vue.js.</li><li><a href="https://experts2.ru/CtxhTz?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=netop">Frontend разработчик на HTML, CSS и JavaScript</a> от Stepik. Вы изучите HTML, CSS, JavaScript, Figma, Photoshop, VS Code, Emmet, BEM, Bootstrap, Vue, Git, GitHub, Gulp. Также на курсе вам расскажут, как составить портфолио, резюме и взять первый заказ на фрилансе.</li><li><a href="https://experts2.ru/LxgqCl?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=netop">Курс Vue.js</a> от CyberBionic Systematics. Начните свой путь во Vue.js с уверенностью! Этот курс создан для новичков, которые хотят освоить востребованный фреймворк для быстрой и качественной разработки. Вы научитесь работать с формами, компонентами, динамическими данными и анимациями. А после успешного завершения курса получите именной сертификат — ваше первое официальное подтверждение новых навыков.</li><li><a href="https://experts2.ru/BcmUqy?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=netop">Frontend Junior (JavaScript + HTML/CSS + Vue.js)</a> от Stepik. На курсе вы освоите веб-разработку с полного нуля: вы не только изучите основы HTML и CSS, но и глубоко познакомитесь с JavaScript, научитесь работать с популярным фреймворком Vue.js и сможете писать чистый, структурированный код, который ценят в профессиональной среде.</li><li><a href="https://experts2.ru/jCOdly?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=netop">Vue JS и Vuex - пишем реальный проект с нуля</a> от Udemy. Очень практический курс, который учит веб-разработке на Vue JS и Vuex через создание настоящего проекта. Вы пройдете весь путь — от пустой папки до полностью рабочего приложения. Поймете, как правильно структурировать программу, создавать компоненты и модули, которые легко масштабировать, и дробить код на небольшие, удобные части. В каждом уроке есть доступ к готовому исходному коду, так что вы всегда сможете свериться и найти свои ошибки.</li><li><a href="https://experts2.ru/GNnhec?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=netop">Vue.js 2.5 Создаем сайт на Vue.JS с Firebase, Vuex и Router</a> от Udemy. Это практическое руководство по созданию сайта с использованием мощной связки технологий: Vue.js, Vuex и Router. Вы научитесь делать динамические и многофункциональные веб-приложения, прокачаете свои навыки в структурировании кода, работе с большими массивами данных и проектировании интерфейсов разной степени сложности. Материал курса разделен на тематические блоки, и каждый включает в себя практическую часть.</li><li><a href="https://experts2.ru/eDqdjY?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=netop">Игра на Vue.js</a> от Udemy. Интересный видеокурс по основам Vue.js, где вы будете создавать настоящую игру. Обучение разделено на две большие части. Первая посвящена интерфейсу: вы с нуля, используя HTML и CSS, сверстаете визуальную часть игры. Во второй части вы займетесь фреймворком Vue.js: напишете структурированный код, добавите алгоритмы и свяжете их с игровой механикой. В финале преподаватель посоветует, куда двигаться дальше и в каком направлении развиваться в IT.</li><li><a href="https://experts2.ru/dSyqXg?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=netop">Vue.js 2 с нуля до про</a> от Tocode. Этот курс поэтапно проведет вас по всем ключевым концепциям и возможностям фреймворка. Он предназначен для подготовки сильных разработчиков и содержит множество практических заданий разного уровня с комментариями и советами от экспертов. В итоге вы получите актуальные знания и навыки для создания динамичных и масштабируемых проектов.</li><li><a href="https://experts2.ru/eVJvmq?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=netop">JavaScript. Программирование от основ до веб-приложений(+Vue.js)</a> от Stepik. На курсе вы освоите JavaScript через решение практических задач, с которыми сталкиваются разработчики в реальной работе. Вам предстоит создать собственное веб-приложение с интерактивными интерфейсами, работой с API и хранением данных, а также познакомиться с React и GitHub. В завершение вы изучите современные фреймворки, включая Vue.js, что позволит вам уверенно работать с самыми востребованными технологиями в веб-разработке.</li><li><a href="https://experts2.ru/jzfoIB?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=netop">Vue Level 2</a> от Дмитрия Лаврик. Здесь вас ждет полное погружение в разработку одностраничных приложений. Вы не просто изучите теорию, а на практике разберетесь с реальными challenges — от построения архитектуры до обработки серверных ошибок и настройки прав доступа. После каждого занятия — домашняя работа с персональной проверкой автора курса. Всегда можно задать вопрос лично Дмитрию во время живых занятий или в закрытом комьюнити, где собираются такие же увлеченные разработчики.</li><li><a href="https://experts2.ru/PqgfLo?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=netop">Vue.js - Разработка клиентских приложений</a> от Учебного центра «Шифт». Если вы уже работаете с веб-разработкой, но хотите вывести свои навыки на новый уровень, этот курс станет вашим надежным проводником в мир Vue.js. Вы глубоко поймете философию фреймворка и научитесь применять его для создания сложных интерфейсов — от концепции до реализации. Здесь дают именно те знания, которые сразу можно перенести в рабочие проекты.</li><li><a href="https://experts2.ru/VileDq?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=netop">Фронтенд - разработчик на Vue.js</a> от Специалист.ru. Это ваш шанс не просто изучить технологии, а полноценно освоить профессию. Начнете с верстки, постепенно перейдете к JavaScript и Git, а затем глубоко погрузитесь во Vue.js. В финале — два ценных документа: государственный диплом о повышении квалификации и международный сертификат. Идеальный вариант для тех, кто хочет не просто научиться программировать, но и получить официальное подтверждение своих знаний.</li><li><a href="https://experts2.ru/wYpyhM?sub1=tproger-kf&amp;sub2=kursy-vue-js&amp;sub4=netop">Vue.js</a> от Ильи Кантора. На основе проекта вы освоите возможности Vue, различные подходы к решению практических задач и ключевые библиотеки экосистемы. В процессе работы вы разработаете компактную библиотеку переиспользуемых UI-компонентов. Параллельно с изучением Vue будут рассмотрены смежные темы фронтенд-разработки: создание одностраничных приложений, работа с инструментами сборки, освоение Vite, основы тестирования и другие важные аспекты современной веб-разработки.</li></ul><h2>Бесплатные курсы Vue.js</h2><p>Начать знакомство с фреймворком можно без финансовых вложений. Хорошие курсы по Vue.js бесплатно познакомят с основами и помогут оценить перспективы дальнейшего углубленного изучения. Такие программы идеально подходят для знакомства с технологией и понимания ее возможностей. Практические задания и понятные объяснения сделают старт в разработке комфортным и интересным.</p><ol><li><a href="https://www.youtube.com/playlist?list=PLNkWIWHIRwMH7ahn9uvvc5PG3o1tLscgB">Vue.js</a> — webDev. Вы рассмотрите работу с JavaScript фреймворком Vue JS актуальной второй версии, а также изучите все необходимые темы и понятия, которые нужны, чтобы начать разрабатывать на Vue.</li><li><a href="https://www.youtube.com/playlist?list=PLuY6eeDuleIPrHjeWPtEw6KWni2W35-XO">Уроки по Vue.js</a> — ITDoctor. Курс состоит из двух глав, в которых вы научитесь работать с различными директивами на Vue.js, создавать циклы, методы и вычисляемые свойства. Плейлист подойдет для веб-разработчиков, которые уже имеют опыт в работе с языками HTML, CSS, JS и желательно понимающих, как работать с гитом.</li><li><a href="https://www.youtube.com/playlist?list=PLvTBThJr861yMBhpKafII3HZLAYujuNWw">Бесплатный курс по Vue.js</a> — JavaScript.Ninja. Курс по Vue.js от сообщества @vuejs_club, с помощью которого вы узнаете о компонентах, двустороннем связывании и еще о многих темах. Для наглядности автор рассматривает примеры разработки веб-приложений на демонстрации экрана. Дополнительно в содержании курса представлено несколько практикумов для самостоятельной работы.</li><li><a href="https://www.youtube.com/playlist?list=PL0lO_mIqDDFVVNsIt02JBIdBkjNVHIoum">Уроки Vue.js для начинающих</a> — Гоша Дударь. В этом видеокурсе вы изучите основные моменты, которые позволят создавать приложения и сайты на Vue.js. Спикер расскажет, как создавать базовые сайты и веб-приложения с нуля.</li><li><a href="https://www.youtube.com/playlist?list=PL-wEcSTifrSn5cae0gFQ7Gy7v3t6c7hLF">Постигаем Vue js: урок 0 - установка и основные понятия</a> — JAVA И SКРИПТЫ. Подборка обучающих видео, направленная на обучение разработчиков, которые имеют опыт программирования на JavaScript. Автор подробно рассмотрит темы по отрисовке графических объектов, подбора стилистики для проекта, работе с реактивностью, пользовательскими событиями и так далее.</li><li><a href="https://www.youtube.com/watch?v=XzLuMtDelGk">Vue 3 фундаментальный курс от А до Я</a> — Ulbi TV. В этом ролике вы разберете основные концепции Vue 3 и пройдетесь по нему от А до Я. Разработаете приложение с основными кейсами, которые встречаются везде: CRUD, сортировка, поиск, пагинация, динамическая пагинация. Также вы сделаете mixins, directives, изучим vuex и composition api.</li><li><a href="https://www.youtube.com/playlist?list=PLOjCcvKYFQgKqNqDBw8G2kLxFbrWYBqJ1">Vue 3</a> — AVIS TV. Теоретический курс, автор которого рассказывает о ключевых особенностях фреймворка Vue.js и его применении в среде веб-разработке. Вы узнаете, как установить программное обеспечение на компьютер и использовать его для создания проектов разной сложности.</li><li><a href="https://www.youtube.com/watch?v=U_-Ht_v-oAs">Vue 3 для начинающих / Разработка интернет-магазина Vue Sneakers</a> — Archakov Blog. Курс по Vue 3 для начинающих, в котором вы будете разрабатывать полноценный проект Vue Sneakers, а хранить данные будете на бесплатном сервисе Mokky.</li></ol><h2>Что такое Vue.js и каковы его ключевые преимущества перед другими фреймворками</h2><p>Vue.js — это как умный помощник для создания веб-интерфейсов. Представьте, что нужно сделать страницу динамической: добавить всплывающие окна, сортировку таблиц или обновляемые формы. Vue делает это постепенно — можно начать с малого, добавив пару-тройку строк кода в проект, а потом развивать до полноценного сложного приложения.</p><h2>Понятный без долгого изучения</h2><p>Фреймворки напоминают сборку мебели по запутанной инструкции — приходится постоянно сверяться со справочником. Vue же работает интуитивно: свяжите поле ввода и данные одной строкой v-model, организуйте цикл элементов через v-for, настройте реакцию на события через v-on. Код читается как обычное предложение — это ценится в командах, где важно быстро понимать друг друга.</p><h2>Не требует революционных изменений</h2><p>Если уже есть рабочий проект на чистом JavaScript или jQuery, Vue не заставит все переписывать. Можно внедрять его точечно — например, сделать интерактивным только фильтр товаров в каталоге или форму обратной связи. Это спасает, когда нужно модернизировать интерфейс без остановки основного функционала.</p><h2>Сам заботится о скорости</h2><p>Vue умно управляет обновлениями интерфейса. Когда данные меняются, он не перерисовывает всю страницу, а находит те элементы, которые нуждаются в обновлении. Как умный редактор, который вносит точечные правки в текст вместо полной перепечатки. Вы сосредотачиваетесь на логике, а фреймворк оптимизирует отображение.</p><h2>Единая экосистема</h2><p>Для типовых задач уже есть проверенные решения: Vue Router для навигации, Pinia для управления состоянием, Nuxt.js для сложных приложений. Они созданы одной командой, поэтому стыкуются друг с другом. Например, Nuxt.js из коробки решает проблемы с SEO — генерирует страницы так, что их сразу видят поисковики.</p><h2>Сообщество, которое помогает</h2><p>Документация Vue написана не для роботов, а для людей — с примерами и типичными сценариями из практики. Если возникают вопросы, в чатах и на форумах всегда найдется разработчик, который сталкивался с похожей задачей. Это ощущение поддержки важно, когда работаешь над сложным проектом.</p><h2>В чем разница между Vue 2 и Vue 3</h2><h2>Архитектура и реактивность</h2><p>Изменение скрыто «под капотом». Vue 2 использовал систему реактивности на основе Object.defineProperty. Это означало, что фреймворк мог автоматически отслеживать изменения только в тех свойствах, которые были в объекте с самого начала. Vue 3 перешел на современный стандарт JavaScript — Proxy. Теперь Vue отслеживает изменения, включая добавление или удаление свойств объекта и даже работу с массивами, без костылей. Для вас, как для разработчика, это означает предсказуемость и меньше скрытых ошибок.</p><h2>Composition API — новый способ организации кода</h2><p>Vue 2 предлагал только один способ структурировать логику компонента — Options API. Вся логика должна была быть разложена по «полочкам»: data, methods, computed и так далее. Это было просто для понимания новичкам, но в больших компонентах логика, относящаяся к одной задаче, оказывалась разбросана по разным разделам. Vue 3 представил Composition API — более гибкий подход, где вы группируете код по его функциональному назначению, а не по типу. Это похоже на написание обычных JavaScript-функций. Такой код легче организовать, переиспользовать и тестировать, особенно в сложных компонентах.</p><h2>Производительность и размер</h2><p>Vue 3 был переписан с прицелом на производительность. В результате базовая библиотека стала на 40% легче. Это ускоряет первоначальную загрузку приложения. Кроме того, механизм рендеринга был серьезно оптимизирован: Vue 3 научился умнее определять, какие части дерева компонентов нужно обновлять при изменении. Это приводит к меньшему количеству ненужных перерисовок и плавной работе интерфейса, особенно в приложениях с большим количеством динамических элементов.</p><h2>Лучшая поддержка TypeScript</h2><p>Если Vue 2 с TypeScript работал, но иногда вызывал головную боль из-за сложной типизации, то Vue 3 был изначально написан на TypeScript. Это означает, что поддержка типов стала первоклассной. Теперь ваша среда разработки (IDE) будет гораздо лучше понимать, что происходит в коде, предлагая умные подсказки и сразу находя многие ошибки. Это огромный плюс для поддержки и масштабирования больших проектов.</p><h2>Фрагменты и телепортация</h2><p>В Vue 2 каждый компонент должен был иметь один корневой элемент. Это часто приводило к появлению лишних div-оберток в разметке. Vue 3 позволяет компонентам возвращать несколько корневых элементов — так называемые Фрагменты (Fragments). Это делает DOM-дерево чище. Также появилась директива &lt;Teleport&gt;, которая позволяет «вырвать» кусок кода из одного места в компоненте и отрендерить его в другом месте DOM, что невероятно удобно для модальных окон, уведомлений и тултипов.</p><p>Важно понимать, что Vue 3 — это не разрыв с прошлым. Options API никуда не делся и по-прежнему поддерживается. Вы можете использовать старый добрый подход для компонентов и подключать Composition API там, где это нужно. Vue 3 предлагает больше возможностей, улучшенную производительность и современную основу для разработки, сохраняя при этом главную философию — постепенное внедрение и удобство для разработчика.</p><p>Выбирать курсы Vue.js нужно на четком понимании карьерных целей и текущего уровня подготовки. Начинающим разработчикам стоит обратить внимание на программы с проработкой основ JavaScript, тогда как опытным специалистам будут полезны узкоспециализированные уроки по продвинутым аспектам Vue.js. Внимание уделите наличию практических заданий и качеству обратной связи — эти факторы часто становятся решающими в освоении материала.</p><p><i>Приглашаем поделиться опытом в комментариях: какой из рассмотренных курсов показался сбалансированным? Возможно, вы уже обучались по одной из программ и добавите отзыв? Ваше мнение поможет другим читателям сделать выбор.</i></p>]]></content:encoded>
    </item>
    <item>
      <title>Руководство по промптам GPT-5: практики для агентов, кодирования и управляемости</title>
      <link>https://tproger.ru/articles/rukovodstvo-po-promptam-gpt-5--praktiki-dlya-agentov--kodirovaniya-i-upravlyaemosti</link>
      <comments>https://tproger.ru/articles/rukovodstvo-po-promptam-gpt-5--praktiki-dlya-agentov--kodirovaniya-i-upravlyaemosti?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Даровская Маша]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/rukovodstvo-po-promptam-gpt-5--praktiki-dlya-agentov--kodirovaniya-i-upravlyaemosti</guid>
      <description><![CDATA[<p>Руководство по промптам GPT-5: практики для агентов, кодирования и управляемости от OpenAI. Готовые шаблоны промптов, настройка reasoning_effort, работа с Responses API и советы по созданию приложений. Повысьте стабильность и эффективность ваших ИИ-решений.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/rukovodstvo-po-promptam-gpt-5--praktiki-dlya-agentov--kodirovaniya-i-upravlyaemosti">Руководство по промптам GPT-5: практики для агентов, кодирования и управляемости</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[Практика]]></category>
      <category><![CDATA[Рефакторинг]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[OpenAI]]></category>
      <category><![CDATA[Markdown]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Промпты]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 07 Oct 2025 14:00:04 GMT</pubDate>
      <content:encoded><![CDATA[<p>Мы перевели <a href="https://cookbook.openai.com/examples/gpt-5/gpt-5_prompting_guide">статью</a> Ануп Кота, Джулиан Ли, Эрика Закариассон из OpenAI. Статья написана для разработчиков агентных систем, инженеров ИИ-продуктов, команд фронтенда/бэкенда, редакторов кода с ИИ.</p><p>GPT-5 — флагманская reasoning-модель с упором на агентные сценарии, кодинг, интеллект и управляемость. «Из коробки» она хорошо решает широкий спектр задач, но качественные промпты (подсказки) заметно повышают стабильность, скорость и соблюдение инструкций. Ниже — проверенные практики, готовые шаблоны и заметки по параметрам API (reasoning_effort, verbosity, Responses).</p><h2>Предсказуемость агентного рабочего процесса</h2><h2>Используйте API Responses для агентов</h2><p>Responses сохраняет логические следы между вызовами инструментов: это снижает задержку, экономит токены и повышает качество планов за счёт механизма previous_response_id.</p><h2>Контролируйте «рвение» агента</h2><p>Сдержанный режим (меньше вызовов, ниже задержки):</p><ul><li>Установите reasoning_effort=low|medium.</li><li>В подсказке ограничьте глубину поиска контекста и задайте ранние критерии остановки.</li></ul><h2>Проактивный режим (больше автономии и настойчивости):</h2><ul><li>Поднимите reasoning_effort.</li><li>Включите явное требование «не возвращаться к пользователю до полного решения».</li></ul><p>Если вы готовы к максимально строгому регулированию, то можете установить фиксированный бюджет на вызовы инструментов, как показано ниже. Бюджет, естественно, может варьироваться в зависимости от желаемой глубины поиска.</p><p>При ограничении основного поведения сбора контекста полезно явно предоставить модели запасной вариант, облегчающий выполнение более короткого этапа сбора контекста. Обычно это делается в виде условия, позволяющего модели продолжать работу в условиях неопределенности, как «even if it might not be fully correct» в примере выше.</p><p>С другой стороны, если вы хотите поощрить автономность модели, увеличить настойчивость в вызове инструментов и сократить количество уточняющих вопросов или иных случаев возврата информации пользователю, рекомендуется увеличить reasoning_effort и использовать такой промпт, чтобы поощрить настойчивость и тщательное выполнение задачи:</p><p>Хорошая практика — чётко указать условия остановки задач агента, обозначить безопасные и небезопасные действия и определить, когда, если это вообще возможно, модель может вернуть данные пользователю. Например, в наборе инструментов для покупок инструменты оформления заказов и оплаты должны явно иметь более низкий порог неопределённости, требующий пояснений пользователя. В то же время инструмент поиска должен иметь чрезвычайно высокий порог; аналогично, в конфигурации кодинга инструмент удаления файлов должен иметь гораздо более низкий порог, чем инструмент поиска grep.</p><h2>«Преамбулы» к инструментам (чтобы пользователь понимал, что происходит)</h2><p>GPT-5 обучен предоставлять чёткие предварительные планы и последовательные обновления о ходе работы с помощью сообщений «преамбулы инструмента».</p><p>Вы можете управлять частотой, стилем и содержанием преамбул инструментов в вашем запросе — от подробных объяснений каждого вызова инструмента до краткого предварительного плана. Вот пример качественной преамбулы:</p><p>Вот пример преамбулы инструмента, которая может быть выведена в ответ на такой запрос. Такие преамбулы могут значительно улучшить способность пользователя следить за работой вашего агента по мере её усложнения:</p><h2>Усилия рассуждения и повторное использование контекста</h2><ul><li>reasoning_effort регулирует интенсивность размышлений и готовность к вызову инструментов. Значение по умолчанию — medium. Но для многошаговых задач повышайте этот показатель.</li><li>Разбивайте сценарий на несколько ходов агента с сохранением previous_response_id в Responses — модель не тратит токены на перестройку плана.</li><li>Настоятельно рекомендуют использовать API Responses в GPT-5, чтобы улучшить потоки агентов, снизить затраты и повысить эффективность токенов в приложениях. Авторы отмечают, что наблюдали статистически значимые улучшения в оценках при использовании API Responses по сравнению с завершением чата. Например, рост оценки Tau-Bench Retail с 73,9% до 78,2% был только благодаря переходу на API Responses и включению previous_response_id (функции передачи предыдущих элементов рассуждений в последующие запросы). Это позволяет модели ссылаться на предыдущие трассировки рассуждений, экономя токены и устраняя необходимость перестраивать план с нуля после каждого вызова инструмента, что снижает latency. Эта функция доступна всем пользователям API Responses.</li></ul><h2>Максимизация продуктивности в кодинге</h2><p>GPT-5 умеет работать с крупными кодовыми базами, накатывать многофайловые изменения, рефакторить и строить новые приложения.</p><h2>Рекомендованный стек для фронтенд-приложений</h2><ul><li>Фреймворк: Next.js (TypeScript), React, HTML</li><li>Стили/UI: Tailwind CSS, shadcn/ui, Radix themes</li><li>Иконки: Lucide / Heroicons / Material Symbols</li><li>Анимации: Framer Motion</li><li>Шрифты: Inter, Geist, Mona Sans, IBM Plex Sans, Manrope</li></ul><h2>Разработка приложений с нуля</h2><p>GPT-5 отлично подходит для создания приложений за один раз. В ходе ранних экспериментов с моделью пользователи обнаружили, что подсказки, подобные приведённой ниже, — где модель итеративно выполняет задания, используя самостоятельно разработанные критерии качества, — повышают качество результатов благодаря использованию возможностей GPT-5 в области тщательного планирования и самоанализа.</p><h2>Соответствие стандартам разработки</h2><p>При внедрении постепенных изменений и рефакторинга в приложения, код, написанный на основе модели, должен соответствовать стандартам стиля и дизайна и максимально аккуратно вписываться в кодовую базу. Без специальных подсказок GPT-5 автоматически ищет справочный контекст в кодовой базе, например, читая package.json для просмотра уже установленных пакетов. Но это поведение можно улучшить с помощью подсказок, обобщающих ключевые аспекты, такие как принципы разработки, структура каталогов и передовой опыт кодовой базы.</p><p>Фрагмент подсказки ниже демонстрирует один из способов организации правил редактирования кода для GPT-5: не стесняйтесь изменять фактическое содержание правил в соответствии со своими предпочтениями в программном дизайне.</p><h2>Форматирование Markdown</h2><p>По умолчанию GPT-5 в API не форматирует свои окончательные ответы в Markdown, чтобы обеспечить максимальную совместимость с разработчиками, чьи приложения могут не поддерживать рендеринг Markdown. Тем не менее, запросы, подобные следующему, в значительной степени успешно обеспечивают иерархические окончательные ответы в Markdown.</p><p>Иногда соблюдение инструкций Markdown, указанных в системном запросе, может ухудшаться в течение длительного разговора. Если вы столкнулись с такой ситуацией, стабильное соблюдение инструкций Markdown будет работать при добавлении их к каждому 3–5 пользовательскому сообщению.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как подключить GPT API в своё приложение</title>
      <link>https://tproger.ru/articles/kak-podklyuchit-gpt-api-v-svoyo-prilozhenie</link>
      <comments>https://tproger.ru/articles/kak-podklyuchit-gpt-api-v-svoyo-prilozhenie?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Вадим Егорцев]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-podklyuchit-gpt-api-v-svoyo-prilozhenie</guid>
      <description><![CDATA[<p>Как оплачивать API ChatGPT в России, рассчитывать стоимость запросов и подключить нейросеть OpenAI к приложению на Python или Javascript. </p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-podklyuchit-gpt-api-v-svoyo-prilozhenie">Как подключить GPT API в своё приложение</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Нейронные сети]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[OpenAI]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 06 Oct 2025 12:00:04 GMT</pubDate>
      <content:encoded><![CDATA[<p>Если вы хотите добавить в свой проект чат-бота, автоматически обрабатывать тексты или генерировать контент — эта публикация сэкономит пару дней экспериментов и поможет избежать типичных ошибок при интеграции. Разберём настройку доступа из России, покажем код на Python и JavaScript, обсудим риски и случаи, когда одного API недостаточно.</p><h2>Считаем расходы и настраиваем лимиты</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-09-29/d50e1490-01ee-4425-be66-1ea978220a91.jpg" alt="" /></figure><p>OpenAI взимает плату за <b>токены</b> — единицы измерения текста. Один токен — это 4 символа английского текста или 2-3 символа русского:</p><ul><li>«привет» — это 2 токена,</li><li>«hello» — 1 токен.</li></ul><p>Вы платите за два типа токенов:</p><ul><li>входящие — ваш запрос к модели,</li><li>исходящие — ответ модели.</li></ul><p>Актуальные цены <a href="https://platform.openai.com/docs/pricing?latest-pricing=priority">смотрите</a> на сайте OpenAI.</p><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-09-29/cead9d84-1f31-462b-bc46-87eccae86b60.jpg" alt="" /></figure><p>Например, GPT-4o стоит $2.50 за миллион входящих токенов и $10 за миллион исходящих. Диалог на 1000 токенов обойдётся примерно в $0.01. При обработке 10 000 таких диалогов в день расходы составят $100 ежедневно.</p><p><b>Настройка финансовой защиты</b></p><p>Перед подключением API к приложению зайдите в настройки биллинга OpenAI и настройте три параметра:</p><ul><li><b>Usage limits</b> — жёсткое ограничение расходов. При достижении лимита API перестаёт отвечать на запросы.</li><li><b>Email notifications</b> — уведомления при достижении определённого процента от лимита (например, 80%).</li><li><b>Rate limits</b> — ограничения по токенам (TPM) и запросам (RPM) в минуту для каждого API-ключа.</li></ul><p>OpenAI показывает статистику с задержкой 5-10 минут. Для контроля в реальном времени используйте библиотеку tiktoken:</p><p>Начинайте с малых лимитов и увеличивайте постепенно. Лучше получить ошибку «превышен лимит» и быстро поднять порог, чем обнаружить пятизначный счёт в конце месяца.</p><blockquote>Я видел много задач, которые прекрасно решаются без LLM, но «пацаны не поймут». Если без LLM и правда никак, то научитесь считать: оптимизируйте промпты, не давайте агентам уходить в долгие циклы взаимодействия с моделями.</blockquote><h2>Работаем с ChatGPT из России</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-09-29/aefcb2bd-1709-4724-bf01-9d3b15a4cc61.jpg" alt="" /></figure><p>OpenAI официально не доступен российским пользователям. Если попробуете зайти на их сайт или отправить запрос к API напрямую — получите ошибку.</p><p>Можно купить подписку на любой сервис обхода блокировок за 200-500 рублей/месяц. Работает, но есть нюансы:</p><ul><li>скорость ответов снижается,</li><li>соединение периодически разрывается,</li><li>если сервис накроется — ваше приложение встанет.</li></ul><p>Более надёжный вариант — арендовать виртуальный сервер в Европе или США за $5-10 в месяц и настроить на нём прокси-сервер. Придётся потратить пару часов на настройку, зато получите стабильное соединение под вашим полным контролем.</p><blockquote>Пришлось настроить собственный прокси — это стабильно, надёжно и недорого.</blockquote><p><b>Платим за API</b></p><p>OpenAI принимает только зарубежные карты, и есть несколько вариантов:</p><ul><li>Виртуальные карты типа Pyypl или RedotPay. Минус один — при пополнении теряете 10-20 рублей на каждой сотне из-за курса, но для личных экспериментов терпимо.</li><li>Физические карты зарубежных банков. Нужно ехать в Казахстан, Армению или Грузию, либо искать посредников. Курс конвертации в таком случае будет менее грабительским.</li></ul><p>Если возиться с обходом блокировок не хочется, есть отечественные аналоги:</p><ul><li>GigaChat.</li><li>YandexGPT.</li></ul><p>Ещё можно рассмотреть OpenRouter. Это агрегатор разных моделей, включая ChatGPT. Работает без смены IP, но платить всё равно придётся зарубежной картой. Цены чуть выше, чем напрямую у OpenAI.</p><blockquote>В личных экспериментах использую OpenRouter, и мне нравится. Это «единое окно» в разные модели, работает без смены IP, совместимо с OpenAI. Также есть «обёртки» во всех популярных фреймворках, таких как langchain/langgraph, очень удобно.</blockquote><blockquote>С одной стороны, с агрегаторами (OpenRouter) проще в плане доступа, оплаты, использования единого OpenAI API для всех моделей, консолидированного учёта расходов. С другой стороны — есть минусы: риски безопасности, стоимость, ограничения глубокой настройки и набора функций / API, ошибки доступа и маршрутизации.</blockquote><h2>Подключаем API на Python</h2><p>Установите библиотеку OpenAI:</p><p>Пример базового запроса по API:</p><p>GPT API работает как любой другой сервис — отправили POST-запрос, получили JSON с ответом.</p><p>Три главных параметра, которые влияют на ответы:</p><ul><li><b>max_tokens</b> — сколько токенов (≈ слов) может содержать ответ. Поставите 50 — получите короткий ответ. Поставите 2000 — модель распишет подробно. Каждый токен стоит денег, помните об этом.</li><li><b>temperature </b>(от 0 до 2) — насколько предсказуемы ответы. При 0 модель выдаёт самый вероятный вариант. При 1.5 начинает фантазировать. Для технической документации ставьте 0.2, для креативных задач — 0.8-1.0.</li><li><b>top_p </b>— альтернатива temperature. Ограничивает выбор слов по вероятности. Обычно используют что-то одно: либо temperature, либо top_p.</li></ul><p>В реальных проектах вы не обойдётесь одним запросом. Чаще всего придётся строить цепочки: сначала извлечь данные, потом проверить их, затем сформировать финальный ответ. Каждый шаг — отдельный промпт со своими параметрами.</p><blockquote>Большинство промышленных задач с LLM не решается одним проходом и одним промптом, тебе нужна совокупность различных инструментов и ухищрений.</blockquote><h2>Подключаем API на JavaScript</h2><p>Установите библиотеку OpenAI:</p><p>Пример базового запроса по API:</p><p>Никогда не пишите API-ключ прямо в коде, используйте файл .env:</p><p>И библиотеку dotenv:</p><h2>Чтобы не уволили и не засудили</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-09-29/47edf285-a276-4892-84ec-50d25ce5f1dd.jpg" alt="" /></figure><p>В 2023 году инженеры Samsung <a href="https://interestingengineering.com/culture/chatgpt-alleged-leak-confidential-information-samsung">отправили</a> исходный код в ChatGPT, когда просили помочь с оптимизацией. После этого корпорация запретила сотрудникам работать с публичными нейросетями. И Samsung не одиноки — Amazon, Apple, JPMorgan Chase ввели похожие ограничения.</p><p>Вы отправляете данные на чужие сервера, и никто не гарантирует, что они там не останутся. OpenAI прямо пишет в документации, что может использовать ваши запросы для обучения моделей.</p><blockquote>Люди внезапно утратили всю бдительность и запихивают в чаты что ни попадя. Безопасники реагируют по всем направлениям, вот и про DLP (Data Leak Prevention) вспомнили.</blockquote><p><b>Как работать безопасно</b></p><p>Перед отправкой заменяйте настоящие данные на фейковые. Вместо «Иван Петров, +79291234045» пишите «USER_NAME, USER_PHONE». После получения ответа подставляйте реальные значения обратно.</p><p>API-ключи храните в переменных окружениях, а не в коде. Меняйте ключи каждые 30-60 дней. Настройте алерты на всплески запросов — если обычно делаете 100 запросов в день, а тут внезапно 10000, значит ключ утёк.</p><h2>Когда ждать ответ целиком, а когда показывать по частям</h2><p>В API есть два режима получения ответов: обычный и потоковый (streaming). В обычном режиме вы ждёте, пока модель сгенерирует весь текст, и получаете его целиком. В потоковом — ответ приходит частями.</p><blockquote>Стриминг нужен для тех случаев, когда не можем ждать конечный ответ (например, голосовые каналы или текстовые, где хотим удержать внимание пользователя). При этом, стриминг не повредит и в других сценариях, но только если вы понимаете, что реализация стриминга с вашей стороны не требует больших усилий.</blockquote><blockquote>Со стримингом больше мороки на стороне вашей системы, например, по частям отправлять результат на фронтэнд, либо собирать результат если требуется обработка полного ответа. Получается, что без стриминга оптимально работать, если ответы короткие, либо результат используется для анализа, классификации.</blockquote><h2>Когда нужны фреймворки</h2><p>Прямых вызовов API достаточно для простых задач — отправить запрос и получить ответ. Фреймворки нужны, когда строите чат-бота с памятью, систему с поиском по документам или многоагентную систему.</p><blockquote>Фреймворки чисто для вызова модели не нужны, они скорее помогают нам комбинировать сложные реализации вызовов, например при разработке агентских систем. Тут мой фаворит LangGraph.</blockquote><blockquote>Если цель сугубо академическая, и хочется детально разобраться, то лучше изучать «низкоуровневые» API. Если строите что-то прикладное, то удобнее, быстрее и проще взять фреймворк. Я люблю langchain/langgraph, но в последнее время DSPy всё увереннее завоёвывает моё сердечко.</blockquote><blockquote>Из фреймворков наиболее универсальное сочетание — LangChain + LangGraph. Также могу выделить LlamaIndex, Haystack, AutoGen, crewAI, Neurite, FlashRAG.</blockquote><h2>Чек-лист перед стартом</h2><ul><li>Зарегистрируйтесь на сайте OpenAI и получите API-ключ в разделе настроек.</li><li>Настройте финансовые лимиты в биллинге OpenAI: Usage limits, Email notifications и Rate limits.</li><li>Подключите зарубежную карту для оплаты (виртуальную Pyypl/RedotPay или физическую карту зарубежного банка).</li><li>Настройте VPN или прокси-сервер для доступа к API из России (или используйте OpenRouter).</li><li>Установите библиотеку OpenAI для вашего языка программирования (pip install openai для Python или npm install openai для JavaScript).</li><li>Создайте файл .env и поместите туда API-ключ.</li><li>Напишите тестовый запрос с базовыми параметрами: model, messages, max_tokens, temperature.</li><li>Настройте обработку ошибок и повторные попытки при сбоях соединения.</li><li>Настройте мониторинг количества запросов и алерты на аномальную активность.</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>Лучшие практики для ускорения фронтенда: чек-лист 2025 года</title>
      <link>https://tproger.ru/articles/luchwie-praktiki-dlya-uskoreniya-frontenda--chek-list-2025-goda</link>
      <comments>https://tproger.ru/articles/luchwie-praktiki-dlya-uskoreniya-frontenda--chek-list-2025-goda?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/luchwie-praktiki-dlya-uskoreniya-frontenda--chek-list-2025-goda</guid>
      <description><![CDATA[<p>Ускорьте свой сайт с помощью чек-листа по оптимизации фронтенда: от HTML и CSS до изображений и серверов. Практические советы для повышения скорости, SEO и конверсий в 2025 году.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/luchwie-praktiki-dlya-uskoreniya-frontenda--chek-list-2025-goda">Лучшие практики для ускорения фронтенда: чек-лист 2025 года</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[CSS]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Дизайн]]></category>
      <category><![CDATA[Дизайн интерфейсов и UX]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 03 Oct 2025 12:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Это перевод <a href="https://crystallize.com/blog/frontend-performance-checklist">статьи</a> с сайта компании Crystallize. Можете поделиться своим мнением в комментариях!</p><h2>Почему скорость сайта так важна</h2><p>В мире, где внимание пользователей <a href="https://time.com/3858309/attention-spans-goldfish/">рассеивается</a> за восемь секунд, быстрая загрузка сайта становится критически важной. Статистика подтверждает: <a href="https://www.thinkwithgoogle.com/consumer-insights/consumer-trends/mobile-site-load-time-statistics/#:~:text=Google%20www.thinkwithgoogle.com%20%2053,statistics%20on%20Think%20with%20Google">53% мобильных пользователей покидают сайт</a>, если он грузится дольше 3 секунд, а 70% потребителей <a href="https://unbounce.com/page-speed-report/#:~:text=Nearly%2070%25%20of%20consumers%20admit%20that%20page%20speed%20influences%20their,time%20is%20slower%20than%20expected.">отмечают</a>, что скорость влияет на их решение о покупке. Walmart, например, <a href="https://wpostats.com/2015/11/04/walmart-revenue/#:~:text=Walmart%20saw%20up%20to%20a,increase%20in">зафиксировал</a> рост конверсий на 2% за каждую секунду сокращения времени загрузки.</p><p>Быстрые сайты обеспечивают:</p><ul><li>Долгое пребывание пользователей на сайте;</li><li>Больше просмотров страниц благодаря быстрой навигации;</li><li>Меньше отказов из-за медленных загрузок;</li><li>Выше конверсии и доходов, так как скорость напрямую влияет на покупки;</li><li>Лучшую удовлетворенность и удержание пользователей;</li><li>Рост органического трафика, так как Google учитывает Core Web Vitals в SEO-ранжировании;</li><li>Экономию на CDN и трафике, ведь оптимизированные сайты потребляют меньше данных;</li><li>Повышение качества рекламы в Google Ads, так как быстрые страницы снижают стоимость кликов.</li></ul><p>Оптимизация фронтенда — это не просто техническая задача, а способ повысить лояльность пользователей и бизнес-показатели.</p><h2>Как измерить производительность сайта</h2><p>Прежде чем оптимизировать, <a href="https://crystallize.com/blog/frontend-performance-measuring-and-kpis">измерьте</a> текущую производительность сайта, чтобы выявить узкие места. Используйте комбинацию лабораторных и полевых инструментов:</p><ul><li><a href="https://pagespeed.web.dev/">Google PageSpeed Insights</a>: быстрый аудит Core Web Vitals с рекомендациями.</li><li><a href="https://developers.google.com/web/tools/lighthouse">Chrome Lighthouse</a>: встроенный в DevTools инструмент для анализа производительности, SEO и лучших практик.</li><li><a href="https://www.webpagetest.org/">WebPageTest</a>: детализированные метрики, визуализация загрузки и советы по оптимизации.</li><li><a href="https://gtmetrix.com/">GTmetrix</a>: анализ скорости загрузки с рекомендациями.</li><li><a href="https://developer.chrome.com/docs/crux/methodology/tools">CrUX в Google Search Console</a>: реальные данные пользовательского опыта (Core Web Vitals) для SEO.</li></ul><p>Лабораторные инструменты дают контролируемые метрики, а мониторинг реальных пользователей (через <a href="https://github.com/GoogleChrome/web-vitals">Web Vitals JS</a>, <a href="https://www.speedcurve.com/">SpeedCurve</a> или <a href="https://calibreapp.com/">Calibre</a>) показывает, как сайт работает в реальных условиях. Это поможет определить приоритеты для оптимизации.</p><h2>Чек-лист оптимизации фронтенда 2025</h2><p>Производительность — это командная работа. Бэкенд должен быть масштабируемым, UX-дизайнеры — балансировать визуал и скорость, а фронтенд-разработчики — реализовывать оптимизированный код. Этот чек-лист подходит для любой платформы: от Next.js и Astro до WordPress и PHP. Адаптируйте его под ваш проект, уделяя внимание ключевым метрикам, таким как LCP, CLS и INP (новый показатель, заменивший FID в 2024 году).</p><h3>HTML</h3><p>HTML — основа страницы, и его оптимизация ускоряет загрузку и улучшает пользовательский опыт.</p><ul><li>Приоритизируйте критический HTML: доставляйте HTML для верхней части страницы первым, чтобы браузер начал рендеринг. Фреймворки вроде Next.js или Astro с SSR/SSG рендерят HTML на сервере, улучшая First Contentful Paint.</li><li>Удаляйте лишний код: уберите ненужные теги, комментарии и пробелы. Компактный HTML загружается быстрее, особенно в мобильных сетях.</li><li>Включите сжатие: используйте GZIP или Brotli, чтобы уменьшить размер HTML. Большинство серверов и CDN это поддерживают.</li><li>Оптимизируйте загрузку ресурсов: размещайте CSS в &lt;head&gt; для быстрого рендера, а скрипты — перед &lt;/body&gt; или с атрибутами async/defer, чтобы не блокировать разбор HTML.</li><li>Минимизируйте iframe: они загружают дополнительные страницы, замедляя сайт. Используйте loading="lazy" для iframe ниже линии сгиба или загружайте их по клику.</li></ul><p><b>Совет:</b> держите DOM компактным. Например, Astro разбивает страницы на «островки», минимизируя гидратацию JavaScript, что ускоряет рендеринг.</p><h3>CSS</h3><p>CSS может блокировать рендеринг, если не оптимизирован. Вот как сделать стили быстрее:</p><ul><li>Удаляйте неиспользуемый CSS: используйте PurgeCSS или Chrome DevTools, чтобы убрать мертвый код, особенно в проектах с Tailwind.</li><li>Модуляризуйте стили: разделяйте CSS по страницам или функциям, загружая только необходимое. Критические стили встраивайте в &lt;head&gt;, остальное загружайте асинхронно.</li><li>Избегайте @import: он создает дополнительные запросы и блокирует рендеринг. Используйте &lt;link rel="stylesheet"&gt; или объединяйте CSS при сборке.</li><li>Используйте критический CSS: встраивайте стили для верхней части страницы в HTML, а остальное загружайте позже (например, через media="print"). Инструменты вроде Critical помогут это автоматизировать.</li><li>Минимизируйте CSS: убирайте пробелы и комментарии с помощью Clean-CSS или cssnano.</li><li>Предварительно загружайте ключевые стили: используйте &lt;link rel="preload" as="style"&gt; для важных CSS-файлов.</li><li>Упрощайте селекторы: избегайте сложных вложенных цепочек, чтобы ускорить вычисления стилей. Например, .headline лучше, чем body div#main article h1.</li><li>Применяйте современный CSS: используйте content-visibility: auto для отложенного рендера контента за пределами экрана. Это ускоряет начальную загрузку и снижает потребление памяти.</li></ul><h2>JavaScript</h2><p>JavaScript часто замедляет страницы из-за объема и времени выполнения. Оптимизируйте его так:</p><ul><li>Заменяйте JS на HTML/CSS: используйте CSS-анимации, &lt;details&gt; или валидацию форм вместо JS, где возможно.</li></ul><ul><li>Минимизируйте фреймворки: избегайте тяжелых библиотек для простых задач. Проверяйте сторонние скрипты (аналитика, реклама) и удаляйте ненужные.</li><li>Разделяйте код: используйте динамический import() или возможности фреймворков для загрузки JS по необходимости.</li><li>Предварительно загружайте важные скрипты: используйте &lt;link rel="preload" as="script"&gt; для ключевых JS-файлов.</li><li>Применяйте async/defer: добавляйте эти атрибуты к &lt;script&gt;, чтобы не блокировать рендеринг. Defer сохраняет порядок выполнения, async подходит для независимых скриптов.</li><li>Минимизируйте JS: используйте UglifyJS или tree shaking для удаления неиспользуемого кода. Настраивайте сборку для ES-модулей.</li><li>Обновляйте зависимости: новые версии фреймворков (esbuild, SWC) часто быстрее. Используйте Renovate или Dependabot для автоматизации.</li><li>Выбирайте подходящий фреймворк: Next.js с React Server Components или Astro с «островковой» архитектурой сокращают объем JS на клиенте, ускоряя загрузку.</li></ul><h2>Изображения</h2><p>Изображения — один из главных факторов загрузки страниц. Оптимизируйте их так:</p><ul><li>Используйте правильный размер: не загружайте изображения больше, чем нужно для отображения. Инструменты вроде ImageMagick или Sharp помогут автоматизировать ресайз.</li><li>Применяйте адаптивные изображения: используйте &lt;img srcset&gt; или &lt;picture&gt; для доставки изображений в зависимости от устройства.</li><li>Сжимайте изображения: используйте ImageOptim, mozJPEG для JPEG, PNGQuant для PNG или SVGO для SVG.</li><li>Предварительно загружайте ключевые изображения: используйте &lt;link rel="preload" as="image"&gt; или fetchpriority="high" для баннеров, влияющих на LCP.</li><li>Откладывайте загрузку: добавляйте loading="lazy" для изображений ниже линии сгиба.</li><li>Используйте WebP/AVIF: эти форматы обеспечивают лучшее сжатие, чем JPEG/PNG. CDN и фреймворки вроде Next.js автоматизируют конвертацию.</li><li>Указывайте размеры: добавляйте width и height или CSS aspect-ratio, чтобы избежать сдвигов макета (CLS).</li><li>Автоматизируйте оптимизацию: используйте Next.js &lt;Image&gt;, Astro или CDN (Cloudinary, Imgix) для автоматической обработки изображений.</li></ul><h2>Видео</h2><p>Видео могут быть тяжелее изображений, поэтому требуют особого внимания:</p><ul><li>Сжимайте видео: используйте Handbrake для MP4/WebM, снижая битрейт или разрешение (например, 720p вместо 1080p).</li><li>Используйте современные кодеки: WebM (VP9) или AV1 обеспечивают лучшее сжатие, чем MP4 (H.264).</li><li>Настройте предварительную загрузку: используйте preload="metadata" или none для видео, чтобы не загружать лишние данные.</li><li>Откладывайте загрузку: применяйте loading="lazy" для iframe или загружайте видео по клику/прокрутке.</li><li>Удаляйте ненужное аудио: уберите звуковую дорожку из фоновых видео с помощью FFmpeg.</li><li>Используйте потоковую передачу: для длинных видео применяйте HLS или DASH для адаптивной загрузки.</li><li>Оптимизируйте сторонние видео: используйте облегченные встраивания (например, lite-youtube-embed) для YouTube/Vimeo.</li></ul><h2>Шрифты</h2><p>Пользовательские шрифты улучшают брендинг, но могут замедлить рендеринг. Оптимизируйте их так:</p><ul><li>Ограничьте количество шрифтов: используйте минимум семейств и начертаний, чтобы сократить запросы.</li><li>Применяйте WOFF2: этот формат компактнее TTF или WOFF и поддерживается всеми браузерами.</li><li>Предварительно подключайтесь к источникам: используйте &lt;link rel="preconnect"&gt; для Google Fonts или других хостов.</li><li>Используйте font-display: swap: это предотвращает FOIT (невидимый текст) и улучшает пользовательский опыт.</li><li>Избегайте сдвигов макета: подбирайте резервные шрифты с похожими метриками или используйте font-size-adjust.</li><li>Рассмотрите переменные шрифты: один файл заменяет несколько начертаний, снижая объем данных.</li><li>Используйте системные шрифты: они не требуют загрузки и работают мгновенно.</li></ul><h2>Хостинг и сервер</h2><p>Конфигурация сервера напрямую влияет на скорость загрузки:</p><ul><li>Используйте HTTPS: это не только безопасно, но и быстрее, благодаря HTTP/2+. Google учитывает HTTPS для SEO.</li><li>Сократите HTTP-запросы: удаляйте ненужные ресурсы и минимизируйте сторонние скрипты.</li><li>Перейдите на HTTP/2 или HTTP/3: HTTP/2 поддерживает мультиплексирование, HTTP/3 (QUIC) ускоряет соединение, особенно на мобильных сетях.</li><li>Используйте CDN: кэшируйте ресурсы на серверах по всему миру для снижения задержек.</li><li>Настройте кэширование: используйте Cache-Control для статических ресурсов и кэширование на уровне приложения.</li><li>Оптимизируйте сервер: держите TTFB ниже 200 мс, оптимизируя запросы к базе данных и вычисления.</li><li>Применяйте статическую генерацию: используйте SSG или ISR (Next.js) для доставки готовых HTML-страниц через CDN.</li></ul><h2>Быстрые улучшения</h2><p>Эти небольшие оптимизации дают заметный эффект:</p><ul><li>Избегайте сдвигов макета: резервируйте место для изображений, iframe и динамического контента, чтобы минимизировать CLS.</li><li>Используйте приоритеты: применяйте fetchpriority="high" для ключевых ресурсов и low для некритических.</li><li>Сократите сторонние запросы: откладывайте загрузку аналитики или рекламы до взаимодействия пользователя.</li><li>Используйте один протокол: избегайте смешанного контента (HTTP/HTTPS).</li><li>Настройте кэширование: используйте длительный max-age для статических ресурсов с хэшами в именах файлов.</li><li>Предварительно загружайте страницы: используйте &lt;link rel="prefetch"&gt; для вероятных переходов.</li><li>Применяйте Service Workers: кэшируйте ресурсы для мгновенной загрузки и оффлайн-доступа.</li></ul><p>Оптимизация фронтенда — это непрерывный процесс, который требует внимания всей команды. Скорость сайта напрямую влияет на пользовательский опыт, SEO и бизнес-показатели. Используйте этот чек-лист, чтобы выявить слабые места и сократить миллисекунды загрузки. Комбинируйте лабораторные тесты и мониторинг реальных пользователей, чтобы отслеживать прогресс. Сделайте скорость приоритетом — ваши пользователи и бизнес скажут спасибо!</p>]]></content:encoded>
    </item>
    <item>
      <title>Как встроить распознавание паспорта СНГ в браузер</title>
      <link>https://tproger.ru/articles/kak-vstroit-raspoznavanie-pasporta-sng-v-brauzer</link>
      <comments>https://tproger.ru/articles/kak-vstroit-raspoznavanie-pasporta-sng-v-brauzer?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Smart Engines]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-vstroit-raspoznavanie-pasporta-sng-v-brauzer</guid>
      <description><![CDATA[<p>Рассказываем, как встроить распознавание паспортов РФ, стран СНГ и других удостоверений личности, а также банковских карт и других объектов прямо в браузер.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-vstroit-raspoznavanie-pasporta-sng-v-brauzer">Как встроить распознавание паспорта СНГ в браузер</a>»</p>]]></description>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[WebAssembly]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 01 Oct 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Эта статья продолжает раскрывать, как с помощью WebAssembly (Wasm) легко встроить технологии распознавания в любую веб-среду. Одними банковскими картами и паспортом РФ дело не ограничивается – на этот раз поговорим об удостоверениях личности стран СНГ: почему распознавание этих документов сегодня не менее актуально для бизнес-задач и как в этом деле помогает технология Wasm. В конце статьи вас ждет традиционный гайд по встраиванию, поехали!</p><h2>Зачем распознавать паспорта СНГ</h2><p>В нашей стране и за ее пределами паспорт – это ключ к любому цифровому сервису. Если вы открываете счет в банке, оформляете заказ в интернет-магазине, регистрируетесь в сервисе каршеринга, самостоятельно заселяетесь в отель или приобретаете билет на концерт, вам практически всегда требуется ввести свои паспортные данные.</p><p>Сегодня в этом помогает искусственный интеллект – он берет на себя <a href="https://smartengines.ru/smart-idreader/">распознавание паспорта</a> и позволяет получить в структурированном виде всю информацию о владельце документа без ошибок и задержек. Однако если решение умеет распознавать только российский паспорт, оно сразу теряет актуальность для Беларуси, Казахстана, Армении, Узбекистана и других стран. Это стратегический недочет – в особенности если бизнес имеет дело с иностранцами: например, связан со сферой туризма, банкингом, перевозками, или просто представлен в соседних с Россией государствах. Существенный спрос на технологии распознавание паспорта СНГ наблюдается со стороны HR-сферы – автоматизация ввода данных позволяет избавиться от бюрократических проволочек при массовом найме и работе с трудовыми мигрантами. Во всех этих случаях поддерживать распознавание документов стран СНГ просто необходимо.</p><p>Распознавание паспортов СНГ позволяет предложить единый, удобный и безопасный сценарий регистрации для пользователей из любых государств региона. В свою очередь, это повышает конверсию, сокращает клиентский путь и делает цифровые продукты доступнее для более широкой аудитории. Сегодня такие возможности искусственного интеллекта доступны не только для нативных приложений, но и для так называемых прогрессивных веб-приложений (PWA) и <a href="https://smartengines.ru/smart-engines-max-ocr/">mini apps в мессенджерах</a>.</p><h2>Как в этом помогает WebAssembly</h2><p>PWA, благодаря своей доступности и независимости от устройств и операционок, уже превратились в золотой стандарт для сферы цифровых услуг. «Прокачанные» сайты уже заменяют классические нативные приложения, поскольку не уступают по функциональности и быстродействию и при этом не требуют скачивания, обновления и поддержки в сторах. Кроме того, сейчас буквально на наших глазах происходит интеграция аналогичного формата в мессенджеры – MAX и Telegram. Туда уже интегрируют платежи и переводы, онлайн-покупки, регистрацию в сервисах и другие возможности, которые раньше оставались прерогативой нативных приложений.</p><p>Для переноса в веб хорошо знакомого пользователю функционала используется технология WebAssembly, или Wasm. Она позволяет выполнять ресурсоемкие вычисления – например, распознавание документов, анализ изображений, работу с графикой, – непосредственно в браузере. Это возможно без потери скорости и без постоянных запросов к серверу. Мы в <a href="https://smartengines.ru/">Smart Engines</a> разглядели перспективность Wasm задолго до того, как о технологии широко заговорили, и к моменту удаления банковских приложений из App Store и Google Play мы уже имели обширную экспертизу в этой области.</p><p>Мы разработали PWA, в котором реализовали распознавание QR-кодов, банковских карт, номеров телефонов, паспортов и других объектов. Это дало возможность ведущим российским банкам внедрить переводы по СБП и оплату квитанций прямо на интернет-странице. Таким образом, проблему блокировки приложений удалось решить – конечный пользователь получает максимально нативный опыт, оставаясь прямо в браузере. Веб-приложение хранит все необходимые ресурсы (включая Wasm-модули) в локальном кеше благодаря Service worker. В результате приложение получается максимально отзывчивым и может работать без интернета.</p><h2>Как работает распознавание паспорта СНГ</h2><p>Распознавание паспортов стран СНГ – задача нетривиальная: разные государства используют свои форматы документов, шрифты и уровни защиты. Мы разработали универсальную технологию, которая одинаково уверенно работает с паспортами России, Казахстана, Беларуси, Армении, Узбекистана, Таджикистана и других государств региона. В общей сложности система поддерживает более 100 языков, включая редкие письменности.</p><p>На распознавание паспорта любой страны СНГ в браузере с помощью нашего движка уходит всего несколько мгновений. Форма заполняется корректными данными за секунды, а пользователь не тратит время на перепечатку.</p><h3>Как встроить распознавание паспорта СНГ в веб</h3><p>Перейдем к делу. Для начала отметим, что источник входа, откуда система будет получать изображения, может быть совершенно любым. Например, камера —  тогда речь о фотографии или видео в реальном времени. Документ также может быть прикреплен из галереи или упакован в многостраничный PDF. Все эти форматы можно отрисовать на canvas и передать на распознавание.</p><p>Вы выбираете в вашем дизайне место для расположения canvas для вывода видео или делаете его скрытым для отрисовки PDF, например. Этот же подход используется, если вы пользователь айфона и хотите распознавать файл в формате HEIC.</p><p>Получаем ссылку на DOM-элемент:</p><p>Вот так мы извлекаем из него данные</p><p>Теперь же мы переключимся на воркер и заберем эти данные уже из него.</p><h3>Воркер</h3><p>Воркер или веб-воркер — это дополнительный поток браузера, который можно использовать для выполнения тяжелых задач, чтобы не нагружать основной поток, где осуществляется отрисовка UI и взаимодействие с пользователем.</p><p>Загружаем наш модуль для инициализации WASM.</p><p>Инициализируем Wasm-модуль</p><p>Создаем инстанс библиотеки распознавания</p><h2>Сессия распознавания</h2><p>Теперь мы подготовим сессию для распознавания. Создаем объект настроек</p><p>Указываем режим распознавания и маску документа. Можно указать маску звездочкой «*», а режим «anydoc», тогда поиск будет осуществляться по всем доступным документам.</p><p>Следующая настройка позволяет вернуть изображение документа, исправленное по перспективе. Эта очень удобная опция для визуальной проверки документа, он всегда возвращается в одной проекции и обрезанным по пропорциям физического документа.</p><p>Теперь мы инициализируем сессию.</p><h3>Передача изображений. Видеопоток</h3><p>В браузере для захвата изображений с камеры необходимо сначала отрисовать видеопоток на canvas, и после этого мы получаем доступ к пикселям, которые передаем в специальный объект Image.</p><p>Отметим, что объект canvas возвращает пиксели в формате RGBA, то есть с альфа каналом.</p><p>Создание объекта seImage класса se.common.image, необходимого для распознавания, возможно практически из любого набора пикселей, в том числе подходит и четырехканальное изображение.</p><p>Изображение создано. Теперь мы можем передать его на распознавание.</p><h3>Результат</h3><p>Объект result содержит в себе всю информацию о документе: текстовые поля, координаты шаблона и полей документа, изображения (подписи и фото держателя).</p><p>И на этом этапе мы рекомендуем не закрывать сессию, а продолжать подавать в нее изображения, то есть мы рекомендуем использовать распознавание документа в видеопотоке.</p><p>У этого подхода есть большое преимущество в виде устойчивости к бликам ламинированных документов и другим артефактам распознавания, поскольку их результаты комбинируются.</p><p>Если система больше не ожидает получить более качественное изображение на вход, она переводит флаг терминальности сессии в true и вы можете забрать результат.</p><p>Проверяйте результат каждый раз на терминальность:</p><p>Теперь вы видите, что добавить магию искусственного интеллекта в ваше веб-приложение совершенно несложно. Все работает прямо в браузере и по скорости практически не уступает нативному приложению. Подчеркнем, что вся обработка происходит локально на устройстве пользователя – это позволяет исключить риск утечек персональных данных на этапе распознавания.</p><p>А если вам интересно узнать больше про возможности искусственного интеллекта на WebAssembly, рекомендуем почитать наши прошлые статьи про распознавание <a href="https://tproger.ru/articles/raspoznavanie-bankovskoj-karty-v-brauzere--kak-s-pomoshhyu-tehnologii-webassembly-integrirovat-raspoznavanie-v-veb-stranicu">банковских карт</a> и <a href="https://tproger.ru/articles/kak-vstroit-raspoznavanie-pasporta-rf-v-brauzer">паспорта РФ</a> в браузере.</p>]]></content:encoded>
    </item>
    <item>
      <title>10 VSCode расширений, которые реально повышают продуктивность</title>
      <link>https://tproger.ru/articles/10-vscode-raswirenij--kotorye-realno-povywayut-produktivnost</link>
      <comments>https://tproger.ru/articles/10-vscode-raswirenij--kotorye-realno-povywayut-produktivnost?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/10-vscode-raswirenij--kotorye-realno-povywayut-produktivnost</guid>
      <description><![CDATA[<p>Топ-10 расширений VSCode для повышения продуктивности: форматирование, тестирование API, управление проектами и многое другое. Ускорьте свою разработку с лучшими инструментами.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/10-vscode-raswirenij--kotorye-realno-povywayut-produktivnost">10 VSCode расширений, которые реально повышают продуктивность</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Тестирование]]></category>
      <category><![CDATA[SEO]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[CSS]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[BASIC]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Intel]]></category>
      <category><![CDATA[ICO]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Английский]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Vue]]></category>
      <category><![CDATA[1C]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 23 Sep 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Visual Studio Code — мощный редактор, который становится ещё лучше с правильными расширениями. В этой подборке мы собрали 10 инструментов, реально ускоряющих разработку: они избавляют от рутины и помогают сосредоточиться на главном — качественном коде.</p><h2>1. TabNine</h2><p>Если вам важна скорость — <a href="https://www.tabnine.com/">TabNine</a> стоит попробовать хотя бы ради этого. Расширение —  лёгкий AI-ассистент, который работает как умный автодополнитель кода, непохожий на аналоги вроде Codeium или Copilot.</p><p>TabNine обучен на миллионах строк открытого кода и умеет предсказывать, что вы напишете дальше, с учётом контекста проекта и языка. Отлично справляется с рутинными вещами: автозавершает функции, переменные, конструкции — всё быстро и чаще всего в тему.</p><p><b>Кому подойдёт</b>: тем, кто хочет ускорить набор кода, но не готов передавать весь проект в облако или открывать чат с Copilot. Поддерживает офлайн-режим и локальное обучение модели.</p><p>Плюсы:</p><ul><li>Работает из коробки, не требует тонкой настройки;</li><li>Есть локальная версия — удобно для закрытых проектов;</li><li>Поддерживает большинство языков и фреймворков.</li></ul><p><b>Чем полезен:</b> экономит время на повседневной разработке — особенно когда вы не хотите отвлекаться на документацию или поиск нужной переменной в другом файле.</p><h2>2. GitLens</h2><p><a href="https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens">GitLens</a> встраивает историю изменений прямо в VSCode — и делает это максимально удобно. Показывает, кто и когда изменил строку, коммит-месседж, хэш, ветку и другие детали. Можно не уходить в консоль или отдельный Git-клиент для поиска информации.</p><p>Особенно полезен, когда работаете с чужим кодом или хотите быстро вспомнить, зачем вы сами что-то написали месяц назад.</p><p><b>Кому подойдёт</b>: тем, кто работает в команде, часто читает историю изменений или ревьюит чужие коммиты. Также пригодится в проектах с долгой историей или нестабильным кодом.</p><p>Плюсы:</p><ul><li>Информация о коммитах отображается прямо в редакторе под строкой;</li><li>Есть таймлайн изменений файла;</li><li>Удобный diff по коммитам, авторам, веткам и даже фрагментам кода.</li></ul><p><b>Чем полезен:</b> помогает быстрее разбираться в чужом коде, искать причины бага или откатывать ошибки. Особенно ценится за то, что делает Git прозрачным и доступным прямо в процессе разработки.</p><h2>3. Error Lens</h2><p><a href="https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens">Error Lens</a> выводит диагностику ошибок и предупреждений прямо в строке кода. Это расширение превращает сообщения линтеров и компиляторов в наглядные подсказки, позволяя сразу видеть, что пошло не так.</p><p>Можно настроить отображение: выделять ошибки цветом, добавлять иконки или даже показывать краткие подсказки с предложениями по исправлению. Поддерживает большинство языков и линтеров, включая ESLint, TypeScript и других.</p><p><b>Кому подойдёт:</b> разработчикам, которые хотят моментально видеть ошибки в коде, и тем, кто ценит визуальную чистоту и скорость отладки.</p><p>Плюсы:</p><ul><li>Ошибки и предупреждения отображаются прямо в редакторе, рядом со строкой кода;</li><li>Гибкая настройка стилей и уровня детализации сообщений;</li><li>Ускоряет процесс отладки, особенно при работе с большими файлами.</li></ul><p><b>Чем полезен:</b> минимизирует время на поиск и анализ ошибок, позволяя сразу фокусироваться на их исправлении. Это особенно ценно, когда вы пишете код в реальном времени или работаете с новыми библиотеками, где легко допустить мелкие недочёты.</p><h2>4. Path Intellisense</h2><p><a href="https://marketplace.visualstudio.com/items?itemName=christian-kohler.path-intellisense">Path Intellisense</a> — одно из тех расширений, которое просто работает и экономит кучу времени. Оно автоматически подсказывает пути к файлам, папкам и модулям в вашем проекте, как только вы начинаете их набирать. Поддерживает абсолютные и относительные пути, учитывает структуру проекта и форматирует предложения так, как это принято в выбранном языке.</p><p>Работает особенно хорошо в проектах с вложенной структурой, когда нужно быстро сослаться на компоненты, конфиги или ассеты.</p><p><b>Кому подойдёт</b>: всем, кто устал вручную прописывать длинные relative-пути или путаться в структуре проекта. Особенно выручает на фронтенде, где модулей десятки и легко ошибиться в названии.</p><p>Плюсы:</p><ul><li>Подсказки появляются автоматически при наборе пути;</li><li>Поддерживает большинство языков и фреймворков;</li><li>Учитывает jsconfig.json и tsconfig.json при работе с alias-ами.</li></ul><p><b>Чем полезен</b>: снижает количество опечаток и неверных импортов, ускоряет переход между файлами и помогает писать код чуть быстрее.</p><h2>5. TODO Highlight</h2><p><a href="https://marketplace.visualstudio.com/items?itemName=wayou.vscode-todo-highlight">TODO Highlight</a> подсвечивает комментарии с задачами (например, TODO, FIXME, NOTE) прямо в коде, делая их заметными и удобными для отслеживания. Расширение помогает не терять важные заметки, которые вы оставляете в коде, и быстро находить места, требующие доработки.</p><p>Можно настроить ключевые слова, цвета подсветки и даже добавить свои собственные метки. Работает с любыми языками программирования и интегрируется с панелью задач VSCode для удобного обзора всех TODO в проекте.</p><p><b>Кому подойдёт</b>: разработчикам, которые оставляют заметки в коде, и командам, которым нужно быстро находить задачи или недочёты в проекте.</p><p>Плюсы:</p><ul><li>Яркая подсветка TODO-комментариев прямо в редакторе;</li><li>Гибкая настройка ключевых слов и стилей;</li><li>Интеграция с панелью задач для быстрого обзора.</li></ul><p><b>Чем полезен</b>: экономит время на поиск и управление задачами в коде, помогая не упустить важные доработки или напоминания. Особенно удобно в больших проектах, где комментарии могут затеряться среди строк.</p><h2>6. Prettier – Code formatter</h2><p><a href="https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode">Prettier</a> — расширение, которое автоматически приводит ваш код к единому стилю, избавляет от ручной правки отступов, кавычек и переносов. Оно поддерживает множество языков (JavaScript, TypeScript, CSS, HTML и другие) и интегрируется с линтерами, чтобы ваш код был не только красивым, но и консистентным.</p><p>Можно настроить правила форматирования под ваш проект или использовать готовые пресеты. Prettier форматирует код при сохранении файла или по команде, а также работает с выделенными фрагментами.</p><p><b>Кому подойдёт</b>: разработчикам, которые хотят экономить время на форматировании, и командам, стремящимся к единообразию кода.</p><p>Плюсы:</p><ul><li>Автоматическое форматирование при сохранении или по хоткеям;</li><li>Поддержка множества языков и кастомных настроек;</li><li>Интеграция с ESLint и другими инструментами для проверки кода.</li></ul><p><b>Чем полезен:</b> убирает рутину ручного форматирования, снижает количество ошибок в стиле кода и помогает сосредоточиться на логике, а не на внешнем виде. Идеально, чтобы ускорить работу и поддерживать чистоту в больших проектах.</p><h2>7. Live Server</h2><p><a href="https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer">Live Server </a>запускает локальный сервер прямо из VSCode, позволяя просматривать изменения в HTML, CSS и JavaScript в браузере в реальном времени. После сохранения файла страница автоматически обновляется, что исключает необходимость ручного перезапуска или обновления браузера.</p><p>Поддерживает кастомные порты, HTTPS, и работает с любыми фронтенд-проектами, от простых HTML-страниц до сложных приложений на React или Vue. Можно настроить, чтобы сервер открывался автоматически при запуске проекта.</p><p><b>Кому подойдёт</b>: фронтенд-разработчикам, которые работают над веб-интерфейсами и хотят мгновенно видеть результат изменений без лишних действий.</p><p>Плюсы:</p><ul><li>Автоматическое обновление страницы при изменении кода;</li><li>Простая настройка и поддержка HTTPS для безопасного тестирования;</li><li>Лёгкий запуск сервера прямо из редактора.</li></ul><p><b>Чем полезен</b>: ускоряет цикл разработки и тестирования веб-приложений, избавляет от ручного обновления страниц. Это особенно экономит время при частых правках в стилях или скриптах, так как можно сразу видеть результат в браузере.</p><h2>8. Project Manager</h2><p>Если работаете над несколькими проектами одновременно — это расширение сэкономит вам часы. <a href="https://marketplace.visualstudio.com/items?itemName=alefragnani.project-manager">Project Manager</a> позволяет создавать список избранных проектов и открывать их в один клик, без ручного поиска папок и недавних вкладок.</p><p>Можно задать свои алиасы, группировать по папкам, запускать с хоткеев — особенно удобно, если у вас десятки репозиториев на локалке или вы фрилансите на несколько команд.</p><p><b>Кому подойдёт</b>: разработчикам, которые ведут сразу несколько проектов, часто переключаются между ними и устали искать нужный путь через File &gt; Open Folder.</p><p>Плюсы:</p><ul><li>Быстрое переключение между проектами через интерфейс или хоткеи;</li><li>Поддержка избранного и тэгов;</li><li>Можно автоматически подтягивать все папки из заданной директории.</li></ul><p><b>Чем полезен:</b> избавляет от рутинных действий при переходе между проектами — особенно когда важно не терять фокус и не сбиваться с рабочего темпа.</p><h2>9. Code Spell Checker</h2><p><a href="https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker">Code Spell Checker </a>выявляет орфографические ошибки в комментариях, строках и именах переменных прямо в редакторе VSCode. Расширение подчёркивает опечатки волнистой линией и предлагает варианты исправления через Ctrl+. или Cmd+., что позволяет быстро исправить ошибки.</p><p>Поддерживает множество ЯП и словари для разных языков (английский, русский, немецкий — с дополнительными расширениями). Можно добавлять свои слова в пользовательский словарь или игнорировать определённые термины, чтобы адаптировать проверку под проект. Работает с camelCase и snake_case, не помечая их как ошибки.</p><p><b>Кому подойдёт</b>: разработчикам, которые пишут много комментариев или документации в коде, и тем, кто хочет избежать опечаток в строках, API или логах, чтобы повысить читаемость.</p><p>Плюсы:</p><ul><li>Мгновенное обнаружение ошибок с подсказками для исправления;</li><li>Гибкая настройка словарей и игнорируемых слов;</li><li>Поддержка технических терминов и различных стилей написания кода.</li></ul><p><b>Чем полезен:</b> экономит время на поиск и исправление опечаток, особенно в документации или пользовательских сообщениях, которые могут повлиять на восприятие проекта.</p><h2>10. REST Client</h2><p><a href="https://marketplace.visualstudio.com/items?itemName=humao.rest-client">REST Client </a>позволяет отправлять HTTP-запросы и просматривать ответы непосредственно в VSCode. Достаточно создать файл с расширением .http или .rest, написать запрос в простом текстовом формате, и вы увидите кнопку Send Request для моментального выполнения.</p><p>Поддерживает все типы запросов (GET, POST, PUT, DELETE и другие), авторизацию (Basic, OAuth, JWT), переменные окружения и даже генерацию кода на разных языках. Запросы можно сохранять в репозиторий, что удобно для командной работы. Расширение также позволяет использовать динамические переменные по типу {{$timestamp}} или {{$guid}}, всё для гибкой настройки запросов.</p><p><b>Кому подойдёт</b>: тем, кто работает с REST API и хочет тестировать эндпоинты прямо в VSCode, сохранять запросы в проекте и почти не переключаться между инструментами.</p><p>Плюсы:</p><ul><li>Простая отправка запросов через .http или .rest файлы с кнопкой Send Request;</li><li>Поддержка переменных окружения и авторизации для сложных API;</li><li>Возможность сохранять запросы в репозитории для совместной работы.</li></ul><p><b>Чем полезен:</b> ускоряет тестирование API, устраняет необходимость в сторонних приложениях. Запросы хранятся рядом с кодом, что упрощает документирование и повторное использование, особенно в проектах, где API-вызовы нужно часто проверять или делиться ими с командой.</p><p><i>А какими расширениями пользуетесь вы? Пишите в комментариях!</i></p>]]></content:encoded>
    </item>
    <item>
      <title>Как Web3 меняет разработку веб-приложений: от серверов к блокчейну</title>
      <link>https://tproger.ru/articles/kak-web3-menyaet-razrabotku-veb-prilozhenij--ot-serverov-k-blokchejnu</link>
      <comments>https://tproger.ru/articles/kak-web3-menyaet-razrabotku-veb-prilozhenij--ot-serverov-k-blokchejnu?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Диана Тажетдинова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-web3-menyaet-razrabotku-veb-prilozhenij--ot-serverov-k-blokchejnu</guid>
      <description><![CDATA[<p>Поговорили с экспертом и узнали, где Web3 даёт практическую пользу разработчикам: сравниваем подходы, исследуем рынок вакансий и особенности новой реальности.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-web3-menyaet-razrabotku-veb-prilozhenij--ot-serverov-k-blokchejnu">Как Web3 меняет разработку веб-приложений: от серверов к блокчейну</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Практика]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[Rust]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Блокчейн]]></category>
      <category><![CDATA[Ethereum]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[смарт-контракты]]></category>
      <category><![CDATA[DeFi]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 22 Sep 2025 12:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Раньше, чтобы запустить приложение, приходилось настраивать сервер и базу данных. В Web3 всё по-другому: вместо серверов — смарт-контракты, вместо базы — блокчейн. <a href="https://www.esparkinfo.com/web3/statistics">По прогнозам</a>, объём рынка Web3‑разработки вырастет с $4,43 млрд в 2024 году до $6,15 млрд в 2025. Кейсы<a href="https://ru.wikipedia.org/wiki/Plume_Network_%E2%80%93_The_Future_of_Real-World_Assets_on_Web3_%F0%9F%8C%90?utm_source=chatgpt.com"> Plume Network</a> и<a href="https://en.wikipedia.org/wiki/The_Graph?utm_source=chatgpt.com"> The Graph</a> показывают, что Web3 уже работает в реальных продуктах. Что, если нас уже сегодня ждет backend в виде блокчейна? Давайте разберём, как меняются инструменты, архитектуры и карьерные треки.</p><h2>Главные отличия Web3 от Web2</h2><p>Перед тем как углубиться в код и практику, полезно увидеть основные различия между привычной Web2-разработкой и новой логикой Web3.</p><figure><img src="https://media.tproger.ru/user-uploads/114509/2025-09-22/3fa1cc2a-0755-4b71-af24-9b8a6f9d22ea.png" alt="" /></figure><p>Представим себе простой сервис для задач. В классическом Web2 его работа привычна: сервер обрабатывает запросы, база данных хранит задачи, а пользователь авторизуется через почту и пароль. Всё централизовано и зависит от владельца сервера.</p><p>В Web3 логика сильно меняется. Пользователь входит в систему с помощью криптокошелька, например, MetaMask. Каждая задача создаётся транзакцией и записывается в смарт‑контракт, а значит становится частью блокчейна. Удалить её уже нельзя — только отметить статус выполнения. Такой подход даёт прозрачность: любой участник сети может проверить, что задача действительно существует, и её статус изменён честно.</p><h2>Стек Web3: что понадобится на практике</h2><p>Чтобы построить работающий DApp, важно понимать, чем он отличается от обычного приложения. DApp — это децентрализованное приложение, в котором логика хранится в смарт-контрактах на блокчейне, а данные — в распределённых хранилищах, а не на сервере компании. Поэтому одного знания блокчейна мало: нужен полный набор инструментов — от языков и фреймворков до кошельков и сервисов подключения.</p><ul><li>Блокчейн: Ethereum, Layer‑2 (Arbitrum, Optimism, Base, Polygon), Solana.</li><li>Языки: Solidity (EVM), Rust (Solana), Go (инфраструктура и сервисы).</li><li>Библиотеки: ethers.js, wagmi.</li><li>Фреймворки: Hardhat, Foundry, Truffle.</li><li>Хранилища: IPFS/Arweave для файлов и метаданных.</li><li>Кошельки/подключение: MetaMask, WalletConnect (v2/WalletConnect Network), Web3Auth.</li></ul><blockquote>Точка входа для новичка — Alchemy, а также ethers.js.</blockquote><p><b>Пример.</b> Быстрое подключение кошелька (ethers.js).</p><h2>Архитектура DApp: из чего состоит современное Web3‑приложение</h2><p>Любое Web3‑приложение строится из нескольких слоёв, каждый со своей ролью. Фронтенд остаётся привычным SPA, но работает не с сервером, а напрямую с кошельком и смарт-контрактами. Контракты содержат бизнес‑логику и хранят ссылки на данные в децентрализованных хранилищах. Оракулы обеспечивают связь с внешним миром, например, передают цены или сообщения между разными блокчейнами. Важную часть играет off‑chain слой — сервисы вне блокчейна (индексаторы, аналитика), которые помогают быстрее искать и обрабатывать данные, при этом не перегружать сеть.</p><p><b>Пример.</b> Возьмём DeFi‑приложение. Пользователь открывает фронтенд и инициирует операцию swap(). В ответ фронтенд обращается к смарт‑контракту, который выполняет обмен токенов. Чтобы определить курс, контракт тянет актуальные данные через оракул. При этом тяжёлые артефакты, изображения или отчёты не хранятся в блокчейне напрямую — они лежат в IPFS. Сам контракт содержит только контент‑идентификаторы CID. Таким образом, получаем баланс: блокчейн отвечает за логику и безопасность, а децентрализованное хранилище — за данные.</p><h2>Практика: ваш первый DApp за вечер</h2><p>Давайте попробуем собрать простейшее приложение своими руками.</p><p><b>Шаг 0. Подготовка</b></p><p>Сначала убедитесь, что у вас стоит Node.js LTS и Git. Также нужен браузер с установленным MetaMask, где можно создать тестовый аккаунт. Чтобы оплачивать транзакции в тестовой сети, заранее возьмите немного тестовых монет через faucet — например, для Sepolia или Polygon Amoy.</p><p><b>Шаг 1. Проект</b></p><p>Создадим новый проект и установим Hardhat вместе с тулзами. Эта среда нужна для компиляции и деплоя контрактов.</p><p><b>Шаг 2. Контракт</b></p><p>В папке contracts/ создаём файл TaskTracker.sol и копируем туда код смарт-контракта из первого раздела. Это и будет бизнес-логика нашего приложения.</p><p><b>Шаг 3. Сценарий деплоя</b></p><p>Пишем скрипт, который разворачивает контракт в сети. Это простой скрипт на JavaScript, который вызывает методы Hardhat.</p><p><b>Шаг 4. Конфиг сети</b></p><p>В файле hardhat.config.js добавляем настройки для подключения к тестовой сети. Используем RPC-URL от Alchemy или Infura и приватный ключ от тестового аккаунта — его можно экспортировать из MetaMask, но использовать только для тестовой сети.</p><p><b>Шаг 5. Деплой в тестнет</b></p><p>Теперь запускаем скрипт деплоя. После выполнения увидите адрес контракта — он понадобится для фронтенда.</p><p><b>Шаг 6. Фронтенд (React + ethers.js + wagmi)</b></p><p>Собираем простое SPA: форма, чтобы добавить задачи, и кнопка «complete». Здесь мы используем ethers.js для обращения к контракту. Сделайте вызовы addTask и completeTask.</p><h2>Подводные камни Web3-разработки и что с ними делать</h2><p><b>Комиссии (gas): </b>любая запись в блокчейн стоит денег и иногда комиссия выше ценности операции — например, $10 за простую задачу.</p><ul><li>Что делать: использовать Layer-2 (Arbitrum/Optimism/Base/Polygon), выбирать сети с низкими комиссиями (Solana, Avalanche), оптимизировать контракты и батчи транзакций.</li></ul><p><b>Скорость: </b>подтверждение транзакции занимает секунды или десятки секунд, что заметно медленнее обычного сервера.</p><ul><li>Что делать: показывать «оптимистичный UI», кешировать данные, переносить часть логики off-chain, использовать быстрые сети (Solana, Near, Aptos).</li></ul><p><b>Безопасность:</b> код контракта неизменяем, и одна ошибка может стоить миллионов.</p><ul><li>Что делать: проходить аудит (CertiK, Trail of Bits), использовать проверенные библиотеки (OpenZeppelin), писать тесты в тестовых сетях (Goerli, Sepolia), внедрять баг-баунти и ролевую модель доступа.</li><li>Ресурс:<a href="https://consensys.io/diligence/smart-contract-security-best-practices/"> ConsenSys Diligence — Smart Contract Security Best Practices</a>.</li></ul><p><b>UX:</b> вход через кошелёк сложнее привычного логина/пароля. Нужно ставить расширение, пополнять баланс и подтверждать каждую транзакцию.</p><ul><li>Что делать: использовать аккаунт-абстракцию (ERC-4337), социальный логин, gasless транзакции через Paymaster, улучшать UI (подсказки, авто-фокус на MetaMask).</li></ul><p><b>Регуляция: </b>законы о Web3 пока разные в каждой стране. Легальное в одной юрисдикции может быть запрещено в другой (например, токенизация акций без лицензии).</p><ul><li>Что делать: консультироваться с юристами, следить за изменениями. Например, MiCA в ЕС — “Markets in Crypto-Assets Regulation” —  это единый регламент по криптоактивам в Евросоюзе.</li></ul><blockquote>Безопасность всегда должна быть на первом месте, потому что в Web3 есть риск потерять реальные деньги пользователей.</blockquote><h2>Карьерные возможности и перспективы</h2><p>Web3‑разработчиков уже активно ищут: <a href="https://web3.career/learn-web3/web3-intelligence-report">зарплаты в среднем предлагают выше</a>, чем у Web2‑коллег. Кроме программистов, востребованы смежные роли: аудиторы смарт‑контрактов, специалисты по безопасности, а также продакт‑менеджеры и аналитики, которые понимают специфику блокчейна.</p><p>Чтобы войти в профессию, начните с изучения Solidity и базовых паттернов смарт‑контрактов. Сделайте пару пет‑проектов и выложите код в GitHub. Отличный вариант прокачки — участвовать в хакатонах и грантовых программах от Ethereum Foundation или Solana Grants. Это даёт и опыт, и контакты, и иногда финансирование.</p><blockquote>Пара пет‑проектов + понимание блокчейна — хороший старт в Web3‑команду.</blockquote><h2>Будущее Web3</h2><p>Web3 не вытеснит Web2 полностью, но поменяет привычный подход к разработке. Разработчику это открывает новые вызовы: комиссии, безопасность и UX, но одновременно и новые возможности — прозрачные данные, токенизация, децентрализованные бизнес‑модели.</p><p>Для тех, кто только входит в сферу, это шанс попасть в индустрию на раннем этапе и быстро нарастить экспертизу. Простые пет‑проекты, хакатоны и знакомство с инструментами дают ощутимый старт.</p><p>Web3 будет развиваться параллельно с Web2, усиливая те области, где важны децентрализация, доверие и контроль за данными. Попробуйте задеплоить первый контракт — и вы сами почувствуете, что это не просто мода, а новый уровень возможностей.</p>]]></content:encoded>
    </item>
    <item>
      <title>Будущее фронтенда: куда движется React, Vue и Angular</title>
      <link>https://tproger.ru/articles/budushhee-frontenda--kuda-dvizhetsya-react--vue-i-angular</link>
      <comments>https://tproger.ru/articles/budushhee-frontenda--kuda-dvizhetsya-react--vue-i-angular?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Вадим Егорцев]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/budushhee-frontenda--kuda-dvizhetsya-react--vue-i-angular</guid>
      <description><![CDATA[<p>Как изменились React, Vue и Angular за последние 5-10 лет? Эксперты ответили, что будет с фронтенд-разработкой в 2026 году и стоит ли переходить на фреймворки без VDOM и гидратации.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/budushhee-frontenda--kuda-dvizhetsya-react--vue-i-angular">Будущее фронтенда: куда движется React, Vue и Angular</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[CSS]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[Собеседование]]></category>
      <category><![CDATA[Навыки]]></category>
      <category><![CDATA[Паттерны проектирования]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Angular]]></category>
      <category><![CDATA[Vue]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 19 Sep 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>За последние пять лет IT-сфера изменилась так сильно, что джун из 2020 года сегодня бы не прошёл собеседование на ту же позицию.</p><p>Если вы фронтенд-разработчик или только планируете им стать, эта публикация поможет вам сориентироваться в текущей ситуации:</p><ul><li>Узнаете, какие крупные изменения произошли в React, Vue и Angular за последние 5-10 лет.</li><li>Поймёте, стоит ли учить новые фреймворки без виртуального DOM или лучше углубиться в проверенные решения.</li><li>Разберётесь, почему компании продолжают требовать знание React, хотя Solid.js работает быстрее.</li></ul><p>Тимлид и разработчики рассказали, как они видят будущее профессии. Объяснили, почему джуну недостаточно знать только JS, какие навыки помогут вам зарабатывать больше и оставаться востребованным специалистом.</p><p>ℹ️ <i>После прочтения вы сможете принять взвешенное решение: продолжать углубляться в текущий стек, осваивать новые инструменты или развивать смежные навыки.</i></p><h2>Как изменились React, Vue и Angular за последние 5-10 лет?</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-09-18/f488b013-32ed-47d0-ada9-3a1c3a84b59f.jpg" alt="" /></figure><h3>React</h3><p>До 2019 года разработчики писали объёмные классы с методами жизненного цикла. Они управляли состоянием через setState и передавали данные через пропсы. Потом появились <b>хуки </b>— с тех пор логику помещают в функции, состоянием управляют через useState и useReducer, побочные эффекты контролируют через useEffect.</p><p>Серверные компоненты решили проблему первой загрузки. Тяжёлые части приложения обрабатывает сервер и отправляет клиенту уже готовыми. Конкурентный режим разбивает отрисовку на части и расставляет приоритеты для обновлений — интерфейс не виснет, когда нагрузка возрастает.</p><h3>Vue</h3><p>Composition API сделал организацию кода более гибкой. Логику теперь группируют по функциональности, а не по типам опций. Ещё реактивность переписали с нуля на прокси-объектах, что ускорило отслеживание изменений.</p><p>Компилятор научился оптимизировать шаблоны на этапе сборки. Телепорты решили проблему с модальными окнами и всплывающими подсказками — компоненты отрисовываются в нужном месте DOM-дерева независимо от родителя.</p><p><a href="https://tproger.ru/articles/v-kakuyu-storonu-razvivaetsya-vue-i-est-li-emu-sovremennye-alternativy">В какую сторону развивается Vue и есть ли ему современные альтернативы</a></p><h3>Angular</h3><p>Каждый компонент сам определяет свои зависимости, поэтому пропала необходимость в модулях. <b>Сигналы</b> заменили зонную детекцию изменений. Теперь Angular точно знает, какие части интерфейса нужно обновлять.</p><p>Строгая типизация и декораторы сделали код более предсказуемым. Встроенные инструменты покрывают все потребности крупных проектов: формы с валидацией, маршрутизация с ленивой загрузкой, HTTP-клиент с перехватчиками.</p><p>Фреймворки уходят от сложных решений к более простым. Тренд последних лет — делать приложения быстрее для пользователей и удобнее для разработчиков.</p><p>Пока большая троица занималась «работой над ошибками», появился запрос на <a href="https://tproger.ru/articles/solidjs-i-qwik--frontend-novogo-pokoleniya">что-то</a> более лёгкое и быстрое.</p><h2>Фронтенд-фреймворки кажутся избыточными — возвращаемся к ванильному JS?</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-09-18/1af1ebd0-69e3-4f07-8d6d-053e8c3e70bb.jpg" alt="" /></figure><blockquote>Тот, кто попробовал фреймворки, никогда не вернется к чистому ванильному JS 🙂 Меняются и развиваются сами фреймворки, но тренда на отказ от них точно нет.</blockquote><p>Несмотря на тенденцию упрощения, разработчики сходятся во мнении, что полного отказа от фреймворков не произойдёт.</p><blockquote>В моде решения на основе концепции «исчезающих фреймворков», которые на выходе выдают почти чистый императивный JS-код. Дело в том, что это общий тренд в IT, где вся сложность и расчёты уходят в инфраструктуру, собирая минимальный бандл, где нет ничего лишнего для клиентов.</blockquote><p>Фреймворки — это ещё и способ стандартизации разработки в командах.</p><blockquote>Фреймворки никогда не будут избыточными. Один из первых вопросов на собеседовании —  инструмент, с которым ты умеешь работать. Больший пласт знаний сегодня — это фреймворк. Остальное, чаще всего, бизнес-логика того или иного проекта.</blockquote><p>Из-за критики традиционных фреймворков появился новый класс решений. Больше всего ругают VDOM и гидратацию, хотя они считались неотъемлемой частью современных SPA.</p><h2>Стоит ли переходить на фреймворки без VDOM и гидратации?</h2><p>Solid.js и Svelte уже несколько лет развивают концепцию тонкой реактивности. В 2021 году появился Qwik, который вообще отказался от гидратации.</p><blockquote>SolidJS хорош для аналогов десктопных приложений в браузере — Figma, Miro. Здесь приложение загружается один раз, а потом работает долго и должно быть максимально отзывчивым. Qwik отлично подойдёт, если вы создаёте сайт, куда пользователь приходит за контентом, и важно показать ему этот контент мгновенно.</blockquote><p>При этом массового перехода на новые фреймворки пока не происходит. Компании продолжают искать React и Vue разработчиков — проекты на Solid.js и Qwik остаются экспериментальными.</p><blockquote>Сами по себе фреймворки мало значат для коммерческой разработки без сторонних библиотек вокруг них. Вот когда критическая масса разработчиков популярных библиотек мигрирует на Qwik, а вместе с ними и сообщество, что-то сдвигается.</blockquote><p>Проблема новых фреймворков — это отсутствие экосистемы. React и Vue окружены тысячами готовых библиотек для любых задач. На Solid.js и Qwik большинство решений придётся писать самостоятельно.</p><blockquote>Без поддержки сообщества пользователей ни один инструмент не сможет стать массовым. Даже если работаешь в заказной разработке и есть возможность расширить кругозор команды, сомнительно брать на тест инструмент, под который придётся писать до 30% базового функционала.</blockquote><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-09-18/74e9b111-b93b-4fdf-a8b5-9db67bf7e95e.jpg" alt="" /></figure><p>Команды, которые захотят перейти на новые фреймворки, столкнутся с дополнительными сложностями. Разработчикам придётся учить новые концепции и подходы, а компаниям — тратить время и деньги на переобучение.</p><blockquote>У новых фреймворков высокий порог входа: вас ждёт переобучение команды и сложности ручной оптимизации.</blockquote><p>Технологии развиваются циклично. То, что сейчас кажется инновацией, переосмысливает старые подходы.</p><blockquote>Во времена DDR/DDR2 было сложно выполнять клиентский рендеринг, а вот серверам ресурсов хватало. Разработчики как могли воплощали подход, который сейчас называется SSR, и возвращали на клиент готовую разметку для компонентов. И никакого тебе VDOM.</blockquote><p>Пока новые фреймворки остаются нишевыми инструментами. React, Vue, Angular продолжат доминировать в коммерческой разработке за счёт экосистемы и сообщества.</p><h2>Как изменится роль фронтенд-разработчика в 2026 году?</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-09-18/6027e94f-65a4-4ab2-9364-6f5e322267f1.jpg" alt="" /></figure><p>В 2020 году джуниор находил работу, если знал HTML, CSS и основы JS. Сегодня работодатели требуют от новичков React или Vue, TypeScript, системы сборки — и это не конец списка. Ещё и вакансий на всех начинающих не хватает, компании сразу ищут мидлов.</p><p>Инструменты с искусственным интеллектом — Copilot, ChatGPT, Cursor — ускоряют работу. Они же повышают планку: если джун с помощью ИИ работает как мидл, то мидл должен демонстрировать более глубокие знания. Работодатели стали больше ценить тех, кто понимает принципы работы кода, а не просто копирует готовые решения.</p><blockquote>Зная JavaScript и любой инструмент даже не из большой тройки, с использованием AI можно быстро погрузиться в другой нужный инструмент.</blockquote><p>Чёткой границы между фронтендом и бэкендом больше нет. От фронтенд-разработчика ждут, что тот разбирается в серверной части, умеет настраивать процессы непрерывной интеграции и доставки, работает с базами данных.</p><h2>Какие навыки развивать разработчику, чтобы оставаться востребованным?</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-09-18/d62a3715-b713-4af3-8658-3ff4a6df7d85.jpg" alt="" /></figure><p>Технические навыки — это основа. Когда понимаете алгоритмы и структуры данных, вы пишете быстрый код. Когда знаете паттерны проектирования, ваши приложения легко поддерживать.</p><p><b>Учитесь быстро разбираться в новых инструментах вместо того, чтобы зацикливаться на одном фреймворке</b>.</p><blockquote>По мне так лучше быть фреймворк-агностиком, нежели фанатом одного, которого легко чем-то обидеть.</blockquote><p>Архитектурное мышление отличает <b>«</b>сильного<b>»</b> разработчика:</p><ul><li>Как организовать код, чтобы его легко поддерживать?</li><li>Как спроектировать API, чтобы оно не ломалось при изменениях?</li><li>Как построить систему, которая выдержит рост нагрузки?</li></ul><p>Те, кто решают эти вопросы, получают офферы с космическими зарплатами.</p><p><b>Софт-скиллы</b> тоже влияют на карьерный рост:</p><ul><li>Объясните техническую проблему менеджеру простыми словами.</li><li>Проводите код-ревью так, чтобы не обидеть коллегу, но улучшить код.</li><li>Оценивайте сроки и управляйте ожиданиями.</li><li>Аргументируйте выбор технологии.</li></ul><p>Когда вы понимаете бизнес, вы становитесь партнёром. Почему мы делаем эту фичу? Как она повлияет на метрики? Какие есть альтернативы? Разработчик, который мыслит категориями бизнеса, становится незаменимым.</p><p>Рынок вынуждает постоянно учиться, потому что индустрия меняется каждый год. Кто застревает в зоне комфорта — отстаёт.</p><p><i>Как ChatGPT повлиял на ценность вашего труда? Успеваете подстраиваться под требования рынка, параллельно работать и пробовать новые технологии? Делитесь в комментариях.</i></p>]]></content:encoded>
    </item>
    <item>
      <title>Оффер во фронтенде в 2025 году: как получить и не облажаться</title>
      <link>https://tproger.ru/articles/offer-vo-frontende-v-2025-godu--kak-poluchit-i-ne-oblazhatsya</link>
      <comments>https://tproger.ru/articles/offer-vo-frontende-v-2025-godu--kak-poluchit-i-ne-oblazhatsya?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/offer-vo-frontende-v-2025-godu--kak-poluchit-i-ne-oblazhatsya</guid>
      <description><![CDATA[<p>Как получить оффер во фронтенде в 2025: разбор кейса с ментором Дмитрием Борцовым. Советы по резюме, переговорам и навыкам, которые помогли кандидату выйти на зарплату в 380К. Анализ рынка и типичных ошибок.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/offer-vo-frontende-v-2025-godu--kak-poluchit-i-ne-oblazhatsya">Оффер во фронтенде в 2025 году: как получить и не облажаться</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Советы]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[Собеседование]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Vue]]></category>
      <category><![CDATA[Пет-проект]]></category>
      <category><![CDATA[Тимлид]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 18 Sep 2025 14:00:04 GMT</pubDate>
      <content:encoded><![CDATA[<p>Рынок фронтенда в 2025 всё ещё платит <a href="https://thecode.media/">хорошо</a>, но платит выборочно. Те, кто умеет строить интерфейсы с мыслью об архитектуре, производительности и продукте, получают предложения, которые заметно выше среднего. На примере <a href="https://t.me/soft_skillz">нашего шоу </a>«Код найма» и кейса ментора Дмитрия Борцова совместно с менти Ярославом Грачёвым покажем, как корректная упаковка, таргетинг и умелая переговорная стратегия превращают «сложный» поиск в оффер на 380к.</p><p>Дмитрий Борцов — руководитель разработки клиентских интерфейсов в PREMIER.ONE. В его подчинении более 60 инженеров, распределённых между вебом, Android, iOS и SmartTV. В индустрии он уже 15 лет: прошёл путь от фриланса и собственной студии до руководства крупными командами. Такой опыт, как он сам говорит, позволяет видеть рынок «с двух сторон» — понимать, что нужно бизнесу и какие компетенции позволяют разработчику стоить дороже. Сегодня Дмитрий совмещает управленческую роль с менторством: вместе с техлидом PREMIER.ONE Андреем Автушенко он развивает платформу <a href="https://frontend-alliance.ru/?utm_source=tproger&amp;utm_medium=post&amp;utm_campaign=kodnaimafinal&amp;utm_content=tproger">Frontend Alliance</a>, где в формате парного наставничества помогает фронтендерам — от джунов до тимлидов — прокачивать хард и софт скиллы, готовиться к собеседованиям и строить карьеру с опорой на реальную практику.</p><h2>Фронтенд под давлением: рынок стал жёстче, но не умер</h2><p>Сегодня фронтенд-разработчикам всё чаще приходится отвечать на вопрос: «А рынок-то живой или всё?» Картинка действительно изменилась. Ещё несколько лет назад компании практиковали агрессивный найм: быстро расширяли команды, нанимали десятки разработчиков сразу, а через полгода без сожалений сокращали половину штата. Это было дорого, но при низкой ключевой ставке позволительно: деньги горели, но продукт успевал расти.</p><p>Теперь правила другие. Ключевая ставка выросла, бюджеты сократились, и каждая новая должность в команде проходит через многослойный фильтр. Набрать людей «про запас» уже нельзя, поэтому требования к кандидатам стали заметно выше.</p><p>Тем не менее, говорить о «смерти» фронтенда было бы <b>ошибкой</b>. Спрос не исчез, он просто сузился до тех, кто способен приносить реальную ценность. И здесь проявляется давний раскол: 95% специалистов ограничиваются задачами уровня интерфейсной косметики, а оставшиеся 5% умеют проектировать системы, предлагать архитектурные решения и смотреть шире макета. Именно за этих людей компании будут бороться при любых условиях.</p><p>Интересно, что попасть в эти «пять процентов» можно и на старте. Даже среди джунов встречаются разработчики, которые выделяются скоростью обучения, широтой мышления и готовностью брать на себя ответственность. Для них рынок остаётся открытым, тогда как «среднячки» рискуют застрять в бесконечных собеседованиях.</p><h2>Что должен уметь фронтендер в 2025 году и как попасть в «5% из 95»</h2><p>Уровень middle и senior во фронтенде больше не определяется знанием пары фреймворков. Базовый «джентльменский набор» очевиден: HTML, CSS, JavaScript и хотя бы один современный фреймворк — React, Vue, Angular или Svelte. Сегодня к нему де-факто добавился TypeScript: без него в резюме вы рискуете выглядеть устаревшими, даже если на проекте TS практически не используется. Работодатели хотят видеть уверенную работу с ним, потому что это напрямую ассоциируется со стабильностью и предсказуемостью кода.</p><p>Дальше идут надстройки, которые начинают выделять кандидата. Это метафреймворки вроде Next.js или альтернативы с упором на SSR и SSG, понимание разных паттернов рендера и умение применять их под конкретный продукт. Сюда же — юнит-тесты. Никто не будет устраивать экзамен на знание Jest, но сам факт владения тестированием сразу повышает ценность инженера.</p><p>Самый заметный маркер — архитектурные практики. Фронтендер, который мыслит архитектурно, понимает FSD, может объяснить, зачем нужны микрофронты (и когда они не нужны), сразу выделяется на фоне тех, кто «просто собирает фичи». Настроить приложение так, чтобы через два года его не пришлось переписывать, — это компетенция, которая превращает разработчика в дорогого специалиста.</p><p>При этом стек сам по себе не делает из мидла сеньора. Настоящее отличие — в мышлении. Сеньор умеет общаться с соседними командами, отстаивать нужные изменения в API или инфраструктуре, учитывать долгосрочные риски продукта. Это опыт, который не заменят ни курсы, ни туториалы. И именно он отличает того, кто «пишет код», от того, кто создаёт систему.</p><h2>Найм и подготовка кандидата: где спотыкаются фронтендеры</h2><p>Первое, что бросается в глаза при просмотре резюме фронтендеров, — это ошибки самопрезентации. Человек может написать «переписал приложение на новый фреймворк» и не уточнить, что это сократило время загрузки на 30% или сняло половину багов в проде. Для HR выглядит как рядовая строчка, хотя на деле это серьёзное достижение. Добавим сюда непонимание того, как работает HeadHunter: большинство кандидатов просто игнорируют логику поиска и фильтров, и их резюме тонет в выдаче. В итоге, 85% проблем — это не недостаток скиллов, а то, как они упакованы.</p><p>Работа ментора начинается именно с этого: помочь собрать рабочее резюме и научить играть по правилам площадок. Но это лишь малая часть. Основная работа — скорректировать харды и софты, довести знания до актуального уровня, натренировать коммуникацию. Ведь первое собеседование с HR часто решает, <b>попадёте ли вы вообще на технический этап</b>. Поэтому вместе с резюме разбирается поведение: как отвечать рекрутеру, какие вопросы задавать, как «продавить» интерес к себе.</p><p>Типичный план менторской работы занимает от двух до шести недель у специалистов с опытом — если задача ограничивается «освежить знания и подтянуть резюме». Для выпускников массовых онлайн-курсов это уже четыре месяца и больше: приходится достраивать базу, убирать пробелы, переучивать. У новичков срок может растянуться до полугода и дальше, и тут всё зависит от предрасположенности к стеку и дисциплины.</p><p>Отдельный вызов — мотивация. Когда человек месяцами безуспешно ищет работу, у него закономерно опускаются руки. Но ментор — не коуч по вере в себя. Его задача — показать ошибки, дать направление, поддержать обратной связью. А вот сама мотивация должна рождаться внутри. Часто оказывается, что проблема банальна: кандидаты игнорируют рекомендации. Например, используют автокликеры, которые рассылают сотни откликов без сопроводительных писем. Конверсия такого «спама» очевидна: <b>нулевая</b>. Настоящая работа требует внимания к деталям, дисциплины и готовности честно исправлять свои ошибки.</p><h2>Кейс «Кода найма»: как Ярослав Грачёв выбил оффер в 380К</h2><p>Когда к Дмитрию обратился Ярослав, сразу стало ясно: этот кандидат будет работать до конца. Мотивация была жёсткой — беременная жена, переезд в Москву, ипотека. На первом звонке ментор проверил главное: что Ярослав не «красит кнопки», а действительно решает задачи. Этого хватило, чтобы выстроить доверие и составить план.</p><p>Первое, что пришлось менять, — резюме. Вместо сухого «работал три года» появилось описание проектов и секция «Обо мне». Ярослав даже перефотографировался, чтобы профиль выглядел живым. Параллельно он учился работать с алгоритмами HeadHunter и GPT: HH поднимал резюме в выдаче, а бот имитировал собеседования. Через две недели у кандидата уже был первый оффер.</p><p>Ситуация была интересной: предложение на 300 тысяч выглядело заманчиво, но ментор настоял не торопиться. Аргументы были простыми: поток откликов и приглашений уже пошёл, значит, офферы будут и дальше. Они вместе придумали безопасную отговорку для HR и договорились ждать неделю. Ставка сыграла — скоро пришёл новый оффер на 360 тысяч.</p><p>И тут началась работа с переговорами. Дмитрий считал, что Ярослав стоит дороже, и предложил сыграть на личных обстоятельствах: «Переезд, ипотека, второй ребёнок — дайте больше». Обычно такой прямолинейный запрос не работает, но в этот раз HR пошёл навстречу и поднял ставку ещё на 20 тысяч. Сработало сочетание доверительной коммуникации и того, что за спиной у кандидата был запасной оффер.</p><p>По словам Дмитрия, ориентироваться стоит не только на цифру. Сигналы того, что можно просить больше, — это стабильный поток интервью и высокая конверсия в техсобесы. Если три технички в неделю превращаются в офферы, значит, цена кандидата — вопрос времени и настойчивости.</p><p>А дальше начинается игра на рынке: один оффер на 250 можно держать как «аварийный», второй на 300 использовать для торга, третий — поднять до 350. Главное — не зажиматься на звонках с HR: «их мотивация — провести тебя дальше, деньги они получают за закрытых кандидатов», — напоминает Дмитрий. Поэтому правило простое: дружелюбие, открытость и готовность разговаривать.</p><p>Итог кейса Ярослава показал, как за 14 дней можно пройти путь от шаблонного резюме до оффера выше ожиданий. Но за этим стояла системная работа: переписанное CV, домашка с тренировками, переговорные сценарии и дисциплина кандидата.</p><h2>Советы начинающим фронтендерам</h2><p>Дмитрий выделяет несколько аспектов, которым стоит уделять внимание в вопросе оффера мечты:</p><h3>Не рассчитывайте только на ментора</h3><p>Ментор может сильно ускорить путь: кто-то готовит к собесам, кто-то учит реально работать. Но это не панацея. Без самостоятельного копания в YouTube, статьях и пет-проектах вы просто застрянете. При этом нужно быть готовым к тому, что половина выученного окажется невостребованной, а рынок попросит ещё десяток дополнительных технологий.</p><h3>Начинайте с основы, а не с фреймворка</h3><p>Ключевой навык фронтендера — JavaScript. «Все есть JavaScript», — как сказал Илья Климов. React, Vue, Angular, Svelte — это лишь надстройки. Если понимаете сам язык и то, как он работает под капотом, вы сможете писать на чем угодно, хоть в фронте, хоть на Node.js в бэке.</p><h3>Не ведитесь на быстрые рецепты успеха</h3><p>Онлайн-школы и ютуберы любят обещать: «выучишь React — и всё в шоколаде». Но без знания JS никакой React не спасёт. На собеседованиях почти всегда спрашивают именно JavaScript, а не то, как вы намагичили интерфейс на очередном фреймворке.</p><h3>Думайте о том, зачем работает код</h3><p>Фронтендер, который просто копирует чужие решения, быстро упирается в потолок. Важно не только знать синтаксис, но и понимать, зачем язык ведёт себя именно так. Это отличает разработчика, который просто «собирает интерфейсы», от того, кто способен решать реальные задачи.</p><p>История Дмитрия Борцова и Ярослава Грачёва — это иллюстрация того, что даже в перегретом и избирательном рынке фронтенда можно найти своё место. Ключ к успеху — не только в технической базе, но и в умении правильно упаковать опыт, показать насмотренность и держать фокус на том, что важно работодателю. Для джунов это часто означает вложиться в JavaScript, а не в очередной модный фреймворк. Для мидлов и выше — развивать софты и стратегически подходить к собеседованиям. А для всех уровней — не замыкаться в одиночном обучении, а искать наставников и сообщество, которые помогают расти быстрее.</p><p>Фронтенд в 2025-м всё ещё щедр, но не прощает случайности. И чем раньше разработчик перестанет полагаться на удачу и начнёт работать над собой системно, тем выше шансы получить оффер, который изменит карьеру.</p>]]></content:encoded>
    </item>
    <item>
      <title>Разработчик объяснил, почему React тормозит развитие фронтенда</title>
      <link>https://tproger.ru/news/razrabotchik-obyasnil--pochemu-react-tormozit-razvitie-frontenda</link>
      <comments>https://tproger.ru/news/razrabotchik-obyasnil--pochemu-react-tormozit-razvitie-frontenda?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/razrabotchik-obyasnil--pochemu-react-tormozit-razvitie-frontenda</guid>
      <description><![CDATA[<p>Разработчик заявил, что React тормозит развитие фронтенда: фреймворк выбирают «по умолчанию», игнорируя более быстрые и современные альтернативы</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/razrabotchik-obyasnil--pochemu-react-tormozit-razvitie-frontenda">Разработчик объяснил, почему React тормозит развитие фронтенда</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Инновации]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 16 Sep 2025 11:01:29 GMT</pubDate>
      <content:encoded><![CDATA[<p>React, один из самых популярных JavaScript-фреймворков, перестал побеждать за счет технических преимуществ и теперь «побеждает по умолчанию». К такому выводу пришел разработчик Лорен Стюарт в своей свежей <a href="https://www.lorenstew.art/blog/react-won-by-default/">статье</a>.</p><h2>«Выбор React — это рефлекс»</h2><p>Автор утверждает, что команды слишком часто выбирают React не потому, что он подходит под задачи, а потому, что «все его знают».</p><p>Это, по его словам, убивает конкуренцию и мешает развитию альтернатив — таких как Svelte, Solid или Qwik. Эти фреймворки предлагают новые архитектурные модели, быстрее работают в ряде сценариев, но редко получают шанс, потому что выбор уже сделан заранее.</p><h2>Технологии 2013 года в 2025-м</h2><p>React до сих пор использует концепции, созданные более 10 лет назад: виртуальный DOM, эффект-хуки, ререндеринг через reconcile.</p><p>Хотя команда React продолжает развивать фреймворк (например, через Server Components и React Compiler), сам подход остается сложным и неэффективным — особенно в сравнении с конкурентами, которые перераспределяют нагрузку на этапе сборки и избегают избыточных вычислений в браузере.</p><h2>Проблема — не в React, а в «React-по-умолчанию»</h2><p>По мнению автора, React сам по себе не плох. Проблема — в «монокультуре», которая блокирует инновации.</p><p>Меньше внимания уделяется веб-стандартам, большинство вакансий требует именно React, а университеты ориентируются на рынок, а не на фундаментальные знания.</p><h2>Что делать</h2><p>Разработчик призывает руководителей и команды делать выбор не по инерции, а осознанно: оценивать реальные требования проекта, пробовать альтернативы, не бояться использовать Svelte, Solid или Qwik хотя бы в отдельных модулях.</p><p>В противном случае, предупреждает он, вся фронтенд-экосистема будет развиваться медленнее — а значит, в убытке окажутся все.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как сеньоры документируют проекты: протокол архитектурных решений</title>
      <link>https://tproger.ru/articles/kak-senory-dokumentiruyut-proekty--protokol-arhitekturnyh-rewenij</link>
      <comments>https://tproger.ru/articles/kak-senory-dokumentiruyut-proekty--protokol-arhitekturnyh-rewenij?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Даровская Маша]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-senory-dokumentiruyut-proekty--protokol-arhitekturnyh-rewenij</guid>
      <description><![CDATA[<p>Как сеньоры документируют архитектуру без боли. Обзор подхода ADR: шаблоны, примеры из практики и комментарии экспертов. Ускорьте онбординг и перестаньте объяснять одно и то же.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-senory-dokumentiruyut-proekty--protokol-arhitekturnyh-rewenij">Как сеньоры документируют проекты: протокол архитектурных решений</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Unity]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Практика]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Tor]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Scala]]></category>
      <category><![CDATA[Amazon]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[GitLab]]></category>
      <category><![CDATA[MIT]]></category>
      <category><![CDATA[Финтех]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Lua]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 09 Sep 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p><i>Это перевод <a href="https://dev.to/koladev/how-senior-software-engineers-document-their-project-1nf4">статьи</a> автора <a href="https://dev.to/koladev">Мангабо Колаволе</a> с портала DevTo с комментариями экспертов.</i></p><p>Есть одна задача, которую программисты терпеть не могут — но именно она отличает хорошего инженера от посредственного: как они документируют свой проект? Несколько лет назад я отвечал за запуск финтех-проекта. Мы выбрали стратегию быстрого старта, поэтому масштабируемость не стала для нас приоритетом. Главной целью было проверить гипотезу — и мы двигались вперёд, разрабатывая API, архитектуру и системы —  с упором на простоту, не особенно задумываясь о будущем.</p><p>Но я отвечал за бэкенд и инфраструктуру — и понимал: как бы хороша ни была моя память, через шесть месяцев я не смогу вспомнить все технические детали.</p><p>Во время работы я наткнулся на подход, который мне очень понравился: ADR — Architectural Decision Record, или «протокол архитектурных решений».</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-09-05/7d1206a7-6729-4bcb-ab55-63d59240df12.png" alt="" /></figure><p>По сути, это документ, в котором
фиксируются все изменения, внесённые в архитектуру: само решение, его влияние и
полученные уроки.</p><p>Проще говоря, это как личный дневник —
только для всей команды.</p><h2>Почему это важно?</h2><p><b>Память
— ненадёжна.</b> Мы часто забываем, почему выбрали одну
архитектурную модель, а не другую. Документирование изменений помогает
восстановить ход мыслей и избежать повторения одних и тех же ошибок.</p><p><b>Это
усиливает команду.</b> Представьте, что вы перепробовали
несколько вариантов решения проблемы и зафиксировали как удачные, так и
неудачные попытки. Это не просто ваш личный опыт — это знание, которым могут
воспользоваться все, включая тех, кто придёт после вас.</p><p><b>Будущие
разработчики скажут вам спасибо.</b> Подумайте о человеке,
который через пять лет будет разбираться в вашем коде. Если вы не оставили
объяснений, он, скорее всего, будет мучиться, пытаясь понять, зачем было
сделано то или иное изменение. А теперь представьте другого разработчика в
другой компании, который находит ADR-документ с чётким объяснением принятого
решения. Он, без сомнения, будет вам благодарен.</p><p>Синьор-фронтендер из ВК Маргарита Лукина, автор телеграм-канала <a href="https://t.me/frontend_kitchen">«Фронтенд кухня»</a>:</p><blockquote>Ценность ADR я впервые осознала в 2019 году. В команду, где работала, активно набирали новых ребят, и приблизительно раз в неделю кто-нибудь из новых разработчиков спрашивал "а почему это сделано так, а не иначе?" Приходилось постоянно давать ответы на одни и те же вопросы, и тогда-то я и поняла, насколько будет удобно записывать ответы где-нибудь в документацию в confluence и просто кидать ссылку новичкам. <br /><br />В 2019 году я еще не знала сам термин ADR и говорила "документация". С термином я познакомилась совсем недавно — этим летом, на курсе по архитектуре монолитных приложений. Тогда я поняла, насколько эффективно можно использовать ADR для ускорения разработки и уменьшения TTM. Дело в том, что начиная разрабатывать новый проект, разработчик первое время (от месяца до полугода! всё зависит от размера проекта) погружается в проект — разбирается, как всё устроено, чтобы вносить изменения соответственно архитектуре. В этот период разработчик, по сути, составляет собственные adr —  обычно в виде мыслеобразов в своей голове :) Если записать основные решения, разработчик сможет намного быстрее погрузиться в проект.</blockquote><h2>Как писать ADR?</h2><p>Существует несколько общепринятых правил, но
вы всегда можете адаптировать их под себя.</p><p>Вдохновившее меня соглашение можно найти на <a href="https://adr.github.io/madr/">GitHub</a>
. Вы также можете ознакомиться с процессом <a href="https://docs.aws.amazon.com/prescriptive-guidance/latest/architectural-decision-records/adr-process.html">ADR на Amazon</a>.</p><p>Вот пример шаблона, который вы можете
использовать.</p><p>Такой тип документа может находиться прямо в репозитории проекта, в Confluence или, например, в JIRA.</p><p>В моей последней компании, где я работал фронтенд-разработчиком, не существовало одного централизованного документа, фиксирующего все архитектурные изменения. Вместо этого мы использовали задачи GitLab и привязывали каждое архитектурное изменение к соответствующей ветке. Это позволяло отслеживать причины изменений даже спустя месяцы после их внедрения.</p><p>Практика спасала нас бесчисленное количество раз. Как я всегда говорю: не важно, насколько вы или ваши коллеги умны — будь то технический директор, менеджер или любой другой участник команды — никто не помнит каждое техническое решение, принятое два года назад.</p><p>Синьор-фронтендер из ВК Маргарита Лукина, автор телеграм-канала <a href="https://t.me/frontend_kitchen">«Фронтенд кухня»</a>:</p><blockquote>Многие руководители хотят видеть на своём проекте разработчиков, которые "сразу, без раскачки" начнут перформить. Совсем избежать периода погружения невозможно, но можно ускорить его в десятки раз за счёт ADR</blockquote>]]></content:encoded>
    </item>
    <item>
      <title>Как сделать сайт доступнее: инструменты accessibility, которые вы можете внедрить прямо сейчас</title>
      <link>https://tproger.ru/articles/kak-sdelat-sajt-dostupnee--instrumenty-accessibility--kotorye-vy-mozhete-vnedrit-pryamo-sejchas</link>
      <comments>https://tproger.ru/articles/kak-sdelat-sajt-dostupnee--instrumenty-accessibility--kotorye-vy-mozhete-vnedrit-pryamo-sejchas?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Дима Державин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-sdelat-sajt-dostupnee--instrumenty-accessibility--kotorye-vy-mozhete-vnedrit-pryamo-sejchas</guid>
      <description><![CDATA[<p>Инструменты для улучшения accessibility сайтов: Lighthouse, WAVE, IBM, Accessibility Insights, Storybook и плагины для разработчиков.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-sdelat-sajt-dostupnee--instrumenty-accessibility--kotorye-vy-mozhete-vnedrit-pryamo-sejchas">Как сделать сайт доступнее: инструменты accessibility, которые вы можете внедрить прямо сейчас</a>»</p>]]></description>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Веб-дизайн]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 04 Sep 2025 14:00:04 GMT</pubDate>
      <content:encoded><![CDATA[<p>При создании современных веб-сайтов разработчики фокусируются на сроках, дизайне и производительности, ставя доступность на второй план. Почему так происходит?</p><p>Помимо низкого приоритета, ситуацию усугубляет распространенный миф:</p><p><i>«Доступность нужна лишь небольшой группе людей»</i></p><p>Давайте сразу развеем это заблуждение. Проблемы с доступностью касаются не только людей с инвалидностью, но и:</p><ul><li>Пожилых пользователей;</li><li>Людей с временными травмами (например, со сломанной рукой);</li><li>Тех, кто пользуется сайтом в неидеальных условиях (яркое солнце или плохая погода).</li></ul><blockquote>Да, доступность нужна не только людям с инвалидностью, но важно помнить, что именно они наиболее уязвимы к проблемам цифровой доступности.</blockquote><p>К тому же, руководство WCAG многим кажется сложным и объёмным документом, что заставляет откладывать изучение.</p><p>В статье мы рассмотрим инструменты, которые помогут вам превратить сложные требования к доступности в понятные и автоматизируемые задачи.</p><h2>Как люди с ограничениями жизнедеятельности пользуются цифровыми сервисами?</h2><p>Прежде чем перейти к инструментам, давайте разберёмся, как именно пользователи с инвалидностью/ограничениями жизнедеятельности пользуются цифровыми сервисами.</p><h3>Скринридеры (NVDA, VoiceOver, Orca)</h3><p>Скринридер — это программа, которая с помощью синтеза речи или шрифта Брайля представляет пользователю содержимое экрана. Например, в случае шрифта Брайля — в форме рельефно-точечного шрифта.</p><p>Скринридер работает <i>не с отрисованной страницей</i>, а с деревом доступности, которое строится на основе семантической HTML-разметки. Чем семантичнее вёрстка, тем точнее скринридер представит контент пользователю.</p><blockquote>Строго говоря, «скринридер» — это жаргонизм. В официальных русскоязычных документах (в частности, ГОСТ-Р 52872-2019) этот класс вспомогательного программного обеспечения называется «программа экранного доступа»</blockquote><h3>Клавиатура</h3><p>Для одних людей клавиатура — альтернатива мыши, которая является вопросом удобства и личных предпочтений, для других — вынужденная необходимость, например, для пользователей с различными нарушениями рук, которые физически не могут использовать мышь или сенсорную панель.</p><p>В этом случае пользователи полагаются на логичный порядок перемещения фокуса (клавиша Tab — переместиться вперёд, Shift+Tab — вернуться назад) и возможность управлять сложными компонентами (меню, слайдерами) с помощью стрелок и других клавиш.</p><blockquote>Пример хорошей поддержки прямого клавиатурного управления можно найти в Web-версиях Яндекс Музыки и на Кинопоиске: в плеере нажатие клавиши k приостанавливает и возобновляет воспроизведение, а курсорные стрелки отвечают за перемотку и изменение громкости</blockquote><h3>Увеличение экрана</h3><p>Пользователи с ослабленным зрением используют целый набор инструментов для увеличения и настройки контента под свои нужды:</p><ul><li>Масштабирование страницы в браузере;</li><li>Программы увеличения экрана;</li><li>Коррекция цветовой палитры;</li><li>Изменение внешнего вида указателей;</li><li>Озвучивание текстовой информации при помощи синтезатора речи;</li><li>Пользовательские стили со своими шрифтами и цветами.</li></ul><p><b>Совет:</b> Прежде чем браться за сложные инструменты, протестируйте интерфейс собственноручно: попробуйте пройтись по сайту только с помощью клавиатурного фокуса и проверьте, как он ведёт себя при масштабировании до 200%. Это даст вам понимание о ключевых проблемах с доступностью.</p><p>Теперь перейдём к инструментам, которые помогут автоматизировать ручные проверки.</p><blockquote>Важно отметить: автоматизированные инструменты находят только 30-40% всех проблем цифровой доступности. ​​Отлично для начала, но дальше идеально — парное экспертное тестирование. <br /><br />Незрячий эксперт и зрячий исследователь в процессе ручного аудита выявляют и приоритезирует проблемы доступности, а также могут представить их в человекочитаемом виде и предложить оптимальные способы исправления.</blockquote><h2>Lighthouse (от Google)</h2><p><i>Lighthouse</i> — простой и популярный инструмент, встроенный прямо в Chrome.</p><figure><img src="https://media.tproger.ru/user-uploads/113154/2025-08-28/30c94755-5162-4a5d-88c0-3f9bb0dcd14e.png" alt="Пример отчёта созданного в Lighthouse" /><figcaption>Пример отчёта созданного в Lighthouse</figcaption></figure><p>Для запуска <i>Lighthouse</i> нужно:</p><ul><li>Открыть браузер;</li><li>Открыть консоль разработчика (F12);</li><li>Перейти во вкладку <i>Lighthouse</i>;</li><li>Выбрать категорию Accessibility;</li><li>Нажать «Analyze page load».</li></ul><p>Схожий функционал можно найти во всех основных браузерах:</p><ul><li>Firefox — <a href="https://firefox-source-docs.mozilla.org/devtools-user/accessibility_inspector/">Accessibility Inspector</a></li><li>Safari — <a href="https://developer.apple.com/safari/tools/">Audit</a></li><li>Microsoft Edge — <a href="https://learn.microsoft.com/en-us/microsoft-edge/devtools/accessibility/reference">Accessibility Checker</a></li></ul><p>После запуска <i>Lighthouse</i> соберёт отчёт с оценкой от 0 до 100 баллов и списком проверенных критериев, разделенных на три группы:</p><ul><li><b>Passed audits:</b> что работает правильно;</li><li><b>Opportunities:</b> рекомендации по улучшению;</li><li><b>Diagnostics: </b>дополнительные советы, не влияющие напрямую на оценку.</li></ul><p>Затем <i>Lighthouse</i> рассортирует проблемы по категориям:</p><ul><li><b>Навигация: </b>доступность с клавиатуры, логичный порядок фокуса;</li><li><b>ARIA: </b>правильное использование ARIA-атрибутов;</li><li><b>Цвет и контраст: </b>достаточность контраста для слабовидящих;</li><li><b>Семантика и структура:</b> правильность HTML-разметки;</li><li><b>Имена и метки:</b> наличие описательных текстов для элементов форм и ссылок;</li><li><b>Прочее:</b> рекомендации согласно лучшим практикам.</li></ul><h2>Accessibility Insights (от Мicrosoft)</h2><p><a href="http://accessibilityinsights.io">Accessibility Insights</a> — это open source-инструмент от Microsoft <a href="https://opensource.microsoft.com/blog/2019/03/12/microsoft-open-sources-accessibility-insights/">выпущенный в 2019 году</a>, который предлагает комплексное решение для поиска и устранения проблем.</p><figure><img src="https://media.tproger.ru/user-uploads/113154/2025-08-28/71557f7b-32eb-4349-8848-94b2a0655aa0.png" alt="Accessibility Insights плагин для Google Chrome" /><figcaption>Accessibility Insights плагин для Google Chrome</figcaption></figure><p><i>Accessibility Insights</i> предоставляет два вида аудита:</p><ul><li>FastPass: быстрый аудит для ежедневного использования, который способен найти критические проблемы сайта за считанные минуты;</li><li>Assessment: глубокий аудит на соответствие стандартам WCAG 2.1 Level AA предназначенный для тестировщика или разработчика.</li></ul><p>Его ключевое преимущество — обучающие элементы. Он не просто находит ошибку, но и объясняет причину проблемы и как её исправить. Также он помогает удобно создавать тикеты в трекере (например, Jira), включая описание, рекомендации и стандарт WCAG.</p><p><i>Accessibility Insights</i> — полноценная экосистема доступности. Отлично подходит для команд, которые хотят глубоко разобраться в теме и встроить a11y в процесс разработки.</p><h2>WAVE</h2><p><a href="https://wave.webaim.org/">WAVE</a> — удобный инструмент для визуальной оценки доступности сайта. Его ключевое преимущество в том, что он показывает ошибки прямо поверх вашего сайта.</p><p>Инструмент доступен как веб-сервис и как браузерное расширение.</p><figure><img src="https://media.tproger.ru/user-uploads/113154/2025-08-28/3e7d0f15-0f0e-4798-8655-0aa3e704c4b8.png" alt="Пример визуальной оценки доступности при помощи WAVE" /><figcaption>Пример визуальной оценки доступности при помощи WAVE</figcaption></figure><p><i>WAVE</i> помечает элементы на странице цветными иконками:</p><ul><li>Красные (Errors): критические ошибки, которые с высокой вероятностью нарушают доступность.</li><li>Желтые (Alerts): предупреждения о возможных проблемах, требующих ручной проверки.</li><li>Зеленые (Features): подсвечивают элементы, которые реализованы правильно.</li><li>Синие (Structural Elements): показывают структурные и семантические элементы HTML5.</li><li>Иконки контрастности — показывают результаты проверки контраста текста и фона.</li></ul><p><i>WAVE</i> более простой инструмент по сравнению с <i>Lighthouse</i>, но он отлично подходит для быстрого визуального поиска и исправления ошибок прямо в процессе верстки.</p><h2>IBM Accessibility (от IBM)</h2><p><a href="https://www.ibm.com/able/">IBM Accessibility</a> — это не просто инструмент, а целая экосистема. Она включает в себя принципы, практики и инструменты для всех этапов жизненного цикла продукта — от проектирования до разработки и тестирования.</p><figure><img src="https://media.tproger.ru/user-uploads/113154/2025-08-28/4bffe477-7419-4070-82b1-3ab584998895.png" alt="" /><figcaption>Экосистема IBM Accessibility</figcaption></figure><p>Из конкретных <a href="https://www.ibm.com/able/toolkit/tools/#develop">инструментов для разработчиков</a> IBM предлагает:</p><ul><li>Браузерные расширения для <a href="https://chrome.google.com/webstore/detail/ibm-equal-access-accessib/lkcagbfjnkomcinoddgooolagloogehp">Chrome</a>, <a href="https://addons.mozilla.org/en-US/firefox/addon/accessibility-checker/">Firefox</a>, <a href="https://microsoftedge.microsoft.com/addons/detail/ibm-equal-access-accessib/ompccpejakabkmfepbijnagedbdfldka">Edge</a>;</li><li>Пакеты для встраивания в CI/CD (<a href="https://central.sonatype.com/artifact/com.ibm.able/accessibility-checker">Java</a>, <a href="https://www.npmjs.com/package/accessibility-checker">NPM</a> и <a href="https://www.npmjs.com/package/cypress-accessibility-checker">Cypress</a>).</li></ul><figure><img src="https://media.tproger.ru/user-uploads/113154/2025-08-28/77b0b7f7-3ed0-4811-9bbc-fc34df3d98a0.png" alt="" /><figcaption>Accessibility Assessment плагин для Google Chrome</figcaption></figure><p><i>IBM Accessibility</i> подойдёт крупным компаниям, желающим системно внедрить доступность на всех этапах работы — от проектирования и разработки до тестирования и поддержки.</p><h2>Библиотеки компонентов</h2><p>Готовые библиотеки с уже продуманной доступностью избавляют от необходимости реализовывать сложную логику управления фокусом и ARIA-атрибутами с нуля.</p><p>Обычно такие библиотеки содержат в себе:</p><ul><li>Набор headless-компонентов с правильным ролями и ARIA-атрибутами;</li><li>Поддержку управления фокусом и навигацией через клавиатуру;</li><li>Набор хуков для кастомной поддержки пользовательский действий.</li></ul><p>Пример библиотек:</p><ul><li>Для React — <a href="https://reakit.io/">Reakit</a>, <a href="https://react-spectrum.adobe.com/react-aria/index.html">React Aria</a>;</li><li>Для Vue — <a href="https://vuetifyjs.com/en/">Vuetify</a>, <a href="https://quasar.dev/">Quasar</a>, <a href="https://www.creative-tim.com/vuematerial">Vue Material;</a></li><li>Для Angular — <a href="https://material.angular.dev/">Angular Material</a>.</li></ul><h2>A11y плагин для Storybook</h2><p><a href="https://storybook.js.org/addons/@storybook/addon-a11y">Плагин</a> автоматически проверяет ваши компоненты на доступность прямо в процессе разработки в <i>Storybook</i>. Он показывает ошибки и предупреждения в панели, мгновенно давая рекомендации по исправлению проблем.</p><figure><img src="https://media.tproger.ru/user-uploads/113154/2025-08-28/fcbc6cc1-4513-4a6d-86b7-aaec63fcb997.png" alt="Storybook Accessibility Addon" /><figcaption>Accessibility аддон для Storybook</figcaption></figure><h2>A11y плагин для среды разработки</h2><p>Интегрировать проверку доступности можно прямо в процесс написания кода. Это помогает отлавливать ошибки на самом раннем этапе. В больших компаниях такие плагины уже неотъемлемая часть процесса разработки.</p><p>Вот основные из них:</p><ul><li>React: <a href="https://github.com/jsx-eslint/eslint-plugin-jsx-a11y">eslint-plugin-jsx-a11y</a> для React;</li><li>Vue: <a href="https://github.com/vue-a11y/eslint-plugin-vuejs-accessibility">eslint-plugin-vuejs-accessibility</a>;</li><li>Angular: <a href="https://github.com/mgechev/codelyzer">Codelyzer</a> и <a href="https://github.com/angular-eslint/angular-eslint">angular-eslint</a>.</li></ul><h2>Заключение</h2><p>Внедрение доступности — это непрерывный процесс, который можно и нужно автоматизировать. Существуют инструменты для любого уровня и задачи: от лёгких плагинов для визуальной проверки до комплексных экосистем.</p><p>Начать можно с малого, например, провести базовый аудит с помощью <i>Lighthouse</i>, протестировать навигацию с клавиатуры или попробовать воспользоваться сайтом с помощью скринридера. Затем постепенно внедрять автоматизацию проверок.</p><p><b>И главное:</b> не забывайте тестировать доступность с реальными пользователями. Ни один автоматический инструмент не заменит обратной связи от человека.</p><figure><img src="https://media.tproger.ru/user-uploads/113154/2025-08-28/5149ae33-ecc9-4540-9e1b-d50c286820d0.png" alt="" /></figure><p>Для этого существуют специальные эксперты по доступности, в том числе люди с особыми потребностями, которые регулярно сталкиваются с ограничениями интерфейсов в реальной жизни.</p><p>Также можно посмотреть <i>логи</i> сессии, где использовались accessibility инструменты для доступа к сайту и увидеть, где именно возникали проблемы.</p><blockquote>Под «логами» обычно понимают технические файлы, которые создаются автоматически и содержат технические сообщения. <br /><br />В то же время нет инструментов, которые позволяют WEB-странице определить, запущены ли в операционной системе вспомогательные технологии, т.е. сайт (в отличие от нативного мобильного приложения) про скринридер не знает.<br /></blockquote><p>Но в этой статье мы сконцентрировались на инструментах и практиках, которые под силу применить любому разработчику, чтобы сделать свой сайт более доступным.</p>]]></content:encoded>
    </item>
    <item>
      <title>SolidJS и Qwik: фронтенд нового поколения</title>
      <link>https://tproger.ru/articles/solidjs-i-qwik--frontend-novogo-pokoleniya</link>
      <comments>https://tproger.ru/articles/solidjs-i-qwik--frontend-novogo-pokoleniya?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Вадим Егорцев]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/solidjs-i-qwik--frontend-novogo-pokoleniya</guid>
      <description><![CDATA[<p>Обзор SolidJS и Qwik — плюсы и минусы фреймворков. Сравнение SolidJS и Qwik, практические рекомендации по переходу и тенденция отказа от React/Vue.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/solidjs-i-qwik--frontend-novogo-pokoleniya">SolidJS и Qwik: фронтенд нового поколения</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[CSS]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Фреймворки и библиотеки]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Angular]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[Vue]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 03 Sep 2025 12:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p><b>Помните, когда впервые попробовали React/Vue после JS и jQuery?</b> Тот момент, когда всё встало на свои места, и вы поняли — вот оно, будущее фронтенда. В 2025 году разработчики <a href="https://www.reddit.com/r/solidjs/comments/1m4hlzj/im_really_impressed_with_solid/">испытывают</a> похожие чувства с SolidJS и Qwik.</p><h2>Последний рубеж React и Vue</h2><p><b>Согласны, что VDOM превратился в бюрократическую прослойку?</b> Изменили состояние в одном месте — получите полный пересчёт дерева компонентов. Фреймворки заставляют загружать всё сразу, тащат багаж служебного кода. И пока этот код не загрузится, пользователь смотрит на белый экран.</p><p>SSR <a href="https://tproger.ru/translations/rendering-on-the-web">ускоряет</a> загрузку страницы: сервер рендерит HTML, пользователь видит контент и пытается с ним взаимодействовать. Но пока JavaScript не загрузится, ничего не заработает.</p><p>Потом JS наконец подгружается и начинает гидратацию. По сути, он заново создаёт в памяти то же дерево компонентов, которое сервер уже отрендерил в HTML. Выполняется двойная работа. Кстати, в это время пользователь тыкает неработающие кнопки — дотерпит ли он до полной загрузки?</p><p>Системные проблемы не исправить очередным хуком или новой версией фреймворка, поэтому появление SolidJS и Qwik — было вопросом времени.</p><blockquote>Поиск новых решений — здоровый признак развития фронтенда. В конце концов, и Vue был создан потому, что Эвану Ю не хватало облегченной альтернативы AngularJS. Большая тройка фреймворков решает огромный спектр задач, имеет колоссальную поддержку сообщества, но их нельзя назвать идеальным инструментом на все случаи жизни.</blockquote><h2>Обзор SolidJS</h2><p>SolidJS во многом похож на React. Самое интересное — его подход к обновлению интерфейса:</p><ul><li><b>Отсутствие виртуального DOM</b> — Solid напрямую обновляет только те DOM-узлы, которые действительно изменились.</li><li><b>Компоненты как функции инициализации</b> — каждый компонент вызывается только один раз для настройки реактивности.</li><li><b>Сигналы вместо хуков</b> — состояние управляется через createSignal(), который возвращает геттер/сеттер пару.</li></ul><p>Например, когда срабатывает счётчик, Solid не перерисовывает весь компонент. Он точечно обновляет только текст внутри &lt;p&gt;, где используется count():</p><h3>Преимущества SolidJS</h3><p>👍 <b>Производительность и размер бандла</b></p><p>Благодаря отсутствию виртуального DOM и мелкозернистым обновлениям, приложения <a href="https://www.reddit.com/r/reactjs/comments/tsx8hw/solidjs_devex_compared_to_react/?tl=ru">работают</a> быстрее аналогов на React.</p><p>👍 <b>Простота освоения</b></p><p>Синтаксис SolidJS похож на React. Функциональные компоненты, JSX, концепции вроде Suspense и Error Boundaries — всё это есть в Solid. Изучение основ <a href="https://www.reddit.com/r/solidjs/comments/1len1pf/comment/myi8qci/?utm_source=share&amp;utm_medium=web3x&amp;utm_name=web3xcss&amp;utm_term=1&amp;utm_content=share_button">займёт</a> 1-2 дня, если есть опыт с MobX/effector/RxJS.</p><p>👍 <b>Стабильность</b></p><p>Фреймворк находится на стабильной версии 1.x. Это означает отсутствие кардинальных изменений API, в отличие, например, от ситуации со Svelte, где сосуществуют версии 4 и 5 с разными подходами.</p><p>👍 <b>Совместимость с React</b></p><p>SolidJS совместим с экосистемой React. Можно переиспользовать дизайн-системы и компоненты в legacy-приложениях.</p><p>👍 <b>Удобное управление состоянием</b></p><p>Функционал сигналов и сторов покрывают 90% потребностей в управлении состоянием без необходимости подключать внешние библиотеки.</p><h3>Минусы SolidJS</h3><p>👎 <b>Ограниченная экосистема</b></p><p>Выбор готовых компонентов и библиотек значительно меньше, чем у React. Команды тратят больше времени на создание компонентов с нуля: тяжко при работе с таблицами, гридами, формами, валидацией.</p><p>👎 <b>Кривая обучения</b></p><p>Несмотря на знакомый синтаксис, модель реактивности SolidJS отличается от React. Разработчики должны усвоить следующие принципы:</p><ul><li>Избегать условных конструкций непосредственно в компонентах.</li><li>Не деструктурировать пропсы и сторы, чтобы сохранить реактивность.</li><li>Не использовать асинхронный код внутри createEffect.</li></ul><p>👎 <b>Проблемы с инструментарием</b></p><p>Возникают сложности с настройкой компилятора в нестандартных окружениях — монорепозиториях, при запуске тестов или интеграции с другими инструментами. DevTools не дотягивает до аналога у React.</p><p>👎 <b>SolidStart всё ещё развивается</b></p><p>SSR-решение SolidStart пока не достигло зрелости Next.js или Nuxt. Разработчики <a href="https://www.reddit.com/r/solidjs/comments/1len1pf/comment/myml5tt/?utm_source=share&amp;utm_medium=web3x&amp;utm_name=web3xcss&amp;utm_term=1&amp;utm_content=share_button">сообщают</a> о проблемах с гидратацией и других сложностях при работе с серверным рендерингом.</p><h2>Обзор Qwik</h2><p>Qwik — это проект Мишко Хевери (создателя Angular). Идея фреймворка заключается в возможности возобновить работу приложения на клиенте без повторного выполнения кода, который уже был выполнен на сервере.</p><p>В Qwik радикально решили проблему гидратации — полностью отказались от неё. Время до интерактивности (TTI) падает в разы. Пользователь может кликать на кнопки сразу после загрузки HTML, без ожидания разогрева всего приложения.</p><p>Qwik автоматически разбивает код на мелкие чанки и загружает их только при необходимости. Символ $ в коде указывает на границы ленивой загрузки.</p><h3>Плюсы Qwik</h3><p>👍 <b>Мгновенная загрузка</b></p><p>Практически нулевой JavaScript при первоначальной загрузке, следовательно отличные показатели Core Web Vitals.</p><p>👍 <b>Автоматическая оптимизация</b></p><p>Оптимизация на уровне компилятора, умная предзагрузка критических ресурсов. Не нужно думать о разделении кода — Qwik делает это автоматически.</p><p>👍 <b>Знакомый синтаксис</b></p><p>👍 <b>Спасибо за SEO</b></p><p>Быстрая загрузка улучшает ранжирование за счёт полноценного SSR из коробки.</p><h3>Минусы Qwik</h3><p>👎 <b>Молодая экосистема</b></p><p>Ограниченное количество библиотек, мало готовых решений и компонентов. Небольшое сообщество разработчиков (если сравнивать с React/Vue).</p><p>👎 <b>Кривая обучения</b></p><p>Придётся изучать новые концепции. Из-за ленивой загрузки усложняется отладка.</p><blockquote>Qwik — это радикально новая ментальная модель. У фреймворка высокий порог входа: вас ждёт переобучение команды и сложности ручной оптимизации. Чтобы Qwik работал идеально, разработчик должен вручную указывать, что можно лениво загружать, а что нет.</blockquote><p>👎 <b>Сложность интеграции</b></p><p>Трудно интегрировать существующие React/Vue компоненты и ограниченная поддержка сторонних библиотек. Скорее всего, придётся с нуля переписывать код существующего проекта.</p><h2>Экосистема и готовность к продакшену</h2><p>Если сравнивать с React, то экосистема — самое слабое место обоих фреймворков.</p><p>SolidJS имеет SolidStart — метафреймворк с роутингом, SSR и серверными функциями. <a href="https://docs.solidjs.com/quick-start">Документация</a> качественная, сообщество активное. Большинство React-библиотек можно адаптировать без особых проблем, для популярных UI-китов есть готовые порты.</p><p>Qwik развивается в связке с <a href="https://qwik.dev/docs/qwikcity/">Qwik City</a>, который покрывает типовые задачи веб-разработки. <a href="https://www.builder.io/m/qwik">Builder.io</a> активно инвестирует в экосистему, регулярно выходят обновления и новые интеграции.</p><p>Риски есть, но они управляемые. Меньший размер сообщества означает меньше готовых решений и ответов на Stack Overflow. Если не боитесь изучать новое, то выигрыш в производительности перевесит неудобства.</p><h2>Сравнение SolidJS и Qwik</h2><p>SolidJS повышает производительность обновлений. Если данные меняются часто и непредсказуемо — графики, мониторинги, редакторы — Solid даст максимальную отзывчивость.</p><p>Qwik повышает производительность загрузки. Если бизнес зависит от первого впечатления, Qwik обеспечит мгновенный старт.</p><p><b>Медиа</b>, <b>блоги</b> с жёсткими требованиями к TTFB/TTI/INP будут лучше работать на Qwik. Пользователи смогут читать и скроллить без задержки. Интерактив добавляется дозированно — это лучшая стартовая стоимость.</p><p><b>E-commerce</b>, <b>каталоги </b>с SEO и карточками рекомендуется разрабатывать на Qwik. Особенно если на главной тяжёлые модули, а клиенты приходят с поисковиков. Вы выигрываете у конкурентов буквально на первом взаимодействии.</p><p><b>Сложный SPA</b> или <b>дашборд </b>с живыми виджетами и апдейтами будет лучше работать на SolidJS. Точечная реактивность упростит жизнь и снизит цену апдейтов. Solid сияет в проектах, где происходят сотни мелких изменений в секунду.</p><blockquote>Solid хорош для аналогов десктопных приложений в браузере — Figma, Miro. Здесь приложение загружается один раз, а потом работает долго и должно быть максимально отзывчивым. Также Solid будет хорош там, где важна плавность анимаций.</blockquote><p><b>Лэндинги</b>, <b>мобильные приложения</b>, <b>визитки</b> — здесь Solid даст сверхбыструю реактивность и облегчит сборку.</p><p>Оба фреймворка умеют SSR/SSG и стриминг. Solid снижает стоимость обновлений, Qwik — стоимость старта. Для LCP/TTI/INP в контентных сценариях выигрывает Qwik. Для интенсивных интерактивных сценариев Solid удерживает FPS и снижает CPU.</p><p>Оба дружат с серверными платформами. SolidStart имеет адаптеры для Vercel/Netlify, Qwik City — тоже.</p><blockquote>Выбирайте Solid.js, если вы создаете сервис, куда пользователь заходит надолго, и ему важна отзывчивость после загрузки. Выбирайте Qwik, если вы создаете сайт, куда пользователь приходит за контентом, и важно показать ему этот контент мгновенно.</blockquote><p>Немного выводов:</p><ul><li>Solidjs быстрее Qwik при рендеринге. Qwik быстрее Solidjs при загрузке страниц.</li><li>У Solidjs документация лучше, чем у Qwik.</li><li>С нуля код на Qwik писать проще и быстрее, чем на SolidJS.</li><li>Typescript в SolidJS может быть головной болью, в Qwik об этом можно не беспокоиться.</li></ul><h2>Практические рекомендации по переходу на SolidJS и Qwik</h2><ol><li><b>Начните с аудита текущих проблем</b>. Посмотрите метрики сайта: сколько времени занимает гидратация? Тормозят ли обновления интерфейса? Где именно проблема — на старте или в процессе работы?</li><li><b>Выберите изолированную часть проекта</b>. Возьмите один виджет, одну страницу, один компонент и реализуйте его на новом фреймворке. Измерьте разницу в производительности и удобстве разработки.</li><li><b>Если проблема в медленной загрузке</b> — попробуйте Qwik. Соберите прототип лендинга или каталога, включите SSG с resumability и протестируйте на медленном соединении.</li><li><b>Если проблема в тормозах интерфейса</b> — попробуйте Solid. Перепишите самый страдальный компонент с частыми обновлениями, уберите мемоизации и посмотрите на результат.</li></ol><p>Оба фреймворка собираются через Vite, имеют TypeScript из коробки и хорошую интеграцию с популярными инструментами. Стоимость эксперимента низкая, а потенциальная выгода высокая.</p><h2>Тенденция отказа от React/Vue</h2><blockquote>Компании и разработчики не столько отказываются от популярных решений, сколько перестают использовать их для всех задач подряд. Раньше выбора практически не было, и эти фреймворки были молотком, для которого любая задача — гвоздь.</blockquote><p><i>А вы что думаете? Готовы попробовать модные фреймворки SolidJS и Qwik в следующем проекте?</i></p>]]></content:encoded>
    </item>
  </channel>
</rss>