openpencil/packages/docs/ru/guide/comparison.md
Danila Poyarkov e5b147148e Add AI & Automation docs section, CLI reference, formatting fixes
New 'AI & Automation' top-level nav section with 9 pages:
- AI Chat: setup, 87 tools, example prompts
- Collaboration: room sharing, cursors, follow mode
- JSX Renderer: elements, style props, visual diffing
- CLI (4 pages): inspecting, exporting, analyzing, scripting
- MCP Server: moved from Reference, setup + 90 tools

New CLI reference page in Reference with all 12 commands,
every option, alias, and default value.

Formatting fixes across all 7 locales:
- Wrap enum values in backticks (FRAME, SOLID, ROUND, etc.)
- Fix single-backtick code blocks → triple backticks
- Use <kbd> for all keyboard shortcuts
- Remove implementation details from user guide
- Delete stale eval-command.md and mcp-tools.md (14 files)
- Update dead links to new locations
2026-03-08 18:25:35 +03:00

293 lines
23 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# OpenPencil vs Penpot: сравнение архитектуры и производительности
Зачем сравнивать? OpenPencil существует, потому что закрытые дизайн-платформы ограничивают возможности. Понимание архитектурных различий показывает, что может предложить открытая, локальная альтернатива.
::: info WASM-рендерер Penpot
Penpot 2.x включает Rust/Skia WASM рендерер (`render-wasm/v1`), который можно включить через серверные флаги или параметр `?wasm=true` в URL. Старый SVG-рендерер остаётся по умолчанию. На этой странице рассматриваются оба варианта.
:::
## 1. Масштаб и размер кодовой базы
| Метрика | OpenPencil | Penpot |
|--------|-------------|--------|
| Всего строк кода | **~26 000** | **~299 000** |
| Файлов исходного кода | ~143 | ~2 900 |
| Языки | TypeScript, Vue | Clojure, ClojureScript, Rust, JS, SQL, SCSS |
| Движок рендеринга | ~3 200 строк (TS, 10 файлов) | 22 000 строк (Rust/Skia WASM) |
| UI-код | ~4 500 строк | ~175 000 строк (CLJS + SCSS) |
| Бэкенд | Нет (локальный подход) | 32 600 строк + 151 SQL-файл |
| Соотношение LOC | **1×** | **~11×** |
OpenPencil **примерно в 11 раз меньше** — и в этом вся суть. Это не упрощение, а принципиально другая архитектура.
## 2. Архитектура
### OpenPencil: монолитный клиент
```
┌─────────────────────────────────┐
│ Tauri (native shell) │
│ ┌───────────────────────────┐ │
│ │ Vue 3 + TypeScript │ │
│ │ ┌─────────┐ ┌──────────┐│ │
│ │ │ Editor │ │ Kiwi ││ │
│ │ │ Store │ │ Codec ││ │
│ │ └────┬─────┘ └──────────┘│ │
│ │ │ │ │
│ │ ┌────▼────────────────┐ │ │
│ │ │ Scene Graph (TS) │ │ │
│ │ │ Map<string, Node> │ │ │
│ │ └────┬────────────────┘ │ │
│ │ │ │ │
│ │ ┌────▼────┐ ┌──────────┐│ │
│ │ │ Skia │ │ Yoga ││ │
│ │ │CanvasKit│ │ Layout ││ │
│ │ │ (WASM) │ │ (WASM) ││ │
│ │ └─────────┘ └──────────┘│ │
│ └───────────────────────────┘ │
└─────────────────────────────────┘
```
**Всё в одном процессе.** Без сервера, без базы данных, без Docker. Граф сцены — плоская `Map<string, SceneNode>` в TypeScript. Рендеринг вызывает Skia CanvasKit напрямую из TS. Макет — Yoga WASM, вызываемый синхронно.
### Penpot: распределённый клиент-сервер
```
┌───────────────────────────────────────────────────────┐
│ Docker Compose │
│ ┌──────────────┐ ┌─────────────┐ ┌──────────────┐ │
│ │ Frontend │ │ Backend │ │ Exporter │ │
│ │ ClojureScript│ │ Clojure │ │ (Chromium) │ │
│ │ shadow-cljs │ │ JVM │ │ │ │
│ │ ┌─────────┐ │ │ ┌────────┐ │ └──────────────┘ │
│ │ │render- │ │ │ │Postgres│ │ │
│ │ │wasm │ │ │ │Valkey │ │ ┌──────────────┐ │
│ │ │(Rust→ │ │ │ │ MinIO │ │ │ MCP │ │
│ │ │ Skia │ │ │ └────────┘ │ │ Server │ │
│ │ │ WASM) │ │ │ │ └──────────────┘ │
│ │ └─────────┘ │ │ │ │
│ └──────────────┘ └─────────────┘ │
└───────────────────────────────────────────────────────┘
```
**Минимум 5+ сервисов.** PostgreSQL для хранения, Redis (Valkey) для pub/sub и кеширования, MinIO для хранения ассетов, JVM-бэкенд, Node.js экспортёр (headless Chromium для серверного рендеринга), плюс ClojureScript фронтенд. Для разработки требуется Docker Compose с настроенной сетью.
### Вердикт: архитектура
Однопроцессная архитектура OpenPencil устраняет:
- Сетевую задержку между фронтендом и бэкендом
- Накладные расходы на сериализацию/десериализацию на границах сервисов
- Сложность оркестрации контейнеров
- Накладные расходы на запросы к базе данных при каждой операции
Архитектура Penpot оптимизирована для **многопользовательских серверных развёртываний**. OpenPencil оптимизирован для **мгновенной локальной производительности**.
## 3. Конвейер рендеринга
### OpenPencil: TS → CanvasKit WASM (напрямую)
```typescript
// renderer.ts — прямые вызовы CanvasKit из TypeScript
renderSceneToCanvas(canvas, graph, pageId) {
// Итерируем узлы, строим Skia paths/paints, рисуем
this.fillPaint.setColor(...)
canvas.drawRRect(rrect, this.fillPaint)
}
```
- **1 пересечение границы:** TS → WASM (CanvasKit)
- Граф сцены живёт в JS-куче — без сериализации для рендеринга
- ~3 200 строк рендерера (разбит на 10 специализированных файлов: scene, overlays, fills, strokes, shapes, effects, rulers, labels)
### Penpot: JS (скомпилированный из CLJS) → Rust WASM → Skia
Penpot 2.x включает Rust/Skia WASM рендерер (`render-wasm/v1`), опционально включаемый через серверные флаги или `?wasm=true`. При включении фигуры рендерятся через:
```
ClojureScript (скомпилированный в JS)
→ декомпозиция в примитивы + бинарная упаковка в линейную память WASM
→ Rust WASM (через Emscripten C FFI)
→ skia-safe (Rust-биндинги Skia)
→ Skia (WebGL)
```
При отключении (по умолчанию) фигуры рендерятся как SVG DOM-дерево через React/Reagent — каждая фигура является DOM-элементом.
- **1 пересечение границы** (JS → WASM), как и у OpenPencil — но с явными накладными расходами на сериализацию: UUID разбиваются на 4×u32, трансформации на 6×f32, заливки/обводки упаковываются в бинарный формат, базовые свойства группируются в 104-байтную структуру на фигуру
- Тайловая система рендеринга с областями интереса
- 11 отдельных поверхностей рендеринга (заливки, обводки, тени и т.д.)
- Глобальное мутабельное состояние через паттерн `unsafe { STATE.as_mut() }`
- 22 000 строк Rust-движка рендеринга
Тайловая система Penpot (`TileViewbox`, `TileTextureCache`, `TILE_SIZE_MULTIPLIER`) предварительно рендерит тайлы вокруг области видимости и кеширует текстуры (до 1024 записей).
OpenPencil перерисовывает всю область видимости каждый кадр, потому что CanvasKit, вызываемый напрямую из TS, достаточно быстр и не нуждается в тайлинге.
### Вердикт: рендеринг
| Аспект | OpenPencil | Penpot |
|--------|-------------|--------|
| Граница JS→WASM | Напрямую (TS-объекты) | Бинарная упаковка (104-байтная структура) |
| Модель рендеринга | Немедленная/полная перерисовка | Тайловое кеширование |
| Управление поверхностями | 1 поверхность | 11 поверхностей |
| Расход памяти | Низкий (без кеша тайлов) | Высокий (кеш на 1024 тайла) |
| Сложность кода | ~3 200 строк (10 файлов) | 22 000 строк |
| Unsafe-код | Нет | `unsafe` глобальное состояние |
Когда WASM-рендерер Penpot включён, оба проекта используют Skia через JS→WASM. OpenPencil вызывает CanvasKit напрямую с TS-объектами. Penpot декомпозирует данные ClojureScript в бинарно упакованные структуры, записывает их в линейную память WASM и рендерит через 22 000-строчный Rust-движок. При отключённом WASM (по умолчанию) Penpot рендерит фигуры как SVG DOM-дерево. Для малых и средних документов прямой путь через CanvasKit быстрее. Тайловая система Penpot может выигрывать на очень больших канвасах (100K+ фигур), где видна лишь малая область — но накладные расходы значительны.
## 4. Граф сцены и модель данных
### OpenPencil
```typescript
// Плоская карта, O(1) поиск
nodes: Map<string, SceneNode>
// 29 типов узлов из Kiwi-схемы Figma
// ~390 полей на NodeChange (совместимо с Figma)
```
- TypeScript-интерфейсы со строгой типизацией
- GUID соответствуют формату Figma `sessionID:localID`
- Прямой доступ к свойствам — без слоёв косвенности
### Penpot
```clojure
;; 20+ файлов определений типов в common/src/app/common/types/
;; shapes_builder.cljc, shapes_helpers.cljc
;; Отдельные системы типов для: color, component, container, fills,
;; grid, modifiers, objects_map, page, path и т.д.
```
- Данные распределены по `common/` (49 600 строк .cljc)
- Отдельные модули геометрии для flex-макета (~6 файлов), grid-макета (~5 файлов), ограничений, границ, углов, эффектов
- Валидация схем в рантайме (Malli)
- Данные должны пересекать границу CLJS→Rust для рендеринга
### Вердикт: модель данных
OpenPencil использует проверенную схему Figma (194 определения Kiwi) напрямую в TypeScript — без преобразований. Penpot поддерживает собственную систему типов в Clojure/ClojureScript/Rust, требующую ручной синхронизации между всеми тремя.
## 5. Движок макетов
### OpenPencil: Yoga WASM (314 строк)
```typescript
import Yoga from 'yoga-layout'
// Прямое сопоставление: поля Figma stack* → свойства Yoga flex
const root = Yoga.Node.create()
root.setFlexDirection(FlexDirection.Row)
root.calculateLayout()
applyYogaLayout(graph, frame, yogaRoot)
```
314 строк всего. Синхронно, внутри процесса.
### Penpot: двойная реализация
1. **ClojureScript** (common): `flex_layout/` (6 файлов), `grid_layout/` (5+ файлов) — собственные реализации
2. **Rust WASM**: `flex_layout.rs` (741 строка), `grid_layout.rs` (843 строки) — реализовано с нуля
Penpot поддерживает **два независимых движка макетов** (CLJS и Rust), которые должны давать идентичные результаты.
### Вердикт: макет
OpenPencil делегирует проверенной библиотеке (Yoga, используется React Native на миллиардах устройств) в 314 строках. Penpot поддерживает ~3 000+ строк собственного кода макета, дублированного на двух языках.
## 6. Формат файлов и совместимость с Figma
### OpenPencil
- **Нативный бинарный формат Kiwi** — та же сериализация, что использует Figma внутри
- Прямой импорт файлов `.fig` через извлечённый Kiwi-кодек (2 178 строк схемы + 551 строка кодека)
- Поддержка вставки из буфера обмена Figma (чтение бинарного Kiwi из буфера обмена)
- Совместимость на уровне протокола с мультиплеерным протоколом Figma
### Penpot
- **ZIP-архив** (файлы `.penpot`), содержащий JSON-манифесты, JSON-данные по файлам, бинарные ассеты и миниатюры (формат v3)
- SVG используется для рендеринга по умолчанию и экспорта (опциональный WASM-рендерер доступен)
- Нет нативного импорта `.fig`
- Три версии формата (v1 legacy Transit, v2, v3 JSON-in-ZIP) с системой миграции
### Вердикт: формат файлов
OpenPencil имеет значительное преимущество — он может читать файлы Figma нативно и даже вставлять данные из буфера обмена Figma. Penpot требует ручного экспорта/импорта и не может открывать файлы `.fig`.
## 7. Управление состоянием и отмена
### OpenPencil
```typescript
// 110 строк — паттерн обратных команд
class UndoManager {
apply(entry: UndoEntry) { entry.forward(); this.undoStack.push(entry) }
undo() { entry.inverse(); this.redoStack.push(entry) }
}
```
110 строк. Forward/inverse замыкания, захватывающие минимальное состояние. Поддержка группировки для многоэтапных операций.
### Penpot
Управление состоянием использует Potok (Redux-подобная библиотека для ClojureScript atoms). События реализуют `UpdateEvent` (чистое state→state) или `WatchEvent` (побочные эффекты через RxJS). Отмена хранит обратные векторы изменений (максимум 50 записей), с транзакциями для группировки быстрых изменений и авто-истечением через 20 секунд.
### Вердикт: состояние
Подход OpenPencil проще и с меньшими накладными расходами. Подход Penpot больше подходит для совместной работы (изменения сериализуемы), но ценой сложности.
## 8. Опыт разработчика
| Метрика | OpenPencil | Penpot |
|--------|-------------|--------|
| Настройка среды | `bun install && bun dev` | Docker Compose + JVM + Node + Rust toolchain |
| Горячая перезагрузка | Vite HMR (~50мс) | shadow-cljs (секунды) |
| Проверка типов | TypeScript (строгий) | В рантайме (схемы Malli) |
| Время сборки | <5с (Vite) | Минуты (запуск JVM + компиляция CLJS + Rust WASM) |
| Порог первого вклада | Низкий (TS/Vue) | Высокий (Clojure + Rust + Docker) |
| Десктоп | Tauri v2 (~5 МБ) | Н/Д (только браузер) |
| Пул разработчиков | Огромный (TS/Vue) | Крошечный (ClojureScript + Rust) |
## 9. Характеристики производительности
| Сценарий | OpenPencil | Penpot |
|----------|-------------|--------|
| Холодный старт | <2с (загрузка WASM) | 10с+ (сервер + клиент + WASM) |
| Задержка операций | <с (в процессе) | 10-50мс (сетевой round-trip) |
| Кадр рендеринга | Прямой вызов Skia | CLJSJSWASM FFISkia |
| Базовый расход памяти | ~50 МБ (вкладка браузера) | ~300 МБ+ (JVM + Postgres + Valkey + браузер) |
| Работа офлайн | Полная (локальный подход) | Нет (зависимость от сервера) |
| Рендеринг 10K фигур | Один проход, без кеширования | Тайловый с 11 поверхностями |
## 10. В чём Penpot лучше
1. **Серверная совместная работа** централизованное многопользовательское редактирование с WebSockets, учётными записями и контролем доступа (OpenPencil использует P2P через Trystero + Yjs без сервера, но и без контроля доступа или сохранения за пределами сессии)
2. **Экспорт PDF** headless Chromium для серверного PDF-рендеринга (OpenPencil экспортирует SVG, но пока не PDF)
3. **Система плагинов** полный API плагинов с изолированным выполнением
4. **Дизайн-токены** нативная поддержка дизайн-токенов
5. **Макет CSS Grid** собственная реализация (OpenPencil ждёт Yoga Grid)
6. **Самостоятельный хостинг** развёртывание на Docker для команд
7. **Зрелость** годы использования в продакшене, проверенный масштабированием
## 11. Скриптинг и расширяемость
OpenPencil поставляется с [командой `eval`](/programmable/cli/scripting), предоставляющей Figma-совместимый Plugin API для headless-скриптинга пакетные операции, автоматизированное тестирование и ИИ-модификации работают без GUI. Кроме того, **90 ИИ-инструментов** доступны через встроенный чат, MCP-сервер (stdio + HTTP) и CLI охватывающие чтение, создание, модификацию, структуру, переменные, векторные пути, анализ (цвета/типографика/отступы/кластеры), сравнение, булевые операции и упорядочивание. Penpot имеет систему плагинов с изолированным выполнением, но без headless-скриптинга или интеграции MCP.
## Итоги
| Аспект | Лидер | Почему |
|-----------|--------|-----|
| **Простота архитектуры** | OpenPencil | Один процесс vs 5+ сервисов |
| **Производительность рендеринга** | OpenPencil | Прямой CanvasKit vs SVG DOM (по умолчанию) или бинарно упакованный WASM |
| **Поддерживаемость кода** | OpenPencil | ~26K строк на 1 языке vs 299K на 4+ языках |
| **Совместимость с Figma** | OpenPencil | Нативный Kiwi-кодек vs отсутствие поддержки .fig |
| **Онбординг разработчиков** | OpenPencil | TS/Vue vs Clojure/Rust/Docker |
| **Десктоп** | OpenPencil | Нативный Tauri vs только браузер |
| **Движок макетов** | OpenPencil | Yoga (проверенный) vs собственная двойная реализация |
| **Совместная работа** | Ничья | Penpot: серверная с контролем доступа; OpenPencil: P2P через Trystero + Yjs, без хостинга |
| **Самостоятельный хостинг** | Penpot | Docker-ready vs только десктоп |
| **Зрелость экосистемы** | Penpot | Годы продакшена vs ранняя стадия |
OpenPencil архитектурно легче однопроцессный CanvasKit-рендерер в ~26K строках TypeScript, совместимый с Figma по дизайну. Penpot полноценная платформа с ~299K строками на Clojure, ClojureScript, Rust и SCSS, плюс парк Docker-сервисов. Оба предлагают совместную работу в реальном времени (с разными архитектурами: P2P vs сервер). Penpot имеет экосистему плагинов и серверный экспорт PDF; OpenPencil имеет Figma-совместимый headless-скриптинг, **90 ИИ/MCP инструментов**, экспорт SVG и нативное десктоп-приложение.