Производительность фронтенда — это не просто «быстрее». Важно понимать, какие операции UI обходятся браузеру в наибольшую цену. Render cost помогает измерять стоимость рендера, обновлений, изменений DOM, расчётов layout и стилей. Это важная метрика для оптимизации интерфейсов.
ℹ️ Что такое render cost?
Render cost — это сумма всех затрат, которые браузер несёт при выполнении операций с пользовательским интерфейсом, включая создание и изменение DOM-узлов, обновление стилей, пересчёт layout, перерисовка элементов и выполнение JS, которое запускает все эти операции. В крупных проектах неправильные UI-операции могут стать причиной лагов и фризов интерфейса.❌ Самые дорогие операции
Перерасчёт геометрии элементов, запуск рендеринга с кистью и смешивание слоёв — все эти процессы могут быть затратными для производительности приложения. Пересчёт геометрии элементов происходит при чтении свойств offsetWidth, getBoundingClientRect(), изменении размеров, положения или шрифтов, а также при применении сложных CSS-правил. Запуск рендеринга с кистью особенно дорог при использовании эффектов, фильтров или градиентов.
Смешивание слоёв обычно несложная операция, но может стать дорогой, если слоёв слишком много. Кроме того, тяжёлые вычисления на JavaScript могут блокировать главный поток и задерживать рендеринг пользовательского интерфейса.✅ Как оценить render cost в реальных проектах
• React DevTools Profiler: Позволяет понять, какие компоненты перерисовываются слишком часто, где тратится больше всего времени и какие пропсы вызывают каскадные обновления.
• Chrome Performance panel: Главный инструмент для анализа. Позволяет увидеть трейсинг JS, layout events, paint events и точные триггеры reflow.
• Performance Insights: Подсвечивает проблемные места и даёт рекомендации по улучшению производительности.
• Lighthouse: Отлично показывает точки деградации на высоком уровне и предлагает пути для их устранения.🤚 Что считается «дорогим» в UI?
В пользовательском интерфейсе (UI) «дорогим» считается всё, что требует значительных ресурсов для выполнения и может замедлять работу приложения. К таким элементам относятся частые полные перерисовки списков вместо частичных обновлений, громоздкие компоненты, где один стейт перерисовывает всю страницу, сложные CSS-стили, например, глубокие селекторы, а также DOM с тысячами узлов на одном экране и последовательное чтение и изменение layout (forcing reflow).⚡️ Как снижать render cost
Чтобы снизить render cost, важно оптимизировать компоненты: делите их на мелкие для уменьшения области перерисовки. Используйте fine-grained реактивность с помощью сигналов, селекторов или memoized stores, чтобы обновлялось только необходимое. Избегайте живых reflow, группируя измерения и изменения DOM.
Применяйте виртуализацию для рендеринга только видимых элементов в DOM. Используйте transform вместо top/left в CSS, избегайте тяжёлых эффектов и следите за структурой CSS. Для тяжёлой логики можно использовать Web Workers, перенося вычисления в основной поток и сохраняя отзывчивость UI.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5❤2👍2👎2👀1
Когда размер вашего фронтенд-бандла начинает расти, вы, вероятно, используете такие инструменты, как Webpack Bundle Analyzer, чтобы увидеть, что именно увеличивает размер. Но на самом деле эти инструменты работают с .map файлами и тут скрывается гораздо больше информации, чем кажется на первый взгляд. Давайте разберемся, что лежит внутри этих файлов и как их использовать для глубокого профилирования.
✅ Что такое .map файлы?
Файлы .map — это JSON-структуры, которые содержат полную информацию о вашем коде. В них хранятся ссылки на оригинальные файлы, сам исходный код, соответствие между минифицированными и оригинальными строками кода, а также список символов и имён.
Это не просто файлы для дебага, это своего рода словарь вашего кода, который позволяет анализировать и профилировать его работу.✅ Почему .map файлы полезны для профилирования?
С помощью этих файлов вы можете выявить множество проблем с бандлом, которые не очевидны при обычном просмотре. Они помогают определить, какой модуль занимает больше всего места, что попадало в бандл случайно, а также какие зависимости или фрагменты кода оказываются тяжёлыми для производительности.
Это важно для профилирования, так как неправильные UI-операции часто вызывают лаги и фризы на страницах с большими бандлами.✅ Что можно увидеть в .map файле?
С помощью .map файлов можно выявить различные проблемы. Например, они помогут понять, если вы случайно импортировали весь пакет lodash вместо конкретной функции или подключили слишком тяжёлый UI-кит, хотя использовали только одну кнопку. Также вы сможете найти дублирование модулей, если разные версии одной и той же библиотеки были добавлены в ваш проект.
В некоторых случаях .map файлы показывают подтягивание ненужных polyfills или «раздутые» функции, которые не были удалены после трешейкинга. Всё это можно обнаружить, если внимательно изучить .map файл.✅ Как читать .map файлы?
Для анализа .map файлов можно использовать специальные инструменты, такие как maps-codec, source-map-explorer или даже встроенные инструменты в браузере через DevTools. Эти инструменты помогут вам понять, что именно добавляет вес вашему бандлу и как это влияет на производительность.
Если вы хотите пройти путь профилирования вручную, можно использовать source-map-explorer, который визуализирует содержимое .map файла и помогает быстро найти проблемные места.✅ Когда вы работаете с .map файлами, стоит следовать нескольким простым рекомендациям
• Во-первых, всегда анализируйте source map на продакшн-сборке, так как staging-сборки могут иметь разные флаги, влияющие на результат.
• Во-вторых, используйте опцию hidden-source-map, чтобы скрыть карты от публичного доступа, но использовать их в CI.
• Также не забывайте отслеживать динамические импорты, ведь .map файл может показать, что именно попадало в ваши чанки.
• И, конечно, сравнивайте .map файлы между сборками, чтобы понять, что именно увеличивает размер бандла.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥3❤2
Forwarded from xCode Journal
Вот вам план на декабрь
Уже завтра выйдет ежегодный адвент-календарь с задачами и головоломками по программированию — Advent of Code. Календарь в этот раз рассчитан на 12 дней, так что каждый день почти полмесяца будут выходить новые задачи. Решать их можно на любом языке программирования.
А если хочется размять голову перед стартом, можно изучить прошлогодние головоломки и их решение на SQL — забираем.
P.S уже вышел
✖️ xCode Journal
Уже завтра выйдет ежегодный адвент-календарь с задачами и головоломками по программированию — Advent of Code. Календарь в этот раз рассчитан на 12 дней, так что каждый день почти полмесяца будут выходить новые задачи. Решать их можно на любом языке программирования.
А если хочется размять голову перед стартом, можно изучить прошлогодние головоломки и их решение на SQL — забираем.
P.S уже вышел
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3🔥1
Многие считают, что event loop в Node.js и браузере работает одинаково. Однако, несмотря на общие черты, существуют важные различия, которые влияют на асинхронное поведение и производительность приложения. Разобравшись с этими различиями, можно писать более эффективный асинхронный код и избежать лагов и задержек. Давайте разберемся, что именно отличает работу event loop в этих двух средах.
❌ Браузер: всё о пользовательском интерфейсе
В браузере event loop сосредоточен на работе с пользовательским интерфейсом (UI). Его основная задача — обеспечить плавность рендеринга, быстроту реакции на события, выполнение JavaScript и обработку Web APIs.
В процессе работы с UI браузер использует несколько типов очередей задач. Это microtasks, такие как обработка Promise и queueMicrotask, и macrotasks, в которые попадают setTimeout, setInterval и MessageChannel. Также есть отдельная фаза для рендеринга. Браузер обязан поддерживать плавность UI, поэтому между макротасками он обязательно вставляет фазу рендеринга, что позволяет минимизировать задержки при обновлении интерфейса.❌ Node.js: event loop от libuv
В Node.js event loop работает на основе библиотеки libuv, которая используется для асинхронных операций, таких как работа с файловой системой, сетью и другими I/O операциями. В отличие от браузера, в Node.js есть несколько фаз, которые позволяют эффективно управлять этими операциями.
Node.js использует шесть фаз, включая Timers (setTimeout, setInterval), Poll (обработка I/O операций), Check (setImmediate) и другие. Основное отличие заключается в том, что Node.js управляет низкоуровневыми операциями с системой, такими как файлы и сеть, в то время как браузер сосредоточен на рендеринге и UI. Это позволяет Node.js быть более гибким в обслуживании серверных запросов и файловых операций.❌ Где начинается путаница
Существует несколько распространенных недопониманий между setTimeout и setImmediate. В браузере нет метода setImmediate, в то время как в Node.js он выполняется в фазе Check, а setTimeout — в фазе Timers. Это может привести к путанице, особенно при переносе кода между Node.js и браузером.
Также стоит отметить различие в работе microtasks. В браузере микротаски выполняются сразу после каждого макротаска, а в Node.js они выполняются после каждой фазы event loop, что позволяет их более эффективно управлять и избегать блокировки цикла.❌ Ещё одним важным отличием является рендеринг
В Node.js нет рендеринга, так как он работает в серверной среде и не требует обновления визуальной части. В браузере, наоборот, рендеринг влияет на порядок выполнения задач и может вызвать задержки, если не правильно управлять этим процессом.
Например, repaint может произойти между macrotask, microtask и снова macrotask, что важно учитывать при оптимизации производительности в браузере.❌ Что важно помнить разработчику
• В Node.js основное внимание уделяется I/O операциям, таким как работа с файлами, сетью и процессами. Эти задачи добавляют свои очереди и обрабатываются в разных фазах event loop.
• В браузере event loop синхронизирован с частотой кадров, что критически важно для обеспечения плавности UI.
• Microtasks в Node.js ведут себя агрессивнее, особенно process.nextTick, который может заблокировать переход между фазами event loop, если заспамить его слишком большим количеством задач.
• setImmediate и setTimeout — это не одно и то же. Порядок их выполнения в Node.js зависит от контекста и фазы event loop, в которой они находятся.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8❤2👍2👀2
Forwarded from Data Science | Machinelearning [ru]
GPT-5.1-Codex-Max: Новый кодинг от OpenAI 🍆
OpenAI анонсировала новинку, которая может стать настоящим прорывом — GPT-5.1-Codex-Max. Выглядит как не просто шаг в ответ на бурю вокруг Gemini, а вполне себе уверенный шаг вперёд.
Так что, эта версия уже доступна для использования в IDE и Codex CLI. Ждете API? Обещают скоро добавить.
Data Science
OpenAI анонсировала новинку, которая может стать настоящим прорывом — GPT-5.1-Codex-Max. Выглядит как не просто шаг в ответ на бурю вокруг Gemini, а вполне себе уверенный шаг вперёд.
Что же интересного в этой версии? Давайте разберёмся.
Революция для Windows и Powershell
Теперь Codex не просто кодит как обычно. Он понял, как работать в среде Windows, и особенно с Powershell. Это означает, что модель теперь точно разбирается в особенностях файловой системы, путях и всем, что связано с Windows. Но это ещё не всё — появилась новая фича под названием "Agent mode". Эта штука позволяет модели работать автономно в терминале, выполняя задачи без постоянного контроля. Не забудьте, что доступ можно настроить, если надо.
Автономность на новом уровне
OpenAI заявляет, что модель способна работать более 24 часов без остановки. Можете себе представить? Правда, тут стоит напомнить про достижение Anthropic с их Sonnet 4.5, которая обещает 30 часов работы. Но всё равно впечатляет, правда?
Новая память — что это значит?
Модель теперь умеет работать с большими контекстами, благодаря новой фиче "compaction". Что это? Когда окно контекста близко к своему пределу, Codex сжимает старую информацию и переносит её в новое окно вместе с актуальной информацией. Как бы креативная версия краткосрочной и долгосрочной памяти, не так ли?
Результаты и метрики
GPT-5.1-Codex-Max показывает отличные результаты — 77.9% точности на SWE-bench Verified, что превосходит даже Gemini 3 и Sonnet 4.5 от Claude. К тому же, модель теперь тратит на 30% меньше токенов при среднем уровне рассуждений, но результаты всё те же.
Так что, эта версия уже доступна для использования в IDE и Codex CLI. Ждете API? Обещают скоро добавить.
Data Science
Please open Telegram to view this post
VIEW IN TELEGRAM
😁6❤3👎2👀2
Большие фронтенд-проекты не рушатся из-за одной ошибки. Чаще всего их «убивают» мелкие, но системные ошибки в архитектуре, которые приводят к бесконечным поломкам. Давайте рассмотрим самые частые анти-паттерны, с которыми сталкиваются реальные команды.
ℹ️ «Глобальное всё»
Когда всё в проекте глобальное: стили, состояния, утилиты. Это создаёт цепочку зависимостей, и любая правка может привести к непредсказуемым поломкам.
Решение: строгое разделение на модули, использование неймспейсов и изоляция слоёв. Это поможет избежать нежелательных побочных эффектов и сделает код более предсказуемым.ℹ️ «Компоненты-монолиты»
Когда в коде все компоненты отвечают за UI, бизнес-логику, запросы, валидацию и управление состоянием, это может привести к тому, что код станет сложным для тестирования, переиспользования и чтения.
Решение: Для улучшения структуры и поддерживаемости кода необходимо разделить его на слои: UI, управление состоянием, доменная логика и взаимодействие с API.ℹ️ «Push-архитектура»
Каждый компонент тянет данные сам и вот тут начинается хаос: дублирование запросов, гонки условий, зависимости на каждом шагу.
Решение: централизованный слой данных. Используйте query-клиенты, сервисы или модели для эффективного управления данными.ℹ️ «Секретные зависимости»
Компоненты, которые используют скрытые зависимости, такие как localStorage, window, сторонние сервисы или скрытые контексты, не указаны явно.
Решение: всегда документируйте зависимости и явно описывайте их в коде. Это упростит тестирование и переносимость компонентов.ℹ️ «Тяжёлые re-render цепочки»
Когда один компонент меняет state, и пол-страницы перерисовывается, вызывая лаги и замедление интерфейса.
Решение: используйте signals, selectors и fine-grained реактивность. Архитектурная изоляция поможет минимизировать лишние ререндеры.ℹ️ «Всё через Redux / Context / глобальный стор»
Когда вы храните глобальный стейт там, где он должен быть локальным. В итоге глобальное состояние становится тяжёлым и трудным для управления.
Решение: минимизируйте использование глобального стейта. Локальные состояния должны храниться локально.ℹ️ «Типизация по настроению»
Когда часть кода типизирована, а часть — нет, или используется any. В итоге типизация не защищает, а мешает.
Решение: установите единые правила типизации и используйте строгий линтинг для соблюдения этих правил.ℹ️ «Сложность вместо простоты»
Когда для решения простых задач используются сложные абстракции, кастомные DI, самописные хуки и роутеры, что усложняет поддержку кода.
Решение: используйте стандартные подходы и решения, не усложняйте систему без нужды. Простейшие функции могут быть более чем достаточны.ℹ️ «Отсутствие архитектурных границ»
Когда компоненты могут импортировать что угодно и откуда угодно, проект превращается в клубок зависимостей, которые сложно отслеживать.
Решение: используйте feature-sliced или modular архитектуру, следите за слоями, внедрите статический анализ зависимостей и запретите пересечения между слоями.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤12👍10👀1
JavaScript сегодня отмечает 30-летие 🎂
Именно 4 декабря 1995 года миру показали язык под знакомым нам названием — JavaScript.
❌ Вот история именинника:
🎉 Поздравляем старичка, который до сих пор двигает весь веб.
🚪 Frontender's notes
Именно 4 декабря 1995 года миру показали язык под знакомым нам названием — JavaScript.
• У языка было три имени за пару месяцев.
Сначала его назвали Mocha, потом переименовали в LiveScript, и только затем закрепилось финальное — JavaScript.
• К Java он почти не имеет отношения.
Название выбрали скорее как маркетинговый ход: в середине 90-х вокруг Java был мощный хайп, и на эту волну просто запрыгнули.
• JS слепили всего за 10 дней.
Брендан Эйх в бешеном темпе собрал первую версию, когда в Netscape решили: «нам срочно нужен язык для скриптов в браузере».
• Создатель языка успел стать CEO Mozilla — и быстро лишиться должности.
Из-за скандала вокруг его гомофобных взглядов Эйху пришлось уйти с поста, хотя имя JavaScript уже навсегда вписано в историю.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤30🔥10⚡3🐳2
Когда пользователь открывает несколько вкладок одного приложения, часто возникает проблема синхронизации состояния. Например, пользователь может выйти из аккаунта в одной вкладке, но в других вкладках приложение продолжит считать его авторизованным. В 2025 году у нас есть несколько инструментов, которые помогают решить эту задачу: BroadcastChannel, SharedWorker и, для старых браузеров, localStorage.
➕ BroadcastChannel — простое решение для синхронизации сообщений
Это API для синхронной передачи сообщений между вкладками браузера. Он позволяет подписываться на канал для получения и отправки данных, что эффективно для уведомлений и событий в разных вкладках. Подходит для синхронизации логина, выбора темы, обновления кеша и уведомлений о новой версии.
Преимущества: простота, быстрая доставка, работа в фоновом режиме.
Ограничения: не поддерживает общее состояние и сложные операции.➕ SharedWorker — когда все вкладки работают как одно приложение
Это инструмент для централизованной работы между вкладками, обеспечивающий синхронизацию состояния, кэширование и управление запросами. Он полезен для приложений, требующих координации между вкладками.
Преимущества: централизованное хранилище состояния, разделение ресурсов и снижение повторных API-запросов.
Ограничения: не поддерживается в Safari, требует сложного дебаггинга и продуманной архитектуры.➕ LocalStorage + storage event — старый, но работающий способ
Один из самых простых методов синхронизации данных. Этот подход подходит для проектов, требующих поддержки старых браузеров и не использующих Service Worker или SharedWorker, а также для простых случаев синхронизации между вкладками.
Преимущества: простота реализации и широкая совместимость.
Ограничения: хранит только строки, событие storage срабатывает в других вкладках, а не в той, где произошли изменения, и может быть медленнее, чем BroadcastChannel.
// BroadcastChannel
const channel = new BroadcastChannel("session");
channel.onmessage = (e) => {
console.log("message:", e.data);
};
channel.postMessage({ loggedOut: true });
// SharedWorker
// main.js
const worker = new SharedWorker("worker.js");
worker.port.postMessage({ type: "ping" });
worker.port.onmessage = (e) => console.log(e.data);
// worker.js
onconnect = (e) => {
const port = e.ports[0];
port.onmessage = () => port.postMessage("pong");
};
// LocalStorage + storage event
window.addEventListener("storage", (e) => {
if (e.key === "logout") {
// синхронизация
}
});Please open Telegram to view this post
VIEW IN TELEGRAM
👍14❤3🔥2
Forwarded from xCode Journal
И, видимо, не зря — реддитор рассказал, что ИИ-агент Antigravity случайно удалил весь его диск, пока пытался исправить баг:
«Я просматриваю журналы с предыдущего шага и с ужасом вижу, что команда, которую я выполнил для очистки кэша проекта (rmdir), по всей видимости, ошибочно указала на корень вашего диска D:, а не на конкретную папку проекта.
Мне очень, очень жаль.»
Please open Telegram to view this post
VIEW IN TELEGRAM
😁28🐳2
В 2025 году концепция ленивой загрузки — это не просто разделение бандлов на чанки. Производительность веб-страниц достигла нового уровня: браузеры становятся умнее, сети быстрее, а пользовательские интерфейсы сложнее. Важно понять новую стратегию приоритетов загрузки, чтобы даже самый идеальный код не стал «тяжёлым» для пользователя.
❌ First-party UI: что грузить первым?
В 2025 году при разработке UI важно сосредоточиться на быстрой загрузке ключевых элементов — каркаса, кнопок, инпутов и навигации. Это улучшит метрику Interaction to Next Paint (INP), ставшую приоритетом для браузеров. Критичные стили и UI-код также должны загружаться немедленно.
Функционал, сложные компоненты и данные ниже первого экрана можно загружать лениво, включая аналитику и фоновые задачи для оптимизации производительности.➡️ Всё, что ниже сгиба, можно загружать лениво
Ленивую загрузку можно применять ко всем тяжелым секциям, изображениями с атрибутом loading="lazy", а также к модулям, которые загружаются после первого скролла. Новый IntersectionObserver 2 делает отслеживание видимости элементов более надёжным и быстрым, что идеально подходит для массового отслеживания lazy-load.❗️ Библиотеки и UI-компоненты — только по мере необходимости
Если пользователь не взаимодействует с модалкой, зачем грузить библиотеку для порталов, анимаций или форм? Используйте React.lazy или его аналоги для ленивой загрузки компонентов. Золотое правило: никогда не грузите компоненты без необходимости.↗️ Статические ассеты: как загрузить их умнее
В 2025 году можно расставлять приоритеты для загрузки ассетов. Для критичных изображений используйте атрибут fetchpriority="high", для шрифтов — preloading, для сторонних API — preconnect, а для фоновых картинок — приоритет low.📣 Не забываем про «delayed-init»
Иногда нужно загрузить код сразу, но выполнить его позже для минимизации нагрузки на UI. Это важно для аналитики, сложных элементов (карт, списков) и операций, которые могут «заморозить» основной поток.
Используйте requestIdleCallback, setTimeout(..., 0), Web Workers и scheduler API для снижения нагрузки на UI. Этот подход не является настоящей lazy-load, но эффективно помогает оптимизировать работу интерфейса.💡 AI-предсказания: предсказываем, что загрузить
Фреймворки начинают использовать данные о поведении пользователей, чтобы предсказать, какие ресурсы будут востребованы. Например, Next.js, Remix, и Astro могут предварительно загружать ссылки при наведении, использовать гироскопические данные для prediction-preloading и статистическое кеширование переходов.
// Пример кода для React:
const FancyModal = lazy(() => import("./FancyModal.js"));
// Для ванильного JS:
if (needsModal) {
import('/modal.js').then(initModal);
}
// Ленивую загрузку стилей тоже стоит включать с использованием атрибута media (html):
<link rel="stylesheet" href="theme-extra.css" media="print" onload="this.media='all'">Please open Telegram to view this post
VIEW IN TELEGRAM
1❤6👍3🐳1👀1
Критическая уязвимость в React Server Components (CVSS 10.0). Рекомендуется обновление
🚨 React-команда официально сообщила о серьёзной проблеме безопасности в React Server Components.
Уязвимость позволяет выполнить произвольный код на сервере без аутентификации — достаточно отправить специально сформированный HTTP-запрос.
Даже если вы не используете React Server Functions напрямую — вы всё равно можете быть уязвимы, если ваш проект поддерживает React Server Components.
Уязвимость получила идентификатор CVE-2025-55182, оценку CVSS 10.0, и затрагивает версии 19.0, 19.1.0, 19.1.1 и 19.2.0 следующих пакетов:
🔘 Что делать прямо сейчас
🔘 В чём суть уязвимости
🔘 Инструкция по обновлению Next.js
📅 Таймлайн
📍 Ссылка на оригинал статьи...
Уязвимость позволяет выполнить произвольный код на сервере без аутентификации — достаточно отправить специально сформированный HTTP-запрос.
Даже если вы не используете React Server Functions напрямую — вы всё равно можете быть уязвимы, если ваш проект поддерживает React Server Components.
Уязвимость получила идентификатор CVE-2025-55182, оценку CVSS 10.0, и затрагивает версии 19.0, 19.1.0, 19.1.1 и 19.2.0 следующих пакетов:
react-server-dom-webpack
react-server-dom-parcel
react-server-dom-turbopack
Патч уже опубликован. Нужно обновиться на версии: 19.0.1, 19.1.2, 19.2.1.
Если ваш React-код вообще не работает на сервере, или вы не используете фреймворки/бандлеры с поддержкой RSC, то вы не затронуты.
Некоторые экосистемы зависели от уязвимых пакетов. В зоне риска:
Next.js
React Router (нестабильные RSC-API)
Waku
@parcel/rsc
@vitejs/plugin-rsc
Redwood SDK
Команда React работает с хостинг-провайдерами, и временные смягчения уже включены.
Но на них рассчитывать нельзя — обновляться всё равно нужно.
React Server Functions позволяют клиенту вызывать функции на сервере. На стороне клиента вызов превращается в HTTP-запрос, который React затем десериализует и мапит на вызов серверной функции.
Проблема — в том, как React декодирует payload от клиента.
Атакующий может создать вредоносный HTTP-запрос, который при десериализации приводит к удалённому выполнению кода.
Подробности раскроют позже, когда обновления будут полностью раскатаны.
Установите патч в рамках вашей версии:
npm install next@15.0.5
npm install next@15.1.9
npm install next@15.2.6
npm install next@15.3.6
npm install next@15.4.8
npm install next@15.5.7
npm install next@16.0.7
Если вы сидите на 14.3.0-canary.77 или выше — откатитесь на стабильную 14.x:
npm install next@14
React Router (нестабильные RSC API)
Обновите зависимости:
npm install react@latest
npm install react-dom@latest
npm install react-server-dom-parcel@latest
npm install react-server-dom-webpack@latest
npm install @vitejs/plugin-rsc@latest
Expo
См. changelog на expo.dev.
Redwood SDK
npm install rwsdk@latest
npm install react@latest react-dom@latest react-server-dom-webpack@latest
Waku
npm install react@latest react-dom@latest react-server-dom-webpack@latest waku@latest
Vite RSC
npm install react@latest react-dom@latest @vitejs/plugin-rsc@latest
Parcel RSC
npm install react@latest react-dom@latest react-server-dom-parcel@latest
Turbopack RSC
npm install react@latest react-dom@latest react-server-dom-turbopack@latest
Webpack RSC
npm install react@latest react-dom@latest react-server-dom-webpack@latest
📅 Таймлайн
29 ноября — уязвимость найденa и отправленa в Meta Bug Bounty.
30 ноября — Meta подтвердила и начала работать над фиксом с командой React.
1 декабря — фикc готов, идёт работа с хостингами и OSS-проекта́ми над валидацией и mitigations.
3 декабря — патч опубликован, уязвимость раскрыта публично.
Please open Telegram to view this post
VIEW IN TELEGRAM
react.dev
Critical Security Vulnerability in React Server Components – React
The library for web and native user interfaces
👀6😱2❤1🔥1😁1🐳1
Когда разрабатываешь фронтенд-API, важно помнить, что это не просто тонкий слой поверх бэкенда. Это полноценный контракт, который определяет, насколько удобным будет продукт, как он будет восприниматься командой и какие проблемы будут возникать в будущем. Вот чеклист, как делать API, которые не только работают, но и легко поддерживаются.
⬆️ Предсказуемость API
Одной из главных проблем является непоследовательность. Разные названия полей, структуры ответов или коды ошибок могут разрушить любые попытки стабильно работать с API. Если разработчик уже сталкивался с одним вашим эндпоинтом, он должен быть уверен, что следующий будет примерно таким же. Это поможет избежать проблем с поддержкой и быстрым внедрением новых функций.⬆️ Документация, которая работает автоматически
Ручная документация быстро устаревает. Используйте инструменты, которые генерируют документацию автоматически. Применяйте OpenAPI или Swagger, JSON Schema, и автоматическую генерацию TypeScript-типов и клиента. Так API и документация будут всегда в актуальном состоянии, и фронтенд станет намного стабильнее.⬆️ Стабильность типов
Проблемы начинаются, когда поля данных могут быть как null, так и отсутствовать. Это ломает UI и делает приложение нестабильным. К примеру, лучше иметь всегда однотипную структуру с корректным значением, чем случайные поля с разными типами данных. Убедитесь, что данные всегда стабильны и предсказуемы.⬆️ Избегайте «магических значений»
Пример плохого API: { "status": 3 }. Какое значение означает 3? Это нечитаемо. Лучше использовать понятные значения, например { "status": "blocked" }. Это снижает количество ошибок, делает API легче в поддержке и чтении, а также повышает понимание со стороны разработчиков.⬆️ Ошибки — это не просто статус коды
Ошибки должны быть обработаны с умом. Базовые коды ошибок 200 и 500 недостаточны для хорошей работы. Вместо этого используйте чёткие коды ошибок с описанием. Например, если сессия истекла, верните:{
"error": {
"code": "INVALID_TOKEN",
"message": "Token expired"
}
}
Это поможет сделать более эффективное восстановление сессий, ретраи и улучшит UX.⬆️ Когда пишете API, учитывайте, что фронтенду важно:
• Меньше мелких запросов
• Возможность кэширования
• Нормализованные данные
• Компактные ответы
• Фронтенд не любит, когда API возвращает огромные ответы с лишними данными. Помните о пагинации, батчинге и стабильных ETags для ресурсов.⬆️ Давайте всё, что нужно для кэширования
API должно поддерживать кэширование. Используйте такие механизмы, как ETag, Cache-Control, Last-Modified и max-age. Это позволяет фронтенду эффективно использовать кэш, уменьшить нагрузку и ускорить работу.⬆️ Защищайте от over-fetching и under-fetching
Убедитесь, что API не отправляет лишние данные (over-fetching), например, если вам не нужны роли пользователей или их настройки. Также не стоит заставлять фронтенд делать несколько запросов для получения нужных данных (under-fetching). Используйте view-модели, которые заточены под конкретные UI-экраны.⬆️ Осознанно подходите к версионированию API
Версионирование API должно быть осознанным. Простой путь с номерами версий /v2, /v3 — это ещё не всё. Важно обеспечивать совместимость внутри каждой версии и предусматривать возможность отката. Версионирование должно быть предсказуемым и чётким.⬆️ Создайте клиентскую обёртку
Фронтенд должен самостоятельно решать такие задачи, как ретраи, отмена запросов, debounce, тайм-ауты и токен-логика. Это не должно быть задачей бэкенда. Создайте единый слой API для клиента с помощью custom fetch wrapper, axios instance или TanStack Query. Один класс для всех запросов поможет добиться более стабильного поведения и улучшить контроль над запросами.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤3🐳2
Недавно мы писали про lazyClick Me Load More в этом посте. Продолжаем тему
Ленивая загрузка — это отличная технология для оптимизации производительности. Однако, при неправильном применении она может привести к замедлению работы сайта, а не улучшению. Я всё чаще сталкиваюсь с одними и теми же ошибками, которые разработчики продолжают допускать. Вот список ошибок, которых стоит избегать, чтобы сделать ваш сайт быстрее и плавнее.
❌ Ленивая загрузка критичного UI
Когда речь идёт о компонентах, которые напрямую влияют на первый экран, интерактивность навигации или основные кнопки и инпуты, их нельзя загружать лениво. Ленивая загрузка не должна касаться того, что важно для начальной интерактивности сайта. Такие элементы должны быть готовы к использованию как можно раньше.❌ Грузить код лениво, но слишком поздно
Ошибка, с которой сталкиваются многие: компонент загружается лениво, но нуждается в немедленной активации. Из-за этого возникает задержка, и пользователь видит лаги или мерцание. Чтобы избежать этого, используйте предзагрузку (prefetch) вместе с ленивой загрузкой.<link rel="prefetch" href="/modal.js">❌ Ленивое загружение там, где нужна отложенная инициализация
Некоторые операции, такие как работа с картами, сложными таблицами или WebGL, требуют, чтобы код был загружен сразу, но его выполнение можно отложить. Для этого используйте requestIdleCallback, setTimeout(0) или Scheduler API.❌ Ленивая загрузка маленьких модулей
Если модуль весит 1-3 KB, разбивать его на отдельный чанк — это лишняя нагрузка. Модули такого размера не нужно загружать лениво, так как это добавит ненужные сетевые запросы и усложнит граф зависимостей. Ленивая загрузка должна применяться только к тяжелым и ресурсозатратным модулям.❌ Ленивая загрузка без учета поведения пользователя
Ошибка заключается в том, что модалки или другие элементы функционала загружаются лениво, даже если пользователь почти сразу же взаимодействует с ними. В 2025 году есть инструменты, как prediction-preload в Next.js, Astro или Remix, которые помогают предугадывать действия пользователя и загружать необходимые компоненты заранее.❌ Ленивая загрузка изображений без настроек fetchpriority
Когда изображения загружаются лениво, они могут быть исключены из нормального потока загрузки, что может привести к исчезновению важного контента с экрана. Используйте fetchpriority="high" для ключевых изображений, чтобы они загружались первыми.<img src="hero.jpg" loading="eager" fetchpriority="high">
<img src="section.jpg" loading="lazy">❌ Ленивая загрузка CSS и блокировка first-paint
При ленивой загрузке тем и дополнительных стилей можно столкнуться с проблемой «unstyled flash» — когда контент появляется без стилей. Чтобы этого избежать, применяйте технику ленивой загрузки для стилей:<link rel="stylesheet" href="theme.css" media="print" onload="this.media='all'">❌ Ленивая загрузка маленьких иконок и SVG-спрайтов
Ленивая загрузка маленьких графических ассетов, таких как иконки или SVG-спрайты, приводит к лишним сетевым запросам, но почти не экономит ресурсы. Вместо этого используйте inline SVG, спрайты в <defs>, или пакуйте через Vite или Next.js.❌ Неправильный threshold в IntersectionObserver
Если вы ставите threshold слишком низким, например, компонент загружается только когда он вошел на 1 пиксель в видимую область, пользователь может увидеть задержку в подгрузке контента. Лучше использовать более высокий порог, чтобы загружать элементы заранее, например:new IntersectionObserver(callback, { rootMargin: '200px' });❌ Отсутствие fallback UI
Когда чанк ещё грузится, а пользователь уже видит пустое пространство, это создаёт ощущение тормозящего приложения. Чтобы этого избежать, всегда добавляйте skeletons, placeholders, мини-лоадеры или заранее зарендеренные контейнеры. Это сделает загрузку более плавной и улучшит восприятие приложения.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤5
Когда проект растёт, настоящая боль для команды не всегда в коде, а в процессе CI/CD. Долгие сборки, случайные ошибки, непонятные артефакты — всё это превращается в ежедневную головную боль. Однако, правильно настроенная система CI/CD может быть гораздо проще и эффективнее, чем кажется.
👨🎨 Линтить → тестировать → билдить
Частая ошибка команд — начинать с билда и только потом замечать пропущенные ошибки. Это может привести к ситуациям, когда сборка занимает 5 минут, а где то одна недостающая запятая. Правильный порядок: линтинг с ESLint и TypeScript, юнит-тесты, E2E и интеграционные тесты, и только потом билд. Так вы сэкономите время и ресурсы.⚡️ Кеш — ваш лучший друг
Использование кеша для ускорения процессов стало нормой. Не стоит недооценивать его влияние на скорость работы. Настроенные кеши в pnpm, npm, yarn, Turbo, Nx, Bun, Vite, и GitHub Actions помогут значительно ускорить процессы и сократить время на каждом пуше.🗳 Разделяйте CI и CD
CI (Continuous Integration) и CD (Continuous Deployment) — это два разных процесса. CI отвечает на вопрос: «Можно ли собрать код и пройти тесты?» CD же решает, готов ли код к деплою в продакшн. Когда эти процессы объединяются в один пайплайн, только добавляется хаос.💡 Feature Environments
Каждая ветка должна иметь свою отдельную превью-среду, как например в Vercel, Netlify, Cloudflare Pages или Render. Это помогает PM увидеть изменения до мерджа, QA не зависеть от локальных настроек, а дизайнерам проверять анимации. Без этой практики рецензировать UI-фичи становится крайне сложно.🔄 Деплой должен быть атомарным
Каждый коммит должен приводить к одному артефакту и одному деплою. Без «подправил на сервере» и «почему на проде другая версия файла?». Артефакты должны быть воспроизводимыми, неизменяемыми и версионируемыми.❌ Прерывание старых джобов
При каждом новом пуше в PR старые CI процессы должны отменяться, чтобы избежать лишних билдов подряд. Это можно настроить в GitHub Actions с помощью простого конфигурационного кода.
📦 Проверка бандла — часть CI, а не когда вспомним
Проверка бандла на каждом этапе CI с помощью таких инструментов как Bundlephobia API, Webpack Bundle Analyzer, Lighthouse-ci поможет избежать случайных увеличений размера бандла.🤚 Rollout фичей — через feature flags
Деплой не всегда означает релиз. Фича-флаги позволяют постепенно выкатывать изменения, откатывать без деплоя, тестировать экспериментальные сценарии и проводить A/B тестирование.
🔄 Автоматический откат
Настройте автоматический откат на таких платформах, как Cloudflare или Vercel, чтобы обеспечить стабильность в случае ошибок.💼 CI/CD должен быть другом, а не врагом
Настоящая система CI/CD должна работать без вашего вмешательства, обеспечивая предсказуемость, скорость и спокойствие для команды.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤3🐳1
Forwarded from xCode Journal
This media is not supported in your browser
VIEW IN TELEGRAM
Чтобы узнать о навыках и опыте работы, нужно исследовать остров и дом разработчика. Можно также взаимодействовать с предметами, приручить утку, написать разрабу письмо через почтовый ящик и попытаться вытащить меч короля Артура.
Все ассеты, кстати, тоже сделаны с нуля.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤14🔥5👀4
Утечки памяти в JavaScript — это не только про забытые таймеры. На самом деле существует множество других скрытых причин, которые могут годами «поглощать» память. Даже опытные разработчики часто упускают эти моменты, которые становятся источниками утечек в продакшене. Сегодня разберем, какие типичные ошибки приводят к утечкам памяти и как их избегать.
❌ Зависшие ссылки в замыканиях
Когда компонент или объект был удалён, но замыкание всё равно сохраняет ссылку на данные, они не могут быть очищены. Это классическая ошибка, особенно при больших данных.
Проблема (в примерах): bigData остаётся в памяти, пока существует ссылка на колбэк.❌ Глобальные переменные
Ошибки с глобальными переменными часто возникают, когда забывают использовать const или let.
Проблема (в примерах): Любой объект в глобальной области будет жить вечно.❌ Слушатели событий и DOM-узлы
Если слушатели событий или DOM-узлы не удаляются после того, как элементы были удалены, это может привести к утечкам. Особенно часто это случается с модальными окнами или кастомными компонентами.
Проблема (в примерах): После удаления элемента слушатель остаётся, удерживая объект в памяти.❌ Неправильное использование таймеров
Таймеры типа setInterval, которые не очищаются при уходе со страницы, могут продолжать работать, удерживая тяжёлые данные.
Проблема: Таймер продолжает работать, сохраняя контекст.❌ Неправильное использование таймеров
Таймеры, такие как setInterval, могут стать серьезным источником утечек памяти, если не очищаются при уходе со страницы или продолжают ссылаться на контекст.
Проблема: Таймер продолжает работать, удерживая тяжелые данные в замыкании, даже после того, как компонент был размонтирован.❌ Кэши без лимитов
Попытки сделать «умное кэширование» без ограничений на размер могут привести к утечкам.
Проблема (в примерах): Без лимитов на кэш память будет заполняться бесконечно.❌ Проблемы с Web Workers
Ошибки в работе с Web Workers, такие как передача данных без Transferables или не закрытые воркеры, могут стать причиной утечек.❌ Сторонние библиотеки
Некоторые библиотеки, особенно для UI, могут создавать скрытые DOM-структуры и не очищать их по завершении работы, что также ведет к утечкам.❌ React: stale effects
В React утечки могут происходить из-за старых ссылок в эффектах, которые не пересоздаются.
Проблема (в примерах): Эффект не пересоздается, старые ссылки остаются.
// Зависшие ссылки в замыканиях
function createTracker() {
const bigData = new Array(1_000_000).fill('x');
return () => console.log(bigData.length);
}
// Глобальные переменные
foo = {}; // теперь это window.foo
// Слушатели событий и DOM-узлы
element.addEventListener('scroll', handler);
// element.removeEventListener(...) забыли
// Кэши без лимитов
const cache = {};
cache[key] = heavyObject;
// React: stale effects
useEffect(() => {
subscribe();
return () => unsubscribe();
}, []); // но зависимость должна быть!Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤1
This media is not supported in your browser
VIEW IN TELEGRAM
Два стрима, которые описывают реальность инженерии точнее любых методологий:
Про тех, кто запускает новое и двигается быстрее ограничений.
AI-агенты, стремительное прототипирование, инструменты, которые снимают барьеры и позволяют выпускать фичи в рекордные сроки. Максимум энергии, минимум трения.
Про тех, кто отвечает за стабильность и качество.
Предсказуемые интерфейсы, архитектура, которая выдерживает рост, безопасность, которая закрывает реальные риски. Чёткие решения для тех, кто держит систему в рабочем состоянии каждый день.
Финал — игры, фуршет и много нетворкинга.
Встречаемся 20 декабря на конференции, где будущее не откладывают на релиз!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5
JSCamp — это полный интенсив, который проведет вас через все основные технологии экосистемы JavaScript, включая HTML, CSS, JavaScript, TypeScript, Node.js, SQL, CI/CD и Docker.
Этот курс — отличная возможность создать настоящий проект с нуля. Это не только поможет закрепить все, что вы узнали, но и добавит крутое приложение в ваше портфолио.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4🔥2
Когда фронтенд-проект растет, качественное ревью кода может спасти не только часы работы, но и нервные клетки. Это не просто проверки на стиль, а конкретный список проверок, которые помогут улучшить производительность, UX и облегчить поддержку. Делюсь проверенным чеклистом для команд.
💬 Архитектура и структура
Первое, на что стоит обратить внимание — это структура кода. Логика должна быть разделена по слоям, например, ui, features, services, libs. Не должно быть гигантских файлов на 500 строк и больше, а импорты не должны образовывать циклических зависимостей. Код должен быть логично организован и легко поддерживаем. Особое внимание стоит уделить отсутствию общих утилит, которые непредсказуемо тянут лишний код.💬 Чистота и читаемость
Код должен быть понятен без дополнительной документации. Названия сущностей и функций должны четко отражать их назначение, избегайте абстрактных сокращений типа a, b, c, если это не map или reduce. Логика функций не должна выходить за пределы одного экрана. Убедитесь, что мусорные console.log удалены из финальной версии.💬 Работа с состоянием
Стейт должен быть локализован в компоненты и в стор, не стоит размывать его между ними. Нужно следить за тем, чтобы не было лишних перерендеров, а также чтобы useMemo и useCallback использовались только по делу. Эффекты должны быть грамотно настроены, чтобы не вызывать побочные действия из-за неправильных зависимостей, а бесконечные циклы useEffect — это то, что нужно избегать.💬 Асинхронность
Везде должны быть учтены ошибки с использованием try/catch или .catch. Важно следить за гонками состояний и отменой запросов через AbortController или аналоги. Промисы не должны «висеть», и все ошибки должны быть разделены на ошибки пользователя и сервера.💬 Производительность
Избегайте ненужных рендеров и перерасчетов layout, таких как работа с DOM вне циклов или синхронные запросы типа offsetWidth. Большие списки должны быть под виртуализацией. Оптимизируйте циклы и тяжелые вычисления, и если нужно — выносите их в Web Worker. В JSX не должно быть больших inline-функций, а ререндеры не должны происходить из-за лишних контекстов.💬 Работа с памятью
Все таймеры должны быть очищены, и слушатели событий удаляться при очистке. Не должно быть бесконтрольных кэшей, утечек из-за замыканий или устаревших эффектов. Важно также следить за тем, чтобы не было «висячих» DOM-нод (detached nodes).💬 Безопасность
Важно исключить прямую вставку HTML через dangerouslySetInnerHTML. Все входные данные должны быть валидированы, чтобы избежать утечек токенов в логах. Работа с localStorage и cookies должна быть безопасной, а ключи и секреты не должны быть жестко закодированы в проекте.💬 Работа с API
API должно быть ясным и с четко определёнными DTO/типами для запросов и ответов. Ошибки от сервера должны обрабатываться отдельно от пользовательских. Избегайте "магических строк", а также убедитесь в правильности заголовков, методов и кодов ответа. Не должно быть повторяющихся запросов, которые должны быть мемоизированы или дедуплицированы.💬 UI и UX
Все загрузочные состояния, такие как loading, error, empty, должны быть правильно реализованы. Спиннеры не должны прыгать по экрану. Весь интерактивный контент должен быть доступен для пользователей с ограниченными возможностями (accessibility), а layout shift не должен происходить при загрузке. Анимации должны быть легкими и не блокирующими.💬 Тестируемость
Код должен быть легко тестируемым, а компоненты не завязаны на глобальные состояния. Логика должна быть вынесена из JSX, а побочные эффекты должны быть минимизированы. Мокинг зависимостей должен быть простым и удобным. Покрытие тестами важно, но не должно быть самоцелью — главное, чтобы тесты действительно проверяли функциональность, а не просто увеличивали процент покрытия.
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍3❤2🐳1
