Оптимизация производительности для response-native-canvas при рисовании множества путей - PullRequest
0 голосов
/ 02 марта 2020

Я хочу отразить отображение аналогового сегмента в моем приложении React Native. Сегментный дисплей довольно сложный, он состоит из более чем 100 различных сегментов. Он содержит три 7-сегментных дисплея для чисел и индикатор выполнения с 20 элементами. Остальные являются пользовательскими формами и символами, которые предоставляют информацию о текущем состоянии машины, к которой он подключен. У меня есть некоторый опыт работы с HTML canvas, я нашел модуль React Native response-native-canvas и хотел попробовать его. Тем не менее, рисование на реагирующем холсте кажется довольно медленным по сравнению с холстом HTML, который я могу использовать в веб-браузере.

Вот что я делаю:

  1. Я импортирую модуль в свой компонент:

import Canvas, {Image as CanvasImage, Path2D, ImageData} from 'react-native-canvas';

Добавить элемент холста в мою функцию рендеринга:

<Canvas ref={this.handleCanvas}/>

Сохраните ссылку на холст и установите его размер:
handleCanvas = (canvas) => {
    if (this.myCanvas === null && canvas !== null){
      canvas.width = 250;
      canvas.height = 250;
      this.myCanvas = canvas;
    }
  }
Затем я могу вызвать для каждого сегмента функцию «рисования», которая использует aws 2D-путь:
draw(ctx){
  ctx.save();
  ctx.strokeStyle="#000000";
  ctx.lineWidth=2;
  ctx.lineJoin="round";
  ctx.font="   10px sans-serif";
  ctx.beginPath();
  ctx.moveTo(158.108112514019,24.324327290058136);
  ctx.lineTo(159.45946389436722,24.324327290058136);
  ctx.lineTo(160.13513958454132,25.67567867040634);
  ...
  ctx.lineTo(162.16216665506363,25.00000298023224);
  ctx.fill("nonzero");
  ctx.stroke();
  ctx.restore();
}

Я получаю контекст, подобный этому: var ctx = this.myCanvas.getContext('2d');

Я сделал прототип с 13 сегментами. Каждый сегмент имеет около 50 узлов, и я рисую все 13 сегментов одновременно. В моем приложении React Native рисование занимает почти одну секунду, что слишком медленно (и есть еще 90 сегментов, которые я еще не рендерил ...). Если я нарисую те же пути на холсте HTML в Google Chrome, это займет всего 2-5 миллисекунд.

У кого-нибудь есть идеи, как я могу улучшить производительность? Или есть другая библиотека, которая более производительна для моих целей? `

Заранее спасибо!

Ответы [ 2 ]

1 голос
/ 20 марта 2020

Iddans ответ был правильным, так как я не могу опубликовать подробное решение о том, как именно мы решили проблему в качестве комментария к его ответу, я отправляю новый ответ сам.

Как сказал Iddan, правильный Решение было действительно минимизировать количество инструкций, отправляемых на холст. Мы изменили пункт 4 моего вопроса. Вместо непосредственного рисования пути с помощью операторов ctx.lineTo(...) мы извлекли все пути SVG в виде строк и сохранили их в массиве:

const svgPaths = [
   'M713.33,497.34a38.67 ... ',
   ...
]

Для каждого цикла рендеринга мы решаем, какое подмножество всех путей SVG мы Если вы хотите рендериться и сохранить их в новом массиве, мы создаем один объект Path2D со всеми желаемыми путями SVG

const svgPathsSubset = [svgPaths[1], svgPaths[7], ... ]
const pathToRender = new Path2D(this.myCanvas, svgPathsSubset)
const ctx = this.myCanvas.getContext('2d')
ctx.fill(pathToRender)

Это очень быстро и занимает всего несколько миллисекунд.

0 голосов
/ 06 марта 2020

спасибо за размещение вашего вопроса с такими подробностями. React Native Canvas довольно медленный по сравнению с HTML canvas, поскольку каждая инструкция передается в WebView. Один из возможных способов улучшить производительность, о котором я могу подумать, - это использовать Path2D , поскольку объект содержит несколько инструкций перед его рендерингом. Можете ли вы попробовать это и проверить, не улучшило ли это производительность?

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