SciChart.js JavaScript 2D Charts API > Performance Tips > Performance Tips & Tricks
Performance Tips & Tricks

SciChart.js is a High Performance WebGL / WebAssembly chart library. Out of the box SciChart.js can achieve incredible performance vs. other JavaScript Chart Libraries on the market, capable of rendering millions of datapoints. However, if you want to get the best possible performance out of SciChart.js then read on!

DataSeries Optimisations

Data is Sorted in X (TimeSeries Data) is Faster than Unsorted (Scatter Data)

SciChart.js uses a number of optimised algorithms when your data is sorted in the X-direction.

Algorithms such as Hit-Test (used by cursors, tooltips), indexing and drawing have a faster path when the data is sorted in X vs. unsorted.

We recommend to ensure time-series data is sorted in X for the best performance, but SciChart.js will still draw charts with big data with unsorted (scatter) data just fine!

Specify Data Distribution & Properties

SciChart will automatically detect the distribution of your data & properties to choose the right algorithms for fastest and most accurate drawing. For example, properties that SciChart detects include:

  • Data is Sorted in X direction
  • Data contains NaN (Not a Number)
  • Data spacing in X is evenly spaced

These properties allow us to choose the best & fastest algorithms for drawing, but detecting these properties takes some CPU time.

You can tell SciChart.js these properties in advance to save the time when creating dataseries, and appending and updating data.

const count = 1_000_000;
const xValues = Array.from(Array(count).keys());
const yValues = Array.from(Array(count).keys());

// Test 1: Create DataSeries with 1 Million points without flags
console.time("create series 1M points without Flags");
const series = new XyDataSeries(webAssemblyContext, { xValues, yValues });
console.timeEnd("create series 1M points without Flags");

// Test 2: Create DataSeries with 1 Million points with flags
console.time("create series 1M points with Flags");
const series2 = new XyDataSeries(webAssemblyContext, {
    xValues,
    yValues,
    dataIsSortedInX: true,
    dataEvenlySpacedInX: true,
    containsNaN: false
});
console.timeEnd("create series 1M points with Flags");
// Results
//
// Time to create 1 Million points without flags: 55ms
// Time to create 1 Million points with flags specified: 11ms

 

Specify Data Distribution properties containsNaN, dataSortedInX, dataEvenlySpacedInX when creating a DataSeries to save CPU time. Note you will need to update these flags if the data properties change.

Enable Resampling

We've enabled drawing optimisations which allow for faster rendering / drawing path in Line, Column, Candlestick, Mountain and Band Series by using data-point resampling.

Set the property FastLineRenderableSeries.resamplingMode = EResamplingMode.Auto to take advantage of this faster drawing path.

import { SciChartDefaults, EResamplingMode  } from "scichart";
// Creates a line series and explicitly enables resampling (default is AUTO)
const lineSeries = new FastLineRenderableSeries(wasmContext, { resamplingMode: EResamplingMode.Auto} );

// Disables resampling
lineSeries.resamplingMode = EResamplingMode.None;

// Enable or disable globally
SciChartDefaults.enableResampling = false;

Set the property FastLineRenderableSeries.resamplingMode = EResamplingMode.Auto to enable new drawing optimisations. Note this property is enabled by default.

To read further about this property see the page on Data Resampling.

 

Batch Updates to DataSeries

SciChart DataSeries have functions like append(), insert(), update(), removeAt() where you can modify the data that the chart is showing. This allows you to achieve real-time updates in SciChart.

It is faster to update the DataSeries in batches aka using functions appendRange(), insertRange(), removeRange() where you modify an array of data than to use single-point changes.

// Test 1: Append 100k points one at a time
const series = new XyDataSeries(webAssemblyContext, { dataIsSortedInX: true, containsNaN: false });
const count = 100_000;
console.time("dataseries.append(x,y) 100k points");
for (let i = 0; i < count; i++) {
    series.append(i, i);
}
console.timeEnd("dataseries.append(x,y) 100k points");
// Test 2: Append 100k points using AppendRange
const series2 = new XyDataSeries(webAssemblyContext, { dataIsSortedInX: true, containsNaN: false });
const xValues: number[] = Array.from(Array(count).keys());
const yValues: number[] = Array.from(Array(count).keys());
console.time("dataseries.appendRange(xValues,yValues) 100k points");
series.appendRange(xValues, yValues);
console.timeEnd("dataseries.appendRange(xValues,yValues) 100k points");

// Results
//
// Append(x,y) 100,000 times: 69ms
// AppendRange(xValues, yValues) with 100,000 points: 1ms
appendRange(), insertRange() and removeRange() are much more performant than append(), insert() and remove(). This performance difference is more noticeable with insert & remove.

Initialize DataSeries with Capacity

Internally, SciChart DataSeries use a geometric resizing algorithm which reserves more memory than needed as you call append(), appendRange(). Starting with a new DataSeries and calling .append() many times may result in several resizes of the underlying vector as the DataSeries grows.

To avoid this, and reduce unnecessary allocations, if the size is known ahead of time you can initialize a DataSeries with capacity.

const dataSeries = new XyDataSeries(wasmContext, {
    capacity: 10000 // Reserves memory for 10,000 elements
});

Multi Chart Optimisations

Use One WebGL Context per SciChartSurface

The function SciChartSurface.create() uses a single shared WebGL context for all chart surfaces. This allows us to have multiple charts (up to hundreds of charts) in a single webpage.

The function SciChartSurface.createSingle() creates one WebGL Context per SciChartSurface. This gives faster drawing performance but will quickly hit the limit of WebGL contexts in a webpage.

Approximate WebGL Context Limits per browser can be found below.

Browser Max WebGL Contexts per Page
Firefox (Windows, macOS) 300
Chrome (Windows, macOS)

16

Edge (Windows) 16
Safari (macOS) 16
Safari (iOS) 16
Chrome (Android) 8
Individual WebGL contexts per SciChartSurface will give faster performance than a shared WebGL context. This is more noticeable in FireFox or Safari than Chrome which performs very well for shared WebGL contexts.

Sharing WebGL Drawing with SubCharts

TODO SUBCHARTS

 

Text Label Optimisations

Native Text Labels

TODO NATIVE TEXT

Shared Label Cache

Previously labels were cached per axis, but it is now possible to reuse cached labels across axes and across charts. This improves label drawing performance in multi-chart scenarios.

You can enable this globally by setting:

SciChartDefaults.useSharedCache = true;

Or you can enable it for a particular axis by setting useSharedCache = true on the axis options, or directly on the axis labelProvider.

This will give significant benefit if you have multiple charts with very similar sets of labels, even if they are not on screen at the same time. Labels are retained in the cache for a minute, so switching to a different chart that has some or all of the same labels will reuse the labels, saving a few hundred ms.

Using shared label cache gives significant performance benefits if you have multiple charts with very similar sets of labels, even if they are not on screen at the same time.
useSharedCache is not enabled by default. If you are overriding getLabelTexture, it is important to ensure that the combination of text and label style is unique for each label texture. See the documentation for getLabelTexture for some ways to handle this.

Async Labels

Async labels was available in earlier versions of ScIChart.js, but has been deprecated in favour of Native text labels below.

 

Misc Optimisations

Use the Fastest Browser!

By far, the fastest browser for WebGL, WebAssembly and JavaScript is Google Chrome.

Browsers such as Safari, Firefox have slower execution of JavaScript code. Please bear this in mind when comparing performance or when making recommendations to your customers!

Use Google Chrome for the best performance with SciChart.js

Retina macOS Performance

When SciChart.js is used on a high resolution display such as Retina, the chart will be rendered at 4x the number of pixels visible on screen. For example a 1,000 x 1,000 chart (1M Pixels) will be rendered at 2,000 x 2,000 (4M Pixels) before scaling down to the correct size.

Higher number of pixels means more work for the browser to display the chart. If you notice any performance degredation on your application you can disable Dpi scaling using the code below.

import { DpiHelper} from "scichart/Charting/Visuals/TextureManager/DpiHelper";

// Note: you will need to call this before any SciChartSurface is created
DpiHelper.IsDpiScaleEnabled = false;

Also, we recommend use of Google Chrome browser as this has by far the best performance metrics, compared to Safari or Firefox, which both struggle to render large canvases.

See Related Article on Retina DPI Support and Browser Zoom for further information. Use Google Chrome on macOS for best performance. You can also disable retina high precision in code.

Dual GPU machines or Macbook Pro

Some Windows PCs and many macOS computers such as Macbook Pro have dual GPUs. A slower integrated GPU which uses less battery power, and a faster dedicated GPU which has better rendering performance.

When using a browser (Safari or Chrome) on macOS, the operating system by default picks the slower, integrated GPU. Here's how you can check and force the dedicated GPU.

Checking which GPU you are using on macOS or Windows

In Chrome on macOS you can navigate to chrome://gpu in the address bar to inspect which GPU the browser is currently using.

Scroll down to GL_RENDERER. On the right you can see the current GPU e.g. 'AMD Radeon Pro 5500M' or 'Intel UHD 630'

Forcing the Faster GPU on macOS

If you are using the integrated GPU and want to force the faster GPU on macOS, you can use an application called gfxCardStatus to force switching to the faster and more powerful GPU. Restart your browser and do the test again. This will improve WebGL performance!

Forcing the Faster GPU on Windows

There are applications which will allow you to switch GPU on Windows as well. Make sure you restart your browser and do the GL_RENDERER test again.

Some computers such as Macbook Pro and certain Windows Laptops have dual-GPUs. Ensure the more powerful GPU is being utilised by your browser to get the best performance from SciChart.js.

Keep Up to Date!

We are always working on improving performance of the overall charting engine.

Staying up to date helps to ensure you have the latest algorithms and optimisations for fast, efficient charting with SciChart.js.

We improve performance and optimise SciChart.js all the time. Stay up to date to ensure you have the latest optimisations!

Still Need Help?

If after all that, do you still need help?

If you have a performance question about SciChart.js or need further improvements and you are a paid (licensed) customer, then contact-us and our team will do their best to help!