feat: per-element deadline scheduling in dateObserver - #370
Draft
mattcosta7 with Copilot wants to merge 2 commits into
Draft
feat: per-element deadline scheduling in dateObserver#370mattcosta7 with Copilot wants to merge 2 commits into
mattcosta7 with Copilot wants to merge 2 commits into
Conversation
Add a WeakMap<RelativeTimeElement, number> tracking each element's next-update deadline so slow-changing elements are skipped on fast ticks driven by a single second-precision element. - dateObserver.deadlines: WeakMap seeds per element in observe(), cleared in unobserve(), checked per tick in update() - update() only calls timeEl.update() when its deadline has passed, then recomputes the deadline as now + getUnitFactor(el) - Per-element try/catch in update() so one throwing element cannot abort the tick or skip the rescheduler - nearest is computed across ALL elements (not just updated ones) so the timer fires at the earliest remaining deadline - 5 new tests covering: fast/slow cadence isolation, slow element eventual update, synchronous first render, datetime-change deadline reset, and error isolation Benchmark: 1 second-precision element + 300 month-old elements over 10s: 3311 update() calls before → 10 after (300× reduction).
Copilot
AI
changed the title
[WIP] Optimize dateObserver for individual update deadlines
feat: per-element deadline scheduling in dateObserver
Jul 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A single second-precision
<relative-time>element drives the entire page to a 1 s tick. Every tick callsupdate()on every observed element — so 300 elements showing "3 months ago" each run a fullelapsedTime()+#resolveFormat()+Intl.format()pass every second, producing identical output each time.Approach
Keep the single shared timer but give each element its own next-due timestamp via a
WeakMap<RelativeTimeElement, number>. Each tick skips elements whose deadline hasn't passed; after updating an element its deadline is reset tonow + getUnitFactor(el). The next timer interval is the minimum remaining time across all observed elements.Key details
WeakMapnotMap— deadlines are only looked up by key (we iteratethis.elements), so no iteration over the map itself is needed andWeakMapgives better GC semantics.observe()during a tick —timeEl.update()callsobserve(this)at the end of every update. The existingif (this.updating) returnguard prevents clobbering the deadline the tick loop is about to set immediately aftertimeEl.update()returns. Attribute changes arriving outside a tick (the normalattributeChangedCallback→ microtask →update()path) always re-enterobserve()withupdating = false, so they correctly recompute the deadline.timeEl.update()call in try/catch, rethrowing async, so one throwing element cannot abort the tick or skip the reschedule.Benchmark
1 second-precision element + 300 month-old elements, 10 s simulated time:
update()callsTests added
connectedCallbackdatetimechange resets the deadline to the fast cadence