Skip to content

[PROF-13950] ⚡️ Memoize getTimeZone to avoid repeated Intl.DateTimeFormat instantiation#4302

Draft
thomasbertet wants to merge 2 commits intomainfrom
thomas.bertet/PROF-13950-investigate-slow-code-path
Draft

[PROF-13950] ⚡️ Memoize getTimeZone to avoid repeated Intl.DateTimeFormat instantiation#4302
thomasbertet wants to merge 2 commits intomainfrom
thomas.bertet/PROF-13950-investigate-slow-code-path

Conversation

@thomasbertet
Copy link
Collaborator

@thomasbertet thomasbertet commented Mar 9, 2026

Motivation

new Intl.DateTimeFormat() can be an expensive browser API call (involves locale negotiation and timezone resolution). It was being executed on every VIEW_UPDATED lifecycle event via getTimeZone() in processViewUpdate().

VIEW_UPDATED fires frequently: on every captured action, error, resource, long task, CLS/LCP/FCP update, context change, and more. Since the timezone never changes during a page session, this repeated work was pure waste.

Related: PROF-13950

Identified while looking at some RUM Browser Profiler INP:
Screenshot 2026-03-09 at 15 41 07

Changes

Memoize the timezone value at module load time in packages/core/src/tools/utils/timezone.ts. resolveTimeZone() runs once, the result is stored in a module-level constant, and getTimeZone() simply returns it.

No behavior change — the returned value is identical.

Test instructions

No specific repro needed. Verify that getTimeZone() still returns the correct timezone string in unit tests.

Checklist

  • Tested locally
  • Tested on staging
  • Added unit tests for this change.
  • Added e2e/integration tests for this change.
  • Updated documentation and/or relevant AGENTS.md file

…rmat instantiation

new Intl.DateTimeFormat() is expensive (locale negotiation + timezone resolution)
and was called on every VIEW_UPDATED event. Since the timezone is static for the
page lifetime, compute it once at module load time instead.
Switch from eager module-level computation to lazy caching:
compute the timezone on first call and cache it, avoiding any
cost at module load time.
@cit-pr-commenter-54b7da
Copy link

Bundles Sizes Evolution

📦 Bundle Name Base Size Local Size 𝚫 𝚫% Status
Rum 174.43 KiB 174.46 KiB +34 B +0.02%
Rum Profiler 6.16 KiB 6.16 KiB 0 B 0.00%
Rum Recorder 25.24 KiB 25.24 KiB 0 B 0.00%
Logs 56.84 KiB 56.84 KiB 0 B 0.00%
Flagging 944 B 944 B 0 B 0.00%
Rum Slim 130.11 KiB 130.15 KiB +34 B +0.03%
Worker 23.63 KiB 23.63 KiB 0 B 0.00%
🚀 CPU Performance

Pending...

🧠 Memory Performance

Pending...

🔗 RealWorld

@datadog-datadog-prod-us1-2
Copy link

✅ Tests

🎉 All green!

❄️ No new flaky tests detected
🧪 All tests passed

🎯 Code Coverage (details)
Patch Coverage: 66.67%
Overall Coverage: 76.76% (+0.01%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 6b7b260 | Docs | Datadog PR Page | Was this helpful? React with 👍/👎 or give us feedback!

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