Only capture stacks for up to 10 frames for Owner Stacks (#34864)
Sebastian "Sebbie" Silbermann committed
Oct 16, 2025 at 18:00 UTC
d8aa94b0f4f22aadd4762b7ca1c690d3d85ae776
1 file changed
+57
-16
packages/react/src/jsx/ReactJSXElement.js
+57
-16
@@ -57,6 +57,14 @@ function getOwner() {
57
return null;
58
}
59
60
+// v8 (Chromium, Node.js) defaults to 10
61
+// SpiderMonkey (Firefox) does not support Error.stackTraceLimit
62
+// JSC (Safari) defaults to 100
63
+// The lower the limit, the more likely we'll not reach react_stack_bottom_frame
64
+// The higher the limit, the slower Error() is when not inspecting with a debugger.
65
+// When inspecting with a debugger, Error.stackTraceLimit has no impact on Error() performance (in v8).
66
+const ownerStackTraceLimit = 10;
67
+
68
/** @noinline */
69
function UnknownOwner() {
70
/** @noinline */
@@ -352,15 +360,24 @@ export function jsxProdSignatureRunningInDevWithDynamicChildren(
360
const trackActualOwner =
361
__DEV__ &&
362
ReactSharedInternals.recentlyCreatedOwnerStacks++ < ownerStackLimit;
363
+ let debugStackDEV = false;
364
+ if (__DEV__) {
365
+ if (trackActualOwner) {
366
+ const previousStackTraceLimit = Error.stackTraceLimit;
367
+ Error.stackTraceLimit = ownerStackTraceLimit;
368
+ debugStackDEV = Error('react-stack-top-frame');
369
+ Error.stackTraceLimit = previousStackTraceLimit;
370
+ } else {
371
+ debugStackDEV = unknownOwnerDebugStack;
372
+ }
373
+ }
374
+
375
return jsxDEVImpl(
376
type,
377
config,
378
maybeKey,
379
isStaticChildren,
360
- __DEV__ &&
361
- (trackActualOwner
362
- ? Error('react-stack-top-frame')
363
- : unknownOwnerDebugStack),
380
+ debugStackDEV,
381
__DEV__ &&
382
(trackActualOwner
383
? createTask(getTaskName(type))
@@ -379,15 +396,23 @@ export function jsxProdSignatureRunningInDevWithStaticChildren(
396
const trackActualOwner =
397
__DEV__ &&
398
ReactSharedInternals.recentlyCreatedOwnerStacks++ < ownerStackLimit;
399
+ let debugStackDEV = false;
400
+ if (__DEV__) {
401
+ if (trackActualOwner) {
402
+ const previousStackTraceLimit = Error.stackTraceLimit;
403
+ Error.stackTraceLimit = ownerStackTraceLimit;
404
+ debugStackDEV = Error('react-stack-top-frame');
405
+ Error.stackTraceLimit = previousStackTraceLimit;
406
+ } else {
407
+ debugStackDEV = unknownOwnerDebugStack;
408
+ }
409
+ }
410
return jsxDEVImpl(
411
type,
412
config,
413
maybeKey,
414
isStaticChildren,
387
- __DEV__ &&
388
- (trackActualOwner
389
- ? Error('react-stack-top-frame')
390
- : unknownOwnerDebugStack),
415
+ debugStackDEV,
416
__DEV__ &&
417
(trackActualOwner
418
? createTask(getTaskName(type))
@@ -408,15 +433,23 @@ export function jsxDEV(type, config, maybeKey, isStaticChildren) {
433
const trackActualOwner =
434
__DEV__ &&
435
ReactSharedInternals.recentlyCreatedOwnerStacks++ < ownerStackLimit;
436
+ let debugStackDEV = false;
437
+ if (__DEV__) {
438
+ if (trackActualOwner) {
439
+ const previousStackTraceLimit = Error.stackTraceLimit;
440
+ Error.stackTraceLimit = ownerStackTraceLimit;
441
+ debugStackDEV = Error('react-stack-top-frame');
442
+ Error.stackTraceLimit = previousStackTraceLimit;
443
+ } else {
444
+ debugStackDEV = unknownOwnerDebugStack;
445
+ }
446
+ }
447
return jsxDEVImpl(
448
type,
449
config,
450
maybeKey,
451
isStaticChildren,
416
- __DEV__ &&
417
- (trackActualOwner
418
- ? Error('react-stack-top-frame')
419
- : unknownOwnerDebugStack),
452
+ debugStackDEV,
453
__DEV__ &&
454
(trackActualOwner
455
? createTask(getTaskName(type))
@@ -667,15 +700,23 @@ export function createElement(type, config, children) {
700
const trackActualOwner =
701
__DEV__ &&
702
ReactSharedInternals.recentlyCreatedOwnerStacks++ < ownerStackLimit;
703
+ let debugStackDEV = false;
704
+ if (__DEV__) {
705
+ if (trackActualOwner) {
706
+ const previousStackTraceLimit = Error.stackTraceLimit;
707
+ Error.stackTraceLimit = ownerStackTraceLimit;
708
+ debugStackDEV = Error('react-stack-top-frame');
709
+ Error.stackTraceLimit = previousStackTraceLimit;
710
+ } else {
711
+ debugStackDEV = unknownOwnerDebugStack;
712
+ }
713
+ }
714
return ReactElement(
715
type,
716
key,
717
props,
718
getOwner(),
675
- __DEV__ &&
676
- (trackActualOwner
677
- ? Error('react-stack-top-frame')
678
- : unknownOwnerDebugStack),
719
+ debugStackDEV,
720
__DEV__ &&
721
(trackActualOwner
722
? createTask(getTaskName(type))