Skip to content

Commit

Permalink
Removed named hooks prefetch step since we are using cached network r…
Browse files Browse the repository at this point in the history
…esponses.
  • Loading branch information
Brian Vaughn committed Sep 8, 2021
1 parent 407574e commit 84224cd
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 131 deletions.
8 changes: 1 addition & 7 deletions packages/react-devtools-inline/src/hookNames.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,7 @@
import {
parseHookNames,
parseSourceAndMetadata,
prefetchSourceFiles,
purgeCachedMetadata,
} from 'react-devtools-shared/src/hooks/parseHookNames';

export {
parseHookNames,
parseSourceAndMetadata,
prefetchSourceFiles,
purgeCachedMetadata,
};
export {parseHookNames, parseSourceAndMetadata, purgeCachedMetadata};
2 changes: 1 addition & 1 deletion packages/react-devtools-shared/src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
export const __DEBUG__ = false;

// Flip this flag to true to enable performance.mark() and performance.measure() timings.
export const __PERFORMANCE_PROFILE__ = false;
export const __PERFORMANCE_PROFILE__ = true;

export const TREE_OPERATION_ADD = 1;
export const TREE_OPERATION_REMOVE = 2;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ export function InspectedElementContextController({children}: Props) {
setParseHookNames(parseHookNamesByDefault || alreadyLoadedHookNames);
}

const prefetchSourceFilesRef = useRef(null);
const purgeCachedMetadataRef = useRef(null);

// Don't load a stale element from the backend; it wastes bridge bandwidth.
Expand All @@ -132,12 +131,10 @@ export function InspectedElementContextController({children}: Props) {
if (hookNamesModule !== null) {
const {
parseHookNames: loadHookNamesFunction,
prefetchSourceFiles,
purgeCachedMetadata,
} = hookNamesModule;

purgeCachedMetadataRef.current = purgeCachedMetadata;
prefetchSourceFilesRef.current = prefetchSourceFiles;

if (
inspectedElement !== null &&
Expand Down Expand Up @@ -185,11 +182,6 @@ export function InspectedElementContextController({children}: Props) {
inspectedElementRef.current !== inspectedElement
) {
inspectedElementRef.current = inspectedElement;

const prefetchSourceFiles = prefetchSourceFilesRef.current;
if (typeof prefetchSourceFiles === 'function') {
prefetchSourceFiles(inspectedElement.hooks, fetchFileWithCaching);
}
}
}, [inspectedElement]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,10 @@ import type {FetchFileWithCaching} from 'react-devtools-shared/src/devtools/view
import {withAsyncPerformanceMark} from 'react-devtools-shared/src/PerformanceMarks';
import WorkerizedParseSourceAndMetadata from './parseSourceAndMetadata.worker';
import typeof * as ParseSourceAndMetadataModule from './parseSourceAndMetadata';
import {
flattenHooksList,
loadSourceAndMetadata,
prefetchSourceFiles,
} from './loadSourceAndMetadata';
import {flattenHooksList, loadSourceAndMetadata} from './loadSourceAndMetadata';

const workerizedParseHookNames: ParseSourceAndMetadataModule = WorkerizedParseSourceAndMetadata();

export {prefetchSourceFiles};

export function parseSourceAndMetadata(
hooksList: Array<HooksNode>,
locationKeyToHookSourceAndMetadata: Map<string, HookSourceAndMetadata>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
// This is the fastest option since our custom metadata file is much smaller than a full source map,
// and there is no need to convert runtime code to the original source.

import LRU from 'lru-cache';
import {__DEBUG__} from 'react-devtools-shared/src/constants';
import {getHookSourceLocationKey} from 'react-devtools-shared/src/hookNamesCache';
import {sourceMapIncludesSource} from '../SourceMapUtils';
Expand All @@ -55,7 +54,6 @@ import {
withSyncPerformanceMark,
} from 'react-devtools-shared/src/PerformanceMarks';

import type {LRUCache} from 'react-devtools-shared/src/types';
import type {
HooksNode,
HookSource,
Expand All @@ -70,14 +68,6 @@ const FETCH_OPTIONS = {cache: 'force-cache'};

const MAX_SOURCE_LENGTH = 100_000_000;

// Fetch requests originated from an extension might not have origin headers
// which may prevent subsequent requests from using cached responses
// if the server returns a Vary: 'Origin' header
// so this cache will temporarily store pre-fetches sources in memory.
const prefetchedSources: LRUCache<string, string> = new LRU({
max: 15,
});

export type HookSourceAndMetadata = {|
// Generated by react-debug-tools.
hookSource: HookSource,
Expand Down Expand Up @@ -462,109 +452,47 @@ function loadSourceFiles(
locationKeyToHookSourceAndMetadata.forEach(hookSourceAndMetadata => {
const {runtimeSourceURL} = hookSourceAndMetadata;

const prefetchedSourceCode = prefetchedSources.get(runtimeSourceURL);
if (prefetchedSourceCode != null) {
hookSourceAndMetadata.runtimeSourceCode = prefetchedSourceCode;
} else {
let fetchFileFunction = fetchFile;
if (fetchFileWithCaching != null) {
// If a helper function has been injected to fetch with caching,
// use it to fetch the (already loaded) source file.
fetchFileFunction = url => {
return withAsyncPerformanceMark(
`fetchFileWithCaching("${url}")`,
() => {
return ((fetchFileWithCaching: any): FetchFileWithCaching)(url);
},
);
};
}
let fetchFileFunction = fetchFile;
if (fetchFileWithCaching != null) {
// If a helper function has been injected to fetch with caching,
// use it to fetch the (already loaded) source file.
fetchFileFunction = url => {
return withAsyncPerformanceMark(
`fetchFileWithCaching("${url}")`,
() => {
return ((fetchFileWithCaching: any): FetchFileWithCaching)(url);
},
);
};
}

const fetchPromise =
dedupedFetchPromises.get(runtimeSourceURL) ||
fetchFileFunction(runtimeSourceURL).then(runtimeSourceCode => {
// TODO (named hooks) Re-think this; the main case where it matters is when there's no source-maps,
// because then we need to parse the full source file as an AST.
if (runtimeSourceCode.length > MAX_SOURCE_LENGTH) {
throw Error('Source code too large to parse');
}
const fetchPromise =
dedupedFetchPromises.get(runtimeSourceURL) ||
fetchFileFunction(runtimeSourceURL).then(runtimeSourceCode => {
// TODO (named hooks) Re-think this; the main case where it matters is when there's no source-maps,
// because then we need to parse the full source file as an AST.
if (runtimeSourceCode.length > MAX_SOURCE_LENGTH) {
throw Error('Source code too large to parse');
}

if (__DEBUG__) {
console.groupCollapsed(
`loadSourceFiles() runtimeSourceURL "${runtimeSourceURL}"`,
);
console.log(runtimeSourceCode);
console.groupEnd();
}
if (__DEBUG__) {
console.groupCollapsed(
`loadSourceFiles() runtimeSourceURL "${runtimeSourceURL}"`,
);
console.log(runtimeSourceCode);
console.groupEnd();
}

return runtimeSourceCode;
});
dedupedFetchPromises.set(runtimeSourceURL, fetchPromise);
return runtimeSourceCode;
});
dedupedFetchPromises.set(runtimeSourceURL, fetchPromise);

setterPromises.push(
fetchPromise.then(runtimeSourceCode => {
hookSourceAndMetadata.runtimeSourceCode = runtimeSourceCode;
}),
);
}
setterPromises.push(
fetchPromise.then(runtimeSourceCode => {
hookSourceAndMetadata.runtimeSourceCode = runtimeSourceCode;
}),
);
});

return Promise.all(setterPromises);
}

export function prefetchSourceFiles(
hooksTree: HooksTree,
fetchFileWithCaching: FetchFileWithCaching | null,
): void {
// Deduplicate fetches, since there can be multiple location keys per source map.
const dedupedFetchPromises = new Set();

let fetchFileFunction = null;
if (fetchFileWithCaching != null) {
// If a helper function has been injected to fetch with caching,
// use it to fetch the (already loaded) source file.
fetchFileFunction = url => {
return withAsyncPerformanceMark(
`[pre] fetchFileWithCaching("${url}")`,
() => {
return ((fetchFileWithCaching: any): FetchFileWithCaching)(url);
},
);
};
} else {
fetchFileFunction = url => fetchFile(url, '[pre] fetchFile');
}

const hooksQueue = Array.from(hooksTree);

for (let i = 0; i < hooksQueue.length; i++) {
const hook = hooksQueue.pop();
if (isUnnamedBuiltInHook(hook)) {
continue;
}

const hookSource = hook.hookSource;
if (hookSource == null) {
continue;
}

const runtimeSourceURL = ((hookSource.fileName: any): string);

if (prefetchedSources.has(runtimeSourceURL)) {
// If we've already fetched this source, skip it.
continue;
}

if (!dedupedFetchPromises.has(runtimeSourceURL)) {
dedupedFetchPromises.add(runtimeSourceURL);

fetchFileFunction(runtimeSourceURL).then(text => {
prefetchedSources.set(runtimeSourceURL, text);
});
}

if (hook.subHooks.length > 0) {
hooksQueue.push(...hook.subHooks);
}
}
}

0 comments on commit 84224cd

Please sign in to comment.