reagraph icon indicating copy to clipboard operation
reagraph copied to clipboard

Low Performance on large graph

Open Hann1bal opened this issue 2 years ago • 19 comments

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

  1. Get data from server.
  2. Send to component.

Expected behavior

As user I expected high performance on 40k+ dataset

Screenshots or Videos

Screenshot_20230726_113134 Screenshot_20230726_113723

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.

Hann1bal avatar Jul 26 '23 08:07 Hann1bal

Would you mind sharing an example repo so I can reproduce this easier?

amcdnl avatar Jul 26 '23 10:07 amcdnl

Would you mind sharing an example repo so I can reproduce this easier?

https://github.com/Hann1bal/ReagraphExampleForDev there

Hann1bal avatar Jul 26 '23 12:07 Hann1bal

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%.

Hann1bal avatar Jul 26 '23 14:07 Hann1bal

Good day @amcdnl, any results or need something more details?

Hann1bal avatar Aug 03 '23 12:08 Hann1bal

Any news on this? I am facing similar issues with large graphs and the browser hangs with just 1000s of nodes

ssunils avatar Sep 22 '23 07:09 ssunils

This might be a regression because this issue was addressed a few months back. I will investigate this weekend.

amcdnl avatar Sep 22 '23 11:09 amcdnl

This might be a regression because this issue was addressed a few months back. I will investigate this weekend.

Hello any news?

Hann1bal avatar Nov 13 '23 11:11 Hann1bal

@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.

amcdnl avatar Nov 13 '23 13:11 amcdnl

@Hann1bal were you able to revert to an older commit that didn't have these issues?

hchaudhary1 avatar Jan 07 '24 10:01 hchaudhary1

@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.

Hann1bal avatar Jan 10 '24 07:01 Hann1bal

Should be much better now!

amcdnl avatar Feb 19 '24 12:02 amcdnl

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 avatar Apr 24 '24 07:04 avalanche-tm

@avalanche-tm - Can you share a example repo w/ me ? The options/config/data can all affect performance so good to know.

amcdnl avatar Apr 24 '24 08:04 amcdnl

@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

avalanche-tm avatar Apr 24 '24 08:04 avalanche-tm

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>
	)
}

optojack avatar Aug 20 '24 14:08 optojack

@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 avatar Aug 30 '24 14:08 optojack

@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 avatar Sep 03 '24 15:09 ghsteff

@ghsteff That looks great, thanks for pointing me towards those PRs. Appreciate the help!

optojack avatar Sep 03 '24 15:09 optojack

Thanks you, that great, what about using webworkers for extra large graphs?

Hann1bal avatar Sep 03 '24 16:09 Hann1bal