— Да, фронтенд перенасыщен. Фреймворков много, технологии постоянно меняются. Все говорят об одном, но пишут по-разному. Но именно это и держит в тонусе — приходится регулярно обновлять знания. Сожалею ли я о своем выборе? Нет. Всегда любил погружаться в математические задачи, а фронтенд затягивает. Можно сутки биться над багом, ненавидеть его, плеваться… А потом решить — и словить кайф. В такие моменты код полностью поглощает, заставляя забыть о сне и еде.
Стоит ли идти во фронтенд сейчас?
— Никогда не поздно. Да, путь у каждого свой, и рынок сейчас нестабилен. Но при глубоком погружении за год можно набрать нужные скиллы и попасть на коммерческий проект.
🔥 Открыт набор на новый марафон!
Сейчас в Clevertec проходит марафон для начинающих фронтенд‑разработчиков. Это возможность погрузиться в профессию, получить реальный опыт и, возможно, стать частью команды. Участие бесплатное. Успей зарегистрироваться!
Запускаем бесплатный онлайн-марафон по фронтенд-разработке. Будет как в «Рокки»
Спринты, дедлайны и финальный тест-бой. Кто пройдет с нами три месяца подготовки — получит шанс на титул. Без метафор — мы реально ищем таланты и готовы взять их на стажировку.
Как записаться?
Заполни анкету по ссылке в профиле и скинь другу. Заявки принимаем до 26 марта.
Что будет?
Интенсивный 3-месячный тренинг. Это бесплатно. По сути, ты будешь поэтапно с дедлайнами писать приложение. Каждый спринт проверяем с помощью автотестов. Плюс будет поддержка менторов, наших крепких разработчиков. Это реальная прокачка твоих навыков и готовый проект в резюме.
Это уже четвертый марафон — после каждого наша команда фронтенд-разработчиков растет.
Кого ждём?
Начинающих веб-разработчиков (JS, React), которые уже изучали теорию и хотят прокачаться на практике в условиях, максимально близких к реальному проекту. Главное — желание кодить. Подойдут:
- студенты профильных вузов
- выпускники курсов
- самоучки
Важное условие: приглашаем участников из Беларуси и России.
Что дальше?
После 26 марта отправим на почту инструкции и первые задания. Старт марафона 1 апреля (это не шутка). До связи, Рокки.
Как мы сокращали количество запросов по фичам в API
Контекст: я отвечаю за разработку конструктора Telegram-приложений. Начинались мы как конструктор кликеров (еще до хомяка). Со временем эволюционировали в конструктор курсов, сообществ, визиток, мероприятий и любых других приложений
Одна из основных сущностей в коде — это BotUser. То есть пользователь, который появился в приложении (зашёл хотя бы раз), имеет имя и Telegram ID
За ~полгода проекта у нас добавилось много фич, привязанных к пользователю. Практически все сопоставляются 1 к 1 по ключу User ID. Например, квизы, бонусные дни, купленные страницы, купленный карточки апгрейдов, тариф и т.д.
Раньше для каждой новой фичи мы добавляли новый запрос в API с фронтенда. И вот мы заметили, что на каждый заход пользователя стало уходить >10 запросов в API ⚠️.
Примерно вот так:
GET /users/user
// Response
{
"tgUsername": ...,
"tgId": ...,
...
}
GET /users/features/quizzes/completed
// Response
{
"completedQuizzes": ...,
}
GET /users/features/pages/bought
// Response
{
"boughtPages": ...,
}
GET /users/features/rates/rate
// Response
{
"userRate": ...,
}
При этом, на каждый запрос мы проверяли авторизацию. В Telegram это делается с помощью хеша от Telegram + проверка подписи токеном бота
Следовательно, на каждый запрос мы делали JOIN пользователя, брали бота (сущность Bot) из кэша и мэтчили подпись (+ логгировали). Это лишняя нагрузка
Сейчас подсобрали все фичи в один запрос. Теперь, на каждый заход пользователя получается только один GET /app/account/data, который возвращает данные пользователя вместе с данными фичей:
не подгружаем связанные сущности, где не нужно (one-to-one, one-to-many);
если подгружаем сущности, всегда делаем это одним JOIN'ом (а не бегаем по 2-3 раза в БД, как любит делать Hibernate);
берём общие часто запрашиваемые данные из кэшей.
Это позволило снизить нагрузку на сервер и БД. К посту прикрепляю график загрузки части наших серверов по CPU до и после оптимизации.
---
Если вам понравился пост или оказался полезным, поставьте, пожалуйста лайк ❤️. Это мотивирует делиться опытом из разработки. И, как полагается, у меня есть Telegram-канал, в котором я рассказываю про разработку, развитие SaaS-сервисов и управление IT проектами.
Вчера впервые попробовал flushSyncб который подвезли в React еще в 18 версии. Классное решение для определенных моментов! Выглядит так, будто React выдал нам костыль, но сразу предупредил: пользоваться с осторожностью.
❓ Почему это вообще нужно? (Для тех, кто не совсем в теме) В React изменения в useState или в useEffect выглядят синхронными, но на самом деле они асинхронны.
Простой пример:
...
const [count, setCount] = useState(0);
console.log(count); // 0
setCount(1); console.log(count); // Всё ещё 0! 😲
...
Кажется, что setCount(1) сразу меняет count, но на самом деле новое значение попадёт в консоль только при следующем ререндере.
То же самое в useEffect:
...
useEffect(() => { console.log("Эффект сработал!"); }, [count]);
setCount(1); console.log("А это после setCount");
...
Лог "А это после setCount" появится в консоли раньше, чем "Эффект сработал!", потому что useEffect выполняется уже после рендера.
Как flushSync меняет поведение?
Обычно React группирует обновления (batching) и откладывает ререндер до конца текущего цикла. flushSync ломает это поведение и заставляет React сразу выполнить ререндер.
Что тут происходит? Без flushSync React подождал бы до конца текущего вызова и только потом обновил DOM. С flushSync обновление происходит немедленно, и console.log видит уже новый DOM.
React нас предупреждает В документации прямо сказано:
"flushSync – это низкоуровневый API. Используйте его только тогда, когда вам действительно нужно измерить DOM сразу после обновления состояния."
Когда не стоит использовать flushSync? Если можно обойтись обычными useEffect или useLayoutEffect. Если batching работает нормально и не мешает. Если нет необходимости немедленного ререндера (иначе можно уронить производительность).
Итог flushSync – мощный инструмент, но использовать его нужно осознанно. Он нужен в случаях, когда важно немедленно обновить стейт и тут же прочитать DOM (например, для анимаций).
Если понравился пост присоединяйтесь к моему каналу в Telegram по ссылке https://t.me/+qbK9ZPuAocI2MWUy. Там я делюсь своим опытом и пишу материалы которые будут полезны как новичкам, так и матерым разработчикам.
(Я запилил штуку, которая ничего не умеет, но ты можешь поверх этой штуки запилить своих костылей для решения проблем, которые у тебя возникнут из-за моей штуки).
CRDT - это просто лог операций (лог операций - это CmRDT и OT, CvRDT даже близко не лог).
Работать с IndexedDB через скомпилированный под WASM SQLite быстрее, чем напрямую работать с IndexedDB (разве что, если руки заточены под обнимашки).
Исследовал интернет и наткнулся на GitHub Unwrapped. Он на основе активности в GitHub создаёт видео, где можно увидеть часто используемые языки, часы спонтанной работы, звёзды и всё остальное. Достаточно ввести только имя профиля, чтобы получить видео. Код открыт.
Сделано с использованием Remotion — тоже с открытым кодом, которая позволяет автоматизировать создание видео на React в веб. Документация хорошая, но надо разбираться. Увидел это и решил, что круто, надо поделиться!
P.S. Моя активность в этом ролике, если кому-то будет интересно.
Мы подготовили гайд по настройке автогенерации с помощью Orval. Он облегчит жизнь разработчиков, которым часто не хватает времени на оптимизацию и рефакторинг приложений. Весь процесс описан пошагово, код и ссылки на библиотеки вы также найдете в статье https://habr.com/ru/articles/848182/
Привет друзья! Сделал максимально простые аналоговые часы на SVG. Можно ли их еще упростить или уменьшить? Или добавить немного улучшений без переусложнения? Буду рад вашим идеям!
Как в нативе: эти Web API поднимут ваше веб-приложение в стратосферу
С ними даже можно сыграть в Техасский Холдем😂
Салют, на связи Clevertec. Сейчас наша команда разрабатывает веб-версию банкинга с использованием React. С помощью Web API даем пользователям фичи, которые они привыкли получать в нативных приложениях. Отрываем от сердца список решений 😉
- Web Share API – для обмена ссылками, текстом и файлами с другими приложениями на устройстве. К примеру, удобно отправить чек об оплате в мессенджере, не покидая банковское приложение.
- Contact Picker API позволяет делиться контактами из своего списка. Можно использовать для перевода по номеру телефона. Не нужно вводить цифры вручную – поле автоматически заполнится контактом из телефонной книги.
- Media Capture and Streams API в нашем случае позволяет отсканировать QR-код с помощью камеры устройства. Нажимаешь на “Сканировать QR” – открывается окно с камерой, она считывает код и переводит пользователя в дерево платежей.
- Web OTP API открывает возможность автоматически вставлять код из смс. Например, для подтверждения оплаты на телефон приходит сообщение. Внизу экрана появляется модальное окно с подтверждением вставки. И после нажатия на “Разрешить” код отображается в поле ввода.
Подробнее про этот опыт использования Web API мы рассказали в отдельной статье. Что вы думаете о Web API, какие используете? Расскажите в комментариях, будем взаимно полезны друг другу.
Разработчик Мишан Пудель представил открытое локальное приложение в виде клона интерфейса Windows 11 на React.js с некоторыми компонентами ОС, включая работающий браузер Chrome, инструментарий VS Code, игру Emoji Tic-Tac-Toe, клиент Spotify в качестве музыкального проигрывателя и калькулятор.
React.js: для создания интерактивного пользовательского интерфейса.
Tailwind CSS: для стилизации компонентов и создания дескопного окружения.
React Router DOM: для управления навигацией и маршрутизацией в приложении.
Framer Motion: для добавления анимации и переходов.
React Draggable: для создания элементов, которые можно перетаскивать.
Страница входа в ОС: можно ввести что угодно на странице входа, чтобы получить доступ к приложению. Фактические учётные данные не нужны. Щёлкните по значкам на рабочем столе, чтобы открыть различные приложения. Используйте панель задач для переключения между открытыми приложениями. Взаимодействуйте с приложениями, чтобы изучить их функции и возможности.
Установка проекта локально:
Clone the repository: git clone https://github.com/MishanPoudel/Windows11-3.0;
Navigate to the project directory: cd Windows11-3.0;
1. All-in подход. Подключение компонента вместе со стилями или без них. Здесь любой компонент — это самостоятельная единица, которая уже содержит всё нужное. Внутри этого подхода можно выделить два подвида:
Инлайн-стили через Styled Components (возможно, добавить просто подключение стилей внутри компонента). Этот метод позволяет писать стили непосредственно в компоненте. При этом стили изолированы, что уменьшает возможность конфликтов между стилями разных компонентов.
Без добавления стилей (Headless). В этом случае компоненты предоставляют только логику без UI, что позволяет самостоятельно управлять стилями. Для создания подобной библиотеки нужно также ознакомиться с паттерном Compound component.
2. Dependency CSS & Bundle CSS подход. Второй большой подход — когда стили и компонент подключаются по отдельности. В этом случае стили и логика компонента отделены друг от друга.
Dependency CSS: этот способ подключения улучшает модульность и позволяет загружать стили только тогда, когда они действительно необходимы.
Bundle CSS предполагает подключение всех стилей сразу и отдельно — компонента. По сути, в этом случае все стили объединены в общий бандл и импортируются в корне проекта.
Но при написании они схожи, и стили к компоненту подключаются как модули.
Команда react.js во всю готовится к предстоящей конференции и видимо, несмотря на большие сомнения, именно на ней они представят React 19. На сайте уже была опубликована страница релиза.
В релизе всё то, о чём рассказывала команда next.js - action для формы, новые хуки, серверные компоненты и серверные действия, метаданные страницы и предзагрузка ресурсов из коробки. Из нового (или упущенного мной) - для передачи ref больше не нужно использовать forwardRef, обновлённое API контекстов и продвинутая поддержка таблиц стилей.
Вместе с релизом был опубликован и гайд на обновление до 19 версии для библиотек. В гайде можно отметить значительные удаления функционала помеченного в последние годы как устаревший.
Также вчера вышел React 18.3.0, а уже сегодня вышла минорка - React 18.3.1. Это промежуточные релизы, в которых добавили предупреждения о том, что будет помечено как устаревшее или удалено. Так можно подготовить проекты к предстоящему обновлению.
useOptimistic — новый хук, который позволяет отобразить “оптимистичное” состояние. Оно называется “оптимистичным”, потому что мы надеемся, что запрос не свалится с ошибкой и после его выполнения состояние будет выглядеть именно так.
❓Как используется
В useOptimistic передаётся реальное состояние и функцию-reducer
Компонент использует “оптимистичное” состояние для рендера
Перед выполнением запроса обновляется “оптимистичное” состояние
Когда запрос завершился, нужно обновить реальное состояние
Как только реальное состояние обновилось, оптимистичное состояние обновится автоматически, так как оно передано в useOptimistic первым параметром.
Если запрос упал с ошибкой, нужно откатить изменения в оптимистичном состоянии.
ℹ️ Первый вопрос, которым я задался, а в чём отличие от обычного setState, путём экспериментов, вот что удалось найти:
useOptimistic работает с формами. Работать с обычной кнопкой в SPA мне не удалось, обновление происходило только после завершения запроса
useOptimistic работает только внутри асинхронного обработчика, что логично. Если убрать async/await, обновление произойдёт только после завершения запроса
Параметр в useState используется только для инициализации, и игнорируется в последующих рендерах. useOptimistic будет сихронизироваться со значением со значением переданным первым параметром.
В любом случае, пока useOptimistic выглядит каким-то низкоуровневым API. Надеюсь скоро появится больше Best Practices.
use — новый хук, который позволяет считывать данные из промиса и при этом интегрирован с Suspense и ErrorBoundary.
Основные моменты:
На этот хук не распространяются правила хуков — его можно использовать внутри циклов и условных операторов.
Если мы используем хук use(Promise), то где-то в родительском компоненте мы должны положить сам промис (не данные как мы делали раньше) в стейт (useState). Это позволяет избавиться от useEffect’а, который был нужен, чтобы запросить данные при первом рендере.
Хук интегрирован с Suspense, поэтому пока промис не разрезолвится — будет показан fallback объявленный в ближайшем Suspense.
Если промис зареджектился, то будет показан fallback объявленный в ближайшем ErrorBoundary.
Как-то я уже упоминал паттерн Compound Components (Составные компоненты) для React, теперь остановимся на нём немного подробнее.
ℹ️ Compound components — это подход позволяет объединить несколько компонентов в единую сущность, которая неявно имеет общее состояние. Эти компоненты тесно взаимодействуют друг с другом и работают как единое целое, представляя собой полноценный UI компонент.
? Основные характеристики:
Используется React контекст, чтобы управлять состоянием
Должен быть главный компонент, в котором хранится состояние и объявляется React контекст
Все дочерние компоненты используют состояние через React контекст
ℹ️ Он состоит из 2 простых подходов React:
Композиция компонентов
Паттерн “Провайдер” — использование контекста React
Здесь идёт речь об обычном использовании контекста реакта, чтобы передавать какие-то данные на любую глубину дерева компонентов, минуя дочерние компоненты.
? Если объединить два этих подхода, то сможем реализовать паттерн Compound Components. Как пример, можно использовать компонент табов из библиотеки material-ui.