Пошук уроків, статей та іншого контенту
Дослідите клієнтський Router Cache та його вплив на навігацію між сегментами маршруту.
Router Cache — це кеш маршрутизатора Next.js, який працює в браузері під час роботи застосунку з App Router.
Під час переходу між сторінками Next.js може не завантажувати весь HTML-документ заново. Замість цього він отримує від сервера дані Server Components у форматі React Server Component Payload і зберігає частини результату в пам’яті браузера.
У Router Cache зберігаються сегменти маршруту, наприклад:
/
├── layout
└── page
/dashboard
├── layout
└── page
/dashboard/settings
├── layout
├── settings
└── pageСегментом є частина шляху або відповідний layout чи page.
Розглянемо перехід:
/dashboard → /dashboard/settingsЯкщо обидва маршрути використовують спільний app/dashboard/layout.tsx, Next.js може:
залишити вже завантажений сегмент dashboard/layout;
завантажити лише сегмент settings;
не перезавантажувати всю сторінку;
зберегти стан клієнтських компонентів у спільному layout.
Завдяки цьому переходи між сегментами маршруту відбуваються швидше.
Layout не перемонтовується, якщо користувач переходить між його дочірніми маршрутами.
Наприклад:
/dashboard
/dashboard/settings
/dashboard/profileУсі ці сторінки можуть використовувати:
app/dashboard/layout.tsxТому навігаційне меню, відкритий стан бокової панелі або інші клієнтські компоненти в layout можуть залишатися без перезавантаження.
Router Cache особливо помітний під час навігації кнопками браузера «Назад» і «Вперед».
Якщо сторінка вже відвідувалася й її сегменти залишилися в Router Cache, Next.js може відновити їх без повного нового завантаження.
Створимо невеликий застосунок із двома сторінками та спільним layout.
app/
├── dashboard/
│ ├── layout.tsx
│ ├── page.tsx
│ └── settings/
│ └── page.tsx
├── components/
│ └── RefreshButton.tsx
└── page.tsx// app/page.tsx
import Link from 'next/link';
export default function HomePage() {
return (
<main>
<h1>Головна сторінка</h1>
<p>
<Link href="/dashboard">Відкрити панель керування</Link>
</p>
</main>
);
}// app/components/RefreshButton.tsx
'use client';
import { useRouter } from 'next/navigation';
export default function RefreshButton() {
const router = useRouter();
return (
<button type="button" onClick={() => router.refresh()}>
Оновити поточний маршрут
</button>
);
}// app/dashboard/layout.tsx
import Link from 'next/link';
import RefreshButton from '../components/RefreshButton';
export default function DashboardLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<section>
<header>
<h1>Панель керування</h1>
<nav>
<Link href="/dashboard">Огляд</Link>{' '}
<Link href="/dashboard/settings">Налаштування</Link>
</nav>
<RefreshButton />
</header>
<hr />
{children}
</section>
);
}// app/dashboard/page.tsx
export const dynamic = 'force-dynamic';
export default function DashboardPage() {
return (
<main>
<h2>Огляд</h2>
<p>Час формування сторінки: {new Date().toLocaleTimeString('uk-UA')}</p>
</main>
);
}// app/dashboard/settings/page.tsx
export const dynamic = 'force-dynamic';
export default function SettingsPage() {
return (
<main>
<h2>Налаштування</h2>
<p>Час формування сторінки: {new Date().toLocaleTimeString('uk-UA')}</p>
</main>
);
}Під час навігації між /dashboard і /dashboard/settings layout залишається спільним. Компонент RefreshButton не створюється заново при кожному переході між цими сторінками.
Щоб побачити різницю, можна:
відкрити сторінку /dashboard;
перейти до /dashboard/settings;
повернутися назад;
натиснути кнопку «Оновити поточний маршрут».
Link і попереднє завантаженняКомпонент Link зазвичай може попередньо завантажувати маршрут, коли посилання з’являється в зоні видимості браузера.
import Link from 'next/link';
export default function Navigation() {
return (
<nav>
<Link href="/dashboard">Панель керування</Link>
</nav>
);
}У такому випадку частина даних маршруту може потрапити до Router Cache ще до того, як користувач натисне посилання. Після натискання навігація відбувається швидше.
Для окремого посилання попереднє завантаження можна вимкнути:
<Link href="/dashboard" prefetch={false}>
Панель керування
</Link>Це не вимикає Router Cache повністю. Воно лише забороняє автоматичне попереднє завантаження цього посилання.
router.refresh()Метод router.refresh() використовується в клієнтському компоненті:
'use client';
import { useRouter } from 'next/navigation';
export default function RefreshButton() {
const router = useRouter();
function handleRefresh() {
router.refresh();
}
return (
<button type="button" onClick={handleRefresh}>
Оновити
</button>
);
}Після виклику Next.js:
робить новий запит для поточного маршруту;
повторно формує Server Components;
отримує новий результат від сервера;
оновлює поточний маршрут у браузері.
При цьому стан клієнтських компонентів і стан браузера зазвичай не втрачаються.
Важливо: router.refresh() не гарантує нові дані, якщо джерело даних саме закешоване на сервері. Він оновлює Router Cache, але не обов’язково скасовує всі інші види кешування.
У Next.js можуть існувати різні рівні кешування:
Router Cache — кеш сегментів маршруту в пам’яті браузера;
Data Cache — кеш результатів запитів даних на сервері;
Full Route Cache — кеш результату серверного рендерингу маршруту.
Router Cache працює саме на стороні клієнта. Він допомагає повторно використовувати вже отримані сегменти під час навігації.
Тому навіть якщо дані на сервері мають власний кеш, Router Cache може показувати користувачеві вже отриманий результат під час повторного переходу.
Router Cache зберігається в пам’яті поточної вкладки браузера. Він може втратитися, коли:
користувач повністю перезавантажує сторінку;
користувач закриває вкладку;
застосунок завантажується заново;
поточний маршрут оновлюється через router.refresh().
Звичайний перехід за допомогою Link не є повним перезавантаженням сторінки, тому кешовані сегменти можуть залишатися доступними.
Розглянемо клієнтський компонент у layout:
'use client';
import { useState } from 'react';
export default function Counter() {
const [count, setCount] = useState(0);
return (
<button type="button" onClick={() => setCount(count + 1)}>
Лічильник: {count}
</button>
);
}Якщо Counter розміщений у спільному layout, перехід між його дочірніми сторінками не обов’язково скине count. Layout залишається змонтованим, а його клієнтський стан продовжує існувати.
Якщо ж компонент розміщений безпосередньо на сторінці, яка змінюється під час навігації, його стан може бути створений заново.
Отже, Router Cache впливає не лише на швидкість. Він також пов’язаний із тим, які сегменти маршруту залишаються змонтованими.
Повернення на вже відвідану сторінку може використати дані з Router Cache.
Якщо потрібно повторно отримати результат для поточного маршруту, використовуйте router.refresh() або відповідний механізм оновлення даних на сервері.
Router Cache — це внутрішній кеш маршрутизатора Next.js. Він не є тим самим, що HTTP-кеш браузера або кеш результатів fetch.
useRouter у Server ComponentuseRouter із next/navigation призначений для клієнтських компонентів.
'use client';
import { useRouter } from 'next/navigation';
export default function Example() {
const router = useRouter();
return (
<button type="button" onClick={() => router.refresh()}>
Оновити
</button>
);
}Без директиви 'use client' такий компонент не зможе використовувати клієнтський Router API.
router.refresh() повним перезавантаженням сторінкиrouter.refresh() не працює як window.location.reload().
Він оновлює Server Components для поточного маршруту, але не повинен без потреби скидати весь стан браузера та клієнтських компонентів.
prefetch={false} усюдиВимкнення попереднього завантаження може збільшити час переходу. Використовуйте його лише тоді, коли автоматичне завантаження конкретного маршруту справді небажане.
Router Cache — це кеш сегментів маршрутів у пам’яті браузера.
Він використовується App Router під час клієнтської навігації.
Next.js може повторно використовувати спільні layout і вже завантажені сегменти.
Переходи між дочірніми маршрутами часто не перемонтовують спільний layout.
Link може попередньо завантажувати маршрут і зберігати його дані в Router Cache.
router.refresh() повторно запитує поточний маршрут і оновлює його результат.
Router Cache не слід плутати з Data Cache або Full Route Cache.
Повне перезавантаження сторінки очищає кеш маршрутизатора в пам’яті вкладки.