Skip to content

Conversation

@seanpdoyle
Copy link
Contributor

@seanpdoyle seanpdoyle commented Nov 17, 2025

What

First, extract the LRUCache (named after the "least recently used"
caching policy
) class from the SnapshotCache. The implementation
is largely unchanged, with the following exceptions:

  1. accept toCacheKey argument to coerce key values
  2. rename this.snapshot property to a more generic this.entries
  3. rename snapshot arguments to entry
  4. rename location arguments to key

Next, implement SnapshotCache in terms of the LRUCache. Since it
served as the original implementation, it is mostly an empty class that
passes the toCacheKey utility function to the constructor, and
provides a snapshots property alias that returns the this.entries
property.

Also implement the PrefetchCache as an extension of the LRUCache.
Rather than storing a reference to the "hot" entry, construct a cache of
size 1. When a new entry is put into the cache, the old entry is
expired. To supplement the "least recently used" purge strategy, also
declare a setInterval function to purge expired entries every
50ms.

Finally, change all PrefetchCache.get call sites to pass the URL
instance directly, rather than the String. Once passed as the
argument, the PrefetchCache.get implementation uses the existing
toCacheKey utility function already used by the SnapshotCache.
Rename any PrefetchCache.setLater call sites to instead invoke
PrefetchCache.putLater (named to match the SnapshotCache and
LRUCache "put" method).

Why

By adjusting the underlying PrefetchCache implementation to expand
upon an existing concept, it opens up possibilities for further
customization and configuration. Future changes could support
client-provided cache size and purge interval configuration to adjust
link prefetching behavior intervals to suit application-specific.

@seanpdoyle seanpdoyle changed the title PrefetchCache: re-use toCacheKey from SnapshotCache PrefetchCache: extract and re-use LRUCache from SnapshotCache Nov 18, 2025
@seanpdoyle
Copy link
Contributor Author

@brunoprietog I'm sorry to ping you again for review, but the original version felt like the wrong abstraction. Upon further reflection and consideration, I decided to try and re-purpose existing concepts (like the SnapshotCache class), rather than superficially refactoring the prior implementation.

What
---

First, extract the `LRUCache` (named after the ["least recently used"
caching policy][LRU]) class from the `SnapshotCache`. The implementation
is largely unchanged, with the following exceptions:

1. accept `toCacheKey` argument to coerce key values
2. rename `this.snapshot` property to a more generic `this.entries`
3. rename `snapshot` arguments to `entry`
4. rename `location` arguments to `key`

Next, implement `SnapshotCache` in terms of the `LRUCache`. Since it
served as the original implementation, it is mostly an empty class that
passes the `toCacheKey` utility function to the constructor, and
provides a `snapshots` property alias that returns the `this.entries`
property.

Also implement the `PrefetchCache` as an extension of the `LRUCache`.
Rather than storing a reference to the "hot" entry, construct a cache of
size 1. When a new entry is put into the cache, the old entry is
expired. To supplement the "least recently used" purge strategy, also
declare a [setInterval][] function to purge expired entries every
`50ms`.

Finally, change all `PrefetchCache.get` call sites to pass the [URL][]
instance directly, rather than the `String`. Once passed as the
argument, the `PrefetchCache.get` implementation uses the existing
`toCacheKey` utility function already used by the `SnapshotCache`.
Rename any `PrefetchCache.setLater` call sites to instead invoke
`PrefetchCache.putLater` (named to match the `SnapshotCache` and
`LRUCache` "put" method).

Why
---

By adjusting the underlying `PrefetchCache` implementation to expand
upon an existing concept, it opens up possibilities for further
customization and configuration. Future changes could support
client-provided cache size and purge interval configuration to adjust
link prefetching behavior intervals to suit application-specific.

[LRU]: https://en.wikipedia.org/wiki/Cache_replacement_policies#LRU
[setInterval]: https://developer.mozilla.org/en-US/docs/Web/API/Window/setInterval
[URL]: https://developer.mozilla.org/en-US/docs/Web/API/URL
@jorgemanrubia jorgemanrubia merged commit b65bf46 into hotwired:main Nov 18, 2025
1 check passed
@seanpdoyle seanpdoyle deleted the debounced-prefetch branch November 18, 2025 20:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants