28 октября 2026 г.

Одна и та же карта, три способа: SVG, Rust и Flutter

Одна и та же карта, три способа: SVG, Rust и Flutter

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

Итак, мы провели эксперимент. Мы взяли карту с нашей главной страницы и перестроили её дважды: один раз на Rust с компиляцией в WebAssembly, и один раз на Flutter. В этой статье все три варианта собраны на одной странице и сравниваются.

1. Оригинал: SVG, CSS и немного JavaScript

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

Vancouver, CanadaLos Angeles, United StatesSan Diego, United StatesCalgary, CanadaVictoria, CanadaToronto, CanadaPortland, United StatesSeattle, United StatesSan Francisco, United StatesNew York, United StatesSydney, AustraliaBoston, United StatesMontreal, CanadaAustin, United StatesChicago, United StatesOttawa, CanadaLondon, United KingdomBengaluru, IndiaEdmonton, CanadaHalifax, CanadaMelbourne, AustraliaEdinburgh, United KingdomMexico City, MexicoBerlin, GermanyMunich, GermanyBarcelona, SpainParis, FranceManchester, United KingdomOsaka, JapanTokyo, JapanAuckland, New ZealandStockholm, SwedenBrisbane, AustraliaMilan, ItalySeoul, South KoreaOslo, NorwayCape Town, South AfricaSão Paulo, BrazilLagos, NigeriaAmsterdam, NetherlandsKarachi, PakistanDenver, United StatesMiami, United StatesRaleigh, United States

Ready Charging Check in Check out

⚠️ Техническая часть впереди. Не по душе? Перейти к Rust →

Это один SVG-рисунок. Браузер выполняет большую часть анимаций с помощью CSS, а небольшой скрипт обрабатывает остальное.

В его пользу: отсутствует этап сборки, поэтому достаточно шаблона Hugo. Это вектор, поэтому изображение остаётся чётким при любом размере. Все 44 точки доступны с клавиатуры, каждая снабжена меткой для экранных читалок. И несколько слов переведены на все наши языки.

Цена — вес на странице. Разметка карты занимает около 107 КБ (около 30 КБ в сжатом виде), а при работе содержит около 670 элементов и примерно 200 CSS-анимаций. Логику также сложно тестировать: тайминги заданы внутри CSS keyframes и скрипта на странице, поэтому единственный способ проверить — просто посмотреть.

2. Rust и WebAssembly

Проще говоря: Rust — это язык программирования, известный своей скоростью и способностью находить множество ошибок до того, как программа запустится. Здесь мы написали «мозг» карты на Rust, упаковали его в компактную форму, которую браузеры могут запускать (называемую WebAssembly), и позволили ему самостоятельно рисовать всю карту, как художнику, который многократно перерисовывает одно и то же полотно каждую секунду. Для вас это выглядит одинаково.

⚠️ Техническая часть впереди. Не по душе? Перейти к Flutter →

Вся карта рисуется на одном холсте с помощью Rust, скомпилированного в WebAssembly. Код на Rust отвечает за всё поведение карты и перерисовывает всё каждый кадр.

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

В итоге страница получается очень лёгкой: один элемент canvas. Но загрузка больше. Скомпилированный модуль занимает около 254 КБ (около 92 КБ в сжатом виде) плюс около 28 КБ JavaScript-клея, который генерирует инструмент сборки. И есть издержки, которые мы ощущаем при работе с этим:

  • Инструментарий. Для сборки требуется Rust, цель WebAssembly и командная утилита, версия которой должна точно совпадать с версией библиотеки. Наш скрипт сборки сначала запускает тесты и останавливается, если один из них не проходит.
  • Нет доступа с клавиатуры или экранного диктора к отдельным городам. Canvas — это изображение. Версия SVG с 44 доступными для фокуса точками исчезла.
  • Только английский язык. Надписи встроены в программу.
  • Размытие. Мягкий край тени использует фильтр размытия canvas, который не поддерживается всеми браузерами. Мы не тестировали Safari, где край может выглядеть жестким.

3. Flutter

Простыми словами: Flutter — это набор инструментов от Google для создания приложений, которые работают на телефонах, компьютерах и в интернете из одного набора кода. Он не использует собственные строительные блоки веб-страницы. Он рисует всё сам. Здесь карта — это небольшое приложение, показанное внутри этой страницы, тот же набор инструментов, который используется в нашем калькуляторе зарядки.

⚠️ Техническая часть впереди. Не ваше? Перейти к результатам →

Карта рисуется с помощью кастомного рисовальщика и показывается здесь в рамке. Flutter также может создавать приложения для телефонов и настольных компьютеров из того же кода, что является его главным аргументом: написать карту один раз, запускать в нескольких местах.

Это та же логика, что и у Rust map, портированная на Dart, с 11 тестами. Около 1100 строк кода, включая тесты. Flutter передаёт каждый город экранным читалкам как кнопку с меткой, чего нет в версии на canvas (мы не проверяли, насколько хорошо это работает с реальной экранной читалкой). Это также самый большой загрузочный файл: приложение весит около 1,8 МБ (около 535 КБ в сжатом виде). Движок рисования Flutter загружается отдельно, но сайт уже делит одну копию с калькулятором, так что посетитель, который открыл калькулятор, не загружает его повторно. Текст задан шрифтом сайта Merriweather, который браузер загружает во время выполнения.

Что мы обнаружили

SVG + CSS + JSRust + WebAssemblyFlutter
Загрузка для картыоколо 107 КБ, в страницеоколо 254 КБ модуль + 28 КБ связующего кодаоколо 1,8 МБ приложение (движок рисования общий)
Элементы на страницеоколо 670, с примерно 200 CSS-анимациями1 canvas1 фрейм
Тесты логикиотсутствуют13, нативные11, нативные
Города доступны с клавиатурыда, все 44нетдоступны экранным читалкам (не тестировалось)
Переведеноданет, только на английскомнет, только на английском
Остаётся чётким при любом увеличениида (вектор)перерисовывается под плотность пикселей экранаперерисовывается под плотность пикселей экрана
Что требуется для сборкиничегоRust toolchain, соответствующая версия инструментовFlutter SDK

Ещё одна заметка о скорости. В нашей проверке SVG карта и Rust карта обе работали с частотой обновления экрана (около 120 кадров в секунду на тестовом дисплее), поэтому частота кадров их не отличала. Мы не измеряли частоту кадров Flutter и не измеряли расход батареи или процессора, поэтому не можем сказать, какой вариант легче для телефона.

Вещи, которые нас удивили

Некоторые детали легко сделать неправильно. Наши первые клоны рисовали ключ и часы с фиксированным размером на карте, поэтому они уменьшались на маленьких экранах и выглядели крошечными по сравнению с оригиналом. Оригинал задаёт их размер в собственной единице шрифта страницы (rem, которая меняется с шириной экрана). Теперь клоны считывают этот размер со страницы. Часы тоже отличаются: стрелки оригинала двигаются шагами по 15 минут, а в версиях на Rust и Flutter они вращаются непрерывно.

Часовые пояса не были встроены. Ни Rust, скомпилированный в WebAssembly, ни Dart не содержат базы данных часовых поясов с информацией о “Asia/Dubai”. Оба запрашивают эту информацию у браузера через встроенный сервис Intl, который также правильно учитывает переход на летнее время.

Все три используют одни и те же входные данные. Карты на Rust и Flutter считывают список городов и контур суши со страницы, на которой находятся, те же данные, что использует SVG-карта. Измените город — изменятся все три. Это также означает, что карты могут работать только на странице, которая их предоставляет.

Flutter web запоминает. Flutter web устанавливает собственный кэш, поэтому после пересборки мы продолжали видеть старую версию, пока не очистили кэш.

Наш вывод

SVG-карта остаётся на главной странице. Для рисунка такого размера она самая лёгкая, доступная, переведённая и не требует сборки. Rust — более интересный претендент: если когда-нибудь понадобится доказать правильность логики карты или выполнить тяжёлые вычисления в браузере, проверенное ядро на Rust — хороший способ это сделать. Flutter имеет смысл, если карта когда-нибудь должна жить внутри Flutter-приложения.

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

Что наши основатели создают дальше

Стабильная платформа оставляет время для других идей. Помимо EVnSteven, наши основатели работают над следующими проектами:

Служба вызова такси, скоро запуск Kimem (opens in a new tab) Служба вызова такси для Бахир-Дара, Эфиопия, от основателя Меконнена Алему. Пассажиры видят предварительную стоимость поездки перед заказом, наблюдают на карте приближение ближайшего водителя и оплачивают поездку наличными по счетчику в конце поездки. Некоммерческий, с открытым исходным кодом StrayCats (opens in a new tab) Проект от Дэвида, чтобы помочь людям, которые заботятся о уличных кошках, бродячих кошках или любых кошках, даже если эта кошка случайно оказалась собакой. Пока что это только идея, приложения ещё нет, и Дэвид будет рад вашим идеям и отзывам. Посвящается Саибо, 2010–2026. Отслеживание наличных, бесплатно, скоро запуск Effectivo (opens in a new tab) Несовершённый учёт с изюминкой, для тех, кто пользуется наличными. Записывайте покупку в несколько касаний, считайте, что у вас в кошельке, и смотрите назад, что было того стоит. Изюминка в том, что каждый, кто продолжает использовать наличные, помогает сохранить их для всех остальных. Бесплатно и без рекламы, скоро на Android и iPhone, сейчас доступна бета-версия и веб-демо.

Ваше здание готово к зарядке электромобилей.

Заряжайте электромобили от уже имеющихся у вас розеток. Водители платят за время использования.

Получить EVnSteven

Подпишитесь на EVnSteven Notes

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

Поддержка и руководства

10 сентября 2026 г.

Сколько инженеров-электриков нужно, чтобы зарядить машину?

Достаточно, чтобы превратить розетку за 500 долларов в проект за 20 000 долларов. Я люблю инженеров — я сам изучал инженерию. Но иногда мы делаем простые вещи слишком сложными. Читать далее · 1 min


4 сентября 2024 г.

Каждая версия становится лучше, как двигатели Raptor от SpaceX

Изучите, как кодовая база EVnSteven воплощает простоту, мощь и повторное использование, проводя параллели с эволюцией двигателей Raptor от SpaceX от V1 до V3. Читать далее · 1 min