Почему я сделал 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 его автор указал на проблему, которая пересеклась с одним из пунктов от модели.

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

U50 Club

20260611_112458_2af53a.webp

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

Вчера вот создал чат. https://t.me/+UM9jvgz6bollNjJi Сегодня набросал манифест. Завтра сделаю еще шажок и напишу анонс, который можно будет пошерить в разные чаты. Вот так и добежим до финиша :)

Если хотите присоединиться, присоединяйтесь. Хоть я и считаю, что чатов и так много, +1 тематический чат нужен, чтобы быть в курсе конкретного события. В нем можно участвовать напрямую или косвенно:

— бежать полную или часть дистанции
— сопровождать
— просто поделиться инфоповодом с друзями


Манифест

Это не соревнование друг с другом. Единственный человек, с которым вы можете соревноваться — вы сами.

Медалей не будет. Если сможем найти спонсоров, можно будет подумать о каких-то более важных вещах типа пунктов питания. Но пока рассчитывать придется на себя.

Финиш — это точка на карте, к которой мы идём вместе. Каждый своим темпом, каждый со своим внутренним диалогом, но в одном направлении.

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

Предварительная дата — 22 ноября. Маршрут пока в разработке.

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

·

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

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

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

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

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

Schweppes. Новый вкус.

·

Иду сегодня на тренировку и вижу как у ТЦ промоутеры раздают Schweppes. Новый вкус. Подошел поближе и понял — не выпить мне Schweppes. Потому что раздают его, сразу открывая. А мне бегать 8 км с отрицательным сплитом (это когда каждый следующий отрезок надо бежать чуточку быстрее), а потом еще 10 раз по 100 метров ускоряться. Развернулся и пошел на стадион.

Побегал хорошо. Если честно, время вообще не заметно пронеслось в хорошей компании. Благодаря Олегу, мы и поускорялись и стометровки побегали так, что пятки сверкали. С шутками, прибаутками, конечно. А потом он меня подбросил до остановки. Выхожу из машины и вижу — стоят промоутеры, Schweppes раздают. Новый вкус.

Тут-то я его и попробовал. Сел на лавку и наслаждался каждым глотком. Все эти 0.33 л. И в этот момент казалось, что весь мир может подождать.

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. В теории можно взять и инвертировать светлоту, получив тем самым светлую тему. В теории теория и практика не отличаются. На практике всё совсем наоборот 😀. Чтобы объяснить почему, полезно сначала посмотреть на то, как устроена работа с цветом в принципе.

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