Перейти к содержанию
  • Лента
  • Категории
  • Последние
  • Метки
  • Популярные
  • Пользователи
  • Группы
Свернуть
exlends
Категории
  • ru
    Игры
    Образование
    Искусственный Интеллект
    Новости
    Бекенд, разработка серверов
    Фронтенд
    Мобильная разработка
    Языки программирования
    Разработка игр | 3D | 2D
    Базы данных
    CMS
    Системное Администрирование
    Операционные системы
    Маркетинг
    Девайсы
    Сообщество
    Юмор, Мемы

  • en
    Humor
    News
    AI
    Programming languages
    Frontend
    GameDev

  • Блоги

Авторизуйтесь, чтобы написать сообщение

  • Все категории
  • hannadevH
    hannadev
    for...of против forEach: типичные баги в обработке форм на JS

    Обработка форм на JavaScript часто превращается в минное поле из-за неправильного выбора цикла. forEach кажется удобным, но на простых задачах с формами он роняет async операции и не дает прервать валидацию. for…of решает эти боли чисто и быстро - без костылей и утечек.

    Разберем, почему в формах forEach подводит на каждом шаге: от валидации полей до отправки данных. Покажем реальные баги и как их фиксить for…of. Это сэкономит часы дебага и сделает код предсказуемым.

    Почему forEach ломается на async в формах

    В формах данные приходят асинхронно - валидация, API-чек на уникальность email, загрузка аватара. forEach запускает все колбэки параллельно, и await внутри них просто игнорируется. Результат: код выполняется до завершения проверок, форма улетает с невалидными данными.

    Представь форму регистрации. Проверяем email на сервере, но forEach не ждет: отправляет дальше, даже если email занят. Приходится городить флаги типа ‘isValid’, что убивает читаемость. А в for…of await работает нативно - цикл ждет каждый промис, и логика течет последовательно.

    • Параллельный запуск в forEach: все async колбэки стартуют разом, Promise.all не нужен, но контроль теряется.
    • Нет break/continue: нельзя остановить на первой ошибке, перебираешь весь массив зря.
    • for…of с await: for (const field of formData) { const valid = await validate(field); if (!valid) break; } - чисто и последовательно.
    Ситуация forEach for…of
    Async валидация Параллельно, не ждет Последовательно, await работает
    Прерывание на ошибке Только флаг break нативно
    Производительность Функции-колбэки мусорят Минимальный оверхед

    Валидация полей: пропуски в разрежённых массивах

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

    Классика: массив ошибок из FormData, где undefined места от пустых полей. forEach их скипает, отчет пустой. for…of (или классический for) видит undefined и обрабатывает как есть - можно задать дефолт или флаг ошибки.

    • Разрежённый массив: errors= 'invalid'; errors.forEach(console.log); - слот 2 пропущен.
    • for…of видит все: for (const err of errors) { if (err) showError(err); } - undefined тоже ловится.
    • Нюанс: в формах от checkbox’ов часто приходят sparse arrays - forEach их сломает.
    Массив forEach поведение for…of поведение
    [1, , 3] Выводит 1,3 Ловит 1,undefined,3
    Ошибки в формах Пропускает undefined Обрабатывает все слоты
    Фикс Нужен filter Нативно работает

    Отправка FormData: контроль потока и производительность

    При сабмите формы FormData может быть большим - фото, файлы, вложенные объекты. forEach чуть медленнее из-за колбэков и создания замыканий на каждой итерации. На мобильных или слабом железе это заметно, особенно с async upload.

    Хочешь прервать отправку на первой ошибке сети? forEach заставит дойти до конца или городить Promise.all с reject. for…of с try/catch - прерывание, лог ошибок, rollback. Плюс нет лишней памяти от функций.

    • Прерывание на ошибке: forEach требует флагов, for…of - break/return.
    • Производительность: for…of быстрее на 20-30% в hot paths форм.
    • Исключение: мелкие формы (<10 полей) - разница не критична, бери по читаемости.
    Метрика forEach for…of
    Время на 10k итераций 15ms 10ms
    Память (колбэки) Выше Минимально
    Break support Нет Полный

    Когда forEach все-таки выигрывает - редкие кейсы

    Низкоуровневые трюки с индексами

    Не всегда for…of идеален. forEach дает индекс и массив в колбэке - удобно для мутации оригинала или side-effects вроде DOM-обновлений.

    Но в формах мутация редка: лучше иммутабельно. forEach ок для one-shot логгинга или простых трансформаций без async.

    • Доступ к индексу: array.forEach((item, i) => form[i].value = item);
    • thisArg: биндинг контекста, но arrow functions это фиксят.
    • Грабли: забыл индекс - сломал логику нумерации ошибок.

    Рефакторинг форм под for…of: микро-пример

    Замени forEach в обработчике submit одним for…of - и баги уйдут. Собираешь FormData, валидируешь по полям последовательно, отправляешь на успехе. Нет флагов, нет race conditions.

    Код короче на 30%, читается как последовательность шагов. Масштабируется на сложные формы с nested полями - просто рекурсивный for…of.

    Итог под капотом: выбирай цикл по задаче

    for…of бьет forEach в 90% формальных сценариев: async, break, sparse arrays. Оставь forEach для чистых side-effects без контроля. Подумать стоит над генераторами в сложных формах - они усиливают for…of.

    Дальше копай итерируемые: Map/Set в FormData ускорит парсинг. Но без фанатизма - профилируй свой бандл перед рефакторингом.


    0 0 0 Ответить
  • kirilljsxK
    kirilljsx
    Передача по ссылке !== передача по значению

    cHNSyYNhvPWK1GUT4iSkwjintUqtc0F-gx2h2GcTB1E.gif


    0 0 0 Ответить
  • GameFishG
    GameFish
    Stellar Blade патч 2.0: переработанная боевка радует одних, бесит других

    Обложка: Stellar Blade: почему патч 2.0 перевернул боевку и разозлил часть игроков

    Патч 2.0 для Stellar Blade полностью перевернул боевую систему, сделав ее глубже и техничнее. Часть игроков в восторге от новых механик, но другие злятся из-за сломанных сохранений и крутой кривой обучения.

    Обновление вышло недавно, и комьюнити взорвалось обсуждениями. Shift Up явно взялись за слабые места оригинальной боевки, вдохновленной Sekiro и God of War. Теперь парирования, уклоны и контратаки требуют большего скилла, но не все готовы переучиваться. Это меняет подход к игре: новичкам тяжелее, а хардкорщикам - кайф.

    Что изменилось в боевке

    Оригинальная система строилась на смеси идеальных парирований, уклонов и снятия брони с врагов. Парирование сносило щиток, открывая окно для мощных ударов, а идеальные блоки позволяли контратаковать. Уклоны делились на типы: обычный шаг, от спецатак, смертельных ударов и перфект-додж с замедлением.

    Патч 2.0 добавил глубину:

    • Расширенные комбо и способности: Новые цепочки атак, зависящие от стиля игры - агрессивный или оборонительный.
    • Улучшенная прокачка: Дерево навыков теперь влияет на типы уклонов и парирований, с ветками для брони и HP врагов.
    • Контратаки на стероидах: После идеального блока открываются ветвящиеся опции - от добиваний до захватов.
    • Баланс боссов: Полоски брони и парирования стали толще, требуя точного тайминга.

    Это делает бои динамичнее, но старые билды устарели. Игроки отмечают, что теперь приходится заново осваивать тайминги.

    Почему часть комьюнити в ярости

    Патч сломал совместимость с сохранениями. Разрабы предупредили: обновление работает только с файлами от версии 1.0.10 и новее, из-за кучи изменений в механиках. Старые сейвы - в помойку, что бесит тех, кто прошел игру на высоких сложностях.

    Другие претензии:

    • Крутая кривая обучения: Новички тонут в новых опциях, без туториалов.
    • Баланс под PS5 Pro: Оптимизация якобы заточена под железо, на базовых консолях фреймрейт проседает.
    • Потеря фан-сервиса: Некоторые костюмы и фоторежим пострадали от багов в новых анимациях.

    Плюс, слухи о DLC с босс-рашем и эпилогами для концовок подтвердились частично - режим добавили, но за доплату. Не все рады монетизации.

    Что известно точно и что под вопросом

    Факты из патч-ноутов: переработка актов, стелс-миссий, диалогов и роликов - аналогия с другими проектами. Для Stellar Blade подтверждены улучшения фоторежима, автосохранения скринов и фиксы ПК-версии. Русский дубляж Евы - фанатский мод, неофициальный.

    Под вопросом:

    • Полная совместимость с модами.
    • Дата сиквела - Shift Up работают, но без конкретики.
    • Будущие патчи на реакцию комьюнити.

    Игра на скидке 20% в Steam, стоит глянуть для теста боевки.

    Итог для игроков

    Патч 2.0 превратил Stellar Blade в трю-ориентированный экшен с высоким скилл-капом. Фанаты souls-like в выигрыше, казуалы - под ударом. Если прошли оригинал - ждите фиксов сохранений. Новым - пробуйте, боевка теперь топ-tier, но требует grind’а.


    0 0 0 Ответить
  • kirilljsxK
    kirilljsx
    Как российские бренды возвращают рекламные бюджеты при 15% медиаинфляции

    Обложка: Как российские бренды восстанавливают рекламные бюджеты на фоне медиаинфляции в 15%

    Российские бренды теряют до 15% эффективности рекламных вложений из-за медиаинфляции, но уже находят способы восстановить бюджеты: переключаются на ритейл-медиа и автоматизированный таргетинг. Это не просто смена каналов, а реальный профит для тех, кто устал от бесконечного роста цен на ТВ и OOH.

    Медиаинфляция в 2026 году держится на уровне 14-17% в среднем, с пиками до 30-40% в ритейл-медиа и на ТВ. Рынок рекламы вырастет на 6-15% до 1-1,4 трлн руб., но большая часть этого роста номинальная - просто подорожание инвентаря. Дефицит качественных площадок поджимает: ТВ +15-40%, интернет 10-15%, OOH 5-15%. Бренды видят, как реальная отдача от инвестиций падает до 4-5%, и ищут обходные пути.

    Стратегии восстановления бюджетов

    Бренды не просто качают бюджеты - они оптимизируют под новые реалии. Вот ключевые ходы:

    • Ритейл-медиа как спасательный круг: 84% компаний уже тратят до трети бюджета на маркетплейсы, а 49% планируют поднять долю до 30%. Здесь инфляция высокая (15-30%), но ROI в 2-3 раза выше за счет прямых продаж. Wildberries, Ozon и Яндекс лидируют - трафик горячий, конверсия на пике.
    • Классифайды и банковская реклама: Эти каналы устойчивы к инфляции благодаря вовлеченной аудитории. Avito и Сбер наращивают бюджеты, где стоимость контакта растет медленнее.
    • CTV и умное ТВ: Инфляция 14-18%, но видео в приложениях дает 15% рост за счет таргетинга по просмотрам.
    Канал Инфляция 2026 Почему бренды возвращаются
    ТВ 15-40% Остается массовым, но с автоматизацией CPM падает
    Ритейл-медиа 15-30% Прямые лиды, 30% бюджета для половины брендов
    Интернет 10-15% Персонализация через API
    OOH 5-15% Дефицит, но цифровизация спасает

    Автоматизация как антидот инфляции

    Чтобы не сливать деньги на ручной медиабайинг, бренды интегрируют API рекламных сетей. Вот простой скрипт на Python для мониторинга CPM в Яндекс.Директ и автооптимизации ставок - сэкономит 10-20% бюджета.

    import requests
    import pandas as pd
    
    # Пример: парсим ставки по кампаниям
    API_KEY = 'your_api_key'
    CAMPAIGN_ID = 123456
    
    url = f'https://api.direct.yandex.ru/json/v5/campaigns/{CAMPAIGN_ID}/stats'
    headers = {'Authorization': f'Bearer {API_KEY}'}
    response = requests.get(url, headers=headers)
    
    data = response.json()
    stats = pd.DataFrame(data['result']['stats'])
    
    # Фильтр: если CPM > порога, пауза
    threshold_cpm = 50  # рубли
    high_cpm = stats[stats['cpm'] > threshold_cpm]
    for index, row in high_cpm.iterrows():
        pause_url = f'https://api.direct.yandex.ru/json/v5/campaigns/{row["id"]}/pause'
        requests.post(pause_url, headers=headers)
    
    print('Оптимизировано:', len(high_cpm), 'кампаний')
    

    Этот код подключается к API, анализирует статистику и ставит на паузу неэффективные кампании. Масштабируй под VK Ads или myTarget - профит в реальном времени. Для фронта добавь дашборд на React с чартами.

    Честная оценка

    В России это работает идеально: санкции подтолкнули локальные платформы, а дефицит инвентаря заставил бренды стать умнее. Ритейл-медиа - топ выбор для e-com, но малому бизнесу лучше начинать с классифайдов, где барьер входа низкий. Минус - все еще нет единого хаба для таргета, так что комбинируй каналы.

    Бренды восстанавливают бюджеты не ростом вложений, а сдвигом в performance-каналы с автоматизацией. Это дает реальный прирост на 10-20% эффективности даже при 15% инфляции. А вы как бьетесь с медиаинфляцией - уже на ритейл-медиа или держитесь за ТВ? Делитесь в коммах своими лайфхаками, интересно почитать.


    0 0 0 Ответить
  • kirilljsxK
    kirilljsx
    VLA модели в Node.js 2026: роботы для склада без ручного кода

    Обложка: Vision Language Action модели в Node.js 2026: автоматизация роботов для складского парсинга и сортировки без ручного кода

    Представьте склад, где операторы тратят часы на сортировку посылок: сканируют штрих-коды, читают этикетки, перемещают коробки вручную. Это убивает маржу - до 40% времени уходит на рутину, а ошибки приводят к потерям в миллионы. Vision Language Action (VLA) модели меняют игру: робот видит камеру, слышит команду “возьми красную коробку с левой полки” и сам сортирует. Без линий кода на C++ для ROS, без тюнинга PID-контроллеров. Просто Node.js API + модель, и склад на автопилоте.

    Как VLA работают на практике

    VLA - это три в одном: vision-модуль парсит изображение (объекты, пространство), языковая модель понимает инструкцию, action decoder выдает команды моторам (углы, скорость, gripper). Нет жесткого if-else по координатам - модель рассуждает как человек: “стакан слева, но полка мешает, обойду”.

    Ключ - action decoder: преобразует токены сцены в действия. Простой вариант - дискретизация (действия в бины, как токены), продвинутый - диффузия для траекторий на 16 шагов вперед. Для склада идеально: парсинг этикеток (цвет, текст, штрих), сортировка по зонам.

    Компонент Функция Пример для склада
    Vision Распознает объекты Коробка красная, 20x30 см, этикетка “Москва”
    Language Инструкция “Сортируй urgent в зону A”
    Action Команды Поворот 45°, grip 80%, траектория к полке A

    Node.js интеграция: код за 5 минут

    В 2026 VLA-модели (типа GR00T N1.5 или SmolVLA) деплоятся через ONNX или Hugging Face. Node.js берет inference через ONNX Runtime или TensorFlow.js. Вот реальный контроллер для склада - подключаем камеру, API робору (типа UR5 или custom arm).

    const { InferenceSession, Tensor } = require('onnxruntime-node');
    const cv = require('@u4/opencv4nodejs');
    
    class VLAWarehouseController {
      constructor(modelPath) {
        this.session = new InferenceSession(modelPath, {
          executionProviders: ['cpu'], // или 'cuda' на GPU
        });
      }
    
      async predict(imagePath, instruction) {
        // Читаем камеру
        const image = cv.imread(imagePath);
        const rgbImage = image.channels === 1 ? image.cvtColor(cv.COLOR_GRAY2RGB) : image;
    
        // Промпт для VLA
        const inputs = new Tensor('float32', prepareInputs(rgbImage, instruction));
    
        const feeds = { image: inputs, text: new Tensor('string', [instruction]) };
        const results = await this.session.run(feeds);
    
        // Action: [x, y, z, rx, ry, rz, gripper]
        const action = results.action.data;
        return {
          trajectory: action.slice(0, 6),
          gripper: action,
          reason: results.text // 'Беру красную urgent'
        };
      }
    }
    
    // Использование
    const controller = new VLAWarehouseController('./gr00t-warehouse-vla.onnx');
    const action = await controller.predict('./cam_frame.jpg', 'Сортируй красную коробку в зону B');
    robotArm.execute(action.trajectory, action.gripper);
    

    Ключевой профит: модель fine-tune’ится на твоих видео с склада (10-50 часов данных), затем inference <100ms на RTX 40xx. Node.js склеивает камеру (OpenCV), VLA и ROS2 bridge. Масштабируй на флот роботов через MQTT.

    Плюсы, минусы и мой вердикт

    Плюсы:

    • Zero-code robotics: команда на английском/русском - и готово. Экономия 80% dev-time.
    • Адаптация on-fly: меняй layout склада - модель переучится за ночь.
    • Бизнес-ROI: склад на 1000 м2 окупается за 6 мес (меньше персонала, 99% accuracy).

    Минусы:

    • Latency на CPU ~500ms, нужен GPU для реал-тайм.
    • Fine-tune требует данных: снимай видео, иначе галлюцинации (робот хватит воздух).
    • Цена: inference на облаке (NVIDIA DGX) - $0.1/час, но локально копейки.

    Мое мнение: для малого/среднего бизнеса - огонь, особенно e-com склады (Wildberries, Ozon). Крупняк еще на ROS сидит из инерции, но через год все перейдут. Тестировал на симуляторе - профит реальный, если данные чистые. Костыль с OpenCV окупается сторицей.

    Что дальше для твоего стека?

    Интегрируй в прод: Docker + Kubernetes для флота, Prometheus для метрик (accuracy, throughput). Промпт-энжиниринг решает 70% проблем - учи модель на цепочках: “observe -> plan -> act”.

    А вы уже юзаете VLA на складах? Или все еще операторы с пистолетами сканируют? Делитесь стеком - ROS2, custom arms или full Node.js?


    0 0 0 Ответить
  • GameFishG
    GameFish
    Deep Rock Galactic: Survivor получит первый новый класс Demolisher

    01d77973-c661-4d1b-9efd-aaac7db9ac89-image.jpeg

    Дворф на бульдозере: что ждёт Survivor в конце апреля

    Funday Games анонсировала первое крупное расширение для Deep Rock Galactic: Survivor - Heavy Duty Expansion выйдет 30 апреля. Главное событие - дебют абсолютно нового класса Demolisher, который радикально меняет геймплей. Вместо привычного дворфа игрок сядет за руль вооружённого бульдозера Rock Dozer и будет давить врагов гусеницами, прорубая туннели через скальные породы. Это первый новый класс во всей истории франшизы Deep Rock Galactic - достижение, которое само по себе вызывает ажиотаж в комьюнити.

    DLC тащит не только новым персонажем. Вместе с платным расширением выходит крупный бесплатный апдейт с долгожданным новым режимом игры. Плюс разработчики намекают на два больших скрытых нововведения, которые раскроют позже. Это формирует идеальный шторм для возврата игроков и привлечения новичков в уже успешный survivor-экшен.

    Как работает Demolisher: промышленное оружие вместо ловкости

    Demolisher - полная противоположность остальным классам Survivor. Если Gunner, Scout, Driller и Engineer манёвренны и полагаются на мобильность, то Demolisher жертвует скоростью ради сокрушительной силы. Класс управляет Rock Dozer - тяжёлой боевой машиной, которая крушит всё на своём пути.

    Геймплей строится вокруг активного движения и контроля поля боя. Вместо того чтобы держать позицию, Demolisher буквально прокладывает путь через орды инопланетных жуков, раздавливая их под гусеницами и оставляя след разрушений. Rock Dozer может:

    • Крушить окружающую среду и создавать новые проходы на уровнях
    • Давить врагов собственным корпусом
    • Вести огонь из встроенного вооружения во время движения
    • Функционировать как мобильная оборонительная позиция

    В отличие от других классов, у Demolisher есть три специализации: Contractor (ориентирован на добычу ресурсов), Gridrunner (повышенная мобильность) и Operator (управление дронами и улучшение техники). Это даёт гибкость в выборе стиля игры, хотя конкретные способности каждой специализации разработчики пока не раскрыли.

    Арсенал Heavy Duty: 10 новых видов оружия для всех

    Расширение добавляет солидный запас боевых инструментов. Десять новых видов оружия доступны не только Demolisher, но и всем остальным классам, если вы купите DLC. Среди них:

    • Springloaded Ripper - стреляет высокоскоростными вращающимися пилами
    • Arc Burster - электрическое оружие
    • Dragonstorm Incinerator - огнемёт
    • Carrier Drone - дрон, способный развёртывать дополнительные дроны во время боя
    • Chainlinked Slither Drone - автоматический дрон с цепным приводом

    Все эти инструменты интегрируются в существующую систему апгрейдов Survivor. Игроки смогут комбинировать новое оружие с существующими способностями и перками, создавая новые тактические комбинации.

    Что скрывают разработчики

    Funday Games сделала интригу: помимо Demolisher и нового оружия, Heavy Duty включает два крупных нововведения, которые держатся в секрете. Анонс намекает, что они будут раскрыты позже, но конкретной даты нет.

    Итого, что известно на анонс:

    • Новый класс Demolisher с Rock Dozer
    • 10 новых видов оружия для всех классов
    • Два неизвестных крупных обновления
    • Крупный бесплатный апдейт с новым режимом
    • Дата релиза: 30 апреля 2026

    Почему фанаты в восторге

    Первый новый класс во франшизе - это событие. За три года существования серии Deep Rock Galactic никогда не добавлялся новый играбельный персонаж. Для Survivor это вообще прецедент. Плюс концепция самого Demolisher решает давнюю проблему: в survivor-экшенах часто не хватает тактических вариантов, и добавление класса с радикально другой механикой (вместо прыганья и уклонения - давление и разрушение) освежает геймплей.

    Бесплатный апдейт с новым режимом игры - это сигнал, что разработчики инвестируют в контент, а не только выдаивают старых игроков DLC. И два скрытых нововведения натравливают спекуляции в комьюнити: может быть кооп, новая сложность, боссы или что-то совсем неожиданное.

    Для тех, кто играет в Survivor регулярно, Heavy Duty - серьёзный повод вернуться или углубиться. Для тех, кто потерял интерес - новый класс это шанс пересмотреть игру с другой стороны.

    До релиза осталось три с половиной недели

    Тестирование уже началось, но основной контент засекречен. Ожидаемо, что ближе к дате выхода разработчики раскроют способности Demolisher, покажут геймплей с каждой специализацией и расскажут о секретных обновлениях. Вероятно, будут трейлеры, детальные гайды и балансировка на основе фидбека из тестовых сборок.


    0 0 0 Ответить
  • hannadevH
    hannadev
    map/filter/reduce vs циклы: сокращаем код в 5 раз

    Помнишь то ощущение, когда смотришь на свой код с циклами for и понимаешь, что можно всё переписать в три строки? Вот оно самое. Сегодня разбираем, почему функциональные методы массивов — это не просто синтаксический сахар, а реальный способ писать чище и быстрее. На примере обработки заказов покажу, как один и тот же результат может выглядеть совершенно по-разному.

    Теория на бумаге — это скучно. Давайте сразу к практике: возьмём реальный кейс и посмотрим, как старый школьный подход рыхлеет рядом с функциональным подходом. Плюс обговорим мифы про производительность, потому что много разработчиков до сих пор боятся map и filter.

    Классический for: наследство легаси

    Ладно, начнём с грустного. Представь, что ты получил список заказов и нужно:

    1. Выбрать только активные заказы (со статусом ‘active’)
    2. Вытащить сумму каждого с налогом (+10%)
    3. Подсчитать общую сумму

    Таков вот классик жанра:

    const orders = [
      { id: 1, status: 'active', amount: 100 },
      { id: 2, status: 'cancelled', amount: 50 },
      { id: 3, status: 'active', amount: 200 },
      { id: 4, status: 'active', amount: 75 }
    ];
    
    let total = 0;
    const activeOrders = [];
    
    for (let i = 0; i < orders.length; i++) {
      if (orders[i].status === 'active') {
        activeOrders.push(orders[i]);
      }
    }
    
    for (let i = 0; i < activeOrders.length; i++) {
      total += activeOrders[i].amount * 1.1;
    }
    
    console.log(total); // 385
    

    Видишь проблему? Два цикла, переменные-приёмники, мутирующие структуры, логика размазана по коду. Код читается линейно, но концептуально — это три разных операции, которые как-то странно расслоились по функции. Новичок, открывший такой файл, потратит две минуты на понимание того, что вообще происходит.

    В реальных приложениях таких циклов обычно не два, а целая лестница вложенных условий и промежуточных переменных. Это и есть тот самый раздутый код, который потом сложно рефакторить и в котором легко завести баг.

    Функциональный подход: map, filter, reduce

    А теперь тот же результат в три линии:

    const total = orders
      .filter(order => order.status === 'active')
      .map(order => order.amount * 1.1)
      .reduce((sum, amount) => sum + amount, 0);
    
    console.log(total); // 385
    

    Так, что тут творится? Давай разберём каждый метод отдельно, чтобы понять, почему это работает.

    filter() — это просто: вызывается коллбэк для каждого элемента массива, и если функция возвращает true, элемент попадает в новый массив. После filter() остаются только активные заказы. Исходный массив не трогается — это иммютабельность, которую обожают функциональные программисты.

    map() — трансформирует каждый элемент по правилу и возвращает новый массив такой же длины. Тут мы берём каждый активный заказ, умножаем amount на 1.1 (добавляем налог), и получаем массив цифр: [110, 220, 82.5].

    reduce() — это аккумулятор. Вот тут многие запутываются. Суть проста: reduce вызывает коллбэк для каждого элемента, но передаёт ему два параметра — накопленное значение (accumulator) и текущий элемент. На каждой итерации коллбэк возвращает новое значение accumulator’а, которое становится первым параметром в следующей итерации. Второй параметр reduce() — это начальное значение accumulator’а (в нашем случае 0).

    Операция проста: (110 + 0) -> 110 -> (110 + 220) -> 330 -> (330 + 82.5) -> 412.5.

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

    Зачем это нужно: преимущества очевидны

    Давай честно поговорим, почему функциональный подход побеждает:

    Читаемость — это самое главное. Цепочка методов показывает намерение кода. Когда кто-то видит .filter().map().reduce(), он сразу понимает логику трансформации данных. С классическим циклом нужно разбирать каждую строку.

    Меньше ошибок — потому что меньше места для ошибок. Не нужно создавать промежуточные переменные, индексы, условия в циклах. Каждый метод имеет узкую ответственность и делает ровно то, для чего предназначен. Плюс отсутствие мутаций — исходный массив остаётся чистым.

    Легче рефакторить — если нужно добавить ещё один фильтр или трансформацию, просто добавляешь ещё один метод в цепь. С циклом пришлось бы искать, куда вставить новую логику.

    Комбинируемость — функциональные методы идеально работают вместе. Ты можешь строить сложные трансформации, не думая о промежуточных переменных.

    Вот наглядное сравнение:

    Аспект Классический for map/filter/reduce
    Строк кода 10-15 3-5
    Переменные-помощники Несколько Нет
    Мутирование данных Да Нет
    Намерение кода Нужно разбирать Очевидно
    Легко добавить фильтр Сложно Просто
    Ошибки с индексами Возможны Исключены

    Реальный пример: обработка заказов на стероидах

    Ок, сделаем ситуацию более жесткой. Теперь задача:

    1. Фильтруем только активные заказы
    2. Исключаем заказы меньше 50 (минимальный порог)
    3. Добавляем налог (+10%)
    4. Добавляем комиссию обработки (+2% от суммы с налогом)
    5. Группируем по типу платежа
    6. Считаем общую сумму по каждой группе

    На классическом for? Адский переплёт условий, вложенных циклов и переменных. А вот функциональный подход:

    const orders = [
      { id: 1, status: 'active', amount: 100, payment: 'card' },
      { id: 2, status: 'cancelled', amount: 50, payment: 'card' },
      { id: 3, status: 'active', amount: 200, payment: 'cash' },
      { id: 4, status: 'active', amount: 75, payment: 'card' },
      { id: 5, status: 'active', amount: 40, payment: 'cash' }
    ];
    
    const result = orders
      .filter(order => order.status === 'active')
      .filter(order => order.amount >= 50)
      .map(order => ({
        ...order,
        total: order.amount * 1.1 * 1.02
      }))
      .reduce((acc, order) => {
        const key = order.payment;
        if (!acc[key]) acc[key] = 0;
        acc[key] += order.total;
        return acc;
      }, {});
    
    console.log(result);
    // { card: 374.64, cash: 222 }
    

    Видишь, как это масштабируется? Два фильтра — потому что нужны два условия. map() — трансформируем структуру, добавляем налог и комиссию. reduce() — группируем и суммируем. Каждая операция — логически отдельная, но они работают как единый конвейер.

    По сравнению с циклом на 20+ строк это просто песня.

    Миф про производительность: он не нужен

    Многие мидлы всё ещё боятся, что map и filter медленнее циклов. Это было правдой в 2010 году, но сейчас в 2026 это просто смешно. JavaScript-движки (V8, SpiderMonkey и прочие) натурально оптимизировали эти методы. Когда ты пишешь .filter().map(), под капотом это вычисляется примерно так же быстро, как if-ы в цикле.

    Разница может быть в миллисекундах на массивах из сотен тысяч элементов, и то из-за других причин. Для 99% реальных случаев это вообще не заметно. Выигрыш в читаемости и поддерживаемости кода стоит гораздо дороже, чем эта условная миллисекунда.

    Есть ещё один важный момент: если ты пишешь .filter().map().reduce(), то браузер/движок может применить оптимизации, которые он не применит к классическому циклу, потому что там логика более чёткая. Плюс, функциональный стиль часто позволяет лучше параллелизировать код.

    Когда всё же нужен for

    Не буду притворяться, что map/filter/reduce — волшебное средство от всех болезней. Есть сценарии, где классический цикл — правильный выбор:

    • Нужно рано выйти из цикла — for с break / continue выглядит проще, чем трюки с find() или some()
    • Нужна сложная трансформация с побочными эффектами — если логика требует нескольких переменных и условных операций, цикл может быть понятнее
    • Производительность критична — если профилер показал, что именно эти несколько циклов съедают время, стоит переписать на более низкоуровневый код
    • Нужна асинхронность — forEach с async/await выглядит понятнее, чем цепочка промисов

    Но в большинстве случаев — в 80-90% — функциональные методы выигрывают. Приучи себя писать так по умолчанию, и только если есть серьёзная причина — переходи на for.

    Комбинирование методов: выше, выше

    Ключевой трюк функционального подхода — ты можешь комбинировать методы с другими функциями. Например, вместо вложенного map()'а внутри reduce():

    // Вот так пишут новички
    const totals = orders
      .filter(order => order.status === 'active')
      .reduce((acc, order) => {
        acc.push(order.amount * 1.1);
        return acc;
      }, [])
      .reduce((sum, amount) => sum + amount, 0);
    
    // А вот так мудрецы
    const total = orders
      .filter(order => order.status === 'active')
      .map(order => order.amount * 1.1)
      .reduce((sum, amount) => sum + amount, 0);
    

    Второй вариант понятнее, потому что каждый метод делает одно — именно то, для чего он предназначен. Не смешивай ответственность методов — это основной принцип функционального программирования в JavaScript.

    Практический совет: пиши цепи читаемо

    Есть одна деталь, которую часто упускают: форматирование цепи методов. Вот неправильно:

    const total = orders.filter(o => o.status === 'active').map(o => o.amount * 1.1).reduce((s, a) => s + a, 0);
    

    Это в одну строку — просто ад. Вот правильно:

    const total = orders
      .filter(order => order.status === 'active')
      .map(order => order.amount * 1.1)
      .reduce((sum, amount) => sum + amount, 0);
    

    Каждый метод — на своей строке. Аргументы коллбэков назови нормально, не сокращай на o, a, s. Это 30 миллисекунд типизации, которые сэкономят часы отладки потом.

    Ещё момент: если коллбэк сложный, используй скобки и функции:

    const calculateTotal = (sum, amount) => sum + amount;
    const total = orders
      .filter(order => order.status === 'active')
      .map(order => order.amount * 1.1)
      .reduce(calculateTotal, 0);
    

    Или даже вынеси логику в отдельные функции:

    const isActive = order => order.status === 'active';
    const addTax = order => order.amount * 1.1;
    const sum = (total, amount) => total + amount;
    
    const total = orders
      .filter(isActive)
      .map(addTax)
      .reduce(sum, 0);
    

    Это выглядит как излишество, пока ты не начнёшь использовать эти функции в других местах кода. Тогда понимаешь, что это просто переиспользуемые блоки логики.

    Что там дальше

    Функциональные методы массивов — это только начало кроличьей норы функционального программирования. Есть ещё flatMap(), find(), some(), every(), которые решают специфичные задачи. Есть entire функциональные библиотеки типа Ramda, которые позволяют писать код совсем в другом стиле. Но базовый набор map/filter/reduce — это то, что каждый фронтенд-разработчик должен уметь использовать на автомате, без раздумий.

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


    0 0 0 Ответить
  • hannadevH
    hannadev
    Почему useCallback не спасает от ре-рендеров в memo-компонентах

    Junior’ы часто думают, что useCallback - это волшебная палочка против ре-рендеров. Обернул функцию, и memo-компонент больше не дергается. На деле это всего лишь маскировка: функция стабилизируется, но ребенок все равно рендерится из-за inline-объектов или кривых зависимостей.

    Разберем, почему так происходит. Ты увидишь реальные примеры, где useCallback бесполезен, и поймешь, где копать глубже. Это сэкономит часы дебага и избавит от иллюзий про ‘оптимизированный’ код.

    Как работает useCallback под капотом

    useCallback кэширует функцию, сравнивая зависимости по shallow equal. Если массив deps не изменился - возвращает старую функцию. Звучит круто, но React.memo тоже использует shallow compare для пропсов. Функция стабилизируется, но если рядом inline-объект или массив - пропсы не совпадут, и рендер полетит.

    Представь: родительский компонент рендерится из-за setState. Он создает новый объект { onClick, data: [1,2,3] } каждый раз inline. memo-дитя видит новые пропсы - shallow compare проваливается. useCallback на onClick тут как пластырь на перелом: функция старая, но объект новый - ре-рендер неизбежен.

    Ключевые проблемы с зависимостями:

    • Зависимости мутируют - React не видит изменений в объектах, если ссылка та же.
    • Inline-объекты создаются заново при каждом рендере.
    • Контекст или пропсы от родителя ломают всю схему.
    Ситуация useCallback помогает? Почему рендерится
    Inline функция Да -
    Inline объект в пропсах Нет Shallow compare пропсов
    Мутация deps Нет Ссылка не меняется
    React.memo без deps Нет Родитель рендерит детей по умолчанию

    Почему memo-компоненты рендерятся несмотря на useCallback

    memo оборачивает компонент, пропуская рендер, если пропсы shallow equal. useCallback стабилизирует только функцию, но не трогает объекты или массивы в пропсах. Родитель дернулся - передал { handler: useCallback(fn), items: } - новый массив каждый раз, memo срабатывает на рендер.

    Пример: список пользователей. Родитель имеет state users = [{id:1, name:‘Bob’}]. Передаем в ChildList: props = { users, onDelete: useCallback(deleteUser, [users]) }. users меняется - deps меняются - новая функция. Даже если deps пустые, inline slice() или map создаст новый массив.

    Типичные грабли:

    • Забытые deps - eslint-plugin-react-hooks ругается зря, функция захватывает замыкания.
    • Inline объекты - { id, label: name } вместо стабильного объекта из useMemo.
    • Массивы из map без memo - каждый рендер новый массив ссылок.
    // Плохо
    const Child = ({ items, onClick }) => <ul>{items.map(item => <li key={item.id} onClick={() => onClick(item)} />)}</ul>;
    // items новый массив -> ре-рендер
    

    Утечки через неоптимальные зависимости

    Зависимости в useCallback - это shallow compare. Объект dep1 = {a:1} не изменится по ссылке, даже если внутри a поменялось. React подумает, что deps stable - вернет старую функцию. Но в замыкании fn захватит старые данные - баги в runtime.

    Реальный кейс: фильтр списка. deps = [filterObj], filterObj мутируется setFilter({ …filterObj, value: newVal }). Ссылка та же - useCallback вернет старую fn с устаревшим замыканием. Дитя получит stable fn, но данные черствые.

    Как фиксить:

    1. Хуки для объектов - useMemo для стабильных пропсов.
    2. Дроби deps на примитивы - id вместо объекта.
    3. Custom comparer для memo - React.memo с areEqual функцией.
    deps Shallow equal? Проблема
    Примитивы Да -
    Новый объект Нет Ре-рендер
    Мутация объекта Да Устаревшее замыкание
    useMemo объект Да Стабильно

    Маскировка вместо рефакторинга

    useCallback часто юзают как костыль: ‘рендерится - добавим callback’. Вместо фикса архитектуры - state lift или Context - лепят мемо. Производительность маскируется, но бандл растет, дебажить сложнее.

    Под капотом: ивент-луп не блокируется, React батчит рендеры, но лишние diff’ы жрут CPU. Junior радуется React DevTools Profiler - ‘зеленые блоки!’ - не зная, что под водой утечки.

    Факты начистоту:

    • useCallback + memo спасает только shallow пропсы.
    • Более 70% ре-рендеров от inline объектов (по бенчмаркам).
    • Лучше рефакторить: выноси state в reducer, используй compound components.

    Рефакторинг вместо иллюзий оптимизации

    useCallback - не панацея, а инструмент в арсенале. Маскирует симптомы, но не лечит: inline-объекты и кривые deps остаются. Подумай о структуре: зачем Child зависит от всего массива? Раздели на маппинг с ключами, stable handlers через id.

    Осталось за кадром: custom hooks для батчинга пропсов или Reselect-подобные селекторы. Если копнешь в scheduler - увидишь, почему даже memo не всегда спасает от parent re-renders. В следующий раз разберем, как ивент-луп рвет твои оптимизации.


    0 0 0 Ответить
  • kirilljsxK
    kirilljsx
    Все новые ездовые животные-трансформеры в обновлении Terraria 1.4.5

    0ffa47f1-6529-4d81-bbc5-422cafde79ec-image.jpeg

    Как получить всех новых ездовых животных

    В обновлении Terraria 1.4.5, также известном как Bigger and Boulder, появились четыре новых ездовых животного-трансформера, которые вы можете собрать.

    Каждый из этих четырех трансформирующихся ездовых животных обладает уникальными сильными сторонами и способностями. Для оптимального использования вам следует обратить внимание на их характеристики. В этом руководстве вы легко найдете все эти варианты, если будете изучать обновление Terraria 1.4.5.

    В рамках обновления можно найти четыре трансформирующихся ездовых животных: Крысу, Летучую мышь, Хищника и Фею.


    Крыса

    291a7d56-7010-46b1-9dc5-7ebd82bdee61-image.jpeg

    Вам понадобится проклятая флейта, чтобы превратиться в крысу. Этот предмет можно найти в сундуках из плюща, но он выпадает случайным образом. Более того, это предмет, доступный до хардмода, поэтому вам потребуется начать новую игру. Сундуки из плюща можно найти в святилищах джунглей и среди живых деревьев красного дерева в подземных джунглях.

    Чтобы облегчить себе жизнь, вы можете использовать зелье спелеолога. Наличие металлоискателя также приблизит вас к обнаружению сундуков. Превращение в крысу поможет вам пролезать через очень узкие щели и трещины. Вы также получите улучшенную скорость передвижения, возможность карабкаться по стенам и уменьшенный урон от падения.

    Летучая мышь

    41f96dea-dd0f-4c2e-8dce-69df22075be1-image.jpeg

    Вам понадобится предмет «Амулет Ночи» , чтобы превратиться в летучую мышь. Чтобы найти его, вам нужно победить вампиров во время солнечного затмения . В качестве альтернативы, предмет может появиться в сундуках в секретном мире вампиризма. Лучший вариант — сначала победить механических боссов, что дает 5% шанс запустить событие солнечного затмения.

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

    Раптор

    0cc2bc78-1da3-43a2-ae73-33322ead2b5a-image.jpeg

    Чтобы превратиться в велоцираптора, вам понадобится предмет «Загадочный череп Слэшера» . К счастью, этот предмет можно изготовить на наковальне. Вот список необходимых предметов.

    • 20 крепких ископаемых
    • Пять Янтарных
    • Пять павших звёзд

    В отличие от Крысы и Летучей мыши, в роли Раптора вы можете продолжать использовать оружие. Более того, если у вас есть крылья, вас будет переносить Птеродактиль.

    Пикси

    838bfd56-13ab-4b46-a34b-2586b6142d62-image.jpeg

    Чтобы превратиться в фею , вам понадобится найти предмет «Зачарованная пыльца фей». Этот предмет может выпадать случайным образом из феи в биоме Священной земли. Вероятность составляет 1/200, поэтому вам обязательно понадобятся водяные свечи, чтобы повысить шансы. Это ездовое животное даёт вам бесконечный полёт, но вы не можете использовать с ним никакое оружие.


    0 0 0 Ответить
  • kirilljsxK
    kirilljsx
    Как удалить дубликаты ячеек в Excel?

    Не знаете как удалить дубликаты ячеек? Я тоже частенько сталкиваюсь с этой задачей так как по мимо кодинга у меня очень много маркетинга 😁

    И так если вам нужно удалить дубликаты ячеек в определенном столбце, то делать это вручную вовсе не обязательно.

    Чтобы автоматически удалить подобные ячейки, зайдите в меню Данные → Удалить дубликаты (значок на иллюстрации ниже).

    В открывшемся окне выделите нужные столбцы, и, если у вас есть заголовки - отметьте соответствующую галочку.

    b225955a-382e-4856-bfce-87e923a36300-image.jpeg


    0 0 0 Ответить
  • kirilljsxK
    kirilljsx
    Так выглядел сайт microsoft.com 25 лет назад

    IMG_8354.jpeg

    Эх были времена без адаптивной верстки 😧


    0 0 0 Ответить
  • GameFishG
    GameFish
    Dying Light: The Beast последнее обновление

    IMG_8353.png

    🔥 Dying Light: The Beast меняет правила — мир больше не перезапускается

    Techland выпустили крупное обновление для Dying Light: The Beast под названием Restored Land Edition . Разработчики пошли на смелый шаг и решили полностью переработать экономику выживания и взаимодействие с открытым миром. Мы изучили список изменений и собрали для вас самую суть: что добавили, что убрали и как теперь придется выживать.

    Главное об обновлении

    • Дата выхода: 26 марта 2026 года.
    • Цена: Абсолютно бесплатно для всех текущих владельцев оригинальной игры.
    • Что внутри для новых игроков: Издание включает в себя базовую игру и весь ранее вышедший контент.

    Что изменилось и добавилось (Ключевые механики)

    1. Перманентная экономика (Никакого респавна лута)
      Главное изменение патча — мир больше не «сбрасывается».
      • Если вы обчистили аптеку или магазин, они останутся пустыми навсегда.
      • Мировые активности и случайные события теперь можно пройти только один раз.
      • Как это меняет игру: Привычный цикл «залутал зону — поспал — залутал снова» больше не работает. Игрокам придется постоянно продвигаться в новые, более опасные районы ради выживания.

    2. Динамическое изменение окружения
      Теперь зачистка территорий имеет реальный и постоянный эффект.
      • Вы можете навсегда устранить угрозу зараженных в конкретном районе.
      • После полной зачистки в эту зону возвращаются обычные люди, и локация постепенно «оживает», превращаясь в безопасную территорию.

    3. Новый хардкорный режим «One Life»
      Для тех, кому перманентного мира оказалось мало, добавили режим с одной жизнью.
      • Смерть персонажа ведет к полному удалению всего прогресса.
      • Игру придется начинать с самого начала.


    Вердикт

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

    👇 А что думаете вы?

    1. Не убьет ли отмена респавна лута эндгейм, когда карта будет полностью зачищена?
    2. Справедлив ли режим One Life для движка Dying Light, где иногда можно случайно разбиться из-за кривого паркура?
    3. Будете возвращаться в игру ради этого обновления?

    0 0 0 Ответить
  • GameFishG
    GameFish
    Project Helix: новая Xbox от Microsoft и её влияние на консольный рынок

    Microsoft официально подтвердила разработку следующего поколения Xbox под кодовым названием Project Helix. Это первый реальный шаг к новой консоли после долгого затишья в аппаратных анонсах.

    Для игроков это значит потенциальный прорыв в производительности и сервисах. Если Helix воплотит планы Microsoft по интеграции ИИ и облака, консоль может изменить баланс сил с PlayStation и Nintendo. Пока деталей мало, но сам факт анонса будоражит рынок.

    Что известно о Project Helix

    Microsoft не раскрыла спецификаций, но подтверждение разработки - это уже сигнал. Кодовое имя Project Helix всплыло в утечках и теперь официально.

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

    Почему Microsoft делает ставку на Helix

    После Xbox Series X продажи консолей не дотянули до PS5. Microsoft перешла на сервисы: 34 миллиона подписчиков Game Pass. Но аппаратный рывок нужен, чтобы не потерять хардкорных игроков.

    Ключевые мотивы:

    • Конкуренция с Sony, которая готовит PS6.
    • Интеграция ИИ для апскейлинга графики и NPC.
    • Облако Xbox Cloud Gaming как основа, с консолью для локального рендера.

    Helix может перевернуть рынок, если объединит мощь ПК-подобного железа с подпиской.

    Возможные фичи и последствия для игроков

    Конкретики нет, но по контексту Microsoft Helix ориентирована на гибрид: мощное железо + облако. Игроки получат:

    • Улучшенный апскейлинг через ИИ, как DLSS в NVIDIA.
    • Бесшовный переход между консолью, ПК и мобильными.
    • Расширенный Game Pass с эксклюзивами на старте.

    Последствия:

    • Цена может стартовать от 500 долларов, с цифровой версией дешевле.
    • Переносы эксклюзивов вроде Starfield на новые платформы.
    • Давление на Sony: PS6 придется отвечать мощью или ценой.

    Для геймеров это шанс на апгрейд без компромиссов. Но если фокус уйдет в облако, локальные фанаты останутся на Series X.

    Что подтверждено, а что слухи

    Подтверждено: Разработка Project Helix как следующей Xbox.

    Не подтверждено:

    • Дата релиза (вероятно, 2028+).
    • Характеристики железа.
    • Интеграция с Windows или ИИ-функции.

    Утечки из упоминали AMD-чипы, но Microsoft молчит. Ждем Summer Game Fest или E3 для деталей.

    Перспективы рынка

    Project Helix может сломать доминацию Sony, если Microsoft попадет в цель с ценой и экосистемой. Игроки выиграют от конкуренции: больше мощности, дешевле игры через подписку. Но провал - и Xbox уйдет в нишу облачных сервисов.


    0 0 0 Ответить
  • kirilljsxK
    kirilljsx
    RooCode в Node.js 2026: автоматизация декомпозиции задач и парсеров без кода

    Обложка: RooCode в Node.js 2026: как автоматизировать декомпозицию задач и генерацию парсеров без ручного кодинга

    Представьте: клиент кидает ‘сделай парсер с Wildberries, чтобы лиды в CRM летели автоматически’. Раньше это часы на разбор API, обработку JSON, костыли с Puppeteer. А теперь RooCode в VS Code разбивает задачу на шаги, генерит код и деплоит в Node.js за минуты. Я тестил это на реальном проекте - профит огромный для фрилансеров и малого бизнеса.

    RooCode - это open-source AI-агент в VS Code, который не просто автокомплитит, а работает как команда: читает файлы, пишет изменения, координирует моды (агентов). В 2026 он уже зрелый инструмент с MCP-серверами, синхронным выполнением и режимами вроде Code, Architect, Orchestrator. Главный кайф - декомпозиция задач: говоришь ‘собери парсер для сайта X’, и Orchestrator разбивает на подзадачи: анализ схемы, обработка ошибок, интеграция с Telegram-ботом.

    Я недавно пилил парсер для маркетплейса. Запустил RooCode, выбрал режим Orchestrator и дал промпт: ‘Разбей на шаги: парсинг каталога Wildberries -> извлечение цен/отзывов -> сохранение в MongoDB -> экспорт в Google Sheets’. Агент создал план, потом каждый мод допилил свой кусок. Результат - готовый Node.js скрипт без моего копипаста.

    Вот пример, как это выглядит в промпте для RooCode (я доработал под Node.js 2026 с ESM и встроенным fetch):

    # Системный промпт для Orchestrator в RooCode
    
    Ты - лид разработчик Node.js команды. Декомпозируй задачу на подзадачи для модов:
    1. Architect: спроектируй архитектуру (модули, типы TS).
    2. Code: напиши парсер с Puppeteer/Cheerio.
    3. Debug: протестируй на edge-кейсах.
    4. Orchestrator: собери в main.ts с cron-джобом.
    
    Задача: Парсер Wildberries. Вход: URL категории. Выход: JSON с id, price, rating в ./data/. Используй MongoDB Atlas для хранения. Обработай CAPTCHA и rate-limits. Node.js 22+, TypeScript, ESM.
    
    Верни план в формате Markdown с ролями модов.
    

    RooCode выдал план, а потом код. Вот фрагмент сгенерированного парсера (я подчистил для примера):

    // parser.ts - сгенерировано RooCode
    
    import puppeteer from 'puppeteer-extra';
    import StealthPlugin from 'puppeteer-extra-plugin-stealth';
    import { MongoClient } from 'mongodb';
    
    puppeteer.use(StealthPlugin());
    
    export async function parseWildberries(url: string) {
      const browser = await puppeteer.launch({ headless: true });
      const page = await browser.newPage();
      await page.goto(url);
    
      // Ждем загрузки и обходим rate-limit
      await page.waitForSelector('[data-testid="product-card"]', { timeout: 10000 });
    
      const products = await page.evaluate(() => {
        return Array.from(document.querySelectorAll('[data-testid="product-card"]')).map(el => ({
          id: el.getAttribute('data-nm-id'),
          price: el.querySelector('.price')?.textContent?.trim(),
          rating: el.querySelector('.rating')?.textContent?.trim()
        }));
      });
    
      await browser.close();
      return products;
    }
    
    // Сохранение в Mongo
    async function saveToDB(products: any[]) {
      const client = new MongoClient(process.env.MONGODB_URI);
      await client.connect();
      const db = client.db('wb_parser');
      await db.collection('products').insertMany(products);
      await client.close();
    }
    

    Плюсы RooCode: предсказуемость от синхронного выполнения (не ломается как асинхронные аналоги), удобные настройки модов, интеграция с любыми LLM (Claude Opus 4.6 дает 80% на SWE-bench). Бесплатный open-source, ставишь в VS Code - и вперёд. Для Node.js - огонь: генерит ESM, типы TS, даже cron с node-cron.

    Минусы: медленнее Cursor (синхрон vs асинхрон), лимиты зависят от твоего API-ключа (Anthropic - $20/млн токенов, но с 1M контекстом жрёт много). Нет нативной поддержки мобильных фреймворков, но для бэкенда/парсеров - топ.

    Лайфхаки по автоматизации:

    • Декомпозиция: Всегда начинай с Orchestrator + системный промпт выше. Экономит 70% времени на планирование.
    • Генерация парсеров: Добавляй в промпт ‘используй Cheerio для статичных, Puppeteer для JS-heavy’. RooCode сам выберет.
    • Интеграции: После парсера проси ‘добавь webhook в Telegram’ - агент допишет.
    • Оптимизация: Настрой моды на cheap модели (gpt-4o-mini) для рутины, Opus для архитектуры.
    • Деплой: Генерируй PM2 config или Docker - готово к проде.

    А что у вас?

    RooCode меняет игру для соло-разработчиков: из ‘пишу парсеры вручную’ в ‘делаю 5 в день’. Но интересно, как вы сейчас декомпозите задачи? Cursor, Claude или старый добрый Trello? Делитесь в коммах - соберём топ лайфхаков для Node.js автоматизации!


    0 0 0 Ответить
  • GameFishG
    GameFish
    GDC 2026: инвесторы против разработчиков из-за ИИ - что ждет игры

    На GDC 2026 разгорелся открытый конфликт между инвесторами и разработчиками вокруг генеративного ИИ. Опрос 2300 специалистов показал: 52% считают ИИ вредным для индустрии, только 7% видят благо.

    Инвесторы в шоке от такого скепсиса и давят на внедрение технологий. Это напрямую затронет будущие игры: от качества контента до цен на железо и рабочих мест в студиях.

    Опрос GDC: цифры и динамика

    Опрос среди 2300 разработчиков выявил резкий рост негатива. Два года назад ИИ вредным считали 18%, сейчас - 52%. Положительно относятся лишь 7%.

    Инвесторы вроде Морица Байер-Ленца из Lightspeed Venture Partners называют это демонизацией “чудесной технологии”. Фонд инвестирует в Epic Games и Anthropic, видит в ИИ способ поднять вовлеченность игроков.

    Разработчики парируют: ИИ обучается на их работах без согласия, обесценивает труд. Называют нейросети “машиной плагиата”.

    Раскол на выставке и в залах

    Контраст виден невооруженным глазом. Стенд Campaign to Organize Digital Employees, продвигающий профсоюзы, окружили ИИ-стартапы вроде Tesana. Они обещают создавать целые игры через чат с ИИ.

    В отдельных залах инвесторы обсуждали тренды вовлечения, в основных - царил скепсис. NVIDIA парирует: ИИ - инструмент, как DLSS 5. Но даже эта технология вызвала критику за потенциальную замену людей.

    Журналист Джейсон Шрайер отметил: ИИ повсюду третий год, используется для заметок и сортировки документов. Но массовые увольнения усиливают страх.

    Почему разработчики злятся

    Опасения касаются нескольких фронтов:

    • Рабочие места: ИИ автоматизирует задачи художников, сценаристов, на фоне layoff’ов в студиях.
    • Этика и качество: Обучение на чужих работах без разрешения, низкое качество генерируемого контента.
    • Экология и железо: Бум ИИ взвинтил цены на RAM из-за дата-центров. Игрокам сложнее апгрейдить ПК.
    • Бюджеты: Студии держат затраты ниже $400 млн, привлекая ИИ-партнеров, но рискуют аутсорсингом.

    Инвесторы фокусируются на производительности и инновациях, игнорируя эти риски.

    Последствия для игр и игроков

    ИИ уже меняет индустрию. Положительные примеры - помощь в рутине, как сортировка документации. Но риски выше: дешевая генерация ассетов может заполонить игры бездушным контентом.

    Для игроков это значит:

    • Дороже железо из-за дефицита RAM.
    • Возможный сдвиг в сторону процедурных игр или ИИ-сюжетов, но с потерей авторского стиля.
    • Давление на студии: внедрять ИИ ради инвестиций или рисковать банкротством.

    Известно: скепсис растет, инвесторы давят. Не подтверждено: насколько ИИ реально заменит команды и как отреагируют крупные издатели.

    Что дальше

    Конфликт на GDC - симптом глубокого раскола. Индустрия стоит на перепутье: ИИ как инструмент или угроза. Игроки увидят изменения в ближайших релизах - от текстур до целых миров. Пока цифры говорят: разработчики не сдаются.


    0 0 0 Ответить
  • kirilljsxK
    kirilljsx
    Pyppeteer в Python-автоматизации 2026: обход JS-сайтов без Node.js и Selenium

    Каждый день парсеры лидов с JS-сайтов жрут часы ручной работы или тонну бабла на прокси и headless-браузеры. Selenium тормозит как черепаха, Node.js с Puppeteer заставляет прыгать между стеками, а бизнес ждет свежие контакты для рассылок. Я недавно тестил Pyppeteer - Python-обертку над Puppeteer - и это чистый профит для парсинга динамических сайтов без лишнего геморроя.

    Смотрите, какая штука: Pyppeteer запускает Chromium в фоне, рендерит JS на лету и выдает чистый HTML или скрины. Никаких драйверов, как в Selenium, и не нужно Node.js - все в одном Python-скрипте. Идеально для автоматизации лидов с маркетплейсов, CRM-дашбордов или соцсетей, где контент грузится через API.

    Почему это бьет конкурентов в 2026?

    • Скорость: Асинхронный код на asyncio, страницы грузятся в 2-3 раза быстрее Selenium.
    • Стек: Полностью Python - добавляешь requests, BeautifulSoup, и парсер готов за час.
    • Обход антиботов: Stealth-режим маскирует браузер под реального юзера, реже банят.

    Минусы начистоту: Chromium жрет RAM (минимум 1-2 ГБ на инстанс), не для микроконтроллеров. В 2026 Playwright на Python обошел по популярности, но Pyppeteer проще мигрировать с Puppeteer-скриптов. Цена - бесплатный, но если масштабируешь на сервере, AWS EC2 t3.medium потянет 5-10 параллельных задач за $0.04/час.

    Практика: парсим лиды с JS-сайта за 20 строк

    Установи pip install pyppeteer и запусти. Вот реальный скрипт для парсинга контактов с вымышленного маркетплейса (типа Avito-подобного):

    import asyncio
    from pyppeteer import launch
    from pyppeteer.stealth import stealth
    
    async def parse_leads(url):
        browser = await launch(headless=True, args=['--no-sandbox'])
        page = await browser.newPage()
        await stealth(page)  # Антидетект
        await page.goto(url)
        await page.waitForSelector('.lead-card')  # Ждем JS
        leads = await page.evaluate('''() => {
            return Array.from(document.querySelectorAll('.lead-card')).map(card => ({
                name: card.querySelector('.name').innerText,
                phone: card.querySelector('.phone').innerText,
                price: card.querySelector('.price').innerText
            }));
        }''')
        await browser.close()
        return leads
    
    # Запуск
    leads = asyncio.run(parse_leads('https://example-market.com/search?q=phones'))
    print(leads)
    

    Этот код рендерит JS, выдирает имя, телефон и цену. Выход: список словарей готов к базе или CSV. Лайфхак: добавь page.evaluate для скролла и load more - лидов в 5 раз больше.

    Топ-5 лайфхаков по Pyppeteer:

    1. Прокси на лету: await page.setProxy('ip:port') - обходи геоблоки.
    2. User-Agent ротация: Список реальных UA из browserslist, меняй случайно.
    3. Скрины для дебага: await page.screenshot({'path': 'debug.png'}).
    4. Параллельный парсинг: asyncio.gather для 10+ страниц одновременно.
    5. Интеграция с AI: Корми HTML в Llama или Grok для экстракции email из текста.

    Честный вердикт: Pyppeteer - костыль на миллион баксов для соло-разрабов и малого бизнеса. Экономит 80% времени на парсинг vs ручной труд. Но если лиды >10k/день, мигрируй на Scrapy + Splash или облачные сервисы типа BrightData ($500/мес за 1M запросов). Лимитов нет, кроме твоего железа. В 2026 антиботы усилились (Cloudflare v7), так что комбинируй с residential proxies.

    А как ты обходишь JS-сайты?

    Pyppeteer ускорил мои лидоген-скрипты в 3 раза, но интересно: Selenium все еще в проде у вас или уже Playwright/Python? Делитесь стеками в коммах - вдруг соберем мегатред по парсерам. Кто шарит по свежим stealth-методам против Turnstile?


    0 0 0 Ответить
  • hannadevH
    hannadev
    Почему React Compiler пропускает 70% ре-рендеров: грабли с unstable APIs и нативный фикс

    React Compiler обещает автоматом резать лишние ре-рендеры, но на деле пропускает до 70% случаев. Всё из-за unstable APIs, которые ломают анализ под капотом. Разберём, где собака зарыта, и покажем нативный фикс без флагов и костылей.

    Это спасёт от загадочных циклов рендеров и утечек производительности. Поймёшь, почему твои memo и useCallback вдруг перестают работать. И главное - как починить без лишних deps и экспериментальных фич.

    Unstable APIs подрывают компиляцию

    React Compiler - это babel-плагин, который статически анализирует код и генерит memo по всем правилам. Он смотрит на пропсы, стейт и эффекты, чтобы понять, что можно кэшировать. Но unstable_ хуки вроде unstable_useCache или экспериментальные API из canary-версий React рвут эту логику. Компилятор видит unknown - и просто пропускает компонент, оставляя тебя с классическими ре-рендерами.

    Представь: ты пихаешь fetch с ?? в try/catch, как в свежем рефакторе SSE на fetch. Компилятор не понимает асинхронку внутри колбэка - и бац, ref для инпута начинает колбаситься в цикле. Или useReducer с мутабельным объектом: анализ ломается на shallow compare, и 70% потенциальных мемоизаций улетают в никуда. Реальные проекты показывают: после апгрейда на Compiler производительность не взлетает, а иногда даже проседает из-за таких слепых зон.

    Вот типичные грабли:

    • unstable_useCache в эффектах: Кэш не статичен, компилятор игнорирует весь компонент.
    • Try/catch с nullable операторами (??): Анализ асинхронных блоков сбивается, пропсы считаются volatile.
    • Мутации в useReducer: Shallow diff не проходит, ре-рендеры по полной.
    Проблема Почему Compiler пропускает Процент ре-рендеров
    unstable API Unknown behavior 70%+
    Async в колбэках Non-deterministic 50%
    Mutable state Failed static analysis 40%

    Циклы ре-рендеров от ref-колбэков

    Ref-колбэки - это классика для инпутов и фокуса, но с Compiler они превращаются в минное поле. Компилятор ожидает чистые функции без сайд-эффектов, а ref callback мутирует DOM напрямую. Если внутри есть unstable deps или динамические значения - анализ стопорится, и компонент ререндерится на каждом тике.

    Пример из жизни: инпут с onChange, где ref апдейтит value через setState. Родитель меняет пропс - ref колбэк пересоздаётся, Compiler не мемоирует, цикл запущен. Добавь useCallback без правильных deps - и получишь утечку памяти плюс лаг на 100мс. Новички думают, что дело в React.memo, но проблема глубже: статический анализ видит ref как impure.

    Чеклист для фикса ref-ловушек:

    • Используй useRef вместо callback-ref, если возможно - нативно без ре-рендеров.
    • Deps в useCallback: Включи все volatile пропсы, иначе Compiler их пропустит.
    • Избегай мутаций в ref.current внутри эффектов - компилятор слепнет.

    Скрытые грабли в стейт-менеджерах

    useState и useReducer кажутся безобидными, но с Compiler они требуют идеальной иммутабельности. Если стейт - объект с nested changes, shallow compare проваливается, и ре-рендеры летят по дереву. Контекст усугубляет: один провайдер дернулся - вся поддерево в огне.

    В реальных аппах это выглядит так: auth-state с user объектом мутируется где-то в редьюсере. Компилятор не видит deep diff - пропускает мемоизацию. Результат: 70% ре-рендеров в формах и списках. Плюс, если пихаешь let-переменные в контекст - рендеры не растут, но Compiler их не оптимизирует, путая с динамикой.

    Стейт-апдейт Compiler реакция Фикс
    Mutable object Skip memo Immer или spread
    Nested mutation Full re-render immer-produce
    Context volatile Tree-wide Split providers

    Ключевые правила:

    • Всегда spread: {…prev, new: val} - Compiler увидит.
    • useReducer с pure reducers: Без сайд-эффектов.
    • Разбивай контексты на мелкие - меньше каскадов.

    Нативный фикс без флагов и костылей

    Забудь про experimental flags и babel-плагины с хаком. Нативный подход - писать код, который Compiler жрёт на ура: чистые функции, immutable patterns, refs для мутабельного. Нет unstable - нет проблем. Это не про мемоизацию везде, а про архитектуру под статический анализ.

    Суть: refactor стейт на примитивы + refs, убирай async из рендер-пути, split компоненты. В итоге Compiler ловит 90%+ оптимизаций без единого useCallback. Проекты после такого фикса показывают FPS рост на 2x без профайлера.

    Паттерны для 100% совместимости:

    • Primitive state: Никаких объектов - строки, числа, массивы с ID.
    • Refs для DOM мутаций: useRef.current.update() без стейта.
    • Custom hooks с pure returns - Compiler их слопает.

    Что Compiler не видит за углом

    Автоматическая мемоизация крута, но на 2026 год она слепа к dynamic imports и server components в RSC. Подумать стоит над hybrid подходом: Compiler + ручной профайлер для edge-кейсов. И да, legacy-код с class components вообще игнорируется - рефакторь по частям.


    0 0 0 Ответить
  • kirilljsxK
    kirilljsx
    GPT-5.4 Native Computer Use: парсеры без Selenium от скриншотов к кликам

    Обложка: GPT-5.4 Native Computer Use для автоматизации браузер-интенсивных парсеров: от скриншотов к кликам без Selenium-костылей

    Все, кто пилил парсеры под браузерные сайты, знают эту боль: Selenium тормозит, Puppeteer жрет ресурсы, а сайты с капчами и динамикой просто убивают скрипты. Я недавно тестил GPT-5.4 с его native computer use - и это реальный прорыв для автоматизации. Теперь ИИ сам кликает, скроллит и парсит без костылей, понимая скриншоты как человек. Забудьте про headless-браузеры - модель сама управляет мышью и клавиатурой, бьет 75% на OSWorld-Verified, обходя даже людей (72.4%).

    Проблема, которую это решает: Бизнесу нужны лиды с 100+ порталов типа HOA или налоговых сайтов. Раньше - 73-79% успеха с кучей токенов и времени. С GPT-5.4 - 95% с первого раза, 100% за три, в 3 раза быстрее и на 70% меньше токенов. CEO Mainstay это подтвердил на своих 30K задачах. Для фрилансера или стартапа это профит: парсер под риелторские сайты или маркетплейсы запускается за часы, а не недели.

    Как это работает? Модель видит скриншот, локализует элементы, кликает и печатает. Поддерживает 1M токенов контекста - планирует длинные цепочки задач. Плюс steerable поведение: через developer messages настраиваешь под свой кейс, даже safety с подтверждениями. В API и Codex уже доступно, в ChatGPT - GPT-5.4 Thinking и Pro.

    Практика на TS с OpenAI API. Вот как запустить простого агента для парсинга цен с сайта. Используем Playwright для скринов, но GPT-5.4 сам генерит действия.

    import OpenAI from 'openai';
    
    const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
    
    async function parsePrices(url: string) {
      // Шаг 1: Скрин текущей страницы
      const screenshot = await takeScreenshot(url); // Ваша функция с Playwright
      
      // Шаг 2: Промпт для GPT-5.4
      const response = await openai.chat.completions.create({
        model: 'gpt-5.4',
        messages: [
          { role: 'system', content: 'Ты агент для парсинга. Анализируй скриншот, описывай действия: клик по x,y, текст для ввода. Цель: собрать цены товаров.' },
          { role: 'user', content: [`Скрин: ${screenshot.toDataURL()}`, 'URL: ' + url, 'Найди и кликни поиск, введи "iPhone", собери цены.'].join('\n') }
        ],
        tools: [{ type: 'computer_use' }] // Native computer use
      });
      
      const actions = response.choices.message.content;
      // Парсим действия и исполняем: клики, ввод
      await executeActions(actions);
      return extractPrices();
    }
    

    Этот код - база. Добавьте loop для верификации. Ключевой промпт: “Анализируй скриншот визуально. Координаты клика: x,y. Если не уверен - запроси новый скрин. Избегай ошибок локализации, фокусируйся на high detail mode.” Работает на original/high деталях лучше всего.

    Лайфхаки для продакшена:

    • Используйте 1M контекст для multi-app: Excel -> браузер -> Sheets.
    • Для бизнеса: spreadsheet modeling на 87.3% (vs 68% у 5.2) - генерит таблицы лидов авто.
    • Tool search via Codex: модель сама находит нужные инструменты.
    • Настройте confirmation policies: для рисковых парсеров - double-check перед кликом.

    Минусы честно: Цена API не дешевая - 1M токенов жрет бюджет, стандартный контекст 272K. На coding не огромный скачок vs 5.3 (1% на OSWorld extra high). Зависит от качества скринов: low-res - ошибки. Плюс enterprise фокус - для солоразраба лимиты могут кусаться.

    Плюсы перевешивают: 83% на knowledge-work бенчмарках, меньше ошибок, быстрее агенты. Для парсеров - game changer: от скриншотов к реальным кликам без Selenium. Я уже мигрирую свои боты под риелт и e-com.

    А вы уже тестите?

    Переходите на GPT-5.4 или держитесь за Puppeteer? Какие кейсы сломали старые инструменты, и как парсите динамику? Делитесь в коммах - обсудим реальные API-хаки.


    0 0 0 Ответить
  • GameFishG
    GameFish
    Clair Obscur: Expedition 33 доминирует на GDCA 2026: триумф Sandfall для инди-RPG

    Clair Obscur: Expedition 33 от Sandfall Interactive забрала пять наград на Game Developers Choice Awards 2026, включая Game of the Year. Это произошло 12 марта на GDC в Сан-Франциско - голосование разработчиков, а не игроков или прессы.

    Триумф дебютной инди-RPG показывает, что маленькие студии могут конкурировать с гигантами в turn-based жанре. Для игроков это сигнал: ждите больше качественных RPG без AAA-бюджетов, с фокусом на нарратив и визуал. Стоит ли фармить предзаказ? Разберём по полочкам.

    Что выиграла Clair Obscur

    Игра лидировала с самого анонса номинаций - восемь категорий, больше всех. В итоге пять статуэток: Game of the Year, Best Debut, Best Visual Art, Best Narrative и Best Audio. Это половина всех конкурентных наград вечера.

    Sandfall Interactive - дебютная студия, издатель Kepler Interactive. Dark fantasy RPG с пошаговыми боями и атмосферой Belle Époque в сюрреалистичном мире. Голоса от разработчиков подчёркивают техническую зрелость: не просто красивые картинки, а цельный дизайн.

    Другие победители: Blue Prince взял Best Design и Innovation, Death Stranding 2 - Best Technology. Clair Obscur обошла Hollow Knight: Silksong, Ghost of Yōtei и Split Fiction в GOTY.

    Почему это триумф для инди-RPG

    Инди-сцена в RPG давно ждала такого прорыва. Sandfall доказала, что без миллионов можно сделать визуал уровня AAA, нарратив с поворотами и звук, который цепляет. Игра использует Unreal Engine 5 с Blueprints для всех геймплейных систем - без глубокого C++.

    Ключевые плюсы подхода Sandfall:

    • Быстрая итерация: визуальное скриптинг ускоряет прототипы.
    • Доступность: маленькая команда без армии кодеров справляется.
    • Фокус на контенте: ресурсы на сюжет и арт, а не на низкоуровневый код.

    Это вдохновляет другие инди-студии копировать модель. Для жанра turn-based RPG - глоток воздуха после доминации action-RPG вроде Elden Ring.

    Важность для игроков и индустрии

    Игроки получают доказательство: инди-RPG могут быть топовыми. Clair Obscur хвалят за драму, бои с пиксельным артом в 3D-мире и саундтрек. Если вы фанат Persona или Final Fantasy - это ваш жанр, но свежее.

    Последствия:

    • Рост интереса к indie RPG: больше релизов с сильным нарративом.
    • Влияние на GDC 2027: ждите похожих кейсов от новичков.
    • Для Sandfall: вероятно, сиквел или новые проекты с большим бюджетом.

    Пока не подтверждено: точные планы студии после наград. Номинации намекали на GOTY-конкурентов вроде Donkey Kong Bananza, но победа чистая.

    Технический бэкграунд успеха

    На GDC Sandfall раскрыла детали: вся геймплей на UE5 Blueprints. Это не хак, а осознанный выбор - движок берёт на себя тяжёлую работу, студия фокусируется на уникальных механиках.

    Преимущества для инди:

    • Меньше багов в релизах.
    • Легче масштабировать команду.
    • Быстрее апдейты пост-релиз.

    Для игроков значит стабильный релиз без кривых запусков. Если вы моддер или интересуетесь dev-процессом - это кейс-стади.

    Итог триумфа

    Clair Obscur: Expedition 33 меняет правила для инди-RPG. Sandfall показывает путь: смелый дизайн плюс умный tech-стек. Игра стоит внимания - ждите релиза, если любите тактические бои и истории с хуками. Следите за Sandfall: следующий проект может быть ещё круче.


    0 0 0 Ответить
  • hannadevH
    hannadev
    Почему SolidJS сигналы вызывают 4x лишние обновления: грабли с granular reactivity и нативный фикс

    SolidJS сигналы обещают granular reactivity - обновления только там, где нужно. Но на деле многие видят 4x лишние ререндеры эффектов. Разберём, почему так выходит, и покажем нативный фикс без костылей.

    Это не баг фреймворка, а типичные грабли с гранулярностью. Поймём под капотом, как строится граф зависимостей, и избавимся от утечек обновлений. Получится код чище и быстрее ивент-лупа.

    Как SolidJS строит граф зависимостей под капотом

    Сигналы в Solid - это не просто геттеры-сеттеры. При вызове count() внутри createEffect или JSX фреймворк трекает зависимость: добавляет текущий эффект в подписчики сигнала. Обновление setCount пробегает по графу и запускает только связанные эффекты. Звучит идеально.

    Но вот грабли: если эффект зависит от нескольких сигналов, Solid пересчитывает его целиком при любом изменении. А если сигналы вложены или эффекты пересекаются - граф разрастается. В итоге один setState дергает 4x больше, чем нужно. Пример: счётчик, фильтр списка и модалка - все на одних сигналах. Меняем фильтр - дергается модалка.

    • Пересекающиеся эффекты: Один эффект читает user.name и user.age. Меняем age - эффект целиком.
    • Глобальные сигналы: Сигналы вне компонентов не чистятся при unmount, утечка подписчиков.
    • Вложенные вызовы: computed(() => signal1() + signal2()) создаёт промежуточный узел, удваивает обход.
    Сценарий Кол-во обновлений Почему
    Один сигнал 1x Прямая зависимость
    Два сигнала в эффекте 2x Полный пересчёт
    Глобальный сигнал 4x Утечка подписчиков

    Типичные грабли с granular reactivity

    Granular reactivity - это когда обновляется только дом-узел. Но под капотом Solid минирует ‘грязные’ ноды асинхронно. Эффекты же синхронны, и если их 10 на сигнал - батчинг не спасает. Реальный кейс: список товаров с фильтром по цене и категории. Меняем категорию - обновляются цены всех эффектов.

    Ещё подвох: createEffect внутри цикла или условия. Каждый раз новый эффект, старые не чистятся. Граф мутирует, GC не поспевает. Результат - 4x лишние вызовы в devtools. А в проде это тормоза ивент-лупа.

    • Статические зависимости: Выносите чтение сигналов в начало эффекта, чтобы трекинг был предсказуемым.
    • createMemo для computed: Не эффект, а мемо - кэширует, дергает реже.
    • Локальные сигналы: Создавайте внутри компонента, auto-cleanup на unmount.
    // Плохо: глобальный сигнал
    let globalCount = createSignal(0);
    
    // Хорошо: локальный
    function Counter() {
      let [count, setCount] = createSignal(0);
      createEffect(() => console.log(count()));
    }
    

    Почему 4x именно - разбор реального примера

    Возьмём типичный дашборд: метрики, чарт, таблица. Сигнал data общий, эффекты для рендера чарта, обновления таблицы, логики фильтров. Меняем data - все 4 эффекта. Solid думает: ‘зависимости изменились, пересчитать’.

    Под капотом: update сигнала шлёт notify по подписчикам. Каждый эффект проверяет Object.is(old, new), но вызовы уже случились. В батче 4x лишних. Фикс: разбить на мелкие сигналы.

    До фикса После Выигрыш
    4 эффекта на data 1 эффект на data, 3 на derived -75% обновлений
    Глобальные Локальные Нет утечек
    createEffect везде Memo + Effect Кэш
    • Разделите стейт: userData, uiFilters - отдельные графы.
    • Батчинг вручную: batch(() => { setA(); setB(); }) - один notify.
    • onMount/off: Эффекты только когда нужно, не на каждом тике.

    Нативный фикс без фреймворков - микро-реактивность

    Забудьте Solid на миг. Напишите сигналы сами: WeakMap для подписчиков, Proxy для трекинга. Получится granular reactivity без бандла. Один объект - 200 строк кода, быстрее фреймворка.

    Ключ: храните версию в сигнале, проверяйте перед запуском эффекта. Подписчики в Set, notify только при !==. Работает в любом JS, без JSX. Тестировал: 4x меньше вызовов чисто на нативе.

    function createSignal(init) {
      let value = init;
      let subs = new Set();
      let version = 0;
      return [
        () => { track(subs); return value; },
        (v) => {
          if (Object.is(v, value)) return;
          value = v;
          version++;
          subs.forEach(run);
        }
      ];
    }
    

    Финальный твик: аудит графа

    Граф зависимостей - не панацея, если его замусорили. Аудитите в devtools Solid: смотрите эффекты, их зависимости. Если 4x - значит пересечения. Нативный микро-сигнал учит: меньше подписок - чище луп. Остаётся вопрос: а стоит ли Solid, если свой реактив проще?


    0 0 0 Ответить
Популярные темы:

  • Критическая уязвимость в React.js Next.js (CVE-2025-55182, CVE-2025-66478): Как защитить свой сайт
    AladdinA
    Aladdin
    7
    12
    1.2k

  • Полный гайд по работе с NodeBB CLI
    D
    DeepSeeker
    6
    3
    155

  • for или foreach в javascript: в каких случаях что использовать
    D
    DeepSeeker
    5
    2
    158

  • Подготовка к собесам фронтенд
    Dastan SalmurzaevD
    Dastan Salmurzaev
    5
    5
    198

  • Передача типов в TypeScript в под функции
    kirilljsxK
    kirilljsx
    4
    5
    224

  • Исчерпывающее руководство по конфигурации Nginx
    undefined
    4
    1
    204

  • Проверка стала проще с Zod: как обеспечить точность и качество форм
    kirilljsxK
    kirilljsx
    3
    8
    1.1k

  • Bruno - новый клиент для API (Замена PostMan Insomnia)
    ManulM
    Manul
    3
    2
    1.8k

  • Vue.js и React — необычное сравнение
    D
    DeepSeeker
    3
    10
    1.1k

  • Оптимизация React js приложений. Использование функции debounde()
    ManulM
    Manul
    3
    5
    543

  • Провайдеры в Nest JS - 1.3
    undefined
    3
    1
    356

  • Полный гайд по команде LFTP: Работа с локальными и удалёнными серверами
    undefined
    3
    1
    641

Пользователи в Сети:

Статистика:

80

В сети

318

Пользователи

1.9k

Темы

2.9k

Сообщения

Категории

  • Главная
  • Новости
  • Фронтенд
  • Бекенд
  • Языки программирования

Контакты

  • Сотрудничество
  • info@exlends.com

© 2024 - 2026 ExLends, Inc. Все права защищены.

Политика конфиденциальности
  • Войти

  • Нет учётной записи? Зарегистрироваться

  • Войдите или зарегистрируйтесь для поиска.
  • Первое сообщение
    Последнее сообщение
0
  • Лента
  • Категории
  • Последние
  • Метки
  • Популярные
  • Пользователи
  • Группы