Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include HMR refresh hash in "use cache" cache keys #75474

Open
wants to merge 10 commits into
base: canary
Choose a base branch
from

Conversation

unstubbable
Copy link
Contributor

@unstubbable unstubbable commented Jan 30, 2025

Today, when editing server components that use "use cache" functions, only updates to the uncached parts of the component will be reflected in the rendered result after the HMR refresh was applied. Any cached functions/components will show the same content as before the edit.

This is problematic when a function with a "use cache" directive is edited. In this case, the edits won't be applied, and stale content is shown in the browser, until the dev server is restarted.

With this PR, we are now including an HMR refresh hash in the cache key for all "use cache" functions. This ensures that those functions are revalidated when a server component is edited, which avoids showing stale content.

However, while the "use cache" functions are revalidated during the HMR refresh, we will still restore any fetches inside of "use cache" from the server components HMR cache (unless their input changed because of the edit).

For Webpack, a real content hash is used, which means that if an edit is reverted to a prior edit, the previously cached data will be retrieved from the cache. For Turbopack, the HMR hash is currently just an incrementing counter, which may be improved in a follow-up PR.

closes NAR-65

@ijjk ijjk added created-by: Next.js team PRs by the Next.js team. type: next labels Jan 30, 2025
@ijjk
Copy link
Member

ijjk commented Jan 30, 2025

Stats from current PR

Default Build (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary vercel/next.js hl/use-cache-fix-hmr Change
buildDuration 18.8s 15.5s N/A
buildDurationCached 14.6s 12.3s N/A
nodeModulesSize 391 MB 391 MB ⚠️ +31.7 kB
nextStartRea..uration (ms) 427ms 407ms N/A
Client Bundles (main, webpack)
vercel/next.js canary vercel/next.js hl/use-cache-fix-hmr Change
5306-HASH.js gzip 54 kB 53.9 kB N/A
8276.HASH.js gzip 169 B 168 B N/A
8377-HASH.js gzip 5.46 kB 5.46 kB N/A
bccd1874-HASH.js gzip 52.9 kB 52.9 kB N/A
framework-HASH.js gzip 57.5 kB 57.5 kB N/A
main-app-HASH.js gzip 240 B 242 B N/A
main-HASH.js gzip 34.5 kB 34.4 kB N/A
webpack-HASH.js gzip 1.71 kB 1.71 kB N/A
Overall change 0 B 0 B
Legacy Client Bundles (polyfills)
vercel/next.js canary vercel/next.js hl/use-cache-fix-hmr Change
polyfills-HASH.js gzip 39.4 kB 39.4 kB
Overall change 39.4 kB 39.4 kB
Client Pages
vercel/next.js canary vercel/next.js hl/use-cache-fix-hmr Change
_app-HASH.js gzip 193 B 193 B
_error-HASH.js gzip 193 B 193 B
amp-HASH.js gzip 512 B 510 B N/A
css-HASH.js gzip 343 B 342 B N/A
dynamic-HASH.js gzip 1.84 kB 1.84 kB
edge-ssr-HASH.js gzip 265 B 265 B
head-HASH.js gzip 363 B 362 B N/A
hooks-HASH.js gzip 393 B 392 B N/A
image-HASH.js gzip 4.59 kB 4.58 kB N/A
index-HASH.js gzip 268 B 268 B
link-HASH.js gzip 2.35 kB 2.35 kB N/A
routerDirect..HASH.js gzip 328 B 328 B
script-HASH.js gzip 397 B 397 B
withRouter-HASH.js gzip 323 B 326 B N/A
1afbb74e6ecf..834.css gzip 106 B 106 B
Overall change 3.59 kB 3.59 kB
Client Build Manifests
vercel/next.js canary vercel/next.js hl/use-cache-fix-hmr Change
_buildManifest.js gzip 748 B 747 B N/A
Overall change 0 B 0 B
Rendered Page Sizes
vercel/next.js canary vercel/next.js hl/use-cache-fix-hmr Change
index.html gzip 523 B 522 B N/A
link.html gzip 539 B 537 B N/A
withRouter.html gzip 520 B 519 B N/A
Overall change 0 B 0 B
Edge SSR bundle Size
vercel/next.js canary vercel/next.js hl/use-cache-fix-hmr Change
edge-ssr.js gzip 129 kB 129 kB N/A
page.js gzip 210 kB 210 kB N/A
Overall change 0 B 0 B
Middleware size
vercel/next.js canary vercel/next.js hl/use-cache-fix-hmr Change
middleware-b..fest.js gzip 673 B 665 B N/A
middleware-r..fest.js gzip 155 B 156 B N/A
middleware.js gzip 31.3 kB 31.3 kB N/A
edge-runtime..pack.js gzip 844 B 844 B
Overall change 844 B 844 B
Next Runtimes
vercel/next.js canary vercel/next.js hl/use-cache-fix-hmr Change
app-page-exp...dev.js gzip 386 kB 386 kB N/A
app-page-exp..prod.js gzip 132 kB 132 kB N/A
app-page-tur..prod.js gzip 145 kB 145 kB N/A
app-page-tur..prod.js gzip 141 kB 141 kB N/A
app-page.run...dev.js gzip 373 kB 373 kB N/A
app-page.run..prod.js gzip 128 kB 128 kB N/A
app-route-ex...dev.js gzip 39.2 kB 39.2 kB N/A
app-route-ex..prod.js gzip 25.6 kB 25.6 kB N/A
app-route-tu..prod.js gzip 25.6 kB 25.6 kB N/A
app-route-tu..prod.js gzip 25.4 kB 25.4 kB N/A
app-route.ru...dev.js gzip 40.8 kB 40.8 kB N/A
app-route.ru..prod.js gzip 25.4 kB 25.4 kB N/A
dist_client_...dev.js gzip 356 B 356 B
dist_client_...dev.js gzip 349 B 349 B
pages-api-tu..prod.js gzip 9.69 kB 9.69 kB
pages-api.ru...dev.js gzip 11.8 kB 11.8 kB
pages-api.ru..prod.js gzip 9.68 kB 9.68 kB
pages-turbo...prod.js gzip 21.9 kB 21.9 kB
pages.runtim...dev.js gzip 31.5 kB 31.5 kB
pages.runtim..prod.js gzip 21.9 kB 21.9 kB
server.runti..prod.js gzip 60.2 kB 60.2 kB
Overall change 167 kB 167 kB
build cache Overall increase ⚠️
vercel/next.js canary vercel/next.js hl/use-cache-fix-hmr Change
0.pack gzip 2.11 MB 2.1 MB N/A
index.pack gzip 75.4 kB 75.7 kB ⚠️ +320 B
Overall change 75.4 kB 75.7 kB ⚠️ +320 B
Diff details
Diff for middleware.js

Diff too large to display

Diff for edge-ssr.js

Diff too large to display

Diff for 5306-HASH.js

Diff too large to display

Diff for main-HASH.js

Diff too large to display

Diff for app-page-exp..ntime.dev.js
failed to diff
Diff for app-page-exp..time.prod.js

Diff too large to display

Diff for app-page-tur..time.prod.js

Diff too large to display

Diff for app-page-tur..time.prod.js

Diff too large to display

Diff for app-page.runtime.dev.js
failed to diff
Diff for app-page.runtime.prod.js

Diff too large to display

Diff for app-route-ex..ntime.dev.js

Diff too large to display

Diff for app-route-ex..time.prod.js

Diff too large to display

Diff for app-route-tu..time.prod.js

Diff too large to display

Diff for app-route-tu..time.prod.js

Diff too large to display

Diff for app-route.runtime.dev.js

Diff too large to display

Diff for app-route.ru..time.prod.js

Diff too large to display

Commit: 2ec6c43

@ijjk ijjk added the tests label Jan 30, 2025
@unstubbable unstubbable marked this pull request as ready for review January 30, 2025 17:35
Today, when editing server components that use `"use cache"` functions,
only updates to the uncached parts of the component will be reflected
in the rendered result after the HMR refresh was applied. Any cached
functions/components will show the same content as before the edit.

This is problematic when a function with a `"use cache"` directive is
edited. In this case, the edits won't be applied, and stale content is
shown in the browser, until the dev server is restarted.

With this PR, we are now including an HMR refresh hash in the cache key
for all `"use cache"` functions. This ensures that those functions
are revalidated when a server component is edited, which avoids showing
stale content.

For Webpack, a real content hash is used, which means that if an edit is
reverted again, the previously cached data will be retrieved from the
cache. For Turbopack, the HRM hash is currently just an incrementing
counter, which may be improved in a follow-up PR.
Copy link
Contributor Author

unstubbable commented Jan 31, 2025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants