* docs: polish localized documentation - Rewrite Russian documentation for natural terminology and current source parity\n- Continue the Polish editorial pass across guides and SDK references\n- Refresh shared localized SDK API data imports * docs(pl): complete editorial pass - Rewrite the remaining advanced Vue SDK references\n- Refresh the Figma compatibility matrix against the canonical source\n- Align terminology and behavior across every Polish documentation page * docs(de): complete editorial pass - Rewrite German guides, automation docs, and Vue SDK references\n- Restore current AI, export, component, and variable behavior\n- Refresh the Penpot comparison and Figma compatibility matrix * docs(es): complete editorial pass - Rewrite Spanish guides, automation docs, and Vue SDK references\n- Restore current AI, export, component, and variable behavior\n- Refresh the Penpot comparison and Figma compatibility matrix * docs(fr): complete editorial pass - Rewrite French guides, automation docs, and Vue SDK references\n- Restore current AI, export, component, and variable behavior\n- Refresh the Penpot comparison and Figma compatibility matrix * docs: correct localized terminology - Replace unnecessary English prose with natural localized terminology\n- Derive documentation aliases from named directory roots\n- Preserve English only for identifiers, APIs, and exact product terms * docs(it): continue editorial pass - Rewrite Italian user guides and automation documentation\n- Update Vue SDK composables and component references\n- Restore current AI, export, component, and variable behavior * docs(it): complete editorial pass - Finish Italian advanced SDK and reference documentation\n- Refresh the Penpot comparison and Figma compatibility matrix\n- Replace literal machine translations with natural technical prose * docs(pl): refine property panel terminology * docs: refine remaining localized prose - Replace overfitted English prose in Polish feature documentation\n- Rewrite the Russian property-list reference in natural terminology * docs(ru): rewrite Penpot comparison naturally - Replace remaining English prose with natural Russian\n- Preserve code identifiers and library names only where required * docs: rewrite localized feature overviews naturally - Replace avoidable English prose in German, Spanish, and French\n- Keep identifiers and product names unchanged * docs(de): refine property panel terminology * docs: refine Spanish and French SDK terminology * docs(ru): continue full prose audit - Rewrite homepage, setup, navigation, and guide index naturally\n- Restore missing zoom shortcuts * docs(ru): audit user and automation guides - Rewrite selection, collaboration, and automation prose naturally\n- Preserve API identifiers while localizing ordinary terminology * docs(ru): audit CLI inspection and analysis * docs(ru): audit Vue SDK overview and guides * docs(ru): audit Vue SDK API prose - Localize ordinary component and composable terminology\n- Preserve API symbols and code identifiers * docs(ru): audit advanced and gradient API references * docs(ru): finish advanced API prose audit * docs(ru): audit JSX renderer guide * docs(ru): audit CLI export and scripting guides * docs(pl): audit Penpot comparison prose * docs(pl): audit selection and automation guides * docs(pl): audit homepage and variable guides * docs(pl): audit vector, layers, and Pen guides * docs(pl): audit Auto layout and shape guides * docs(pl): audit context menu and export guides * docs(pl): audit JSX and analysis guides * docs(pl): audit AI Chat guide * docs(pl): audit components and CLI inspection * docs(pl): audit scripting and SDK overview prose * docs(pl): audit SDK API indexes * docs(pl): audit SDK component references * docs(pl): audit SDK composable references * docs(ru): refine usePosition terminology * docs(pl): audit advanced SDK references * docs(pl): audit Figma compatibility matrix * docs(pl): finish residual SDK terminology audit * docs(pl): finish component terminology audit * docs(pl): finish SDK guide terminology audit * docs(de): begin full user guide prose audit * docs(de): audit navigation, Pen, and layers guides * docs(de): audit Auto Layout, shapes, menu, and export * docs(de): audit components, text, and vector guides * docs(de): audit variables and automation overview * docs(de): audit AI Chat and collaboration guides * docs(de): audit CLI inspection, analysis, and export * docs(de): audit scripting and JSX guides * docs(de): audit Vue SDK overview and guides * docs(de): audit SDK API indexes * docs(de): audit SDK component references * docs(de): audit SDK composable references * docs(de): audit advanced SDK references * docs(de): audit Penpot comparison prose * docs(de): audit Figma compatibility reference * docs(es): begin full user guide prose audit * docs(es): audit document organization guides * docs(es): audit editing workflow guides * docs(es): audit automation and collaboration prose * docs(es): audit CLI inspection and export guides * docs(es): audit CLI scripting guide * docs(es): audit JSX and feature overview prose * docs(es): audit Penpot comparison prose * docs(es): audit SDK overview and guides * docs(es): begin SDK component reference audit * docs(es): audit SDK navigation component references * docs(es): audit SDK color and layout components * docs(es): begin SDK composable reference audit * docs(es): audit SDK property composable references * docs(es): audit SDK editor composable references * docs(es): begin advanced SDK reference audit * docs(es): audit advanced SDK state references * docs(es): complete advanced SDK reference audit * docs(es): audit Figma compatibility reference * docs(es): complete residual terminology sweep * docs(fr): begin full prose second audit * docs(fr): audit AI and variables prose * docs(fr): audit core user guide prose * docs(fr): audit editing workflow guides * docs(fr): audit CLI and JSX prose * docs(fr): audit Penpot comparison prose * docs(fr): audit SDK overview and guides * docs(fr): begin SDK API reference audit * docs(fr): audit SDK navigation component references * docs(fr): audit SDK color and layout components * docs(fr): begin SDK composable reference audit * docs(fr): audit SDK property composable references * docs(fr): audit editor composables and advanced APIs * docs(fr): audit advanced SDK state references * docs(fr): complete advanced SDK reference audit * docs(fr): audit Figma compatibility reference * docs(fr): complete residual terminology sweep * docs(it): begin full prose second audit * docs(it): audit document workflow guides * docs(it): audit editing and automation prose * docs(it): audit CLI and JSX prose * docs(it): audit Penpot comparison and SDK guides * docs(it): begin SDK API reference audit * docs(it): audit SDK component and state references * docs(it): audit residual SDK references * docs(it): audit Figma compatibility reference * docs(it): complete residual terminology sweep * docs(i18n): verify residual locale terminology
183 lines
9.6 KiB
Markdown
183 lines
9.6 KiB
Markdown
# OpenPencil i Penpot: architektura oraz wydajność
|
||
|
||
OpenPencil i Penpot to narzędzia projektowe o otwartym kodzie źródłowym, ale różnią się przeznaczeniem i architekturą.
|
||
|
||
::: info Renderer WASM w Penpot
|
||
Penpot 2.x zawiera renderer Rust/Skia WASM `render-wasm/v1`, włączany opcjami serwera albo parametrem `?wasm=true`. Domyślnie nadal działa renderer SVG. Poniżej uwzględniono oba warianty.
|
||
:::
|
||
|
||
## 1. Rozmiar bazy kodu
|
||
|
||
| Wskaźnik | OpenPencil | Penpot |
|
||
|----------|------------|--------|
|
||
| Wiersze kodu | **około 26 000** | **około 299 000** |
|
||
| Pliki źródłowe | około 143 | około 2 900 |
|
||
| Języki | TypeScript, Vue | Clojure, ClojureScript, Rust, JavaScript, SQL, SCSS |
|
||
| Kod renderera | około 3 200 wierszy, TypeScript | 22 000 wierszy, Rust/Skia WASM |
|
||
| Interfejs | około 4 500 wierszy | około 175 000 wierszy, CLJS i SCSS |
|
||
| Część serwerowa | Brak, architektura lokalna | 32 600 wierszy i 151 plików SQL |
|
||
| Stosunek | **1×** | **około 11×** |
|
||
|
||
OpenPencil jest około jedenaście razy mniejszy. Wynika to przede wszystkim z innej architektury, a nie tylko z mniejszej liczby funkcji.
|
||
|
||
## 2. Architektura
|
||
|
||
### OpenPencil: jeden proces klienta
|
||
|
||
```text
|
||
┌─────────────────────────────────┐
|
||
│ Tauri native shell │
|
||
│ ┌───────────────────────────┐ │
|
||
│ │ Vue 3 + TypeScript │ │
|
||
│ │ Editor + Kiwi codec │ │
|
||
│ │ SceneGraph in TypeScript │ │
|
||
│ │ CanvasKit + Yoga WASM │ │
|
||
│ └───────────────────────────┘ │
|
||
└─────────────────────────────────┘
|
||
```
|
||
|
||
Edytor, SceneGraph, kodek plików i renderer działają w jednym procesie. Oddzielny serwer, baza danych i Docker nie są potrzebne. SceneGraph jest przechowywany jako `Map<string, SceneNode>`. TypeScript wywołuje CanvasKit bezpośrednio, a Yoga WASM synchronicznie oblicza układ.
|
||
|
||
### Penpot: platforma klient-serwer
|
||
|
||
```text
|
||
┌───────────────────────────────────────────────────────┐
|
||
│ Docker Compose │
|
||
│ ClojureScript frontend │ Clojure/JVM backend │
|
||
│ Rust/Skia WASM │ PostgreSQL, Valkey, MinIO │
|
||
│ Chromium exporter │ MCP server │
|
||
└───────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
Pełna instalacja Penpota obejmuje interfejs, część serwerową JVM, PostgreSQL, Valkey, MinIO i eksporter oparty na Chromium bez interfejsu. Środowisko programistyczne wymaga Docker Compose, JVM, Node i zestawu narzędzi Rust.
|
||
|
||
OpenPencil unika opóźnień sieciowych, serializacji między usługami, zarządzania kontenerami i zapytań do bazy danych podczas zwykłych operacji. Penpot jest przeznaczony do wieloosobowej pracy na serwerze, a OpenPencil — do lokalnej edycji z małym opóźnieniem.
|
||
|
||
## 3. Potok renderowania
|
||
|
||
### OpenPencil: TypeScript → CanvasKit WASM
|
||
|
||
```typescript
|
||
renderSceneToCanvas(canvas, graph, pageId) {
|
||
this.fillPaint.setColor(...)
|
||
canvas.drawRRect(rrect, this.fillPaint)
|
||
}
|
||
```
|
||
|
||
- Bezpośrednie przejście z TypeScript do WASM.
|
||
- SceneGraph pozostaje w pamięci JavaScript i nie jest serializowany przed renderowaniem.
|
||
- Renderer liczy około 3 200 wierszy podzielonych na wyspecjalizowane moduły.
|
||
|
||
### Penpot: ClojureScript → Rust WASM → Skia
|
||
|
||
```text
|
||
ClojureScript → JavaScript
|
||
→ rozłożenie i pakowanie binarne w pamięci WASM
|
||
→ Rust WASM przez Emscripten C FFI
|
||
→ skia-safe
|
||
→ Skia/WebGL
|
||
```
|
||
|
||
Bez WASM każdy kształt jest renderowany jako element SVG DOM przez React/Reagent. W trybie WASM identyfikatory UUID, transformacje, zalewy i obwiednie są pakowane do struktur binarnych. Renderer używa pamięci podręcznej kafelków, obszarów zainteresowania, jedenastu powierzchni i globalnego zmiennego stanu przez `unsafe`.
|
||
|
||
Pamięć podręczna może przechowywać do 1024 tekstur. OpenPencil przerysowuje całą widoczną część dokumentu.
|
||
|
||
| Aspekt | OpenPencil | Penpot |
|
||
|--------|------------|--------|
|
||
| JavaScript → WASM | Bezpośrednie wywołania z obiektami TypeScript | Struktury binarne |
|
||
| Model | Pełne przerysowanie widoku | Pamięć podręczna kafelków |
|
||
| Powierzchnie | 1 | 11 |
|
||
| Dodatkowa pamięć | Brak kafelków | Do 1024 kafelków |
|
||
| Rozmiar renderera | około 3 200 wierszy | 22 000 wierszy |
|
||
| Kod niebezpieczny | Brak | Stan globalny przez `unsafe` |
|
||
|
||
Bezpośredni potok CanvasKit wymaga mniej przetwarzania pośredniego w małych i średnich dokumentach. Kafelki Penpota mogą być korzystne przy ponad 100 000 kształtów, gdy widoczny jest tylko niewielki obszar.
|
||
|
||
## 4. SceneGraph i model danych
|
||
|
||
```typescript
|
||
nodes: Map<string, SceneNode>
|
||
```
|
||
|
||
OpenPencil zapewnia wyszukiwanie po identyfikatorze w O(1), 29 typów obiektów ze schematu Kiwi, około 390 pól w `NodeChange`, ścisłe typy TypeScript i identyfikatory GUID w formacie Figma `sessionID:localID`.
|
||
|
||
Penpot utrzymuje własne definicje typów w Clojure/ClojureScript i Rust. Oddzielne moduły odpowiadają za kolory, komponenty, kontenery, zalewy, siatkę, modyfikatory, strony i ścieżki. Malli sprawdza schematy podczas działania, a dane renderowania przekraczają granicę CLJS → Rust.
|
||
|
||
## 5. Silnik układu
|
||
|
||
OpenPencil synchronicznie korzysta z Yoga WASM:
|
||
|
||
```typescript
|
||
const root = Yoga.Node.create()
|
||
root.setFlexDirection(FlexDirection.Row)
|
||
root.calculateLayout()
|
||
```
|
||
|
||
Penpot utrzymuje własne implementacje Flex i Grid w ClojureScript i Rust WASM. Oba silniki muszą zwracać ten sam wynik. OpenPencil używa Yoga, w tym odmiany z obsługą Grid; Penpot utrzymuje tysiące wierszy własnego kodu układu w dwóch językach.
|
||
|
||
## 6. Formaty i Figma
|
||
|
||
OpenPencil używa binarnego formatu Kiwi Figma, bezpośrednio importuje `.fig`, odczytuje dane Kiwi ze schowka i jest zgodny z protokołem współpracy Figma.
|
||
|
||
Plik `.penpot` to archiwum ZIP z manifestami JSON, danymi dokumentu, zasobami binarnymi i miniaturami. Penpot nie importuje `.fig` bezpośrednio i obsługuje kilka generacji formatu przez migracje.
|
||
|
||
## 7. Stan i cofanie
|
||
|
||
OpenPencil używa poleceń odwrotnych: funkcje wykonania i cofania przechowują tylko niezbędny stan, a kilka operacji można grupować.
|
||
|
||
Penpot korzysta z Potok. `UpdateEvent` zmienia stan, `WatchEvent` wykonuje skutki uboczne przez RxJS, a historia przechowuje odwrotne zestawy zmian, ogranicza się do 50 wpisów i grupuje szybkie zmiany w transakcje.
|
||
|
||
## 8. Programowanie
|
||
|
||
| Wskaźnik | OpenPencil | Penpot |
|
||
|----------|------------|--------|
|
||
| Przygotowanie | `bun install && bun dev` | Docker Compose, JVM, Node i Rust |
|
||
| Szybkie odświeżanie | Vite | shadow-cljs |
|
||
| Typy | Ścisły TypeScript | Schematy Malli podczas działania |
|
||
| Wersja komputerowa | Tauri v2 | Przeglądarka |
|
||
| Główne technologie | TypeScript i Vue | Clojure, ClojureScript, Rust i Docker |
|
||
|
||
## 9. Wydajność
|
||
|
||
| Scenariusz | OpenPencil | Penpot |
|
||
|------------|------------|--------|
|
||
| Zimny start | poniżej 2 s z WASM | ponad 10 s dla serwera, klienta i WASM |
|
||
| Zwykła operacja | W jednym procesie | Możliwa wymiana sieciowa |
|
||
| Klatka | Bezpośrednie wywołanie Skia | CLJS → JS → WASM FFI → Skia |
|
||
| Pamięć bazowa | około 50 MB w karcie | JVM, baza danych, pamięć podręczna i przeglądarka |
|
||
| Praca bez sieci | Pełna | Wymaga serwera |
|
||
| 10 000 kształtów | Jedno przejście | Renderer kafelkowy z 11 powierzchniami |
|
||
|
||
## 10. Zalety Penpota
|
||
|
||
1. **Współpraca przez serwer:** konta, kontrola dostępu i centralne przechowywanie.
|
||
2. **Eksport PDF:** oddzielny eksporter Chromium.
|
||
3. **System wtyczek:** wykonanie w izolacji i API wtyczek.
|
||
4. **Tokeny projektu:** wbudowana obsługa.
|
||
5. **CSS Grid:** własna implementacja; OpenPencil używa odmiany Yoga z Grid.
|
||
6. **Samodzielne wdrożenie:** platforma zespołowa uruchamiana przez Docker.
|
||
7. **Dojrzałość:** wiele lat użycia produkcyjnego.
|
||
|
||
## 11. Skrypty i rozszerzanie
|
||
|
||
Polecenie [`eval`](/programmable/cli/scripting) udostępnia API zgodne z Figma Plugin API dla skryptów bez interfejsu, operacji grupowych i automatycznych testów. AI Chat, serwer MCP i CLI oferują również 90 narzędzi do odczytu, tworzenia, modyfikacji, pracy ze strukturą, zmiennymi, ścieżkami wektorowymi, analizą, różnicami, operacjami logicznymi i rozmieszczaniem.
|
||
|
||
Penpot oferuje wtyczki wykonywane w izolacji, ale nie ma porównywalnego API dla skryptów bez interfejsu ani integracji MCP.
|
||
|
||
## Podsumowanie
|
||
|
||
| Obszar | Przewaga | Powód |
|
||
|--------|----------|-------|
|
||
| Prostota | OpenPencil | Jeden proces zamiast wielu usług |
|
||
| Renderowanie | OpenPencil | Bezpośredni potok CanvasKit |
|
||
| Kod | OpenPencil | Około 26 000 wobec 299 000 wierszy |
|
||
| Zgodność z Figmą | OpenPencil | Natywne Kiwi i `.fig` |
|
||
| Programowanie | OpenPencil | TypeScript i Vue zamiast Clojure, Rust i Docker |
|
||
| Aplikacja komputerowa | OpenPencil | Tauri |
|
||
| Układ | OpenPencil | Yoga zamiast dwóch własnych implementacji |
|
||
| Współpraca | Różne mocne strony | Penpot: serwer i kontrola dostępu; OpenPencil: P2P bez hostingu |
|
||
| Samodzielne wdrożenie | Penpot | Docker |
|
||
| Dojrzałość | Penpot | Wieloletnie użycie produkcyjne |
|
||
|
||
OpenPencil to zwarty edytor działający w jednym procesie, z CanvasKit i natywną obsługą `.fig`. Penpot to pełna platforma klient-serwer wykorzystująca Clojure, ClojureScript, Rust, bazy danych i usługi Docker. Oba narzędzia obsługują współpracę, ale korzystają z innych modeli.
|