绘制多条路径时react原生画布的性能优化



我想在我的React Native应用程序中镜像模拟段显示。分段显示相当复杂,它由100多个不同的分段组成。它包含三个7段数字显示和一个包含20个元素的进度条。剩下的是自定义形状和符号,它们提供了有关它所连接的机器的当前状态的信息。我对HTML画布有一些经验,找到了React Native模块React Native画布,并想尝试一下。然而,与我可以在web浏览器中使用的HTML画布相比,在react原生画布上绘制似乎相当慢。

我是这样做的:

  1. 我在组件中导入模块:

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

  1. 将画布元素添加到我的渲染函数中:

<Canvas ref={this.handleCanvas}/>

  1. 存储对画布的引用并设置其大小:
handleCanvas = (canvas) => {
if (this.myCanvas === null && canvas !== null){
canvas.width = 250;
canvas.height = 250;
this.myCanvas = canvas;
}
}
  1. 然后我可以为每个段调用一个绘制2D路径的"draw"函数:
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多个片段我还没有渲染…(。如果我在谷歌Chrome上的HTML画布上绘制相同的路径,只需要2-5毫秒。

有人知道我该如何提高表现吗?或者有没有另一个图书馆对我来说更具表演性?">

提前感谢!

Iddans的答案是正确的,因为我不能发布我们如何准确解决问题的详细解决方案作为对他的答案的评论,所以我自己发布了一个新的答案。

正如Iddan所说,正确的解决方案确实是尽量减少发送到画布上的指令数量。我们改变了我问题的第4点。我们没有直接用ctx.lineTo(...)语句绘制路径,而是将所有SVG路径提取为字符串并存储在一个数组中:

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

对于每个渲染周期,我们决定要渲染所有SVG路径的哪个子集,并将它们存储在一个新的数组中,然后我们创建一个包含所有所需SVG路径的单个Path2D对象

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

这非常快,只需要几毫秒。

感谢您发布如此详细的问题。与HTML画布相比,React Native Canvas相当慢,因为每条指令都被传递到WebView。我能想到的一种提高性能的潜在方法是使用Path2D,因为对象在渲染之前包含多个指令。你能试试看它是否提高了性能吗?

最新更新