preactjs / preactjs/preact-devtools

Memory is leaked when a component is updated - Simple Reproduction

Open
#473 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
345
Forks
39
PR merge metrics
No merged PRs in 30d

Description

Describe the bug

Memory is leaked when a component is updated.

My Electron (happens in Chrome also, see below!) application has a progress display (status text showing transferred bytes, progress bar) which updates very often. As Electron has the V8 Memory Cage enabled since version 21, limiting the memory to a few gigabytes (they say 4 GB, but it is 3 GB in my tests), the application frontend goes away after a while (leaving an empty BrowserWindow).

After spending a lot of time tracking down this issue, I was able write a simple reproduction - see below - which fills up the memory very fast in Chrome (see Chrome DevTools -> Memory).

To Reproduce

Use a current version of Chrome.

import { render, useState } from 'preact/compat';

// The only purpose of ChildComponent is to create a complex tree, eating up memory fast.

interface ChildComponentProps {
    readonly level: number;
}

function ChildComponent({ level }: ChildComponentProps) {
    return (
        <div>
            <div>{new Date().valueOf().toString()}</div>
            {level < 4 && Array(3).fill(0).map((_, index) => (
                <ChildComponent key={index} level={level + 1} />
            ))}
        </div>
    );
}

function RootComponent() {
    const [counter, setCounter] = useState(0);
    setTimeout(() => setCounter(counter + 1), 0); // simply force updating all the time
    return (
        <div>
            <span>{counter.toString()}</span>
            <div style={{ display: 'none' }}>
                <ChildComponent level={0} />
            </div>
        </div>
    );
}

const rootElement = document.getElementById('root');
render(<RootComponent />, rootElement!);

Expected behavior

Memory usage should remain quite constant. It should definitely not lead to an out-of-memory error.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the TypeScript reproduction in the issue and run it in a current Chrome version while inspecting memory in Chrome DevTools. Trace repeated component updates and compare memory usage over time; done means memory remains broadly constant and the reproduction no longer reaches an out-of-memory state.

Written by the indexing model from the issue text.

Assessment

Tech stack
electron, typescript
Domain
frontend, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.