Comments (26)
I found the memory leak happens again.
I reproduced the problem with ReactVegaLiteDemo as follows:
- install react-timeout to stories
- change ReactVegaLiteDemo.jsx to follows:
import React from "react";
import { action } from "@storybook/addon-actions";
import { Vega, createClassFromSpec } from "../../react-vega/src";
import ReactTimeout from "react-timeout";
const data1 = {
myData: [
{ a: "A", b: 20 },
{ a: "B", b: 34 },
{ a: "C", b: 55 },
{ a: "D", b: 19 },
{ a: "E", b: 40 },
{ a: "F", b: 34 },
{ a: "G", b: 91 },
{ a: "H", b: 78 },
{ a: "I", b: 25 },
{ a: "A", b: 20 },
{ a: "B", b: 34 },
{ a: "C", b: 55 },
{ a: "D", b: 19 },
{ a: "E", b: 40 },
{ a: "F", b: 34 },
{ a: "G", b: 91 },
{ a: "H", b: 78 },
{ a: "I", b: 25 }
]
};
const data2 = {
myData: [
{ a: "A", b: 28 },
{ a: "B", b: 55 },
{ a: "C", b: 43 },
{ a: "D", b: 91 },
{ a: "E", b: 81 },
{ a: "F", b: 53 },
{ a: "G", b: 19 },
{ a: "H", b: 87 },
{ a: "I", b: 52 }
]
};
const spec1 = {
$schema: "https://vega.github.io/schema/vega-lite/v4.0.0-beta.10.json",
data: { name: "myData" },
description: "A simple bar chart with embedded data.",
encoding: {
x: { field: "a", type: "ordinal" },
y: { field: "b", type: "quantitative" }
},
mark: "bar"
};
const spec2 = {
data: { name: "myData" },
description: "A simple bar chart with embedded data.",
encoding: {
x: { field: "b", type: "quantitative" },
y: { field: "a", type: "ordinal" }
},
mark: "bar"
};
const BarChart = createClassFromSpec({ mode: "vega-lite", spec: spec1 });
const code1 = `<VegaLite data={this.state.data} spec={this.state.spec} />`;
const code2 = `const BarChart = ReactVegaLite.createClassFromLiteSpec(spec1);
<BarChart data={this.state.data} />`;
class Demo extends React.Component {
constructor(props) {
super(props);
this.state = {
data: data1,
info: "",
spec: spec1
};
this.handleHover = this.handleHover.bind(this);
this.handleToggleSpec = this.handleToggleSpec.bind(this);
this.handleUpdateData = this.handleUpdateData.bind(this);
this.handlers = { hover: this.handleHover };
}
setTimer = () => {
var timer = function() {
this.handleUpdateData();
this.handleToggleSpec();
this.timerHandle = this.props.setTimeout(timer.bind(this), 1);
};
this.timerHandle = this.props.setTimeout(timer.bind(this), 1);
};
componentDidMount = () => {
this.setTimer();
};
handleHover(...args) {
action("hover", {
limit: 5
})(args);
this.setState({
info: JSON.stringify(args)
});
}
handleToggleSpec() {
const { spec } = this.state;
action("toggle spec")(spec);
if (spec === spec1) {
this.setState({ spec: spec2 });
} else {
this.setState({ spec: spec1 });
}
}
handleUpdateData() {
const { data } = this.state;
action("update data")(data);
if (data === data1) {
this.setState({ data: data2 });
} else if (data === data2) {
this.setState({ data: data1 });
}
}
render() {
const { data, spec, info } = this.state;
return (
<div>
<div style={{ float: "right" }}>
<iframe
title="star"
src="https://ghbtns.com/github-btn.html?user=vega&repo=react-vega&type=star&count=true"
frameBorder="0"
scrolling="0"
width="100px"
height="20px"
/>
</div>
<button type="button" onClick={this.handleToggleSpec}>
Toggle Spec
</button>
<button type="button" onClick={this.handleUpdateData}>
Update data
</button>
<h3>
<code><VegaLite></code> React Component
</h3>
Will recompile when spec changes and update when data changes.
<pre>{code1}</pre>
<Vega data={data} spec={spec} />
<h3>
<code>ReactVegaLite.createClassFromLiteSpec()</code>
</h3>
Use the given spec to create a reusable component.
<pre>{code2}</pre>
<BarChart data={data} />
{info}
</div>
);
}
}
export default ReactTimeout(Demo);
- Check the system memory costs. You could find the memory used by browser keep increasing.
from react-vega.
Is this a Vegas or react Vega issue? Could you help us find out?
from react-vega.
I checked out codes of react-vega. It release old view with finalize function. I also look at vega-embed. But I do not find possible reason by now. I think it maybe caused by async or vega's implementation of finalize function.
from react-vega.
Can you try to reproduce this issue with just Vega?
from react-vega.
Ok. By now, I found that when we use onNewView in react-vega and update state in the function called. The memory leaks will be serious. Even I try to release the view with finalize function. Could you help me to explain why and what we could do? Thanks.
from react-vega.
Can you see whether the same happens with just Vega?
from react-vega.
I reproduced the problem with ReactVegaLiteDemo as follows:
- install react-timeout to stories
- change ReactVegaLiteDemo.jsx to follows:
import React from "react";
import { action } from "@storybook/addon-actions";
import { Vega, createClassFromSpec } from "../../react-vega/src";
import ReactTimeout from "react-timeout";
const data1 = {
myData: [
{ a: "A", b: 20 },
{ a: "B", b: 34 },
{ a: "C", b: 55 },
{ a: "D", b: 19 },
{ a: "E", b: 40 },
{ a: "F", b: 34 },
{ a: "G", b: 91 },
{ a: "H", b: 78 },
{ a: "I", b: 25 },
{ a: "A", b: 20 },
{ a: "B", b: 34 },
{ a: "C", b: 55 },
{ a: "D", b: 19 },
{ a: "E", b: 40 },
{ a: "F", b: 34 },
{ a: "G", b: 91 },
{ a: "H", b: 78 },
{ a: "I", b: 25 }
]
};
const data2 = {
myData: [
{ a: "A", b: 28 },
{ a: "B", b: 55 },
{ a: "C", b: 43 },
{ a: "D", b: 91 },
{ a: "E", b: 81 },
{ a: "F", b: 53 },
{ a: "G", b: 19 },
{ a: "H", b: 87 },
{ a: "I", b: 52 }
]
};
const spec1 = {
$schema: "https://vega.github.io/schema/vega-lite/v4.0.0-beta.10.json",
data: { name: "myData" },
description: "A simple bar chart with embedded data.",
encoding: {
x: { field: "a", type: "ordinal" },
y: { field: "b", type: "quantitative" }
},
mark: "bar"
};
const spec2 = {
data: { name: "myData" },
description: "A simple bar chart with embedded data.",
encoding: {
x: { field: "b", type: "quantitative" },
y: { field: "a", type: "ordinal" }
},
mark: "bar"
};
const BarChart = createClassFromSpec({ mode: "vega-lite", spec: spec1 });
const code1 = `<VegaLite data={this.state.data} spec={this.state.spec} />`;
const code2 = `const BarChart = ReactVegaLite.createClassFromLiteSpec(spec1);
<BarChart data={this.state.data} />`;
class Demo extends React.Component {
constructor(props) {
super(props);
this.state = {
data: data1,
info: "",
spec: spec1
};
this.handleHover = this.handleHover.bind(this);
this.handleToggleSpec = this.handleToggleSpec.bind(this);
this.handleUpdateData = this.handleUpdateData.bind(this);
this.handlers = { hover: this.handleHover };
}
setTimer = () => {
var timer = function() {
this.handleUpdateData();
this.handleToggleSpec();
this.timerHandle = this.props.setTimeout(timer.bind(this), 1);
};
this.timerHandle = this.props.setTimeout(timer.bind(this), 1);
};
componentDidMount = () => {
this.setTimer();
};
handleHover(...args) {
action("hover", {
limit: 5
})(args);
this.setState({
info: JSON.stringify(args)
});
}
handleToggleSpec() {
const { spec } = this.state;
action("toggle spec")(spec);
if (spec === spec1) {
this.setState({ spec: spec2 });
} else {
this.setState({ spec: spec1 });
}
}
handleUpdateData() {
const { data } = this.state;
action("update data")(data);
if (data === data1) {
this.setState({ data: data2 });
} else if (data === data2) {
this.setState({ data: data1 });
}
}
render() {
const { data, spec, info } = this.state;
return (
<div>
<div style={{ float: "right" }}>
<iframe
title="star"
src="https://ghbtns.com/github-btn.html?user=vega&repo=react-vega&type=star&count=true"
frameBorder="0"
scrolling="0"
width="100px"
height="20px"
/>
</div>
<button type="button" onClick={this.handleToggleSpec}>
Toggle Spec
</button>
<button type="button" onClick={this.handleUpdateData}>
Update data
</button>
<h3>
<code><VegaLite></code> React Component
</h3>
Will recompile when spec changes and update when data changes.
<pre>{code1}</pre>
<Vega data={data} spec={spec} />
<h3>
<code>ReactVegaLite.createClassFromLiteSpec()</code>
</h3>
Use the given spec to create a reusable component.
<pre>{code2}</pre>
<BarChart data={data} />
{info}
</div>
);
}
}
export default ReactTimeout(Demo);
- Check the system memory costs. You could find the memory used by browser keep increasing.
from react-vega.
Can you reproduce the same with just Vega (no react)?
Note that Vega uses a reactive data flow and therefore has to keep track of some data. However, this doesn’t mean that memory usage continuously increases.
from react-vega.
Hi. I reproduce the same problem with just vega-lite as follows.
<!DOCTYPE html>
<head>
<meta charset="utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vega@5"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-embed@5"></script>
</head>
<body>
<div id="vis"></div>
<script>
const spec1 = {
$schema: "https://vega.github.io/schema/vega-lite/v3.json",
description: "A simple bar chart with embedded data.",
width: 360,
data: {
values: [
{ a: "A", b: 28 },
{ a: "B", b: 55 },
{ a: "C", b: 43 },
{ a: "D", b: 91 },
{ a: "E", b: 81 },
{ a: "F", b: 53 },
{ a: "G", b: 19 },
{ a: "H", b: 87 },
{ a: "I", b: 52 }
]
},
mark: "bar",
encoding: {
x: { field: "a", type: "ordinal" },
y: { field: "b", type: "quantitative" },
tooltip: { field: "b", type: "quantitative" }
}
};
const spec2 = {
$schema: "https://vega.github.io/schema/vega-lite/v3.json",
description: "A simple bar chart with embedded data.",
width: 500,
data: {
values: [
{ a: "A", b: 33 },
{ a: "B", b: 32 },
{ a: "C", b: 16 },
{ a: "D", b: 28 },
{ a: "E", b: 35 },
{ a: "F", b: 81 },
{ a: "G", b: 90 },
{ a: "H", b: 10 },
{ a: "I", b: 5 }
]
},
mark: "bar",
encoding: {
x: { field: "a", type: "ordinal" },
y: { field: "b", type: "quantitative" },
tooltip: { field: "b", type: "quantitative" }
}
};
let spec = spec1;
function myFunction() {
setInterval(function() {
if (spec === spec1) spec = spec2;
else spec = spec1;
vegaEmbed("#vis", spec)
.then()
.catch(console.warn);
}, 1000);
}
</script>
<button onclick="myFunction()">Update</button>
</body>
from react-vega.
The embed example is fixed by using .finalize()
. See vega/vega-embed#270
React Vega already uses finalize so I'm not sure yet what's happening here
.from react-vega.
I tried react-vega. It has the problem.
from react-vega.
Moving discussion to vega/vega-embed#270.
from react-vega.
@eeyshen I notice that in the react-vega
example, you setTimeout
every 1ms
while the vega-lite
one is every 1000ms
.
Is that intentional?
from react-vega.
I also tried vega-lite with 1ms. The problem will show itself more quick.
from react-vega.
To fix this, please call result.finalize() in Embed 6.2.0.
from react-vega.
Do you mean what have done in VegaEmbed.tsx:
clearView() {
this.modifyView(view => {
view.finalize();
});
this.viewPromise = undefined;
return this;
}
from react-vega.
No, we should fix react Vega to call this. Users shouldn’t need to call finalize directly.
from react-vega.
@domoritz Hi, when will the next release of react-vega be published with the bug fixed? Thanks.
from react-vega.
I don't have the cycles to add the fix. Maybe you can send a or @kristw may have time.
from react-vega.
@kristw Do you have time to fix this bug with Vega-Embed 6.2 and release a new version?
from react-vega.
As Vega, Vega-Lite, Vega-Embed upgrades, is there some plan for react-vega upgrade? Thanks.
from react-vega.
I am on vacation with limited access. However, pull requests are welcome.
from react-vega.
Is this resolved?
from react-vega.
I believe so.
from react-vega.
I believe the problem appear again. The screenshot below show the memory profile of the example above.
<!DOCTYPE html>
<head>
<meta charset="utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vega@5"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-embed@6"></script>
</head>
<body>
<div id="vis"></div>
<script>
const spec1 = {
$schema: "https://vega.github.io/schema/vega-lite/v4.json",
description: "A simple bar chart with embedded data.",
width: 360,
data: {
values: [
{ a: "A", b: 28 },
{ a: "B", b: 55 },
{ a: "C", b: 43 },
{ a: "D", b: 91 },
{ a: "E", b: 81 },
{ a: "F", b: 53 },
{ a: "G", b: 19 },
{ a: "H", b: 87 },
{ a: "I", b: 52 }
]
},
mark: "bar",
encoding: {
x: { field: "a", type: "ordinal" },
y: { field: "b", type: "quantitative" },
tooltip: { field: "b", type: "quantitative" }
}
};
const spec2 = {
$schema: "https://vega.github.io/schema/vega-lite/v4.json",
description: "A simple bar chart with embedded data.",
width: 500,
data: {
values: [
{ a: "A", b: 33 },
{ a: "B", b: 32 },
{ a: "C", b: 16 },
{ a: "D", b: 28 },
{ a: "E", b: 35 },
{ a: "F", b: 81 },
{ a: "G", b: 90 },
{ a: "H", b: 10 },
{ a: "I", b: 5 }
]
},
mark: "bar",
encoding: {
x: { field: "a", type: "ordinal" },
y: { field: "b", type: "quantitative" },
tooltip: { field: "b", type: "quantitative" }
}
};
let spec = spec1;
function myFunction() {
setInterval(function() {
if (spec === spec1) spec = spec2;
else spec = spec1;
vegaEmbed("#vis", spec)
.then()
.catch(console.warn);
}, 1000);
}
</script>
<button onclick="myFunction()">Update</button>
</body>
from react-vega.
I responded in the related Vega embed issue.
from react-vega.
Related Issues (20)
- builds try to import a missing prop-types dependency HOT 11
- Infinite requests when the loader prop is passed
- Unable to highlight the vega chart from outside vega component
- Out of date CHANGELOG.md HOT 1
- Replace travis with GitHub actions HOT 2
- Dark theme does not pass on to signals or text marks HOT 1
- Unable to embed vega-lite visualization in react HOT 2
- When will react-vega migrate to react 18 HOT 2
- Re-rendering with className causes react-embed to lose styling
- Approach#1 in your documentation is not working HOT 5
- Setting height to "container" (i.e. responsive sizing) does not work as expected HOT 1
- Support for newer typescript version
- Generated Charts passing in data as an attribute messes up title ... extra space at top - pie chart
- Will the VegaLite component re-render on spec change? HOT 1
- Is it possible to use [email protected] with react native?
- [Security issue] - CVE-2022-25883-semver HOT 1
- Provide a more beginner-friendly documentation
- [Question] Does it support server side rendering? HOT 1
- Open links in a new window
- Fit vertically-concatenated Vega-Lite (react-vega) visualization to container size, and keep the interactive brush feature HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from react-vega.