При розробці онлайн-редактора, аналогічного Canva, часто виникають проблеми з продуктивністю: N+1 запитів при завантаженні зображень, витоки пам'яті через неправильне керування canvas, кривий експорт у SVG з втратою якості. Ми накопичили досвід вирішення цих завдань на кількох продакшн-проектах. Правильний вибір архітектури на старті економить 60% часу на налагодження.
Як розробити онлайн-графічний редактор з нуля?
Для рендерингу canvas-елементів ми використовуємо Konva.js — він доступний на GitHub. У тестах з 1000 об'єктами Konva.js показує 60 FPS, тоді як Fabric.js — близько 30. Це досягається за рахунок WebGL та шарової архітектури. Крім того, react-konva дозволяє писати декларативний код, що прискорює розробку. Порівняння характеристик:
| Характеристика | Konva.js | Fabric.js |
|---|---|---|
| FPS (1000 об'єктів) | 60 | 30 |
| Рендеринг | WebGL | Canvas 2D |
| Декларативний API | Так (react-konva) | Ні |
Як уникнути витоків пам'яті при роботі з canvas?
Витоки виникають через неочищені таймери та посилання на DOM-вузли. Ми використовуємо useEffect cleanup і обнуляємо refs при розмонтуванні компонентів. Для історії змін застосовуємо глибоке копіювання масиву elements, зберігаючи останні 50 снапшотів. Також відключаємо непотрібні обробники подій.
Архітектура стану та управління історією — розробка онлайн графічного
Центральна структура — дерево об'єктів EditorElement. Стан управляється через Zustand (бібліотека доступна на GitHub):
interface EditorElement { id: string; type: 'rect' | 'circle' | 'text' | 'image' | 'group'; x: number; y: number; width: number; height: number; rotation: number; opacity: number; zIndex: number; locked: boolean; visible: boolean; fill?: string; stroke?: string; strokeWidth?: number; text?: string; fontSize?: number; fontFamily?: string; src?: string; } interface EditorState { elements: EditorElement[]; selectedIds: string[]; canvasWidth: number; canvasHeight: number; zoom: number; history: EditorElement[][]; historyIndex: number; } Undo/Redo реалізовано через снапшоти масиву elements. При кожній зміні викликаємо commit, зберігаючи поточний стан. Гарячі клавіші: ctrl+z для undo, ctrl+shift+z для redo, ctrl+d для дублювання.
Робота з контентом: завантаження зображень і текст
Завантаження зображень
Зображення завантажуються в S3-сумісне сховище через API-ендпоінт. На сервері використовується Sharp для ресайзу до 2000px по більшій стороні та конвертації в JPEG з якістю 85%. Це знижує розмір файлу на 40% без видимої втрати якості. На клієнті підтримується drag-and-drop та вставка з буфера обміну.
Текстовий редактор
Текст редагується по подвійному кліку — поверх canvas показується textarea для введення. Після завершення введення текст рендериться як елемент Konva.Text. Підтримуються базові стилі: розмір, шрифт, жирність, колір. Для більш складного форматування (списки, вирівнювання) використовуємо окремий компонент на основі Lexical.
Експорт і збереження: формати та шаблони
Експорт. Підтримується експорт у PNG, JPEG (з якістю 0-1) та SVG. Для PNG/JPEG використовуємо stage.toDataURL з pixelRatio=2 для ретина-дисплеїв. SVG експортуємо через ручну серіалізацію масиву elements у SVG-рядок. На запит додаємо PDF (через jsPDF) та WebP.
Збереження і шаблони. Дизайн серіалізується в JSON і зберігається на сервері кожні 30 секунд (автозбереження). Прев'ю генерується через stage.toDataURL з pixelRatio=0.2. Шаблони зберігаються окремо як набори elements з прив'язкою до користувача. При завантаженні шаблону elements копіюються в поточний дизайн.
Типові помилки та їх вирішення
| Проблема | Рішення |
|---|---|
| N+1 запитів при завантаженні зображень | Завантажувати пачками через один запит |
| Витоки пам'яті | Очищати обробники та таймери в useEffect |
| Кривий експорт SVG | Використовувати спеціалізовані бібліотеки серіалізації |
| Ігнорування шарів | Враховувати zIndex та видимість |
| Відсутність лінивого завантаження | Використовувати прев'ю та підвантаження на вимогу |
Процес тестування
Ми використовуємо інтеграційні тести з Puppeteer для перевірки експорту та взаємодії з canvas. Кожен коміт проходить перевірку на витоки пам'яті через Chrome DevTools Heap Snapshot.Процес розробки: покроково
- Аналіз вимог і проектування архітектури.
- Налаштування canvas і реалізація базових фігур (прямокутник, коло, лінія).
- Додавання тексту та зображень із завантаженням.
- Реалізація undo/redo та гарячих клавіш.
- Робота з шарами (порядок, видимість, блокування).
- Експорт у PNG, JPEG, SVG і збереження в JSON.
- Інтеграція з бекендом, налаштування автозбереження та шаблонів.
- Тестування і оптимізація продуктивності.
Що входить у результат?
- Вихідний код фронтенду та бекенду з документацією.
- Розгорнутий редактор на вашому сервері або в хмарі.
- Навчання вашої команди (2-3 сесії).
- Гарантія на код 6 місяців та підтримка протягом цього терміну.
- Інструкції з експлуатації та налаштування.
Отримайте консультацію по вашому проекту — ми оцінимо складність та запропонуємо оптимальне рішення. Замовте розробку редактора під ключ і отримайте сучасний інструмент для вашого бізнесу.







