@@ -19,33 +19,13 @@ import {
19
19
localStorageSetItem ,
20
20
} from 'react-devtools-shared/src/storage' ;
21
21
import DevTools from 'react-devtools-shared/src/devtools/views/DevTools' ;
22
+ import { __DEBUG__ } from 'react-devtools-shared/src/constants' ;
22
23
23
24
const LOCAL_STORAGE_SUPPORTS_PROFILING_KEY =
24
25
'React::DevTools::supportsProfiling' ;
25
26
26
27
const isChrome = getBrowserName ( ) === 'Chrome' ;
27
28
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
-
49
29
let panelCreated = false ;
50
30
51
31
// The renderer interface can't read saved component filters directly,
@@ -237,52 +217,89 @@ function createPanelIfReactLoaded() {
237
217
// never reaches the chrome.runtime.onMessage event listener.
238
218
let fetchFileWithCaching = null ;
239
219
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 ) ;
253
223
}
254
224
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
+ }
258
247
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
+ ) ;
272
252
}
253
+
254
+ // No matching URL found; fall back to fetch.
255
+ fetchFromPage ( url , resolve ) ;
273
256
}
257
+ } ) ;
258
+ } ;
274
259
275
- chrome . runtime . onMessage . addListener ( onPortMessage ) ;
260
+ const fetchFromPage = ( url , resolve , reject ) => {
261
+ if ( __DEBUG__ ) {
262
+ console . log ( '[main] fetchFromPage()' , url ) ;
263
+ }
276
264
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 ) ;
286
303
} ) ;
287
304
} ;
288
305
}
@@ -441,9 +458,6 @@ function createPanelIfReactLoaded() {
441
458
442
459
// Re-initialize DevTools panel when a new page is loaded.
443
460
chrome . devtools . network . onNavigated . addListener ( function onNavigated ( ) {
444
- // Clear cached requests when a new page is opened.
445
- cachedNetworkEvents . clear ( ) ;
446
-
447
461
// Re-initialize saved filters on navigation,
448
462
// since global values stored on window get reset in this case.
449
463
syncSavedPreferences ( ) ;
@@ -460,9 +474,6 @@ function createPanelIfReactLoaded() {
460
474
461
475
// Load (or reload) the DevTools extension when the user navigates to a new page.
462
476
function checkPageForReact ( ) {
463
- // Clear cached requests when a new page is opened.
464
- cachedNetworkEvents . clear ( ) ;
465
-
466
477
syncSavedPreferences ( ) ;
467
478
createPanelIfReactLoaded ( ) ;
468
479
}
0 commit comments