Skip to content

feat: optimize page leave events for bfcache#2458

Merged
saikumarrs merged 2 commits into
developfrom
feature/sdk-3739-spike-investigate-if-we-can-get-away-with-beforeunload-event
Sep 12, 2025
Merged

feat: optimize page leave events for bfcache#2458
saikumarrs merged 2 commits into
developfrom
feature/sdk-3739-spike-investigate-if-we-can-get-away-with-beforeunload-event

Conversation

@saikumarrs

@saikumarrs saikumarrs commented Sep 1, 2025

Copy link
Copy Markdown
Member

PR Description

As beforeunload event registration impacts bfcache optimisation on modern browsers, so restricting it to only IE 11.

Linear task (optional)

https://linear.app/rudderstack/issue/SDK-3739/spike-investigate-if-we-can-get-away-with-beforeunload-event-handler

Cross Browser Tests

Please confirm you have tested for the following browsers:

  • Chrome
  • Firefox
  • IE11

Sanity Suite

  • All sanity suite test cases pass locally

Security

  • The code changed/added as part of this pull request won't create any security issues with how the software is being used.

Summary by CodeRabbit

  • Bug Fixes

    • Improved reliability of page leave/unload handling across browsers; IE11-specific listener behavior prevents duplicate or missed callbacks.
  • Refactor

    • Moved IE11 detection into a shared utility so capability checks are consistent across packages.
  • Tests

    • Expanded IE11 and page lifecycle tests covering beforeunload/pagehide, visibility changes, and multiple-event scenarios.
  • Chores

    • Updated bundle size limit to reflect current build size.

@saikumarrs saikumarrs self-assigned this Sep 1, 2025
@coderabbitai

coderabbitai Bot commented Sep 1, 2025

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds an isIE11 detector to analytics-js-common, uses it to conditionally register beforeunload only on IE11, updates tests to simulate IE11 and switch a test to pagehide, removes the local isIE11 export from the capabilities manager detection module, and increments a size-limit value.

Changes

Cohort / File(s) Summary
IE11 detection introduction
packages/analytics-js-common/src/utilities/detect.ts
Adds and exports isIE11(): boolean that checks globalThis.navigator.userAgent for the IE11 Trident pattern.
Page leave logic adjustment
packages/analytics-js-common/src/utilities/page.ts
Imports isIE11 and registers the beforeunload listener only when isIE11() is true; other listeners unchanged; public API unchanged.
Tests — detection and page leave
packages/analytics-js-common/__tests__/utilities/detect.test.ts, packages/analytics-js-common/__tests__/utilities/page.test.ts
Adds parameterized tests for isIE11; updates page.leave tests to simulate IE11 UA, restore original UA after each test, and add IE11-specific beforeunload/visibility/blur scenarios.
Capabilities manager import refactor
packages/analytics-js/src/components/capabilitiesManager/CapabilitiesManager.ts
Switches isIE11 import to @rudderstack/analytics-js-common/utilities/detect; usage unchanged.
Removal of local IE11 detection export
packages/analytics-js/src/components/capabilitiesManager/detection/browser.ts, packages/analytics-js/src/components/capabilitiesManager/detection/index.ts
Removes local isIE11 implementation and its export; re-export list updated to exclude isIE11.
Test alignment with new page leave flow
packages/analytics-js/__tests__/app/RudderAnalytics.test.ts
Replaces simulated beforeunload on window with pagehide dispatched on document.
Build config size limit tweak
packages/analytics-js/.size-limit.mjs
Increases “Core (Content Script) - Modern - NPM (CJS)” size limit from 41 KiB to 41.5 KiB (data value change only).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant App
  participant PageUtils as analytics-js-common/utilities/page
  participant Detect as analytics-js-common/utilities/detect

  Note over App,PageUtils: onPageLeave(callback) initialization
  App->>PageUtils: onPageLeave(callback)
  PageUtils->>Detect: isIE11()
  alt IE11
    Note right of PageUtils: register beforeunload listener
    PageUtils->>PageUtils: addEventListener('beforeunload', ...)
  else Non-IE11
    Note right of PageUtils: skip beforeunload
  end
  Note over PageUtils: register blur, focus, pagehide, visibilitychange listeners

  rect rgba(230,245,255,0.6)
  Note over App,PageUtils: Page exit signals
  App-->>PageUtils: pagehide / visibilitychange / blur
  PageUtils-->>App: invoke callback (true/false depending on path)
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs


📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 88bc148 and 49076a2.

📒 Files selected for processing (2)
  • packages/analytics-js-common/__tests__/utilities/page.test.ts (6 hunks)
  • packages/analytics-js-common/src/utilities/detect.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/analytics-js-common/src/utilities/detect.ts
  • packages/analytics-js-common/tests/utilities/page.test.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Bundle size checks
  • GitHub Check: Code quality checks
  • GitHub Check: Unit Tests and Lint

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/analytics-js-common/src/utilities/page.ts (1)

51-55: Also listen for pagehide on window to match the spec

pagehide is a Window event in specs; some engines may not deliver it to document. Safe to register on window in addition to document.

-  document.addEventListener('pagehide', () => {
+  // Listen on both Window and Document for broader compatibility
+  (globalThis as typeof window).addEventListener('pagehide', () => {
+    isAccessible = document.visibilityState === 'hidden';
+    handleOnLeave();
+  });
+  document.addEventListener('pagehide', () => {
     isAccessible = document.visibilityState === 'hidden';
     handleOnLeave();
   });
🧹 Nitpick comments (4)
packages/analytics-js/__tests__/app/RudderAnalytics.test.ts (1)

804-806: Good switch to pagehide; consider exercising bfcache via PageTransitionEvent

Dispatching pagehide on document aligns with the listener site. Optionally, emit a PageTransitionEvent (when available) to validate bfcache scenarios (persisted true/false).

-      const event = new Event('pagehide');
-      document.dispatchEvent(event);
+      const event =
+        typeof (globalThis as any).PageTransitionEvent === 'function'
+          ? new (globalThis as any).PageTransitionEvent('pagehide', { persisted: false })
+          : new Event('pagehide');
+      document.dispatchEvent(event);
packages/analytics-js-common/src/utilities/page.ts (1)

39-45: Blur-based fallback can overfire on simple tab switches

Blur fires on tab switches too; consider narrowing to iOS Safari only to avoid false positives.

-  (globalThis as typeof window).addEventListener('blur', () => {
+  const isIosSafari =
+    /iP(hone|ad|od)/.test(globalThis.navigator?.platform || '') &&
+    /Safari/.test(globalThis.navigator?.userAgent || '') &&
+    !/Chrome|CriOS|FxiOS/.test(globalThis.navigator?.userAgent || '');
+  (globalThis as typeof window).addEventListener('blur', () => {
     isAccessible = true;
     handleOnLeave();
-  });
+  }, { passive: true });
packages/analytics-js/src/components/capabilitiesManager/detection/index.ts (1)

2-2: isIE11 re-export removed — verify no remaining imports rely on this path

Search for imports from './detection' pulling isIE11 and update them to @rudderstack/analytics-js-common/utilities/detect to avoid breakages.

Optionally, keep a transitional re-export to ease migration:

 export { isBrowser, isNode, hasCrypto, hasUAClientHints, hasBeacon } from './browser';
+export { isIE11 } from '@rudderstack/analytics-js-common/utilities/detect';
packages/analytics-js-common/__tests__/utilities/page.test.ts (1)

49-51: Prefer spying on navigator.userAgent over direct assignment

userAgent may be non-writable; spying is safer and avoids global mutation. Consider a small helper to DRY the pattern.

Example helper:

const withUserAgent = (ua: string, fn: () => void) => {
  const spy = jest.spyOnProperty(globalThis.navigator, 'userAgent', 'get').mockReturnValue(ua as any);
  try { fn(); } finally { spy.mockRestore(); }
};

Usage:

withUserAgent('Mozilla/5.0 (Windows NT 10.0; Trident/7.0; rv:11.0) like Gecko', () => {
  const evCallback = jest.fn();
  onPageLeave(evCallback);
  dispatchWindowEvent('beforeunload');
  expect(evCallback).toHaveBeenCalledTimes(1);
  expect(evCallback).toHaveBeenCalledWith(false);
});

Also applies to: 106-109, 118-121, 181-184, 201-204

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 7ca8a6e and 88bc148.

📒 Files selected for processing (9)
  • packages/analytics-js-common/__tests__/utilities/detect.test.ts (2 hunks)
  • packages/analytics-js-common/__tests__/utilities/page.test.ts (6 hunks)
  • packages/analytics-js-common/src/utilities/detect.ts (1 hunks)
  • packages/analytics-js-common/src/utilities/page.ts (2 hunks)
  • packages/analytics-js/.size-limit.mjs (1 hunks)
  • packages/analytics-js/__tests__/app/RudderAnalytics.test.ts (1 hunks)
  • packages/analytics-js/src/components/capabilitiesManager/CapabilitiesManager.ts (1 hunks)
  • packages/analytics-js/src/components/capabilitiesManager/detection/browser.ts (1 hunks)
  • packages/analytics-js/src/components/capabilitiesManager/detection/index.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/002-javascript-typescript.mdc)

Code must work in browsers AND service workers (no Node.js APIs)

Files:

  • packages/analytics-js/__tests__/app/RudderAnalytics.test.ts
  • packages/analytics-js-common/src/utilities/detect.ts
  • packages/analytics-js/src/components/capabilitiesManager/CapabilitiesManager.ts
  • packages/analytics-js/src/components/capabilitiesManager/detection/index.ts
  • packages/analytics-js-common/__tests__/utilities/detect.test.ts
  • packages/analytics-js/src/components/capabilitiesManager/detection/browser.ts
  • packages/analytics-js-common/src/utilities/page.ts
  • packages/analytics-js-common/__tests__/utilities/page.test.ts
packages/*/__tests__/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place unit tests under packages/[package-name]/tests/

Files:

  • packages/analytics-js/__tests__/app/RudderAnalytics.test.ts
  • packages/analytics-js-common/__tests__/utilities/detect.test.ts
  • packages/analytics-js-common/__tests__/utilities/page.test.ts
packages/*/__tests__/**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use Jest for tests and MSW for HTTP mocking

Files:

  • packages/analytics-js/__tests__/app/RudderAnalytics.test.ts
  • packages/analytics-js-common/__tests__/utilities/detect.test.ts
  • packages/analytics-js-common/__tests__/utilities/page.test.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Adhere to the repository’s ESLint configuration for JavaScript/TypeScript code

Files:

  • packages/analytics-js/__tests__/app/RudderAnalytics.test.ts
  • packages/analytics-js-common/src/utilities/detect.ts
  • packages/analytics-js/src/components/capabilitiesManager/CapabilitiesManager.ts
  • packages/analytics-js/src/components/capabilitiesManager/detection/index.ts
  • packages/analytics-js-common/__tests__/utilities/detect.test.ts
  • packages/analytics-js/src/components/capabilitiesManager/detection/browser.ts
  • packages/analytics-js-common/src/utilities/page.ts
  • packages/analytics-js-common/__tests__/utilities/page.test.ts
packages/*/src/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place all package source code under packages/[package-name]/src/

Files:

  • packages/analytics-js-common/src/utilities/detect.ts
  • packages/analytics-js/src/components/capabilitiesManager/CapabilitiesManager.ts
  • packages/analytics-js/src/components/capabilitiesManager/detection/index.ts
  • packages/analytics-js/src/components/capabilitiesManager/detection/browser.ts
  • packages/analytics-js-common/src/utilities/page.ts
packages/analytics-js/src/**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use @preact/signals-core for reactive state in the core SDK (analytics-js)

Files:

  • packages/analytics-js/src/components/capabilitiesManager/CapabilitiesManager.ts
  • packages/analytics-js/src/components/capabilitiesManager/detection/index.ts
  • packages/analytics-js/src/components/capabilitiesManager/detection/browser.ts
packages/!(analytics-js-common)/**/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Prefer shared TypeScript types from analytics-js-common across packages

Files:

  • packages/analytics-js/src/components/capabilitiesManager/CapabilitiesManager.ts
  • packages/analytics-js/src/components/capabilitiesManager/detection/index.ts
  • packages/analytics-js/src/components/capabilitiesManager/detection/browser.ts
🧠 Learnings (16)
📓 Common learnings
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1754
File: packages/analytics-js-service-worker/README.md:0-0
Timestamp: 2024-10-08T15:52:59.819Z
Learning: saikumarrs prefers simplified language in documentation, avoiding redundant phrases.
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1754
File: packages/analytics-js-service-worker/README.md:0-0
Timestamp: 2024-06-14T09:50:33.511Z
Learning: saikumarrs prefers simplified language in documentation, avoiding redundant phrases.
📚 Learning: 2024-10-09T06:41:05.073Z
Learnt from: MoumitaM
PR: rudderlabs/rudder-sdk-js#1876
File: packages/analytics-js/src/app/RudderAnalytics.ts:0-0
Timestamp: 2024-10-09T06:41:05.073Z
Learning: The `trackPageLifecycleEvents` method in `packages/analytics-js/src/app/RudderAnalytics.ts` does not require refactoring as the current implementation is preferred.

Applied to files:

  • packages/analytics-js/__tests__/app/RudderAnalytics.test.ts
  • packages/analytics-js/src/components/capabilitiesManager/CapabilitiesManager.ts
  • packages/analytics-js-common/src/utilities/page.ts
📚 Learning: 2024-07-27T07:02:57.329Z
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1708
File: packages/analytics-js/__tests__/nativeSdkLoader.js:31-33
Timestamp: 2024-07-27T07:02:57.329Z
Learning: The loading snippet in `packages/analytics-js/__tests__/nativeSdkLoader.js` is a standard part of the SDK, and no changes are desired on it.

Applied to files:

  • packages/analytics-js/__tests__/app/RudderAnalytics.test.ts
📚 Learning: 2024-10-08T15:52:59.819Z
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1708
File: packages/analytics-js-plugins/__tests__/deviceModeTransformation/index.test.ts:10-11
Timestamp: 2024-10-08T15:52:59.819Z
Learning: The misuse of `IHttpClient` in type assertions within the file `packages/analytics-js-plugins/__tests__/deviceModeTransformation/index.test.ts` has been corrected by the user.

Applied to files:

  • packages/analytics-js/__tests__/app/RudderAnalytics.test.ts
  • packages/analytics-js/src/components/capabilitiesManager/CapabilitiesManager.ts
  • packages/analytics-js/src/components/capabilitiesManager/detection/index.ts
  • packages/analytics-js-common/__tests__/utilities/detect.test.ts
  • packages/analytics-js/src/components/capabilitiesManager/detection/browser.ts
  • packages/analytics-js-common/__tests__/utilities/page.test.ts
📚 Learning: 2024-10-08T15:52:59.819Z
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1754
File: packages/analytics-js-common/src/utilities/page.ts:1-34
Timestamp: 2024-10-08T15:52:59.819Z
Learning: The compatibility issue with `globalThis` in `packages/analytics-js-common/src/utilities/page.ts` is handled elsewhere in the codebase as per user `saikumarrs`.

Applied to files:

  • packages/analytics-js/__tests__/app/RudderAnalytics.test.ts
  • packages/analytics-js/src/components/capabilitiesManager/CapabilitiesManager.ts
  • packages/analytics-js/src/components/capabilitiesManager/detection/index.ts
  • packages/analytics-js/src/components/capabilitiesManager/detection/browser.ts
  • packages/analytics-js-common/src/utilities/page.ts
  • packages/analytics-js-common/__tests__/utilities/page.test.ts
📚 Learning: 2024-07-11T08:44:37.825Z
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1782
File: packages/analytics-js-common/src/utilities/eventMethodOverloads.ts:0-0
Timestamp: 2024-07-11T08:44:37.825Z
Learning: In `packages/analytics-js-common/src/utilities/eventMethodOverloads.ts`, the `delete` operator has been replaced with setting the value to `undefined` for better performance.

Applied to files:

  • packages/analytics-js/__tests__/app/RudderAnalytics.test.ts
  • packages/analytics-js/src/components/capabilitiesManager/detection/index.ts
  • packages/analytics-js/src/components/capabilitiesManager/detection/browser.ts
  • packages/analytics-js-common/src/utilities/page.ts
📚 Learning: 2024-11-08T13:17:51.356Z
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1823
File: packages/analytics-js-common/src/utilities/retryQueue/utilities.ts:0-0
Timestamp: 2024-11-08T13:17:51.356Z
Learning: The issue regarding missing test coverage for the `findOtherQueues` function in `packages/analytics-js-common/src/utilities/retryQueue/utilities.ts` is no longer applicable.

Applied to files:

  • packages/analytics-js/__tests__/app/RudderAnalytics.test.ts
📚 Learning: 2024-10-28T08:03:12.163Z
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1902
File: packages/analytics-js-plugins/src/utilities/eventsDelivery.ts:0-0
Timestamp: 2024-10-28T08:03:12.163Z
Learning: In `packages/analytics-js-plugins/src/utilities/eventsDelivery.ts`, the issue regarding inconsistent error handling approaches in `getDMTDeliveryPayload` is no longer valid.

Applied to files:

  • packages/analytics-js/__tests__/app/RudderAnalytics.test.ts
  • packages/analytics-js/src/components/capabilitiesManager/detection/index.ts
  • packages/analytics-js/src/components/capabilitiesManager/detection/browser.ts
📚 Learning: 2024-11-09T06:40:30.520Z
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1823
File: packages/analytics-js-common/src/types/LoadOptions.ts:0-0
Timestamp: 2024-11-09T06:40:30.520Z
Learning: In the `packages/analytics-js-common/src/types/LoadOptions.ts` file, the `dataplanes` property within the `SourceConfigResponse` type has been removed as it is no longer necessary.

Applied to files:

  • packages/analytics-js/__tests__/app/RudderAnalytics.test.ts
  • packages/analytics-js/src/components/capabilitiesManager/CapabilitiesManager.ts
  • packages/analytics-js/src/components/capabilitiesManager/detection/index.ts
  • packages/analytics-js/src/components/capabilitiesManager/detection/browser.ts
📚 Learning: 2024-07-27T07:02:57.329Z
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1740
File: packages/analytics-js-common/src/utilities/url.ts:10-10
Timestamp: 2024-07-27T07:02:57.329Z
Learning: The `isValidURL` function in `packages/analytics-js-common/src/utilities/url.ts` uses `string | undefined` instead of `any` for the `url` parameter to enhance type safety.

Applied to files:

  • packages/analytics-js/src/components/capabilitiesManager/CapabilitiesManager.ts
📚 Learning: 2024-07-27T07:02:57.329Z
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1730
File: packages/analytics-js/src/constants/logMessages.ts:0-0
Timestamp: 2024-07-27T07:02:57.329Z
Learning: The `INVALID_POLYFILL_URL_WARNING` function in `packages/analytics-js/src/constants/logMessages.ts` should use `string` instead of `any` for the `customPolyfillUrl` parameter to enhance type safety.

Applied to files:

  • packages/analytics-js/src/components/capabilitiesManager/CapabilitiesManager.ts
📚 Learning: 2024-11-09T06:16:23.609Z
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1823
File: packages/analytics-js-common/src/utilities/time.ts:19-29
Timestamp: 2024-11-09T06:16:23.609Z
Learning: In the file `packages/analytics-js-common/src/utilities/time.ts`, prefer using the regex-based implementation for timezone detection in the `getTimezone()` function instead of `Intl.DateTimeFormat().resolvedOptions().timeZone`.

Applied to files:

  • packages/analytics-js-common/__tests__/utilities/detect.test.ts
📚 Learning: 2024-10-08T15:52:59.819Z
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1730
File: packages/analytics-js/src/components/utilities/url.ts:10-10
Timestamp: 2024-10-08T15:52:59.819Z
Learning: The `removeTrailingSlashes` function in `packages/analytics-js/src/components/utilities/url.ts` now uses optional chaining for better safety and readability.

Applied to files:

  • packages/analytics-js/src/components/capabilitiesManager/detection/browser.ts
📚 Learning: 2024-11-06T16:32:46.257Z
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1823
File: packages/analytics-js-plugins/src/xhrQueue/index.ts:34-34
Timestamp: 2024-11-06T16:32:46.257Z
Learning: The deprecated plugins have been removed from the `PluginName` type, so the explicit `PluginName` type annotation is no longer necessary in `packages/analytics-js-plugins/src/xhrQueue/index.ts`.

Applied to files:

  • packages/analytics-js/src/components/capabilitiesManager/detection/browser.ts
📚 Learning: 2024-10-07T05:43:26.038Z
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1823
File: packages/analytics-js-integrations/__tests__/integrations/Amplitude/browser.test.js:193-194
Timestamp: 2024-10-07T05:43:26.038Z
Learning: In the Amplitude integration tests (`browser.test.js`), the tests no longer rely on `appVersion`, so including `appVersion` in the mocked navigator object is unnecessary.

Applied to files:

  • packages/analytics-js-common/__tests__/utilities/page.test.ts
📚 Learning: 2024-11-08T12:31:40.009Z
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1823
File: packages/analytics-js-integrations/src/integrations/Sprig/browser.js:10-22
Timestamp: 2024-11-08T12:31:40.009Z
Learning: Tests for the constructor in `packages/analytics-js-integrations/src/integrations/Sprig/browser.js` are not required.

Applied to files:

  • packages/analytics-js-common/__tests__/utilities/page.test.ts
🧬 Code graph analysis (3)
packages/analytics-js/__tests__/app/RudderAnalytics.test.ts (1)
packages/analytics-v1.1/src/utils/pageProperties.js (1)
  • document (53-53)
packages/analytics-js-common/__tests__/utilities/detect.test.ts (1)
packages/analytics-js-common/src/utilities/detect.ts (1)
  • isIE11 (9-9)
packages/analytics-js-common/src/utilities/page.ts (1)
packages/analytics-js-common/src/utilities/detect.ts (1)
  • isIE11 (9-9)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Code quality checks
  • GitHub Check: Unit Tests and Lint
🔇 Additional comments (7)
packages/analytics-js/.size-limit.mjs (1)

116-116: Size limit bumped — confirm CODEOWNERS approval

The file header says “DO NOT EDIT … contact CODEOWNERS.” Please confirm approval and capture rationale in the PR description or commit message.

packages/analytics-js/src/components/capabilitiesManager/detection/browser.ts (1)

23-23: Stale imports cleared: verified no remaining imports of ./detection/browser; all isIE11 references correctly use the shared detector from @rudderstack/analytics-js-common.

packages/analytics-js-common/src/utilities/page.ts (1)

30-37: Gate beforeunload to IE11 — nice bfcache-friendly change

Scoped beforeunload to IE11 to avoid bfcache busting on modern browsers. Looks correct.

packages/analytics-js-common/__tests__/utilities/detect.test.ts (2)

1-1: Import changes look correct

isIE11 should come from analytics-js-common now. LGTM.


8-8: No-op change

Nothing to note here.

packages/analytics-js-common/__tests__/utilities/page.test.ts (2)

19-20: Good: snapshot original UA

Capturing original UA prevents test bleed. LGTM.


1-220: Confirm listener cleanup to avoid accumulation across tests

If onPageLeave registers listeners globally, ensure it de-dupes or returns a disposer that tests can call. Otherwise callbacks may accumulate.

Comment thread packages/analytics-js-common/__tests__/utilities/detect.test.ts
Comment thread packages/analytics-js-common/__tests__/utilities/page.test.ts
Comment thread packages/analytics-js-common/src/utilities/detect.ts Outdated
@github-actions

github-actions Bot commented Sep 1, 2025

Copy link
Copy Markdown

size-limit report 📦

Name Size Delta Limit check
Cookies Utils - Legacy - NPM (ESM) 1.54 KB 0 B (0% 🟢) 2 KB (✅)
Cookies Utils - Legacy - NPM (CJS) 1.74 KB 0 B (0% 🟢) 2 KB (✅)
Cookies Utils - Legacy - NPM (UMD) 1.52 KB 0 B (0% 🟢) 2 KB (✅)
Cookies Utils - Modern - NPM (ESM) 1.16 KB 0 B (0% 🟢) 1.5 KB (✅)
Cookies Utils - Modern - NPM (CJS) 1.39 KB 0 B (0% 🟢) 1.5 KB (✅)
Cookies Utils - Modern - NPM (UMD) 1.15 KB 0 B (0% 🟢) 1.5 KB (✅)
Plugins Module Federation Mapping - Legacy - CDN 330 B 0 B (0% 🟢) 512 B (✅)
Plugins Module Federation Mapping - Modern - CDN 330 B 0 B (0% 🟢) 512 B (✅)
Plugins - Legacy - CDN 13.55 KB 0 B (0% 🟢) 15 KB (✅)
Plugins - Modern - CDN 5.48 KB 0 B (0% 🟢) 6 KB (✅)
Service Worker - Legacy - NPM (ESM) 29.26 KB 0 B (0% 🟢) 31 KB (✅)
Service Worker - Legacy - NPM (CJS) 29.5 KB 0 B (0% 🟢) 31 KB (✅)
Service Worker - Legacy - NPM (UMD) 29.23 KB 0 B (0% 🟢) 31 KB (✅)
Service Worker - Modern - NPM (ESM) 25.64 KB 0 B (0% 🟢) 26 KB (✅)
Service Worker - Modern - NPM (CJS) 25.9 KB 0 B (0% 🟢) 26.5 KB (✅)
Service Worker - Modern - NPM (UMD) 25.64 KB 0 B (0% 🟢) 26 KB (✅)
Load Snippet 780 B 0 B (0% 🟢) 1 KB (✅)
Common - No bundling 5.73 KB 44 B (+0.76% 🔺) 6 KB (✅)
Core - Legacy - NPM (ESM) 48.04 KB 12 B (+0.03% 🔺) 50 KB (✅)
Core - Legacy - NPM (CJS) 48.3 KB -9 B (-0.02% 🟢) 50 KB (✅)
Core - Legacy - NPM (UMD) 48.07 KB -8 B (-0.02% 🟢) 50 KB (✅)
Core - Legacy - CDN 48.14 KB 32 B (+0.07% 🔺) 50 KB (✅)
Core - Modern - NPM (ESM) 27.67 KB 9 B (+0.04% 🔺) 28 KB (✅)
Core - Modern - NPM (CJS) 27.93 KB 74 B (+0.26% 🔺) 28 KB (✅)
Core - Modern - NPM (UMD) 27.69 KB 11 B (+0.04% 🔺) 28 KB (✅)
Core - Modern - CDN 27.92 KB 13 B (+0.05% 🔺) 28 KB (✅)
Core (Bundled) - Legacy - NPM (ESM) 48.04 KB 12 B (+0.03% 🔺) 50 KB (✅)
Core (Bundled) - Legacy - NPM (CJS) 48.26 KB 6 B (+0.02% 🔺) 50 KB (✅)
Core (Bundled) - Legacy - NPM (UMD) 48.07 KB -8 B (-0.02% 🟢) 50 KB (✅)
Core (Bundled) - Modern - NPM (ESM) 40.79 KB 19 B (+0.05% 🔺) 41 KB (✅)
Core (Bundled) - Modern - NPM (CJS) 41.03 KB 15 B (+0.04% 🔺) 41.5 KB (✅)
Core (Bundled) - Modern - NPM (UMD) 40.78 KB -35 B (-0.09% 🟢) 41 KB (✅)
Core (Content Script) - Legacy - NPM (ESM) 47.97 KB 6 B (+0.02% 🔺) 50 KB (✅)
Core (Content Script) - Legacy - NPM (CJS) 48.23 KB 15 B (+0.04% 🔺) 50 KB (✅)
Core (Content Script) - Legacy - NPM (UMD) 48.01 KB -4 B (-0.01% 🟢) 50 KB (✅)
Core (Content Script) - Modern - NPM (ESM) 40.75 KB 81 B (+0.2% 🔺) 41 KB (✅)
Core (Content Script) - Modern - NPM (CJS) 41.01 KB 8 B (+0.02% 🔺) 41.5 KB (✅)
Core (Content Script) - Modern - NPM (UMD) 40.75 KB 33 B (+0.08% 🔺) 41 KB (✅)

@sonarqubecloud

sonarqubecloud Bot commented Sep 1, 2025

Copy link
Copy Markdown

@saikumarrs saikumarrs marked this pull request as ready for review September 1, 2025 19:10
Copilot AI review requested due to automatic review settings September 1, 2025 19:10
@saikumarrs saikumarrs requested a review from a team as a code owner September 1, 2025 19:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR optimizes browser back/forward cache (bfcache) performance by restricting the beforeunload event handler to only IE11, as this event registration negatively impacts bfcache optimization in modern browsers.

  • Moved IE11 detection from analytics-js package to shared analytics-js-common utilities
  • Conditionally registered beforeunload event only for IE11 browsers
  • Updated tests to reflect IE11-specific behavior and added comprehensive browser detection tests

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/analytics-js/src/components/capabilitiesManager/detection/index.ts Removed isIE11 export from local detection module
packages/analytics-js/src/components/capabilitiesManager/detection/browser.ts Removed isIE11 function implementation
packages/analytics-js/src/components/capabilitiesManager/CapabilitiesManager.ts Updated import to use isIE11 from shared utilities
packages/analytics-js/tests/app/RudderAnalytics.test.ts Changed test to use pagehide event instead of beforeunload
packages/analytics-js/.size-limit.mjs Increased bundle size limit to accommodate changes
packages/analytics-js-common/src/utilities/page.ts Added conditional beforeunload registration for IE11 only
packages/analytics-js-common/src/utilities/detect.ts Added isIE11 detection function to shared utilities
packages/analytics-js-common/tests/utilities/page.test.ts Updated tests to mock IE11 user agent for beforeunload tests
packages/analytics-js-common/tests/utilities/detect.test.ts Added comprehensive tests for isIE11 detection

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment thread packages/analytics-js-common/src/utilities/detect.ts
@saikumarrs saikumarrs merged commit 48c1f20 into develop Sep 12, 2025
26 of 28 checks passed
@saikumarrs saikumarrs deleted the feature/sdk-3739-spike-investigate-if-we-can-get-away-with-beforeunload-event branch September 12, 2025 07:17
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.

3 participants