@@ -19,33 +19,13 @@ import {
1919 localStorageSetItem ,
2020} from 'react-devtools-shared/src/storage' ;
2121import DevTools from 'react-devtools-shared/src/devtools/views/DevTools' ;
22+ import { __DEBUG__ } from 'react-devtools-shared/src/constants' ;
2223
2324const LOCAL_STORAGE_SUPPORTS_PROFILING_KEY =
2425 'React::DevTools::supportsProfiling' ;
2526
2627const isChrome = getBrowserName ( ) === 'Chrome' ;
2728
28- const cachedNetworkEvents = new Map ( ) ;
29-
30- // Cache JavaScript resources as the page loads them.
31- // This helps avoid unnecessary duplicate requests when hook names are parsed.
32- // Responses with a Vary: 'Origin' might not match future requests.
33- // This lets us avoid a possible (expensive) cache miss.
34- // For more info see: github.com/facebook/react/pull/22198
35- chrome . devtools . network . onRequestFinished . addListener (
36- function onRequestFinished ( event ) {
37- if ( event . request . method === 'GET' ) {
38- switch ( event . response . content . mimeType ) {
39- case 'application/javascript' :
40- case 'application/x-javascript' :
41- case 'text/javascript' :
42- cachedNetworkEvents . set ( event . request . url , event ) ;
43- break ;
44- }
45- }
46- } ,
47- ) ;
48-
4929let panelCreated = false ;
5030
5131// The renderer interface can't read saved component filters directly,
@@ -237,52 +217,89 @@ function createPanelIfReactLoaded() {
237217 // never reaches the chrome.runtime.onMessage event listener.
238218 let fetchFileWithCaching = null ;
239219 if ( isChrome ) {
240- // Fetching files from the extension won't make use of the network cache
241- // for resources that have already been loaded by the page.
242- // This helper function allows the extension to request files to be fetched
243- // by the content script (running in the page) to increase the likelihood of a cache hit.
244- fetchFileWithCaching = url => {
245- const event = cachedNetworkEvents . get ( url ) ;
246- if ( event != null ) {
247- // If this resource has already been cached locally,
248- // skip the network queue (which might not be a cache hit anyway)
249- // and just use the cached response.
250- return new Promise ( resolve => {
251- event . getContent ( content => resolve ( content ) ) ;
252- } ) ;
220+ const fetchFromNetworkCache = ( url , resolve , reject ) => {
221+ if ( __DEBUG__ ) {
222+ console . log ( '[main] fetchFromNetworkCache()' , url ) ;
253223 }
254224
255- // If DevTools was opened after the page started loading,
256- // we may have missed some requests.
257- // So fall back to a fetch() and hope we get a cached response.
225+ chrome . devtools . network . getHAR ( harLog => {
226+ for ( let i = 0 ; i < harLog . entries . length ; i ++ ) {
227+ const entry = harLog . entries [ i ] ;
228+ if ( url === entry . request . url ) {
229+ entry . getContent ( content => {
230+ if ( content ) {
231+ resolve ( content ) ;
232+ } else {
233+ if ( __DEBUG__ ) {
234+ console . log (
235+ '[main] fetchFromNetworkCache() Invalid content returned by getContent():' ,
236+ content ,
237+ ) ;
238+ }
239+
240+ // Edge case where getContent() returned null; fall back to fetch.
241+ fetchFromPage ( url , resolve ) ;
242+ }
243+ } ) ;
244+
245+ return ;
246+ }
258247
259- return new Promise ( ( resolve , reject ) => {
260- function onPortMessage ( { payload, source} ) {
261- if ( source === 'react-devtools-content-script' ) {
262- switch ( payload ?. type ) {
263- case 'fetch-file-with-cache-complete' :
264- chrome . runtime . onMessage . removeListener ( onPortMessage ) ;
265- resolve ( payload . value ) ;
266- break ;
267- case 'fetch-file-with-cache-error' :
268- chrome . runtime . onMessage . removeListener ( onPortMessage ) ;
269- reject ( payload . value ) ;
270- break ;
271- }
248+ if ( __DEBUG__ ) {
249+ console . log (
250+ '[main] fetchFromNetworkCache() No cached request found in getHAR()' ,
251+ ) ;
272252 }
253+
254+ // No matching URL found; fall back to fetch.
255+ fetchFromPage ( url , resolve ) ;
273256 }
257+ } ) ;
258+ } ;
274259
275- chrome . runtime . onMessage . addListener ( onPortMessage ) ;
260+ const fetchFromPage = ( url , resolve , reject ) => {
261+ if ( __DEBUG__ ) {
262+ console . log ( '[main] fetchFromPage()' , url ) ;
263+ }
276264
277- chrome . devtools . inspectedWindow . eval ( `
278- window.postMessage({
279- source: 'react-devtools-extension',
280- payload: {
281- type: 'fetch-file-with-cache',
282- url: "${ url } ",
283- },
284- });
285- ` ) ;
265+ function onPortMessage ( { payload, source} ) {
266+ if ( source === 'react-devtools-content-script' ) {
267+ switch ( payload ?. type ) {
268+ case 'fetch-file-with-cache-complete' :
269+ chrome . runtime . onMessage . removeListener ( onPortMessage ) ;
270+ resolve ( payload . value ) ;
271+ break ;
272+ case 'fetch-file-with-cache-error' :
273+ chrome . runtime . onMessage . removeListener ( onPortMessage ) ;
274+ reject ( payload . value ) ;
275+ break ;
276+ }
277+ }
278+ }
279+
280+ chrome . runtime . onMessage . addListener ( onPortMessage ) ;
281+
282+ chrome . devtools . inspectedWindow . eval ( `
283+ window.postMessage({
284+ source: 'react-devtools-extension',
285+ payload: {
286+ type: 'fetch-file-with-cache',
287+ url: "${ url } ",
288+ },
289+ });
290+ ` ) ;
291+ } ;
292+
293+ // Fetching files from the extension won't make use of the network cache
294+ // for resources that have already been loaded by the page.
295+ // This helper function allows the extension to request files to be fetched
296+ // by the content script (running in the page) to increase the likelihood of a cache hit.
297+ fetchFileWithCaching = url => {
298+ return new Promise ( ( resolve , reject ) => {
299+ // Try fetching from the Network cache first.
300+ // If DevTools was opened after the page started loading, we may have missed some requests.
301+ // So fall back to a fetch() from the page and hope we get a cached response that way.
302+ fetchFromNetworkCache ( url , resolve , reject ) ;
286303 } ) ;
287304 } ;
288305 }
@@ -441,9 +458,6 @@ function createPanelIfReactLoaded() {
441458
442459 // Re-initialize DevTools panel when a new page is loaded.
443460 chrome . devtools . network . onNavigated . addListener ( function onNavigated ( ) {
444- // Clear cached requests when a new page is opened.
445- cachedNetworkEvents . clear ( ) ;
446-
447461 // Re-initialize saved filters on navigation,
448462 // since global values stored on window get reset in this case.
449463 syncSavedPreferences ( ) ;
@@ -460,9 +474,6 @@ function createPanelIfReactLoaded() {
460474
461475// Load (or reload) the DevTools extension when the user navigates to a new page.
462476function checkPageForReact ( ) {
463- // Clear cached requests when a new page is opened.
464- cachedNetworkEvents . clear ( ) ;
465-
466477 syncSavedPreferences ( ) ;
467478 createPanelIfReactLoaded ( ) ;
468479}
0 commit comments