From 97fac348f8cf4a2dd775175c11cc94a1da618858 Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Thu, 9 Apr 2020 21:36:27 -0700 Subject: [PATCH] Cache the result in DEV In DEV it's somewhat likely that we'll see many logs that add component stacks. This could be slow so we cache the results of previous components. --- packages/shared/ReactComponentStackFrame.js | 24 +++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/packages/shared/ReactComponentStackFrame.js b/packages/shared/ReactComponentStackFrame.js index 3906504caabd..e1420e475e2e 100644 --- a/packages/shared/ReactComponentStackFrame.js +++ b/packages/shared/ReactComponentStackFrame.js @@ -53,6 +53,11 @@ export function describeBuiltInComponentFrame( } let reentry = false; +let componentFrameCache; +if (__DEV__) { + const PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map; + componentFrameCache = new PossiblyWeakMap(); +} export function describeNativeComponentFrame( fn: Function, @@ -63,6 +68,13 @@ export function describeNativeComponentFrame( return ''; } + if (__DEV__) { + const frame = componentFrameCache.get(fn); + if (frame !== undefined) { + return frame; + } + } + const control = Error(); reentry = true; @@ -119,7 +131,11 @@ export function describeNativeComponentFrame( if (sampleLines[s] !== controlLines[c]) { // Return the line we found. // V8 adds a "new" prefix for native classes. Let's remove it to make it prettier. - return '\n' + sampleLines[s - 1].replace(' at new ', ' at '); + const frame = '\n' + sampleLines[s - 1].replace(' at new ', ' at '); + if (__DEV__) { + componentFrameCache.set(fn, frame); + } + return frame; } } } @@ -132,7 +148,11 @@ export function describeNativeComponentFrame( } // Fallback to just using the name if we couldn't make it throw. const name = fn ? fn.displayName || fn.name : ''; - return name ? describeBuiltInComponentFrame(name) : ''; + const syntheticFrame = name ? describeBuiltInComponentFrame(name) : ''; + if (__DEV__) { + componentFrameCache.set(fn, syntheticFrame); + } + return syntheticFrame; } const BEFORE_SLASH_RE = /^(.*)[\\\/]/;