Performance: Revalidation after mutation
This affects how quickly updated data appears on the page after a user changes it, impacting perceived responsiveness and freshness.
Jump into concepts and practice - no test required
import { mutate } from 'swr'; async function handleUpdate() { await fetch('/api/update', { method: 'POST', body: JSON.stringify(data) }); mutate('/api/data', updatedData, false); }
async function handleUpdate() { await fetch('/api/update', { method: 'POST', body: JSON.stringify(data) }); router.refresh(); }
| Pattern | DOM Operations | Reflows | Paint Cost | Verdict |
|---|---|---|---|---|
| Full router.refresh() after mutation | High (full page data reload) | Multiple reflows due to layout recalculation | High paint cost due to full content update | [X] Bad |
| Cache mutation with mutate() after mutation | Low (only updated nodes) | Single reflow or none | Low paint cost with partial update | [OK] Good |
router.refresh() to reload data without full page reload.router.reload() reloads whole page, router.push() and router.replace() change routes.import { useRouter } from 'next/navigation';
export default function UpdateButton() {
const router = useRouter();
async function handleClick() {
await fetch('/api/update', { method: 'POST' });
router.refresh();
}
return Update;
}router.refresh() to reload data.import { useRouter } from 'next/navigation';
export default function DeleteButton() {
const router = useRouter;
async function handleDelete() {
await fetch('/api/delete', { method: 'DELETE' });
router.refresh();
}
return Delete;
}const router = useRouter; missing parentheses, so router is a function reference, not the router object.router.refresh() fails because router is not an object but a function reference.router.push('/current-page') navigates and reloads route, window.location.reload() reloads full page, and doing nothing won't update data.router.refresh() triggers Next.js to revalidate data and update UI efficiently.