RangeError (stack overflow) when enough "operations" happen in a single render
ashvinsrivatsa opened this issue · comments
Consider this code:
<html>
<head>
<script type="module">
import "https://esm.sh/preact/debug";
import { h, render } from "https://esm.sh/preact";
import { useState } from "https://esm.sh/preact/hooks";
import htm from "https://esm.sh/htm";
const html = htm.bind(h);
const App = () => {
const [showTree, setShowTree] = useState(false);
if (showTree) {
return html`<${Tree} depth=${14} />`;
} else {
return html`<button onClick=${() => setShowTree(true)}>Show Tree</button>`;
}
};
const Tree = ({ depth }) => {
if (depth === 0) {
return null;
} else {
return html`<div>${depth}<${Tree} depth=${depth-1} /><${Tree} depth=${depth-1} /></div>`;
}
};
render(html`<${App} />`, document.body);
</script>
</head>
<body></body>
</html>
When the user clicks the "Show Tree" button, Preact is able to render the large Tree
component without issue. But if the Preact Devtools (v4.7.1) are attached, the browser tab will crash:
RangeError: Maximum call stack size exceeded
Specifically, it crashes here:
In the above example, operations.length === 294907
here, which exceeds the number of arguments that may be passed to a function (at least on Chrome M123; the exact limit varies depending on browser).
(The <Tree depth={14} />
component here is comparable in size to a component our codebase actually contains; the component in question renders in a way that has operations.length
around 200,000. This precludes the use of Preact Devtools when working on this component.)