Skip to content

fix: remove xhr loadend listener after each request - #295

Open
velocitysystems wants to merge 1 commit into
masterfrom
fix/xhr-loadend-listener
Open

velocitysystems wants to merge 1 commit into
masterfrom
fix/xhr-loadend-listener

Conversation

@velocitysystems

Copy link
Copy Markdown
Contributor

Follow-up to the non-blocking review comment on #269 (thread).

Problem

Each intercepted send() added an anonymous loadend listener and never removed it. In React Native, abort() resets an XMLHttpRequest to UNSENT, so it can be opened and sent again. A reused request kept one listener for every earlier send, and each completion called onResponse for all of them: N reuses made N(N+1)/2 calls. The RUM WeakMap ignored the extra calls, so no duplicate events were sent, but the work grew with each reuse.

Normal requests are not affected. After a request completes without abort(), open() throws, and libraries such as axios create a new XMLHttpRequest for each request.

Fix

The loadend listener now removes itself when it runs.

The fix does not use { once: true }. In React Native 0.81 to 0.87, XMLHttpRequest.addEventListener(type, listener) passes only those two arguments to EventTarget, so the option would be ignored on devices but would pass in Jest.

Tests

  • New test: reuse one XMLHttpRequest for three requests, and expect onResponse to be called 3 times. Without the fix, it is called 6 times.
  • Add removeEventListener to the fake XMLHttpRequest in NetworkInterceptor.test.ts and RealUserMonitor.test.ts.

Verification

  • npm test: 43 pass.
  • tsc --noEmit passes for tsconfig.json and tsconfig.test.json. ESLint and Prettier pass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant