Skip to content

[Feature] Lazy-initialize InteractionTracker to avoid unnecessary network requests on page load #76

@numbers-official

Description

@numbers-official

Summary

The InteractionTracker class is instantiated as a module-level singleton at import time (src/modal/interaction-tracker.ts, line 163), which immediately triggers a network request to fetch the decryption key from CDN and sends a SCRIPT tracking event. This happens on every page load regardless of whether the user ever interacts with the Capture Eye widget.

Affected Code

File: src/modal/interaction-tracker.ts

Line 163:

const instance: InteractionTracker = new InteractionTracker();

Constructor (lines 20-26):

constructor() {
    this.domain = window.location.hostname;
    this.path = window.location.pathname;
    this.path = this.path.startsWith('/') ? this.path.substring(1) : this.path;
    this.token = null;
    this.getToken();  // Immediately fetches key from CDN
}

ModalManager constructor (line 15):

private constructor() {
    interactionTracker.trackInteraction(TrackerEvent.SCRIPT);  // Fires immediately
}

Impact

  • Performance: Every page load incurs a fetch to static-cdn.numbersprotocol.io/capture-eye/token-crypto-key.txt + a POST to the events API, even if the user never clicks the Capture Eye button
  • Bandwidth: Unnecessary network requests impact page load metrics (LCP, TTI) for sites embedding Capture Eye
  • Privacy: Users who never interact with the widget still have their page visit tracked via the SCRIPT event

Suggested Approach

  1. Convert the module-level singleton to a lazy-initialized pattern:
let instance: InteractionTracker | null = null;

export function getInteractionTracker(): InteractionTracker {
    if (!instance) {
        instance = new InteractionTracker();
    }
    return instance;
}

export default { getInteractionTracker };
  1. Defer the SCRIPT tracking event to the first user interaction (e.g., first openEye() call) rather than on import
  2. Defer getToken() call until the first trackInteraction() call actually needs it

This change would eliminate 2 network requests per page load for users who never interact with the widget, improving page performance and reducing unnecessary server load.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions