# 性能
Chart.js 图表渲染在 canvas
元素上,这使得渲染非常快。对于大型数据集或对性能敏感的应用程序,您可能需要考虑以下提示。
# 数据结构和格式
# 解析
提供数据集和比例尺接受的内部格式的准备数据,并设置 parsing: false
。有关更多信息,请参见 数据结构。
# 数据归一化
如果您提供具有唯一、排序且跨数据集一致的索引的数据,Chart.js 将最快。提供 normalized: true
选项以让 Chart.js 知道您已执行此操作。即使没有此选项,提供排序数据有时仍然更快。
# 抽取
抽取您的数据将获得最佳效果。当图表上有大量数据要显示时,在只有几百像素宽的图表上显示数万个数据点是没有意义的。
抽取插件 可与折线图一起使用,在渲染图表之前抽取数据。这将提供最佳性能,因为它将减少渲染图表所需的内存。
折线图能够在满足某些条件时进行 绘制期间自动数据抽取。您仍然应该考虑在传递数据之前自己抽取数据以获得最大性能,因为自动抽取发生在图表生命周期的后期。
# 刻度计算
# 旋转
通过将 minRotation
和 maxRotation
设置为相同的值来 指定旋转值,这避免了图表必须自动确定要使用的值。
# 采样
设置 ticks.sampleSize
选项。这将通过仅查看标签的子集来确定标签的大小,从而更快地渲染轴。如果标签的大小没有很大的差异,这最有效。
# 禁用动画
如果您的图表渲染时间很长,最好禁用动画。这样做意味着图表在更新时只需要渲染一次,而不是多次。这将减少 CPU 使用率并提高整体页面性能。当禁用动画且 Path2D 可用时,折线图使用 Path2D 缓存。
要禁用动画
new Chart(ctx, {
type: 'line',
data: data,
options: {
animation: false
}
});
# 为比例尺指定 min
和 max
如果您指定 min
和 max
,则比例尺不必从数据中计算范围。
new Chart(ctx, {
type: 'line',
data: data,
options: {
scales: {
x: {
type: 'time',
min: new Date('2019-01-01').valueOf(),
max: new Date('2019-12-31').valueOf()
},
y: {
type: 'linear',
min: 0,
max: 100
}
}
}
});
# 使用 Web 工作线程进行并行渲染(仅限 Chromium)
Chromium(Chrome:版本 69,Edge:79,Opera:56)添加了 将画布的渲染控制权转移到 Web 工作线程 (在新窗口中打开) 的功能。Web 工作线程可以使用 OffscreenCanvas API (在新窗口中打开) 从 Web 工作线程渲染到 DOM 中的画布。Chart.js 是一个基于画布的库,支持在 Web 工作线程中渲染 - 只需将 OffscreenCanvas 传递给 Chart 构造函数,而不是 Canvas 元素。请注意,截至目前,此 API 仅在基于 Chromium 的浏览器中受支持。
通过将所有 Chart.js 计算移到一个单独的线程,主线程可以腾出用于其他用途。在 Web 工作线程中使用 Chart.js 时的一些提示和技巧
- 在线程之间传输数据可能很昂贵,因此请确保您的配置和数据对象尽可能小。如果您能做到的话,请尝试在工作线程端生成它们(工作线程可以发出 HTTP 请求!)或将它们作为 ArrayBuffers 传递给您的工作线程,这些 ArrayBuffers 可以快速地在线程之间传输。
- 您不能在线程之间传输函数,因此如果您的配置对象包含函数,您必须在传输之前将它们剥离,然后在之后添加回来。
- 您无法从工作线程访问 DOM,因此使用 DOM 的 Chart.js 插件(包括任何鼠标交互)可能无法正常工作。
- 如果支持除最现代的 Chromium 浏览器之外的浏览器,请确保您有备用方案。
- 必须手动调整图表大小。请参见下面工作线程代码中的示例。
主线程代码示例
const config = {};
const canvas = new HTMLCanvasElement();
const offscreenCanvas = canvas.transferControlToOffscreen();
const worker = new Worker('worker.js');
worker.postMessage({canvas: offscreenCanvas, config}, [offscreenCanvas]);
工作线程代码示例,在 worker.js
中
onmessage = function(event) {
const {canvas, config} = event.data;
const chart = new Chart(canvas, config);
// Resizing the chart must be done manually, since OffscreenCanvas does not include event listeners.
canvas.width = 100;
canvas.height = 100;
chart.resize();
};
# 折线图
# 保持贝塞尔曲线禁用
如果您在图表上绘制线条,禁用贝塞尔曲线将提高渲染时间,因为绘制直线比绘制贝塞尔曲线性能更高。贝塞尔曲线默认情况下处于禁用状态。
# 绘制期间自动数据抽取
当 tension
、stepped
和 borderDash
保持设置为其默认值(分别为 false
、0
和 []
)时,线条元素将自动抽取数据。这通过跳过绘制不可见的线段来提高渲染速度。
# 启用 spanGaps
如果您有很多数据点,启用 spanGaps
可能性能更高。这会禁用线条的分段,这可能是多余的步骤。
要启用 spanGaps
new Chart(ctx, {
type: 'line',
data: {
datasets: [{
spanGaps: true // enable for a single dataset
}]
},
options: {
spanGaps: true // enable for all datasets
}
});
# 禁用线条绘制
如果您有很多数据点,禁用数据集的线条渲染并仅绘制点可能性能更高。这样做意味着画布上绘制的内容更少,这将提高渲染性能。
要禁用线条
new Chart(ctx, {
type: 'line',
data: {
datasets: [{
showLine: false // disable for a single dataset
}]
},
options: {
showLine: false // disable for all datasets
}
});
# 禁用点绘制
如果您有很多数据点,禁用数据集的点渲染并仅绘制线条可能性能更高。这样做意味着画布上绘制的内容更少,这将提高渲染性能。
要禁用点绘制
new Chart(ctx, {
type: 'line',
data: {
datasets: [{
pointRadius: 0 // disable for a single dataset
}]
},
options: {
datasets: {
line: {
pointRadius: 0 // disable for all `'line'` datasets
}
},
elements: {
point: {
radius: 0 // default to disabled in all datasets
}
}
}
});
# 使用 Babel 进行转译时,请考虑使用 loose
模式
Babel 7.9 改变了类构造的方式。除非与 loose
模式一起使用,否则它很慢。 更多信息 (在新窗口中打开)