Все записи с тэгом dev

Почему я сделал Micra

·

Я помню время, когда jQuery стоял почти на каждом сайте. Тогда еще не было фреймворков и jQuery был простым способом дотянуться до DOM: навесить обработчик, что-то показать, что-то спрятать, дёрнуть запрос. Тогда это решало большинство задач. Потом фронтенд стал сложнее. Во многом по делу, потому что приложения выросли, и React, Vue, Svelte выросли вместе с ними. Но такая сложность нужна не всегда.

Осталось много проектов, где сервер уже отдаёт готовую HTML-разметку, а на клиенте требуется лишь немного реактивности: открыть модалку, обновить счётчик, отфильтровать таблицу, переключить вкладку. Разворачивать ради этого полноценный фреймворк со сборкой и роутингом часто не хочется. А писать на чистом JavaScript быстро становится неудобно, когда нужно отслеживать состояние и синхронизировать его с DOM.

Я искал решение, которое даёт реактивность, но при этом остаётся максимально лёгким и не требует отдельного билда. Хотелось просто подключить скрипт к уже существующей серверной разметке — и чтобы она начала реагировать на изменения состояния.

Читать далее →

Micra.js под капотом: как устроен реактивный фреймворк

·

Это длинный текст про то, как изнутри устроена Micra.js — маленькая библиотека, которая добавляет реактивность к HTML, отрендеренному на сервере. Я написал её, чтобы закрыть конкретную нишу: страницы и админки, где сервер уже отдаёт готовую разметку, а на клиенте нужно лишь немного интерактивности — переключить вкладку, открыть модалку, отфильтровать таблицу, сходить за данными. Раньше для этого тянулись к jQuery, потом к Alpine. Micra — это попытка дать тот же «сахар», но предсказуемо, типизированно и с учётом Content-Security-Policy.

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

Читать далее →

Релиз Micra.js 2.5.0

·

Пару недель назад я писал, что у библиотеки появился второй читатель — языковая модель. Тогда я думал, что главная задача — научить LLM правильно её готовить. Но потом решил, что не менее полезно послушать, что LLM думает о самой библиотеке.

Я скормил llms.txt другой модели и попросил разобрать: чего не хватает «идеальному фреймворку для тех, кому React — оверхед». Часть идей взял на заметку. Примерно тогда же я доводил до конца PR с Micra в js-framework-benchmark — один из самых авторитетных бенчей JS-фреймворков, где рядом React, Vue, Svelte, Solid и другие. При ревью этого PR его автор указал на проблему, которая пересеклась с одним из пунктов от модели.

Читать далее →

Micra.js, две недели спустя

·

В прошлой заметке я выложил Micra.js — маленький реактивный фреймворк для server-rendered страниц. Дальше пошли две недели, за которые я выпустил несколько версий.

Добавил в Micra кросс-библиотечный бенчмарк. Постарался сделать честную страницу, где Micra, Alpine, petite-vue, Stimulus и голый ванильный JS гоняют одни и те же сценарии в соседних фреймах.

Цифры оказались приятно-неприличными. Обновить 5 строк в списке из 1000:

— Micra — 0 мс
— Alpine.js — 919 мс
— petite-vue — 1005 мс

Читать далее →

Micra.js — лёгкий реактивный фреймворк для простых сайтов

·

Я помню время когда jQuery был UI-библиотекой для работы с DOM по умолчанию. Потом появился Knockout.js, Backbone.js и так мы дошли до React/Vue/Svelte. Фронтенд стал сложнее. Но такая сложность нужна не всегда. В мире всё ещё существуют простые сайты, состоящие из нескольких страниц, небольшие SaaS, панели управления и блоги. Часто таким решениям не требуется большой и сложный фронтенд. И в этом случае тоже приходится думать с помощью какого инструмента решать задачу создания интерфейса. В своих проектах я пробовал разные подходы — от Vanilla.js до React-а и всё пытался подобрать удобное решение, позволяющее совместить в себе реактивность и возможности взаимодействия с DOM и поддержку серверного рендеринга. А еще для простых сайтов не хочется тянуть кучу зависимостей. Иногда достаточно просто подключить библиотеку извне.

Так в ходе поиска баланса я набросал Micra.js — небольшую UI библиотеку на 5 Kb. Она имеет свои плюсы и минусы, абсолютно неуникальна и не претендует на звание заменителя всех других библиотек. Скорее это сборник практик, которые сформировались в единое решение.

Что это и как работает

Micra.js — это лёгкий реактивный фреймворк, который работает через shallow‑Proxy, отслеживая только верхний уровень state. Любое изменение top‑level свойства вызывает ререндер, а вложенные объекты нужно заменять целиком. Все синхронные обновления состояния батчатся в один microtask, поэтому несколько записей приводят к одному ререндеру. При первом рендере Micra сканирует DOM, собирает директивы (data-text, data-if, data-model и др.) и кэширует их, чтобы последующие обновления были быстрыми и не требовали повторного обхода дерева.

Выражения в директивах выполняются через быстрый путь для простых обращений к свойствам или через компиляцию с глобальным кэшем для сложных выражений. Внутри выражений доступен расширенный exprState, включающий методы компонента и хелперы (prop, emit, fetch). Списки с data-each и data-key обновляются через keyed‑diff: переиспользуются существующие DOM‑ноды, создаются только новые, а исчезнувшие удаляются. Каждый data-component создаёт независимый инстанс со своим состоянием, методами, props из data-* и собственным жизненным циклом. Компоненты общаются через event bus, а доступ к конкретному экземпляру возможен через Micra.instances().

Как видите, ничего нового и уникального. Некоторые решения компромиссны. Например, проксирование top-level. Для решений типа "показать модалку", "отфильтровать таблицы" выглядит достаточно. Меньше багов, выше производительность, так как нет лишних обходов. Но я не исключаю, что позже приду необходимости deep‑proxy.

В то же время, я собрал сборник рецептов и набор компонентов, которые можно копировать и использовать. В качестве эксперимента, хочу попробовать обучить AI использовать Micra.js в качестве замены React. Задачка, конечно, требует времени, потому что кодовая база с React огромна. В то же время, это не всегда играет на руку. Примеры кода могут быть и хорошими и плохими и корректировка достигается с помощью правильный скиллов и гайдлайнов. И я думаю, что если это можно сделать с одной библиотекой, то можно и с другой.

Нельзя просто взять и сгенерировать тему

·

В рамках работы над open-source проектом работал над задачкой по генерации тем. То есть в проекте было несколько тем: одни темы имели светлый и темный режим, другие - только светлый или только темный. И задача сводилась к тому, чтобы сделать для всех тем светлый и темный режим.

20260429_090506_ae78eb.webp

Вот на скриншоте показаны несколько темных тем: Dracula, Solarized, Gruvbox, Monokai, Moonlight. В теории можно взять и инвертировать светлоту, получив тем самым светлую тему. В теории теория и практика не отличаются. На практике всё совсем наоборот 😀. Чтобы объяснить почему, полезно сначала посмотреть на то, как устроена работа с цветом в принципе.

Читать далее →

Про подключение Garmin MCP к Claude Code и забег в Бечее

·

На днях с подачи приятеля подключил Garmin MCP к Claude Code. Опыт интересный. В первую очередь, потому что все эти данные мне и так известны и доступны в виде сухой статистики в Garmin Connect. Хотелось попробовать новый опыт взаимодействия.

20260328_202912_0a7bbc.webp

Читать далее →

TrueNorth для ясности в делах

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

20260118_132929_a4d078.webp
TrueNorth Dashboard

Читать далее →

Как найти удобное время для встречи, когда команда разбросана по миру

·

Недавно добавил на Syn-co.me новую функцию — поиск удобного времени для встреч. Если вы уже пользовались сайтом, то знаете: он показывает время всей команды на одном таймлайне. Просто добавляете участников с их часовыми поясами, и сразу видно, кто работает, кто спит, кто только проснулся.

Теперь при добавлении участников из разных городов, а алгоритм предлагает, когда лучше всего созвониться. Причем не просто "когда все не спят", а когда время действительно удобное для всех. Или хотя бы максимально справедливое, если идеального варианта не существует.

20251016_075043_f3deed.webp

Проблема

Представьте: ваш коллега в Токио, партнер в Нью-Йорке, а вы в Москве. Когда в Москве 14:00 (отличное время для звонка), в Нью-Йорке 6 утра (кто-то еще спит), а в Токио уже 20:00 — конец рабочего дня.

Можно, конечно, открыть мировые часы и начать перебирать: "А если в 10 утра по Москве? Нет, подождите, тогда в Токио будет..." Через пять минут такой арифметики голова идет кругом.

Как это работает

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

Оптимальное время — середина рабочего дня, примерно с 10 до 16 часов. Люди уже проснулись, выпили кофе, разобрали почту. Максимальная продуктивность.

Хорошее время — начало или конец рабочего дня. С 9 до 10 утра или с 16 до 17 вечера. Можно созвониться, но кто-то может быть не в лучшей форме.

Приемлемое время — чуть за границами обычного расписания. Например, 8:30 утра или задержаться до 18:00. Неудобно, но терпимо.

Некомфортное время — приходится серьезно менять планы. Встать пораньше в 7 утра или остаться после работы до 19:00. Такие встречи лучше избегать, но иногда выбора нет.

Алгоритм выбирает варианты, где всем хотя бы приемлемо, и сортирует их от лучших к худшим.

20251016_075109_ecec26.webp

Что делает время действительно удобным

Тут начинается самое интересное. Я бы выделил три столпа на которых основана логика алгоритма.

Справедливость важнее общего удобства. Лучше, когда всем "хорошо", чем когда двоим "отлично", а одному "ужасно". Поэтому алгоритм в первую очередь смотрит на того, кому хуже всего. Если есть вариант, где минимальный комфорт выше — он побеждает.

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

Избегаем экстремальных часов. Никто не хочет созваниваться в 5 утра или в 11 вечера. Такие варианты получают серьезный штраф. Также учитывается обеденное время — встреча с 12 до 13 нравится немногим.

Гибкость как параметр

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

Поэтому в инструменте есть параметр гибкости — от 0 до 12 часов. С нулевой гибкостью алгоритм ищет только время в пределах рабочих часов. С гибкостью в 3-4 часа появляются варианты, где кто-то начинает чуть раньше или задерживается. Чем выше гибкость, тем больше вариантов, но тем менее комфортными они становятся.

Когда компромиссы неизбежны

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

Для Москвы, Нью-Йорка и Токио практически невозможно найти время, когда всем комфортно. Разница часовых поясов слишком велика. В таких случаях алгоритм предлагает несколько вариантов с разными компромиссами.

Может быть, один раз неудобно будет Токио, в следующий раз — Нью-Йорку. Справедливость можно обеспечить не за одну встречу, а в серии созвонов.

Про Syn-co.me

20251016_075151_e87e85.webp

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

Изначально Syn-co.me создавался как простой таймлайн часовых поясов команды. "Stop doing timezone math in your head" — главная идея. Поиск времени встреч — логичное продолжение: показывать не просто "когда все свободны", а "когда всем будет действительно удобно".

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

Подборка ссылок #06

·

Статья «Rails for Everything» на Literally The Void отстаивает универсальность Ruby on Rails для разработки различных типов проектов, опровергая стереотип о его ограниченной применимости и подчеркивая преимущества использования полного стека Rails вместо разделения на микросервисы, в то время как комментарии на Reddit отражают разнообразие мнений разработчиков об актуальности фреймворка в 2025 году, его производительности и сравнении с современными альтернативами.

Petr.codes в «Flexible API versioning with Rails» предлагает гибкий подход к версионированию API в Ruby on Rails, рассматривая проблемы традиционных методов и демонстрируя эффективную архитектуру с использованием наследования и модулей в контроллерах, что позволяет разработчикам легко управлять изменениями между версиями API без дублирования кода.

Статья Мартейна Холса «The European Accessibility Act for websites and apps» разъясняет требования Европейского акта о доступности для цифровых продуктов, описывая сроки внедрения, технические стандарты и необходимые меры соответствия, которые должны предпринять разработчики и владельцы бизнеса для обеспечения доступности своих веб-сайтов и приложений в соответствии с законодательством ЕС.

Марк Мэнсон в статье «Why You Should Quit the News» утверждает, что следует отказаться от регулярного потребления новостей, поскольку они вызывают стресс, фокусируются на негативе и отнимают время, которое можно потратить на более ценные занятия, при этом большинство новостных материалов не имеют практического влияния на нашу повседневную жизнь.

Статистика от Stackoverflow по использованию технологий за 2024 год

Алекс Рассел в своей статье «If Not React, Then What?» критикует React за создание избыточного уровня абстракции над веб-платформой, что приводит к проблемам с производительностью и большим JavaScript-пакетам, и предлагает Web Components как более эффективную альтернативу, которая работает в гармонии с нативными возможностями браузера и следует принципам прогрессивного улучшения.

Ахмад Шадид выпустил гайд о новых CSS свойствах — «Relative Colors».