echarts-for-react
echarts-for-react copied to clipboard
Memory Leaks!
The ReactEcharts library is causing memory leaks. During Dev mode, while I am on the same page and constantly refreshing after changes, in about a few hours, I get a javascript memory heap problem that kills my code. This is not good, as I'm unable to launch to production with the library in fear of it causing memory issues and killing my site.
With normal echarts, you have to call the dispose
method. Please see article. I see in your source code that it does have the call in the unmount:
componentWillUnmount() {
this.dispose();
}
But, it seems I still get this memory issue after staying on the same page and refreshing.
I am also tracking the the memory limits as below:
console.log("jsHeapSizeLimit", abbreviateNumber(memory.jsHeapSizeLimit))
console.log("totalJSHeapSize", abbreviateNumber(memory.totalJSHeapSize))
console.log("usedJSHeapSize", abbreviateNumber(memory.usedJSHeapSize))
And it increases after each refresh
This is a problem for many people as well in the echarts community. Here's some with the issue as well. This is a crucial issue or else this library cannot be used in production! Here is my code below
import * as echarts from "echarts/core";
// import ReactEcharts from "echarts-for-react";
import ReactEChartsCore from "echarts-for-react/lib/core";
import {
GridComponent,
DatasetComponent,
DataZoomComponent,
TooltipComponent
} from "echarts/components";
import { ScatterChart, LineChart, BarChart } from "echarts/charts";
import { UniversalTransition } from "echarts/features";
import { CanvasRenderer } from "echarts/renderers";
import {useEffect, useState} from "react";
import Styles from "./depth.module.css";
import { GetCollectionDepth } from "../../../../lib/Listings/GetCollectionDepth";
export default function Depth(props) {
echarts.use([
DataZoomComponent,
DatasetComponent,
GridComponent,
LineChart,
ScatterChart,
BarChart,
CanvasRenderer,
UniversalTransition,
TooltipComponent
]);
const [options, setTempOptions] = useState(null)
const [depth_data, setDepthData] = useState(null)
useEffect(async () => {
if (props == null || props.contract_address == null) {return}
console.log(props.contract_address)
let results = await GetCollectionDepth(props.contract_address, 10, 1000, 0)
setDepthData(results)
let chart_data = results.chart
let xs = []; let all_markets = results.all_markets
chart_data.forEach((item) => {
xs.push((item.x).toString() + "Ξ")
let temp_markets = {}
item.details.forEach((order) => {
if (temp_markets[order.market] == null) { temp_markets[order.market] = 1 }
else {temp_markets[order.market] += 1 }
})
for (let key in all_markets) {
if (!(key in temp_markets)) { all_markets[key].push(0)}
else { all_markets[key].push(temp_markets[key])}
}
})
// create series
let temp_options = {
title: {
text:"foo",
subtext:"bar",
x:'center',
textStyle: {
color: "white"
}
},
tooltip: {
trigger: 'axis',
axisPointer: {
// Use axis to trigger tooltip
type: 'shadow' // 'shadow' as default; can also be 'line' or 'shadow'
}
},
legend: {},
grid: {
// left: '3%',
// right: '4%',
// bottom: '3%',
// containLabel: true
},
yAxis: {
type: 'value'
},
xAxis: {
type: 'category',
data: xs
},
series: []
};
for (let key in all_markets) {
let temp_series = {
name: key,
type: 'bar',
stack: 'total',
// label: {
// show: true
// },
emphasis: {
focus: 'series'
},
data: all_markets[key]
}
temp_options.series.push(temp_series)
}
setTempOptions(temp_options)
},[props])
return (
<div className = {Styles.container}>
{options != null ? <ReactEChartsCore
echarts={echarts}
option={options}
style={{
width: "100%",
display: "flex",
color: "white",
height: "100%",
flexDirection: "column",
overflow: "scroll"
}}
/> : null}
</div>
)
}


i'm also having this exact same issue! it would be nice to have a way to dispose unused instances or at least give us a way to workaround it