Low Performance on large graph
Describe the bug
Hello, I'm trying to build an interactive circular graph. When I load 400+ nodes and the same number of edges, I get 12-28 frames per second, on 2600+ nodes there is a hang for 40 seconds and 1-3 frames per second, on 40k+ the browser crashes.
deps: "@microsoft/signalr": "^7.0.9", "leva": "^0.9.35", "react": "^18.2.0", "react-dom": "^18.2.0", "reagraph": "4.10.4", "typia": "^4.1.7"
npm --version: 9.6.5
node --version: v18.13.0
NodeViewer:
import INode from "./INode";
import { button, useControls } from 'leva'
import { asserParse as parse } from './generated/assertParse'
import { GraphCanvas } from 'reagraph';
import { useEffect, useRef, useState } from "react";
import Graph from "./Graph";
import IEdge from "./IEdge";
const NodeContainer = (props: any) => {
return (
<GraphCanvas animated={false} labelType="nodes" layoutType="radialOut2d"
nodes={nodesStore}
edges={edgesStore}
/>
)
}
export default NodeContainer;
import { useEffect, useRef, useState } from 'react'
import './App.css'
import { asserParse as parse } from './generated/assertParse'
import NodeContainer from './NodeContainer'
import SignalR from './SignalR';
import { button, useControls } from 'leva';
import Graph from "./Graph";
import IEdge from "./IEdge";
import INode from './INode';
import {GraphCanvas } from 'reagraph';
function App () {
const signalR = new SignalR();
const [nodesStore, setNodes] = useState<INode[]>([]);
const [edgesStore, setEdges] = useState<IEdge[]>([]);
const [cdepth, cdepthSet] = useState<number>(2)
const t = useRef(0)
const { on, isParentOnly, depth } = useControls({ isParentOnly: true, depth: { value: 4, onChange: (value: number) => { t.current = value }, transient: false }, color: color, on: true, get: button(() => get()) })
signalR.on("Get", (data: string) => append(data))
function get() {
console.log(cdepth)
fetch(`http://localhost/ControlUI/Get/${t.current}?parent_only=${isParentOnly}`)
}
function append(values: string) {
console.log(values)
const dataSerialized: Graph = parse(values);
const nodesTmp: INode[] = dataSerialized.nodes;
const edgeTmp: IEdge[] = dataSerialized.edges;
console.log(dataSerialized)
setNodes([...nodesTmp])
setEdges([...edgeTmp])
}
return <GraphCanvas labelType="nodes" layoutType="radialOut2d"
nodes={nodesStore}
edges={edgesStore}
/>
}
export default App
Steps to Reproduce the Bug or Issue
- Get data from server.
- Send to component.
Expected behavior
As user I expected high performance on 40k+ dataset
Screenshots or Videos
Platform
- Reagraph Version: [e.g. 4.10.4]
- OS: [e.g. Windows 11, Linux Debian 11]
- Browser: [e.g. Chrome, Chromium, Firefox]
- NodeJS version: v18.13.0
- Npm version: 9.6.5
Your Example Website or App
No response
Additional context
At the idle stage, when the data is not loaded, the reagraph update function loads the processor core by more than 30%, and the GPU by 20%. Shows a performance trace, the rendering function was called 2698 times in 3 seconds.
Would you mind sharing an example repo so I can reproduce this easier?
Would you mind sharing an example repo so I can reproduce this easier?
https://github.com/Hann1bal/ReagraphExampleForDev there
To get information about my computers at workstation i have i5 8600, hd graphics and 16gb ram, at demonstration stand have r9 5950x, 3080ti, 64gb Ram. Demonstration stand better for 5-10%.
Good day @amcdnl, any results or need something more details?
Any news on this? I am facing similar issues with large graphs and the browser hangs with just 1000s of nodes
This might be a regression because this issue was addressed a few months back. I will investigate this weekend.
This might be a regression because this issue was addressed a few months back. I will investigate this weekend.
Hello any news?
@Hann1bal - Sorry we've been busy. This is still on my radar as I need it too. If you want, I'm happy to accept a PR if you have a solution.
@Hann1bal were you able to revert to an older commit that didn't have these issues?
@Hann1bal were you able to revert to an older commit that didn't have these issues?
I tried it on an earlier version because... I saw another issue with a proposal to try to downgrade the version and there were also problems. I can try again a little later to run about 3-5 earlier commits and measure the performance.
Should be much better now!
I'm using version 4.17.0 and rendering 1000+ nodes is very slow. @amcdnl which version was supposed to fix this issue?
@avalanche-tm - Can you share a example repo w/ me ? The options/config/data can all affect performance so good to know.
@amcdnl Zooming and panning around nodes is slow and gets stuck. Here is the code:
function ComputeGraph() {
const ref = useRef<GraphCanvasRef | null>(null)
const [nodes, setNodes] = useState<GraphNode[]>([])
const [edges, setEdges] = useState<GraphEdge[]>([])
const generateNNodes = (n: number) => {
const newNodes = Array.from({ length: n }, (_, i) => ({
id: `n-${i + 1}`,
label: `${i + 1}`,
}))
setNodes(newNodes)
}
useEffect(() => {
generateNNodes(5000)
}, [])
return (
<>
<GraphCanvas ref={ref} nodes={nodes} edges={edges} animated={false} />
</>
)
}
export default ComputeGraph
Hate to be a broken record amongst others, but is there any update here? I am trying to render about 10,000 nodes but also struggling to load more than ~2000 with any real speed, not to mention interactivity is incredibly slow once the 2,000 nodes loads.
Here is my current code:
import { getData } from '@/services/api/data'
import { useQuery } from '@tanstack/react-query'
import React from 'react'
import { GraphCanvas } from 'reagraph'
export function Graph() {
const { data, isLoading } = useQuery({
queryKey: ['dataQuery'],
queryFn: async () => await getData(),
})
const nodes = data.slice(0, 2000).map((data) => ({
id: data.id.toString(),
label: data.name,
}))
if (isLoading) return <div>Loading...</div>
return (
<div className="fixed h-[600px] w-[1250px]">
<GraphCanvas nodes={nodes} edges={[]} draggable={false} animated={false} />
</div>
)
}
@amcdnl Is there any update here? If not, would you be willing to direct me towards an area you have identified in the past as being a potential issue or where you think the issue is ocurring? Happy to take a look and potentially make a PR. Would love to continue to use this library in other parts of the app
@optojack we memoized some components in this PR that helped performance quite a bit. And hid small unreadable labels from rendering in this PR that also helped alot.
There's no existing known issues, but memoizing and minimizing the amount of rendering we're doing could be 2 places to start 😁
@ghsteff That looks great, thanks for pointing me towards those PRs. Appreciate the help!
Thanks you, that great, what about using webworkers for extra large graphs?