@samitouri / QOS-React / commits / 24a2ba03fb

[DevTools] fix: dedupe file fetch requests and define a timeout (#34566)

If there is a large owner stack, we could potentially spam multiple fetch requests for the same source map. This adds a simple deduplication logic, based on URL. Also, this adds a timeout of 60 seconds to all fetch requests initiated by fileFetcher content script.

Ruslan Lesiutin committed Sep 23, 2025 at 11:38 UTC 24a2ba03fb2e1b59844d98a1ce68dce1e502d8ad
2 files changed +17 -1
packages/react-devtools-extensions/src/contentScripts/fileFetcher.js
+1 -1
@@ -23,7 +23,7 @@ function fetchResource(url) {
23 });
24 };
25
26 - fetch(url, {cache: 'force-cache'}).then(
26 + fetch(url, {cache: 'force-cache', signal: AbortSignal.timeout(60000)}).then(
27 response => {
28 if (response.ok) {
29 response
packages/react-devtools-extensions/src/main/fetchFileWithCaching.js
+16
@@ -78,6 +78,18 @@ const fetchFromNetworkCache = (url, resolve, reject) => {
78 });
79 };
80
81 +const pendingFetchRequests = new Set();
82 +function pendingFetchRequestsCleanup({payload, source}) {
83 + if (source === 'react-devtools-background') {
84 + switch (payload?.type) {
85 + case 'fetch-file-with-cache-complete':
86 + case 'fetch-file-with-cache-error':
87 + pendingFetchRequests.delete(payload.url);
88 + }
89 + }
90 +}
91 +chrome.runtime.onMessage.addListener(pendingFetchRequestsCleanup);
92 +
93 const fetchFromPage = async (url, resolve, reject) => {
94 debugLog('[main] fetchFromPage()', url);
95
@@ -97,7 +109,11 @@ const fetchFromPage = async (url, resolve, reject) => {
109 }
110
111 chrome.runtime.onMessage.addListener(onPortMessage);
112 + if (pendingFetchRequests.has(url)) {
113 + return;
114 + }
115
116 + pendingFetchRequests.add(url);
117 chrome.runtime.sendMessage({
118 source: 'devtools-page',
119 payload: {