Реалізація Whiteboard (спільна дошка) в мобільному додатку
При одночасному малюванні кількох користувачів на одній дошці виникають конфлікти змін. Ми вирішуємо цю проблему за допомогою CRDT (Conflict-free Replicated Data Types) — синхронізація холста в реальному часі без блокувань. Розробляємо whiteboard під ключ на Flutter або React Native з нульовою затримкою. Оцінимо ваш проєкт за один день.
Спільна дошка — нескінченний холст з об'єктами: лінії, фігури, стікери, зображення, текст. Користувачі малюють пальцями або стилусом з підтримкою pressure sensitivity, бачать дії один одного в реальному часі. На мобілі ключові виклики — пальцеве введення, pinch-to-zoom та рендеринг під навантаженням. Ми гарантуємо стабільну роботу при 100+ одночасних користувачах.
Архітектура даних: об'єктна модель холста
Кожен об'єкт на дошці — документ у distributed state. Добре підходить Y.Map, де ключ — UUID об'єкта, значення — його властивості (тип, координати, розмір, колір, z-index). Для складених об'єктів (шлях з точок) — Y.Array точок всередині об'єкта.
const yobjects = ydoc.getMap('objects'); // Додаємо стрілку yobjects.set(uuid(), { type: 'arrow', x1: 100, y1: 200, x2: 400, y2: 350, strokeColor: '#1a1a2e', strokeWidth: 2 }); Конкурентне переміщення одного об'єкта двома користувачами: Last-Write-Wins — прийнятно для координат. Конкурентне видалення об'єкта одним і зміна іншим — стандартна проблема CRDT: операція зміни застосовується до вже видаленого об'єкта і втрачається. Потрібна tombstones-логіка або тимчасове зберігання «примарних» об'єктів.
Малювання пензлем: стрімінг точок
Вільне малювання (freehand) генерує 60–120 точок на секунду на 60Hz дисплеї. Відправляти кожну точку через WebSocket — надмірно. Оптимізація:
- Буферизація — надсилаємо batch точок кожні 50ms.
- Алгоритм спрощення — Douglas-Peucker прибирає зайві точки з configurable epsilon. Крива з 500 точок стискається до 30–50 без видимої втрати якості.
- Stroke prediction — на iOS з Apple Pencil UITouch.predictedTouches передбачають наступні точки, знижуючи сприйнятну затримку.
Stroke як CRDT-об'єкт: починаємо з тимчасового Y.Array точок в Awareness (не в документі — не потрібна повна історія кожної точки). При завершенні (touchEnd) — фіксуємо спрощений шлях в документ як єдиний об'єкт. Це скорочує трафік до 90%.
Як вибрати технологію рендерингу?
Вибір стеку рендерингу залежить від платформи та вимог до продуктивності:
| Платформа | Технологія | Продуктивність | Складність |
|---|---|---|---|
| iOS Native | Metal + MetalKit | Максимальна | Висока |
| Android Native | OpenGL ES / Vulkan | Висока | Висока |
| Flutter | CustomPainter | Висока | Середня |
| React Native | react-native-skia | Середня | Середня |
React Native: react-native-skia (Skia graphics engine) — найкращий варіант для продуктивного 2D-рендерингу. @shopify/react-native-skia підтримує Path, Paint, Text, Image. react-native-svg — простіше, але повільніше для анімованих об'єктів.
Flutter: CustomPainter з Canvas API — нативний шлях. Для production використовуємо кастомний CustomPainter з dirty-region optimization (перемальовуємо лише змінену область через Canvas.clipRect).
iOS Native: Metal + MetalKit для максимальної продуктивності, UIBezierPath + CALayer для середнього рівня складності. Apple PencilKit — готовий компонент з підтримкою Pencil, але обмежена кастомізація.
Android Native: Canvas API з Path для простих випадків, OpenGL ES / Vulkan через GLSurfaceView для складних.
Віртуалізація нескінченного холста
При 1000+ об'єктах рендеринг всього холста в кожному кадрі — проблема. Потрібен spatial index (R-tree або простий grid-based) для визначення об'єктів у поточному viewport. Рендеримо лише видимі об'єкти + невеликий буфер за краями viewport. rbush — JavaScript R-tree бібліотека, працює в React Native.
Синхронізація: що відправляти і коли
Cursor/viewport awareness (позиція користувача на холсті) — через Y.js Awareness, не в документ, 10fps достатньо.
Об'єкти в процесі створення — два режими:
- Тимчасовий preview через Awareness (інші бачать незафіксований об'єкт).
- Тільки фінальний об'єкт після touchEnd (простіше, але немає real-time preview малювання).
Перший режим дає кращий UX, другий — менше трафіку та складності.
Чому CRDT, а не OT?
CRDT (Yjs) забезпечує автоматичне вирішення конфліктів без серверного координатора. OT вимагає центрального сервера для впорядкування операцій, що збільшує затримку при поганому з'єднанні. CRDT з Yjs вдвічі швидший за OT в умовах нестабільної мережі, що критично для мобільних додатків. Детальніше про CRDT та Yjs.
Як ми розробляємо whiteboard: покроково
- Аналіз вимог — визначаємо стек, опрацьовуємо об'єктну модель та сценарії синхронізації.
- Проектування архітектури — схема даних, вибір CRDT-бібліотеки (Yjs), налаштування WebSocket/WebRTC.
- Реалізація інструментів — пензель, фігури, текст, зображення з оптимізацією рендерингу.
- Інтеграція синхронізації — підключення Yjs, тестування конфліктів.
- Оптимізація продуктивності — віртуалізація холста, стиснення даних (коефіцієнт до 95% для шляхів), зниження затримки до 50 мс.
- Тестування на реальних пристроях — iOS/Android, різні версії ОС, навантаження 100+ користувачів.
- Деплой та підтримка — публікація в App Store/Google Play, документація API.
Типові помилки при реалізації whiteboard
- Нехтування стисненням шляхів — надсилання всіх точок призводить до перевантаження каналу. Використовуйте Douglas-Peucker.
- Синхронізація через OT — збільшує затримку та потребує сервер. Обирайте CRDT.
- Рендеринг всього холста — падіння FPS при 500+ об'єктах. Обов'язково впроваджуйте віртуалізацію.
- Ігнорування Apple Pencil prediction — зайва затримка на iOS.
Етапи та терміни
| Етап | Тривалість |
|---|---|
| Аналіз та проектування | 2–4 тижні |
| Розробка базового функціоналу | 6–10 тижнів |
| Просунуті інструменти (пензель, віртуалізація) | 8–16 тижнів |
| Тестування та деплой | 2–4 тижні |
Базовий whiteboard (фігури, текст, стрілки, синхронізація) на Flutter або React Native — 10–16 тижнів. З малюванням пензлем, pressure sensitivity, розумним спрощенням шляхів та віртуалізацією холста — 20–32 тижні. Вартість розраховується індивідуально залежно від складності.
Що входить у розробку whiteboard
- Документація архітектури та API.
- Вихідний код у репозиторії з CI/CD.
- Інтеграція з вашою системою аутентифікації (опціонально).
- Навчання команди замовника.
- Гарантійна підтримка 3 місяці.
Докладніше про оптимізацію рендерингу
Ми використовуємо dirty-region optimization, що дозволяє перемальовувати лише змінені ділянки холста. Це знижує навантаження на GPU та збільшує FPS.Зв'яжіться з нами для оцінки вашого проєкту. Ми підберемо оптимальний стек та запропонуємо індивідуальні терміни.







