Как стать автором
Обновить

Делаем схему выбора мест в кинозале на React: о canvas, красивом дизайне и оптимизации

Время на прочтение6 мин
Количество просмотров23K
Всего голосов 54: ↑54 и ↓0+54
Комментарии30

Комментарии 30

>>Konva, PixiJS и Phaser
Можно еще упомянуть FabricJS (есть 4 статьи на хабре). Делал на нем графический калькулятор — для новичков в целом неплох. При выборе как раз отказался от Pixi, что также показалось, что заточен под игры.
FabricJS:
+: полно разных ответов/вопросов, потихоньку развивается, есть поясняющие статьи.
-: документация «не очень».
Спасибо, интересная либка! добавил упоминание

Вставляйте код текстом, пожалуйста!

Обязательно исправлюсь)

А почему не WebGL, разве там не должно быть еще больше производительность?

Pixi автоматически использует WebGL в современных браузерах. Canvas2d в старых.
Но опять же, такое более актуально для игр где много чего происходит на экране. Или для красивых 3D анимаций. Для статичных схем как у нас вся мощь WebGL не раскрывается. Поэтому подкапотные оптимизации от Pixi — скорее приятный бонус)

Минусы:
Не получится совместить с Server Side Rendering.

Почему это минус?
Выбор места на канвасе — это не контент. Это функционал. Ему не нужно индексироваться.

Привет. Сейчас поясню. Для нас тут дело не в индексации поисковиками.


Есть случаи, когда пользователь сразу открывает страницу где должна быть схема. И при этом схема сразу во вьюпорте. Но, так как SSR на неё нет, то ему приходится ждать прогрузки js-кода и инициализации.


Это, конечно, для кого-то и не минус, но мы на tinkoff.ru стараемся по максимуму отрисовывать на сервере то, что пользователь может увидеть сразу. Чтобы у пользователя был более плавный UX. Поэтому я и записал это в минусы.

Так что мешает на сервере нарисовать все на HTML/SVG, а когда загрузится JS, то зареплейсить HTML/SVG на Canvas? Если уж вы так сильно заморочены на этом и для вас это минус.
что мешает

К сожалению, ресурсы разработки не бесконечные. Приходится искать компромиссы.
В идеальном мире можно было сразу все идеально сделать)

Возможно, это будет одной из доработок на будущее ;)
К сожалению, ресурсы разработки не бесконечные.

Ах ну понятно))
Значит SSR для вашего кейса все таки не нужен. И его отсутствие минусом то не является)
Я не понимаю как то, что мы решили не делать SSR для схемы должно отменять этот «минус»? По моему мнению, эти факты между собой не связаны и не взаимоисключающие. Можешь пояснить подробнее?
Ну смотрите, есть минус, как бы минус настоящий, то есть вещь серьезная, ощутимая, реальный недостаток.
А есть «минус», ну как бы такое, высосанное из пальца, и названо минусом так чисто ради придирки.

Допустим есть у меня машина и вот лично мой экземпляр кушает на 0.1 литра на 100 км больше, чем у остальных, ну вот прямо где-то просочился малюсенький такой дефект, так вот, это можно назвать «минусом» который именно в кавычках и высосанный из пальца. И если переложить ещё сильнее на вашу статью, то при этом, она быстрее чем у всех остальных скажем на 50% разгоняется, двигатель работает ровнее, масло не поджирает, но есть вот у нее «минус», на 0.1 литра она все таки больше съедает на 100ку.

И вот дилема, можно ли называть это минусом вообще?) Или же все таки это минус чисто по приколу, не имеющий отношения к реальному недостатку?)

А теперь представьте, что она бы теперь кушала в 3 раза больше бензина чем остальные, но при этом все так же на 50% разгонялась быстрее, и вот тут уже этот минус ощутим и осязаем по настоящему, т.к. 10 литров и 30 литров очень большая разница, даже с учетом выигрыша по разгону.

Ах да, вы же написали
Не получится совместить с Server Side Rendering.

Но самом деле то получается, ещё как, просто вам лень) Потому что есть SSR в вашем кейсе или нет, роли реальной вообще никак для пользователя не сыграет.

Я понял, с вашей точки зрения это не минус, но сравнения с машинами меня все равно не убедило убрать это из статьи.


просто вам лень

Я не знаю как тут на Хабре принято. Но это уже явно переход границы профессионального общения.


Если хочется ещё поговорить, я предлагаю созвониться и поболтать голосом)

меня все равно не убедило убрать это из статьи.

Не получится совместить с Server Side Rendering

Это утверждение не верно. Почему это вас не убеждает убрать это из статьи? Или изменить текст, на «совместить с Server Side Rendering можно в паре с HTML/SVG/Canvas to PNG и при загрузке JS реплейснуть на canvas для большей производительности и отзывчивости»
Но это уже явно переход границы профессионального общения.

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

Человек делится результатами своей работы, а вы даете личную оценку человеку, это и есть нарушение этики профессионального общения. Личная оценка человека это уже точно не конструктивная критика к этой статье

Какие мы нежные и находимся в королевском Английском обществе с зашкаливающем этикетом.
Так может лучше вообще статьи не писать и вообще ни с кем не разговаривать? А то вдруг кто-то не будет восхищаться тем, что ты пишешь или говоришь.
Специально хотите кого-то задеть? В чем ваша проблема? Не пишите комментарии тогда, а я не буду писать статьи. На том и порешим.
Можно на коленке «накостылять» SSR canvas в png безголовым браузером, как временное решение — особых человекочасов не понадобится, а потом уже написать генератор SVG по тем данным, по которым у вас рисуется зал.
Да, конечно, можно! Но, мы были ограничены в сроках и ресурсах, поэтому рассматривали больше именно варианты «из коробки», нежели собственную разработку.

Но, движения в сторону новых схем есть. Решим проблемы и обязательно напишем про это ещё одну статью)
Не получится совместить с Server Side Rendering

Разве в такого рода специфических страницах/проектов это так необходимо и можно отнести к минусам?

А как в итоге задачу решили? Что видит пользователь, пока загружается pixi и react-pixi-fiber (это уже 150Кб минимум), плюс еще ваш код?

JS-код схемы (код компонента + либы) мы получаем отдельным асинхронным чанком и у нас отдельные бандлы на разные страницы, поэтому пока схема не понадобится для показа — браузер не грузит этот код. Пользователь видит скелетон схемы.

За статью конечно спасибо! Давно ждал нечто подобного, что кто-то возьмет, и сделает это: скрестит React и Canvas. В добавок тема отрисовки концертных залов мне знакома (фулстек разработчик Myslo-кассы).


Года 4 назад нужно было создать инструмент, для продажи билетов. Тоже был выбор SVG или canvas. Делать на чистом HTML не рассматривал как вариант, потому что там ожидали проблема с масштабированием. В тот момент как раз Павел Дуров устраивал как раз конкурс на отрисовку графиков, и там как раз в чатах была борьба, какой механизм отрисовки лучше: SVG или canvas. SVG проиграл. Поэтому я выбрал canvas.


Я выбрал делать на canvas в нативе (canvas 2D). На тот момент образцом для подражания была афиша яндекса с монстуозной схемой. У нее был только один минус -все очень сильно тормозило. Одним из требований было то что это все должно работать очень быстро. В итоге, выбор сектора были сделан на SVG, а выбор мест на canvas (пример можно посмотреть тут как работает схема зала).


Нюансы при отрисовки:


  1. Не отрисовывать места которые выходят за пределы области canvas
  2. Не делать лишних перерендеров, перерендер выполняется только по внешнему событию: перемещение схемы, изменение масштаба, изменение размера страницы.
  3. FPS при отрисовки схема должен быть 60 кадров в секунду!

Пожалуй FPS было самым главным требованием! Да, схема зала получилась очень простой, но отрисовка мест происходит очень быстро.


Выводы которые сделал я:


  1. SVG — это максимум 1000 элементов в DOM дереве — все остальное медленно.
  2. canvas — отрисовка в 5000 областей за раз не вызывает просидания FPS. Все что больше требует принятия дополнительных мер: дробить цикл на кадры, кеширование областей.
  3. Избегать отрисовки больше 1000 мест на одном экране.

Я решил посмотреть как это работает на вашем сайте, на примере этого мероприятия. Сразу пройдусь по багам которые заметил:


  1. Шаг изменения масштаба зала происходит очень резко: есть вариант с выводом всего зала и сразу с супер увеличением.
  2. Из 2 вытекает проблема что если нужно выбрать место с краю, нужно drug&drop-ом двигать схему зала. И тут конечно заметно просидание FPS по отрисовки на Core i5! По ощущению, ну кадров 5 в секунду (Firefox, в хроме лучше).
  3. Меняем размер страницы и все зависает, а потом загружается начальная страница.
  4. Запаздывающий эффект наведения.
  5. Возможность выбора мест на начальной схеме зала без увеличения масштаба. Каждое место на экране занимает ровно 3 пикселя. Я не думаю что это удобный способ выбора мест. Тем более в этом режиме однозначно будут просидания в производительности

Низкий FPS

Запаздывающий эффект наведения

Выбор мест на начальной схеме зала

Выводы:


  1. В целом конечно видно, что все еще очень сырое. Вчера выкатили, а сегодня написали статью. Этот комментарий я хотел написать еще вчера, но я просто не мог не посмотреть как работает схема потому что она просто падала, с ошибкой связаной с booking. Схема зала не работала не в одном из опробованных браузеров.
  2. Мне кажется Pixi нужно менять на что-то другое (возможно свое). Возможно стоит делать отрисовку только на canvas 2D, раз 3D не используется. Canvas отрисовку нужно хорошенько кешировать, тогда она будет работать быстро.
  3. За React нужно конечно тщательно следить, потому что с ним очень просто наделать кучу лишних перерендеров.
  4. На счет максимального кол-ве мест в зале — нужно было выбирать олимпийский — и пытаться отрисовать их 3 на одном экране. Здесь конечно, мне кажется, нужно использовать какой то механизм создания контура секторов исходя из координат мест, и на большой схеме показывать только эти контуры, а при увеличении уже подгружать места для секторов. Тогда не будет проблемы отрисовки больше 1000 мест на одном экране и показ первого экрана станет быстрее. В своей реализации, я пытался тоже сделать механизм автоматического создания контуров, но потом счет это слишком сложной задачей.
У меня всё это дело вообще очень долго прогружается и нет возможности увеличить/уменьшить.
Напиши в личку что за браузер и ОС.
Спасибо за огромный комментарий! Кажется, тебе стоит и самому написать статью про такие схемы)

И спасибо большое за баг-репорты и советы!

Сам столкнулся с canvas в реакте. Нужно было сделать линейный график для криптовалют в реальном времени. В принципе сделал его на нативном канвасе, но переодически выскакивают проблемы производительностью возникают. Тоже задумался прикрутить библиотеку какую. Можете посоветовать?

Привет. Я не эксперт в области либ по канвасу)
Можешь посмотреть приведенные в статье, попробовать накидать по прототипу на каждой и сравнить. Линейный график — достаточно распространенная визуализация, возможно, у каждой либы есть уже готовый компонент/код для такого.

Вообще, раз уже есть написанное решение, я бы посоветовал сначала попрофилировать код. Возможно, всплывут узкие места, которые связаны не с самой отрисовкой на канвасе, а с чем нибудь другим.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий