# 效能
Chart.js 圖表會在 canvas
元素上渲染,這使得渲染速度相當快。對於大型資料集或對效能敏感的應用程式,您可能需要考慮以下提示。
# 資料結構與格式
# 解析
以資料集和刻度接受的內部格式提供準備好的資料,並設定 parsing: false
。請參閱資料結構以了解更多資訊。
# 資料正規化
如果您提供的資料具有唯一、排序且在各資料集之間一致的索引,並且提供 normalized: true
選項讓 Chart.js 知道您已完成此操作,則 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 Worker 進行平行渲染(僅限 Chromium)
Chromium (Chrome:版本 69,Edge:79,Opera:56) 新增了將畫布的渲染控制權轉移 (開啟新視窗)給 Web Worker 的功能。Web Worker 可以使用 OffscreenCanvas API (開啟新視窗)從 Web Worker 渲染到 DOM 中的畫布上。Chart.js 是一個基於畫布的程式庫,並支援在 Web Worker 中進行渲染 - 只需將 OffscreenCanvas 傳遞到 Chart 建構函式中,而不是 Canvas 元素。請注意,截至目前,此 API 僅在基於 Chromium 的瀏覽器中受支援。
透過將所有 Chart.js 計算移至單獨的執行緒,可以將主執行緒釋放以用於其他用途。在 Web Worker 中使用 Chart.js 時的一些提示和技巧
- 在執行緒之間傳輸資料可能很昂貴,因此請確保您的配置和資料物件盡可能小。盡可能在 Worker 端產生它們(Worker 可以發出 HTTP 請求!),或將它們以 ArrayBuffer 的形式傳遞給您的 Worker,這樣可以快速地在一個執行緒和另一個執行緒之間傳輸。
- 您無法在執行緒之間傳輸函式,因此如果您的配置物件包含函式,您必須在傳輸之前將它們移除,然後稍後再將它們新增回去。
- 您無法從 Worker 執行緒存取 DOM,因此使用 DOM 的 Chart.js 外掛(包括任何滑鼠互動)可能無法運作。
- 如果您支援除了最新 Chromium 瀏覽器以外的其他瀏覽器,請確保您有後備方案。
- 必須手動調整圖表大小。請參閱以下 Worker 程式碼中的範例。
主執行緒程式碼範例
const config = {};
const canvas = new HTMLCanvasElement();
const offscreenCanvas = canvas.transferControlToOffscreen();
const worker = new Worker('worker.js');
worker.postMessage({canvas: offscreenCanvas, config}, [offscreenCanvas]);
Worker 程式碼範例,在 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();
};
# 折線圖
# 保持 Bézier 曲線停用
如果您在圖表上繪製線條,停用 Bézier 曲線將縮短渲染時間,因為繪製直線比 Bézier 曲線更有效能。Bézier 曲線預設為停用。
# 繪製期間自動數據抽樣
當 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
模式一起使用,否則速度會很慢。更多資訊 (開啟新視窗)