diff --git a/core/gather/driver/network-monitor.js b/core/gather/driver/network-monitor.js index 814c357a3703..4788037ab94c 100644 --- a/core/gather/driver/network-monitor.js +++ b/core/gather/driver/network-monitor.js @@ -129,7 +129,7 @@ class NetworkMonitor extends NetworkMonitorEventEmitter { * Returns whether the network is completely idle (i.e. there are 0 inflight network requests). */ isIdle() { - return this._isActiveIdlePeriod(0); + return this._isIdlePeriod(0); } /** @@ -144,10 +144,13 @@ class NetworkMonitor extends NetworkMonitorEventEmitter { const rootFrameRequest = requests.find(r => r.resourceType === 'Document'); const rootFrameId = rootFrameRequest?.frameId; - return this._isActiveIdlePeriod( + return this._isIdlePeriod( 0, + // Return true if it should be a candidate for critical. request => request.frameId === rootFrameId && + // WebSocket and Server-sent Events are typically long-lived and shouldn't be considered critical. + request.resourceType !== 'WebSocket' && request.resourceType !== 'EventSource' && (request.priority === 'VeryHigh' || request.priority === 'High') ); } @@ -156,7 +159,7 @@ class NetworkMonitor extends NetworkMonitorEventEmitter { * Returns whether the network is semi-idle (i.e. there are 2 or fewer inflight network requests). */ is2Idle() { - return this._isActiveIdlePeriod(2); + return this._isIdlePeriod(2); } /** @@ -166,7 +169,7 @@ class NetworkMonitor extends NetworkMonitorEventEmitter { * @param {(request: NetworkRequest) => boolean} [requestFilter] * @return {boolean} */ - _isActiveIdlePeriod(allowedRequests, requestFilter) { + _isIdlePeriod(allowedRequests, requestFilter) { if (!this._networkRecorder) return false; const requests = this._networkRecorder.getRawRecords(); let inflightRequests = 0; @@ -174,7 +177,7 @@ class NetworkMonitor extends NetworkMonitorEventEmitter { for (let i = 0; i < requests.length; i++) { const request = requests[i]; if (request.finished) continue; - if (requestFilter && !requestFilter(request)) continue; + if (requestFilter?.(request) === false) continue; if (NetworkRequest.isNonNetworkRequest(request)) continue; inflightRequests++; } diff --git a/core/test/gather/driver/network-monitor-test.js b/core/test/gather/driver/network-monitor-test.js index 73f6dabcdb6c..77751eecb93b 100644 --- a/core/test/gather/driver/network-monitor-test.js +++ b/core/test/gather/driver/network-monitor-test.js @@ -359,6 +359,22 @@ describe('NetworkMonitor', () => { expect(monitor.is2Idle()).toBe(false); expect(monitor.isCriticalIdle()).toBe(true); }); + + it('should treat longlived stuff as noncritical', () => { + const messages = networkRecordsToDevtoolsLog([ + // WebSockets usually dont have a priority on them. SSE usually is a 'High' + {url: 'http://example.com/ws', priority: undefined, requestId: `314.1`, resourceType: 'WebSocket'}, + {url: 'http://example.com/sse', priority: 'High', requestId: `314.2`, resourceType: 'EventSource'}, + ], {skipVerification: true}).filter(event => event.method === 'Network.requestWillBeSent'); + + for (const message of messages) { + rootDispatch(message); + } + + expect(monitor.isCriticalIdle()).toBe(true); + expect(monitor.isIdle()).toBe(false); + expect(monitor.is2Idle()).toBe(true); + }); }); describe('#findNetworkQuietPeriods', () => {