Репозиторий проекта WebMarkupMin на сайте CodePlex в 2014 году
Репозиторий проекта WebMarkupMin на сайте CodePlex в 2014 году

За 13,5 лет я создал 12 опенсорс-проектов для платформы .NET и особое место среди них для меня занимает проект WebMarkupMin. Я не могу точно сказать, что мне больше всего нравится в нем: интересная исследовательская работа, лавры первопроходца на платформе .NET или не уходящая с годами актуальность.

В этой статье будет мало технических подробностей, потому что подобных статей о WebMarkupMin написано предостаточно. Здесь будет сделан акцент на разработке концепции опенсорс-проекта, его продвижении и взаимодействии с другими людьми.

200X

Скриншот сайта Freeware.ru (Источник: m-r-w.narod.ru)
Скриншот сайта Freeware.ru (Источник: m-r-w.narod.ru)

В начале 00-х отечественный опенсорс только зарождался и ассоциировался с такими системно значимыми для Рунета проектами, как Russian Apache. В то время в России уже было много энтузиастов, которые писали бесплатное или условно-бесплатное ПО, а затем публиковали его на сайтах Freeware.ru и DOWNLOAD.RU.

Для меня, как студента, обучающегося по ИТ-специальности, эти сайты были просто кладезью полезного ПО (например, в 2002 году я там даже нашел один из первых чат-ботов на основе ИИ – nus). Благодаря этим сайтам я познакомился с новым типом настольного ПО под названием HTML-оптимизаторы. В конце 90-х и начале 00-х многие веб-разработчики начинали свой путь с использования WYSIWYG HTML-редакторов. Ранние версии Microsoft FrontPage, Netscape Composer и подобных им редакторов генерировали избыточный HTML-код. В первую очередь, задачей HTML-оптимизаторов была очистка кода от мусора, добавляемого WYSIWYG’ами, а во вторую, уменьшение размера документа за счет удаления лишних пробельных символов, комментариев и другого необязательного кода. Некоторые из используемых ими оптимизаций затрагивали семантику HTML-документа, а, следовательно, изменяли функциональность исходного кода, поэтому их нельзя считать минификаторами в современном понимании этого слова.

Первые HTML-оптимизаторы появились примерно в 1997 году и это были программы для Windows: HTML (Un)Compress и WebTrimmer. Наиболее известным HTML-оптимизатором первой волны для Windows был WebOverdrive, на Mac OS в это время были популярны сразу два продукта: Mizer (более позднее название SpaceAgent) и VSE HTML Turbo (более позднее название VSE Web Site Turbo).

Настоящий бум создания HTML-оптимизаторов в сообществе русскоязычных программистов начался после публикации Артемием Лебедевым 17-го параграфа «Ководства» под названием «Паранойя оптимизатора — ужимаем файлы до минимума» и достиг своего пика в 2000 году. Я экспериментировал со многими из этих программ, знал их основные достоинства и недостатки. Когда я научился верстать руками и освоил CSS, то перестал ими пользоваться, т.к. в их использовании уже не было никакой необходимости.

К середине 00-х из-за распространения стандарта XHTML подобные программы потеряли свою актуальность.

2012

В начале 2012 года я работал над серией статей о клиентской оптимизации в ASP.NET MVC для журнала MSDeveloper.RU. Всего было опубликовано две статьи, которые затрагивали тему минификации JavaScript и CSS. Планировалась и третья статья, которую я хотел посвятить минификации HTML и HTTP-сжатию. По ряду причин эту задумку реализовать не удалось.

В середине 2012 года я прочитал документ «Google HTML/CSS Style Guide»1 и на примерах увидел сколько новых возможностей предоставляет стандарт HTML5 для сокращения размера HTML-документа. Вообще, отказ от XHTML 2.0 в пользу HTML5 в начале 10-х заставил веб-разработчиков по-новому взглянуть на уже подзабытые техники HTML-оптимизации.

В тот момент для платформы .NET не существовало полноценного минификатора HTML-кода. Были лишь наборы регулярных выражений, которые могли выполнять всего две операции: удаление ненужных пробельных символов и удаление HTML-комментариев. Поэтому я загорелся идеей создания современного HTML-минификатора для платформы .NET и расширений для его интеграции с ASP.NET.

В конце ноября я приступил к разработке WebMarkupMin, а точнее приступил к исследовательской работе. Теоретического материала было немного, поэтому я почти сразу начал смотреть инструменты на других платформах. Я нашел только два HTML-минификатора, поддерживающих стандарт HTML5: HtmlCompressor Сергея Ковальчука (Java) и Experimental HTML Minifier Юрия Зайцева (JavaScript). HtmlCompressor в процессе минификации использовал набор из нескольких десятков регулярных выражений, что с одной стороны делало его легко переносимым на .NET, а с другой крайне неэффективным с точки зрения производительности. Experimental HTML Minifier, наоборот, использовал HTML-парсер2, что делало его очень производительным и роднило с минификаторами JS- и CSS-кода. Первой моей мыслью было просто портировать минификатор Зайцева на C#, но, как выяснилось в процессе, он не так просто назывался «экспериментальным». Минификатор был довольно сырой и часто ломался на нестандартной разметке.

В итоге я решил взять лучшие идеи из обоих проектов. Парсер из минификатора Зайцева лег в основу моего парсера, но я его очень сильно модифицировал. Из минификатора Ковальчука я позаимствовал идею использования внешних минификаторов JS- и CSS-кода.

В тот момент для платформы .NET существовала прекрасная библиотека для минификации JS- и CSS-кода - Microsoft Ajax Minifier. Мне очень нравилась эта библиотека, поэтому я считал, что моя библиотека должна дополнять ее, производя минификацию различных видов веб-разметки (HTML, XHTML и XML). Отсюда и появилось полное название библиотеки - Web Markup Minifier. У Microsoft Ajax Minifier было также краткое название – AjaxMin, так появилось сокращение - WebMarkupMin.

2013

Я уже точно не могу вспомнить, когда я непосредственно начал писать программный код WebMarkupMin. Помню лишь, что когда у меня появился первый прототип библиотеки, то я задумался о создании графического интерфейса для нее. Так началась работа над проектом, который потом будет называться WebMarkupMin Online, и эта работа точно началась в 2013 году.

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

После того, как минификаторы разметки стали стабильными, я занялся созданием модулей для внешних минификаторов JS- и CSS-кода. Потом последовала очередь и за ASP.NET-расширениями.

В конце марта я создал репозиторий на CodePlex и опубликовал там альфа-версию библиотеки. Помню, что запускаться пришлось без модуля для ASP.NET Web Forms, потому что были какие-то сложности с его реализацией. Через пару дней я разместил сайт WebMarkupMin Online на бесплатном хостинге AppHarbor. За период тестирования предварительных версий пользователи ASP.NET-расширений помогли обнаружить несколько ошибок в HTML-парсере.

В середине апреля я выпустил стабильную версию. Чуть позже я наконец-то закончил модуль для ASP.NET Web Forms. А в конце апреля я опубликовал первую статью о WebMarkupMin на Хабре, но, к сожалению, она не нашла особо отклика у читателей.

Закончив работу по запуску своего проекта, я решил поделиться с Юрием Зайцевым своими наработками и помог исправить ошибку «wrong HTML element nesting after minification» с помощью следующего пулл-реквеста.

В июле сотрудник компании Microsoft Мэдс Кристенсен добавил в предварительную версию VS-расширения Web Essentials 2013 возможность минификации выделенных фрагментов HTML-кода. Данная возможность была реализована средствами библиотеки WebMarkupMin. В октябре после выхода стабильной версии Web Essentials 2013 я написал статью, в которой подробно рассказывал о данной возможности.

Журнал изменений на официальном сайте VS-расширения Web Essentials 2013
Журнал изменений на официальном сайте VS-расширения Web Essentials 2013

Примерно в это же время вышел июльский номер немецкого журнала dotnetpro, на обложку которого попало полное название моей библиотеки:

Обложка июльского номера журнала dotnetpro за 2013 год
Обложка июльского номера журнала dotnetpro за 2013 год

Кроме того, сборки WebMarkupMin версии 0.8.5, наряду с другим ПО, присутствовали на компакт-диске, прилагаемом к журналу:

Конверт для компакт-диска, прилагаемого к июльскому номеру журнала dotnetpro за 2013 год
Конверт для компакт-диска, прилагаемого к июльскому номеру журнала dotnetpro за 2013 год

В декабре Мэдс Кристенсен добавил в Web Essentials 2013 возможность минификации HTML-файлов и создания HTML-бандлов. Об этом нововведении я немного запоздало написал в своей статье.

2014

2014 год можно назвать годом кооперации с Мэдсом Кристенсеном. Сначала Мэдс Кристенсен добавил поддержку HTML-минификации средствами WebMarkupMin в свой старый проект MiniBlog, а затем и в новые проекты: StaticWebHelper и Web Essentials 2015. В августе он опубликовал в своем блоге две статьи на тему клиентской оптимизации HTML-содержимого: «Effect of tabs vs. spaces in HTML files» и «Effects of GZipping vs. minifying HTML files», в которых хорошо отзывался о WebMarkupMin.

Комментарий Мэдса Кристенсена к своей собственной статье «Effect of tabs vs. spaces in HTML files»
Комментарий Мэдса Кристенсена к своей собственной статье «Effect of tabs vs. spaces in HTML files»

Я тоже не сидел без дела, и почти все лето работал над добавлением в ядро WebMarkupMin поддержки минификации представлений KnockoutJS и AngularJS. Чтобы сделать доступным этот функционал для пользователей Visual Studio, осенью я стал контрибьютером проекта Web Essentials 2013. О результате этой работы я рассказал в статье на Хабре.

Все той же осенью появилась немного неожиданная реакция на WebMarkupMin со стороны международного научного сообщества. В сентябрьском номере научного журнала International Journal of Advanced Computer Science and Applications было опубликовано исследование «XML Schema-Based Minification for Communication of Security Information and Event Management (SIEM) Systems in Cloud Environments», проведенное учеными из Хелуанского университета (Египет). В абзаце, рассказывающем о техниках XML-минификации, был упомянут сайт WebMarkupMin Online:

Фрагмент страницы 76 сентябрьского номера журнала International Journal of Advanced Computer Science and Applications
Фрагмент страницы 76 сентябрьского номера журнала International Journal of Advanced Computer Science and Applications

A. XML-минификация
XML-сообщения строятся на основе иерархической структуры. Обычно ее обозначают с помощью табуляции или пробелов, чтобы добавить отступы для улучшения читаемости. К сожалению, эти пробельные символы увеличивают размер сообщения, даже несмотря на то, что для хранения структуры требуется огромное количество данных (например, открывающие и закрывающие теги с описательными именами).

Техники XML-минификации направлены на уменьшение размера сообщения; однако большинство техник сосредоточены на пробельных символах и удалении комментариев. Продвинутые минификаторы могут сворачивать теги, не имеющие содержимого; например, «<idmef:real></idmef:real>» заменяется на «<idmef:real/>». Примерами XML-минификаторов являются THE XML MINIFIER (http://www.nathanael.dk/tools_thexmlminifier.php) и WEB MIN - XML Minifier (http://webmarkupmin.apphb.com/minifiers/xml-minifier).

2015

Весной я всерьез задумался о добавлении в WebMarkupMin поддержки .NET Core. Работы предстояло проделать много. Нужно было полностью переписать систему конфигурации, потому что библиотека System.Configuration не поддерживалась в .NET Core. Также нужно было поменять архитектуру ASP.NET-расширений, чтобы в нее вписался модуль для ASP.NET 53. Поскольку новая версия имела очень много критических изменений, то я решил разделить разработку WebMarkupMin на две ветви: стабильную 1.X на CodePlex и предварительную 2.X на GitHub. В июле я создал репозиторий на GitHub и выпустил предварительную версию.

В июне Мэдс Кристенсен начал разработку новой библиотеки под названием Bundler and Minifier. Фактически, в эту библиотеку из Web Essentials был перемещен весь функционал, связанный с минификацией и созданием бандлов.

2016

Основные работы на проекте в 2016 году так или иначе были связаны с переходом на .NET Core.

Лишь весной появилась достаточно крупная задача, несвязанная с .NET Core. Было необходимо обеспечить корректную обработку представлений современных JS-фреймворков, таких как Angular 2, Aurelia и Polymer.

В начале июня случился главный провал в истории проекта WebMarkupMin: Мэдс Кристенсен в проекте Bundler and Minifier заменил библиотеки AjaxMin (полное название Microsoft Ajax Minifier) и WebMarkupMin на недавно появившуюся библиотеку NUglify. Библиотека NUglify изначально создавалась, как форк библиотеки AjaxMin с поддержкой .NET Core. Последняя версия AjaxMin вышла еще в январе 2015 года и о никакой поддержке .NET Core этой библиотекой не могло быть и речи, поэтому появление библиотеки NUglify было вполне закономерным явлением. Мейнтейнером NUglify в то время был очень известный в .NET-сообществе человек - Александр Мютель. Будучи разработчиком с огромным опытом, он решил не ограничиваться только минификацией JS- и CSS-кода, и создать собственный HTML-минификатор. За основу он взял последнюю на тот момент версию минификатора Зайцева и в дополнение написал свой собственный высокопроизводительный HTML-парсер, при реализации которого не использовались регулярные выражения.

Помимо VS-расширения и старого NuGet-пакета BuildBundlerMinifier, библиотека NUglify также вошла в новый пакет BundlerMinifier.Core. BundlerMinifier.Core использовался в качестве зависимости во всех шаблонах ASP.NET Core-приложений, что обеспечило NUglify миллионы дополнительных загрузок через NuGet. Вообще, новый тип NuGet-пакетов для приложений командной строки, появившийся в .NET Core, был очень выгоден для авторов сторонних библиотек, т.к. пакет с приложением командной строки явно ссылался на используемые библиотеки.

В конце июня вышла стабильная версия .NET Core, а вслед за ней вышла и стабильная версия WebMarkupMin 2.0. Через две недели я выпустил модуль с внешними минификаторами JS- и CSS-кода на основе NUglify.

В конце июля я опубликовал статью, в которой описал процесс добавления поддержки .NET Core в WebMarkupMin и привел инструкции по обновлению библиотеки в существующих приложениях. Поскольку это была одна из первых русскоязычных статей о переходе на .NET Core, то она сразу же попала в поле зрения «Майкрософт Рус». Его сотрудники опубликовали анонс моей статьи почти на всех медиа-ресурсах русского представительства корпорации.

Анонс моей статьи в группе «Microsoft для разработчиков» в одной из ныне запрещенных соцсетей
Анонс моей статьи в группе «Microsoft для разработчиков» в одной из ныне запрещенных соцсетей

После достаточно успешного запуска 2-й версии я все еще не мог забыть о потере проекта Bundler and Minifier. Но в сентябре Эндрю Лок, известный многим как автор книги «ASP.NET Core в действии», опубликовал в своем блоге статью «HTML minification using WebMarkupMin in ASP.NET Core».

Фрагмент статьи Эндрю Лока «HTML minification using WebMarkupMin in ASP.NET Core»
Фрагмент статьи Эндрю Лока «HTML minification using WebMarkupMin in ASP.NET Core»

В статье давалось краткое, но в тоже время достаточно емкое описание WebMarkupMin, в котором делался акцент на его основных преимуществах:

WebMarkupMin – это очень зрелый минификатор, не только для HTML, но также для XML и XHTML, а также для тегов script и style, встроенных в ваш HTML. Они предоставляют множество NuGet пакетов для подключения к вашим ASP.NET приложениям, как для ASP.NET 4.x использующих MVC, HttpModules, WebForms(!), так и к счастью для нас, ASP.NET Core.

Таким образом, поддержка нестандартной разметки и наличие расширений для разных версий ASP.NET позволили WebMarkupMin сохранить свои позиции на платформе .NET.

В ноябре я добавил во все минификаторы возможность игнорировать определенные фрагменты разметки с помощью специальных комментариев (<!--wmm:ignore-->…<!--/wmm:ignore-->).

2017

В 2017 году я уделял проекту WebMarkupMin меньше времени, чем обычно, т.к. заканчивал перевод других своих опенсорс-проектов на .NET Core. Основные изменения в проекте были связаны с выходом .NET Core 2.0 и добавлением в ASP.NET-расширения возможностей по их более тонкой настройке.

Осенью Мэдс Кристенсен выпустил новый проект под названием Miniblog.Core, который являлся портом на ASP.NET Core его старого проекта MiniBlog. HTML-минификация в этом проекте была реализована с помощью расширения WebMarkupMin.AspNetCore2.

2018

В мае выяснилось, что ASP.NET Core-расширения не могут корректно работать с потоковым содержимым. Из-за этого пришлось переделать сравнительно простую реализацию класса WebMarkupMinMiddleware на более сложную, основанную на архитектуре ResponseCompressionMiddleware от Microsoft. Данное изменение сделало реализацию расширений более зависимой от используемой версии ASP.NET Core. Именно с этого момента для каждой мажорной версии ASP.NET Core стал выпускаться свой NuGet-пакет.

2018 год можно назвать золотым временем для сообщества .NET-разработчиков Москвы - MskDotNet. Встречи проводились ежемесячно, иногда даже несколько раз в месяц. Июнь не стал исключением: в этом месяце прошло 3 встречи. На последнем июньском митапе, который проходил в офисе Mail.Ru Group, один из лидеров сообщества Никита Цуканов обратился к аудитории. Он рассказал, что в данный момент очень много компаний готовы предоставить сообществу площадки для проведения митапов, но у нас не хватает докладчиков. Помимо стандартного формата докладов предлагался короткий формат fast track продолжительностью 15 минут для презентации опенсорс-проектов. В конце встречи я подошел к Никите и начал рассказывать о своих опенсорс-проектах. Когда очередь дошла до WebMarkupMin, то Никита остановил меня и сказал: «Это то, что нужно! Об этом проекте можно сделать полноценный доклад…».

Вообще, проекту WebMarkupMin уже давно требовалась дополнительная раскрутка в России. Даже из той скудной статистики по HTTP-заголовкам X-HTML-Minification-Powered-By и X-XHTML-Minification-Powered-By, которую мне удавалось получать с помощью поисковых систем, было видно, что подавляющее число пользователей библиотеки находилось в США, а затем с большим отрывом шли Турция, Бразилия, Вьетнам, Нидерланды и Иран. В отличии от других моих опенсорс-проектов, WebMarkupMin не снискал популярности у себя на родине. В 2012 году выступление на митапе сообщества MoscowJS помогло мне привлечь интерес русскоязычной аудитории к проекту Bundle Transformer. В данном случае, я хотел добиться такого же эффекта для проекта WebMarkupMin.

За три недели я подготовил презентацию и текст доклада, а затем отправил заявку на доклад. Через два дня лидер сообщества Юлия Цисык создала в Telegram чат для обсуждения доклада. В этот же день была сформирована группа из 4 рецензентов. Еще через два дня мы провели тестовый прогон доклада через сервис видеоконференций Google Hangouts, после которого стало понятно, что доклад достаточно большой и его нужно урезать. После внесения правок последовал второй прогон, на котором доклад был полностью утвержден и включен в программу ближайшего митапа. Митап проводился на площадке Технологического Центра Дойче Банка, и стоит отметить, что Дойче Банк активно продвигал это мероприятие на своих медиа-ресурсах.

Анонс MskDotNet Meetup #25 в социальной сети «ВКонтакте»
Анонс MskDotNet Meetup #25 в социальной сети «ВКонтакте»

В день митапа я приехал на площадку за час до начала регистрации. Сотрудники центра сразу отвели меня конференц-зал. Зал был достаточно большим, думаю, что он мог бы вместить больше ста человек. Через какое-то время приехал второй спикер - Айрат Худайгулов и мы начали загружать файлы наших презентаций на ноутбук, предоставленный площадкой. Затем в зал вошел первый зритель и сообщил нам неприятную новость, что на улице идет ливень и по всей Москве объявлено штормовое предупреждение. Из-за урагана зал оказался заполненным только на треть.

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

Я, Айрат Худайгулов и Юлия Цисык подключаем мой ноутбук к проектору
Я, Айрат Худайгулов и Юлия Цисык подключаем мой ноутбук к проектору

Чтение самого доклада прошло хорошо и без каких-либо происшествий. Лишь в конце доклада случился один неприятный момент: после показа последнего слайда оператор завершил съемку, из-за чего сессия вопросов и ответов осталась за кадром. Запись доклада доступна на YouTube-канале «DotNetRu», а также кто-то разместил копию записи на Rutube.

Хотел бы поблагодарить активистов MskDotNet, принимавших участие в организации данного митапа: Юлию Цисык, Никиту Цуканова (@kekekeks), Александра Чертова, Евгения Макарова, Елизавету Цуканову, а также отдельная благодарность Кириллу Маурину (@Bonart) за ценные советы при подготовке доклада и Даниилу Соколюку за то, что пришел поддержать меня морально.

При подготовке доклада ты обсуждаешь свой проект с большим количеством людей и начинаешь смотреть на него под другим углом. Так появляются новые идеи по развитию проекта. Именно в процессе подготовки доклада я узнал о проблеме удаления HTML-комментариев, генерируемых компонентами React DOM, и появилась идея создать модуль, добавляющий в ASP.NET-расширения поддержку алгоритма сжатия Brotli.

Осенью я серьезно занялся повышением производительности всех модулей библиотеки.

2019

Была продолжена работа по повышению производительности.

В апреле появилась возможность минифицировать JSON-код в тегах script.

Начиная сентября логика удаления пустых и избыточных атрибутов стала учитывать новые исследования Йенса Оливера Мейерта.

2020

В 2019 году я снова стал посещать митапы MoscowJS, а также митапы других сообществ, связанных с фронтендом. И в январе 2020 года я загорелся идеей сделать доклад о HTML-минификации, ориентированный на фронтенд-разработчиков.

В конце января на митапе MskDotNet в офисе Dodo Engineering я встретил Никиту Цуканова. Никита пытался меня убедить сделать доклад о библиотеке JavaScript Engine Switcher. Я сказал ему, что сейчас работаю над другим докладом и изложил ему основную идею доклада о HTML-минификации, на что он мне ответил: «Да, ты с таким докладом сможешь гастролировать по митапам и конференциям!».

К концу февраля я закончил презентацию и текст доклада. C помощью OBS Studio я записал видео и опубликовал его на YouTube с доступом по ссылке. Это должно было облегчить процесс подачи заявки на доклад и сократить количество возможных прогонов. По тематике для доклада лучше всего подходило сообщество MoscowCSS, т.к. иногда там читались доклады посвященные HTML. Я подал заявку на доклад и уже в начале марта мне ответила лидер сообщества Алена Сиприкова. Доклад продолжительностью 42 минуты хорошо подходил для митапа с часовыми слотами, но никак не укладывался в получасовой слот, принятый в сообществе MoscowCSS. В идеале продолжительность доклада нужно было сократить до 20 минут, чтобы оставалось время на вопросы.

Когда я находился в процессе доработки доклада, началась пандемия. Все запланированные на тот момент митапы были отменены, и у меня появилось много различных проблем, из-за которых работа над докладом ушла на второй план. В итоге доклад был убран в долгий ящик, и я не вспоминал о нем вплоть до 2025 года. Тестовая видеозапись доклада до сих пор доступна на YouTube. Если вы интересуетесь историей и теорией HTML-минификации (или историей веб-разработки в целом), то найдете в этом докладе много полезной информации. Единственный недостаток исторической части в том, что в докладе не охватывается временной промежуток до 1998 года. Возможно, когда-нибудь я напишу большую статью, в которой полностью расскажу историю HTML-минификации.

Пандемия также негативно сказалась на разработке WebMarkupMin. Релизов в 2020 году было гораздо больше, чем в предыдущие три года, но все они были связаны с исправлением ошибок или подстраиванием под постоянно меняющийся ИТ-ландшафт. Пожалуй, единственной запоминающейся возможностью в том году было добавление поддержки маркеров Blazor.

В октябре количество загрузок ядра библиотеки через NuGet наконец-то превысило 1 миллион.

2021

2021 год был хуже 2020. Я уделял проекту намного меньше времени, чем обычно. Основные изменения коснулись лишь ASP.NET-расширений. Они стали еще более настраиваемыми. Если раньше минификация и сжатие применялась только к страницам, возвращающим код состояния HTTP равный 200, то теперь можно было разрешить эти операции и для других кодов состояния.

2022

В декабре 2021 года через сообщество DotNetRu я узнал о конкурсе «Open Source трибуна», который проводился в рамках конференции HighLoad++ Foundation.

Анонс конкурса «Open Source трибуна» на странице сообщества DotNetRu в социальной сети «ВКонтакте»
Анонс конкурса «Open Source трибуна» на странице сообщества DotNetRu в социальной сети «ВКонтакте»

В заявке на конкурс я указал проект WebMarkupMin, потому что всегда считал его своим лучшим опенсорс-проектом.

В конце января мне пришло письмо от организаторов, в котором говорилось, что моей проект вошел в число номинантов. Из 16 номинантов путем открытого голосования должны были определиться 5 победителей, которые и получали право рассказать о своем опенсорс-проекте на конференции. Голосование проходило на сайте конференции. Старт голосования был объявлен 28 января, a завершиться оно должно было 26 февраля.

Фрагмент списка номинантов конкурса «Open Source трибуна»
Фрагмент списка номинантов конкурса «Open Source трибуна»

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

Способы авторизации для голосования в конкурсе «Open Source трибуна»
Способы авторизации для голосования в конкурсе «Open Source трибуна»

Шансов на победу у меня было немного, потому что я практически не пользовался этими соцсетями и из-за этого количество моих подписчиков было невелико. Единственной социальной сетью, где количество моих подписчиков превышало 100 человек был GitHub. Тем не менее, я все же разместил в указанных соцсетях посты, агитирующие голосовать за мой проект.

Мой пост в социальной сети «ВКонтакте», агитирующий голосовать за мой проект
Мой пост в социальной сети «ВКонтакте», агитирующий голосовать за мой проект

Буквально через полчаса после публикации поста на своей стене во «ВКонтакте», через VK-мессенджер мне пришло сообщение следующего характера:

Деловое предложение от незнакомца через VK-мессенджер
Деловое предложение от незнакомца через VK-мессенджер

Из профиля этого человека было видно, что он, обладая огромным количеством подписчиков, занимался продвижением постов и участников онлайн-голосований. На мой взгляд, пользоваться такими услугами для обеспечения победы в конкурсе – это еще более нечестно, чем покупать фальшивые звезды на GitHub.

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

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

Затем я добавил возможность выбора стиля перевода строки, который будет применяться к минифицированному коду. Такая возможность присутствует во многих минификаторах JS- и CSS-кода, но отсутствует в современных минификаторах разметки. Например, замена CR+LF на LF может привести к существенной экономии при минификации больших файлов.

В ноябре хостинг AppHarbor прекратил свое существование, поэтому сайт WebMarkupMin Online пришлось в экстренном порядке переносить на FreeASPHosting.net.

2023

Я продолжил добавлять возможности, о которых давно просили пользователи. Весной я добавил в минификаторы HTML и XHTML возможность выбора стиля кавычек для значений атрибутов. Помимо стандартных стилей кавычек, также был реализован «оптимальный» стиль, когда символ кавычки определялся на основе значения атрибута.

2024

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

Ближе к осени я начал подготовку к выходу стабильной версии .NET 9. Начал я с проблем, которые накапливались в ASP.NET Core-расширениях уже давно: стал регистрировать сервисы с помощью методов TryAdd, написал логгер-обертку вокруг стандартного логгера из библиотеки Microsoft.Extensions.Logging и провел реорганизацию этих расширений. Затем добавил поддержку новых API классов GZipStream, DeflateStream и BrotliStream. В декабре я рассказал о результатах этой работы в статье на Хабре.

2025

О программе грантов Yandex Open Source я знал еще c 2024 года, но в прошлом году заявку подавать не стал. Также я посещал первый Yandex Open Source Jam, на котором смотрел выступления победителей 2024 года.

Анонс программы грантов Yandex Open Source 2025 в социальной сети «ВКонтакте»
Анонс программы грантов Yandex Open Source 2025 в социальной сети «ВКонтакте»

Когда в марте количество загрузок ядра WebMarkupMin через NuGet приблизилось к 7 миллионам, то я решил, что это знак и 13 марта подал заявку на конкурс. На какое-то время я об этом забыл и даже думал, что не прошел. Но 25 апреля я получил от Яндекса письмо, в котором мне сообщили, что я стал одним из победителей. Из письма я понял, что Джема в этом году не будет и вместо этого на Хабре будет опубликована статья, в которой расскажут о победителях. От меня требовалось лишь завести аккаунт Yandex Cloud и заполнить опросник. Опросник содержал ряд вопросов об опенсорс-проекте, ответы на которые должны были помочь сотрудникам Яндекса написать статью о победителях конкурса. Грант появился в моем аккаунте Yandex Cloud на следующий же рабочий день. После этого оставалось только ждать выхода статьи.

7 мая, ближе к концу рабочего дня, мне пришло письмо от Яндекса со ссылкой на черновик статьи. Кроме того, в письме содержался дополнительный бонус: мне предложили принять участие в ярмарке опенсорс-проектов, которая проводилась в рамках международного киберфестиваля PHDays Fest. От меня лишь требовалось заполнить анкету участника. В тот день я сосредоточился на вычитке черновика статьи и составлении списка уточнений к ней.

На следующий день я вернулся к заполнению анкеты и понял, что опоздал: в тексте был указан крайний срок 7 мая. Поскольку были праздники и не было возможности связаться с сотрудниками Яндекса, я все же решил заполнить анкету. Анкета оказалась довольно большой и отличалась от опросника Яндекса. На заполнение анкеты у меня ушло примерно 40 минут, и именно в этот момент мне пришла в голову идея написать данную статью.

В эти дни я не был уверен в своем участии в ярмарке на 100%. В любом случае, нужно было быть наготове: держать под рукой презентации 2018 и 2020 годов, а также сделать релиз WebMarkupMin хотя бы с частью изменений, упомянутых в опроснике Яндекса.

Немного забегая вперед, скажу, что 19 мая на странице программы грантов Yandex Open Source был опубликован список победителей 2025 года.

Список победителей 2025 года на странице программы грантов Yandex Open Source
Список победителей 2025 года на странице программы грантов Yandex Open Source

А также в этот день был опубликован официальный пресс-релиз и статья на Хабре.

Спасибо компании Яндекс за поддержку независимых опенсорс-разработчиков! Отдельная благодарность Елизавете Ивтушок (@thunderbeth) и Сергею Бережному (@veged)!

А теперь вернемся к ярмарке. 14 мая мне на почту пришло подтверждение участия в ярмарке опенсорс-проектов. Из письма стало понятно, что ярмарка пройдет в выставочном формате, и соответственно у каждого проекта будет свой стенд. При желании можно было принести роллап. Также было сказано, что ярмарка будет работать два дня (23 и 24 мая) во время двухчасовых перерывов между докладами трека, посвященного опенсорс-разработке. На главном экране на сцене и экранах в зале будет демонстрироваться слайд-шоу с информацией о проектах, поэтому каждому проекту требовалось сделать слайд с информацией о проекте: название, описание и QR-код со ссылкой на репозиторий. Организаторы предоставили шаблоны презентаций, гайдлайны и фирменные шрифты, т.е. все то, что обычно предоставляется спикерам крупных конференций. Компании при желании могли использовать свой фирменный стиль. Содержание самих выступлений никак не регламентировалось.

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

Слайд с информацией о проекте на главном экране на сцене
Слайд с информацией о проекте на главном экране на сцене
Слайд с информацией о проекте на экранах в зале
Слайд с информацией о проекте на экранах в зале

У меня уже был опыт участия в выставке, посвященной безопасности. В конце 2002 года я участвовал во Всероссийской научно-технической конференции-выставке с международным участием «Качество и безопасность продовольственного сырья и продуктов питания», которая проходила в моем университете, тогда он еще назывался Московским Государственным Университетом Пищевых Производств. Я представлял проект информационной системы «Портал МГУПП», которая должна была заменить устаревший статический сайт университета. Проект разрабатывался еще формирующимся студенческим КБ на базе кафедры «Кибернетика и Прикладной Системный Анализ». В тот момент КБ состояло всего из трех человек: меня, еще одного студента и преподавателя. В основном посетителями выставки были представители пищевых предприятий, который, как правило, были нашими выпускниками. Многие крупные предприятия помогали родному университету, поэтому моей задачей на выставке было, говоря современным языком, питчить проект перед потенциальными инвесторами. Система еще находилась на ранней стадии разработки, поэтому мы могли продемонстрировать лишь презентацию.

Тогда: представляю проект ИС «Портал МГУПП» на выставке «Качество и безопасность продовольственного сырья и продуктов питания»
Тогда: представляю проект ИС «Портал МГУПП» на выставке «Качество и безопасность продовольственного сырья и продуктов питания»

Для ярмарки опенсорс-проектов тоже нужно было сделать презентацию, потому что нельзя рассказывать о проекте, показывая лишь репозиторий на GitHub. Вообще, я не отношусь к числу спикеров, у которых всегда есть под рукой актуальная версия презентации и которые готовы в любой момент сорваться с места и мчаться на другой конец страны на очередной ивент. Я обычный разработчик, который выступает, в лучшем случае, раз в пятилетку на митапах местных сообществ. Поэтому за основу я взял презентацию 2018 года и добавил в нее немного теории из презентации 2020 года. Требовалось актуализировать довольно много информации: примеры кода, информацию о том, кто пользуется библиотекой, рассмотреть актуальные альтернативные решения и рассчитать эффективность минификации на примере реальных сайтов. К счастью, часть этой работы уже была сделана при заполнении опросника Яндекса и анкеты ярмарки. Самым сложным был расчет эффективности минификации, потому что в Рунете осталось мало сайтов, которые не используют HTML-минификацию.

При работе над слайдами я тоже решил придерживаться фирменного стиля конференции. В данном случае, основная проблема была с форматированием листингов. При копировании кода из Visual Studio с включенной темной темой, код оставался подсвеченным, как при использовании светлой темы. Решить эту проблема помогла установка VS-расширения Copy As Html 2022 от Microsoft DevLabs.

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

Сейчас: представляю проект WebMarkupMin на ярмарке опенсорс-проектов в рамках PHDays Fest
Сейчас: представляю проект WebMarkupMin на ярмарке опенсорс-проектов в рамках PHDays Fest

Вообще, неделя с 19 по 24 мая в России стала своего рода кульминацией многих мероприятий на тему опенсорса. Помимо объявления победителей программы грантов от Yandex Open Source 19 мая и ярмарки опенсорс-проектов 23-24 мая, было еще два интересных события: 21 мая в Питере прошел митап ProIT OpenSource Meetup x VK Tech и в полночь 23 мая завершился прием статей на конкурс «Сезон Open Source на Хабре».

PHDays Fest проходил в формате городского фестиваля и позиционировался как мероприятие для всей семьи. Из мероприятий подобного формата я посещал лишь Демодуляцию. Выступать я должен был в профессиональной зоне под названием «Киберхаб», для доступа в которую требовался билет. У меня не было спикерского статуса, но как волонтеру, организаторы предоставили мне бесплатный билет на все дни мероприятия. К сожалению, из нехватки свободного времени я смог посетить только ярмарку.

Ярмарка проходила в конференц-зале «Попов» в пространствах слева и справа от сцены.

Слайд с информацией о ярмарке опенсорс-проектов на главном экране на сцене
Слайд с информацией о ярмарке опенсорс-проектов на главном экране на сцене

Известные спикеры и команды разработчиков из отечественных компаний представляли свои опенсорс-проекты. Была даже целая команда специалистов по ИИ из одного престижного технического вуза. Я был единственным победителем программы грантов Yandex Open Source, кто участвовал в ярмарке. Еще два победителя программы выступали на конференции в качестве спикеров. Кроме того, на ярмарке я был единственным представителем .NET-сообщества.

Оба дня мой стол располагался в левой стороне от сцены.

Подготовка к началу ярмарки опенсорс-проектов
Подготовка к началу ярмарки опенсорс-проектов

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

Табличка с названием проекта, утяжеленная монетами
Табличка с названием проекта, утяжеленная монетами

Во второй день я уже использовал брелок, привезенный с первого Джема:

Табличка с названием проекта, утяжеленная брелоком
Табличка с названием проекта, утяжеленная брелоком

Первый день ярмарки оказался на редкость продуктивным. В этот день было очень много разработчиков, и я смог прочитать два полноценных доклада. После докладов, помимо моего проекта, мы еще говорили о .NET, Visual Studio и использовании ИИ-ассистентов в разработке ПО.

Рассказываю о проекте в первый день ярмарки (фото предоставлено организаторами)
Рассказываю о проекте в первый день ярмарки (фото предоставлено организаторами)

Во второй день ярмарки аудитория уже была менее подготовленной, поэтому я прочитал один полный доклад и три кратких. Также я демонстрировал эффективность минификации с помощью сайта WebMarkupMin Online. Говорили в основном о проблемах современного опенсорса.

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

Хотел бы поблагодарить Ксению Романову (@kseniya_ro) за организацию ярмарки и Георгия Кучерина (@gkucherin) за помощь в фотосъемке.

Заключение

Это конец статьи, но не конец истории проекта WebMarkupMin. Впереди еще много работы. В общем, как говорится на одной из наклеек на крышке моего ноутбука: «Глаза болят, а руки делают».


1 Намного позже я узнал, что автором этого документа был известный специалист по HTML и CSS Йенс Оливер Мейерт. Работая над новыми версиями WebMarkupMin в конце 10-х и начале 20-х годов, я часто опирался на результаты его новых исследований.

2 Модифицированный HTML-парсер Джона Резига.

3 Название ASP.NET Core появилось только в 2016 году.

Комментарии (2)


  1. Ydav359
    10.06.2025 11:02

    Интересная статья


    1. elpis_cablegateast
      10.06.2025 11:02

      школьники 90ых сразу начинали изучать html&etc генерируя руками в плейн-текст редактор - всякий софт использовали только чтобы оттуда/генерации выдрать оформление и про виртуал-сисопов знали тк уже сами в нейросетевое программирование могли (вузы по этой теме работали со школами - даже вузы/леспопилки в сибирях)