> ## Documentation Index
> Fetch the complete documentation index at: https://inertiajs-vi.tuantq.online/llms.txt
> Use this file to discover all available pages before exploring further.

# Prefetching

Inertia hỗ trợ prefetch dữ liệu cho những trang có khả năng được truy cập tiếp theo. Điều này giúp cải thiện hiệu năng cảm nhận của ứng dụng bằng cách cho phép dữ liệu được tải ở nền trong khi người dùng vẫn đang tương tác với trang hiện tại.

## Prefetch bằng Link

Để prefetch dữ liệu cho page, thêm prop `prefetch` vào Inertia link component. Mặc định Inertia prefetch dữ liệu khi user hover lên link hơn 75ms. Bạn có thể tùy chỉnh hover delay bằng tùy chọn `prefetch.hoverDelay` trong [application defaults](/v3/installation/client-side-setup#configuring-defaults).

<CodeGroup>
  ```vue Vue icon="vuejs" theme={null}
  import { Link } from '@inertiajs/vue3'

  <Link href="/users" prefetch>Users</Link>
  ```

  ```jsx React icon="react" theme={null}
  import { Link } from "@inertiajs/react";

  <Link href="/users" prefetch>
    Users
  </Link>;
  ```

  ```svelte Svelte icon="s" theme={null}
  import { inertia } from '@inertiajs/svelte'

  <a href="/users" use:inertia={{ prefetch: true }}>Users</a>
  ```
</CodeGroup>

Mặc định, dữ liệu được cache 30 giây trước khi bị evict. Bạn có thể tùy chỉnh bằng tùy chọn `prefetch.cacheFor` trong [application defaults](/v3/installation/client-side-setup#configuring-defaults), hoặc theo từng link bằng prop `cacheFor` của component `Link`.

<CodeGroup>
  ```vue Vue icon="vuejs" theme={null}
  import { Link } from '@inertiajs/vue3'

  <Link href="/users" prefetch cache-for="1m">Users</Link>
  <Link href="/users" prefetch cache-for="10s">Users</Link>
  <Link href="/users" prefetch :cache-for="5000">Users</Link>
  ```

  ```jsx React icon="react" theme={null}
  import { Link } from '@inertiajs/react'

  <Link href="/users" prefetch cacheFor="1m">Users</Link>
  <Link href="/users" prefetch cacheFor="10s">Users</Link>
  <Link href="/users" prefetch cacheFor={5000}>Users</Link>
  ```

  ```svelte Svelte icon="s" theme={null}
  import { inertia } from '@inertiajs/svelte'

  <a href="/users" use:inertia={{ prefetch: true, cacheFor: '1m' }}>Users</a>
  <a href="/users" use:inertia={{ prefetch: true, cacheFor: '10s' }}>Users</a>
  <a href="/users" use:inertia={{ prefetch: true, cacheFor: 5000 }}>Users</a>
  ```
</CodeGroup>

Thay vì prefetch khi hover, bạn cũng có thể bắt đầu prefetch tại sự kiện `mousedown` bằng cách truyền giá trị `click` vào prop `prefetch`.

<CodeGroup>
  ```vue Vue icon="vuejs" theme={null}
  import { Link } from '@inertiajs/vue3'

  <Link href="/users" prefetch="click">Users</Link>
  ```

  ```jsx React icon="react" theme={null}
  import { Link } from "@inertiajs/react";

  <Link href="/users" prefetch="click">
    Users
  </Link>;
  ```

  ```svelte Svelte icon="s" theme={null}
  import { inertia } from '@inertiajs/svelte'

  <a href="/users" use:inertia={{ prefetch: 'click' }}>Users</a>
  ```
</CodeGroup>

Nếu chắc chắn người dùng sẽ truy cập một trang tiếp theo, bạn cũng có thể prefetch dữ liệu ngay khi component được mount.

<CodeGroup>
  ```vue Vue icon="vuejs" theme={null}
  import { Link } from '@inertiajs/vue3'

  <Link href="/users" prefetch="mount">Users</Link>
  ```

  ```jsx React icon="react" theme={null}
  import { Link } from "@inertiajs/react";

  <Link href="/users" prefetch="mount">
    Users
  </Link>;
  ```

  ```svelte Svelte icon="s" theme={null}
  import { inertia } from '@inertiajs/svelte'

  <a href="/users" use:inertia={{ prefetch: 'mount' }}>Users</a>
  ```
</CodeGroup>

Bạn cũng có thể kết hợp nhiều chiến lược prefetch bằng cách truyền một mảng giá trị vào prop `prefetch`.

<CodeGroup>
  ```vue Vue icon="vuejs" theme={null}
  import { Link } from '@inertiajs/vue3'

  <Link href="/users" :prefetch="['mount', 'hover']">Users</Link>
  ```

  ```jsx React icon="react" theme={null}
  import { Link } from "@inertiajs/react";

  <Link href="/users" prefetch={["mount", "hover"]}>
    Users
  </Link>;
  ```

  ```svelte Svelte icon="s" theme={null}
  import { inertia } from '@inertiajs/svelte'

  <a href="/users" use:inertia={{ prefetch: ['mount', 'hover'] }}>Users</a>
  ```
</CodeGroup>

## Prefetch bằng lập trình

Bạn có thể prefetch dữ liệu bằng lập trình với `router.prefetch`. Chữ ký của phương thức này giống `router.visit`, ngoại trừ đối số thứ ba cho phép bạn chỉ định các tùy chọn prefetch.

Khi không chỉ định tùy chọn `cacheFor`, giá trị mặc định là 30 giây.

```js theme={null}
router.prefetch("/users", { method: "get", data: { page: 2 } });

router.prefetch(
  "/users",
  { method: "get", data: { page: 2 } },
  { cacheFor: "1m" },
);
```

Inertia cũng cung cấp hook `usePrefetch` để theo dõi trạng thái prefetch của trang hiện tại. Hook trả về thông tin cho biết trang có đang prefetch hay không, đã được prefetch chưa, lần cập nhật gần nhất là khi nào, cùng phương thức `flush` để chỉ xóa cache của trang hiện tại.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { usePrefetch } from "@inertiajs/vue3";

  const { lastUpdatedAt, isPrefetching, isPrefetched, flush } = usePrefetch();
  ```

  ```js React icon="react" theme={null}
  import { usePrefetch } from "@inertiajs/react";

  const { lastUpdatedAt, isPrefetching, isPrefetched, flush } = usePrefetch();
  ```

  ```js Svelte icon="s" theme={null}
  import { usePrefetch } from "@inertiajs/svelte";

  const { lastUpdatedAt, isPrefetching, isPrefetched, flush } = usePrefetch();
  ```
</CodeGroup>

Bạn cũng có thể truyền các tùy chọn visit khi cần phân biệt nhiều cấu hình request khác nhau cho cùng một URL.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { usePrefetch } from "@inertiajs/vue3";

  const { lastUpdatedAt, isPrefetching, isPrefetched, flush } = usePrefetch({
    headers: { "X-Custom-Header": "value" },
  });
  ```

  ```js React icon="react" theme={null}
  import { usePrefetch } from "@inertiajs/react";

  const { lastUpdatedAt, isPrefetching, isPrefetched, flush } = usePrefetch({
    headers: { "X-Custom-Header": "value" },
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { usePrefetch } from "@inertiajs/svelte";

  const { lastUpdatedAt, isPrefetching, isPrefetched, flush } = usePrefetch({
    headers: { "X-Custom-Header": "value" },
  });
  ```
</CodeGroup>

## Cache tags

Cache tag cho phép bạn nhóm dữ liệu prefetch có liên quan và vô hiệu hóa toàn bộ dữ liệu cache mang tag đó khi một sự kiện cụ thể xảy ra.

Để gắn tag cho dữ liệu cache, hãy truyền prop `cacheTags` vào component `Link`.

<CodeGroup>
  ```vue Vue icon="vuejs" theme={null}
  <script setup>
  import { Link } from "@inertiajs/vue3";
  </script>

  <template>
    <Link href="/users" prefetch cache-tags="users">Users</Link>
    <Link href="/dashboard" prefetch :cache-tags="['dashboard', 'stats']"
      >Dashboard</Link
    >
  </template>
  ```

  ```jsx React icon="react" theme={null}
  import { Link } from '@inertiajs/react'

  <Link href="/users" prefetch cacheTags="users">Users</Link>
  <Link href="/dashboard" prefetch cacheTags={['dashboard', 'stats']}>Dashboard</Link>
  ```

  ```svelte Svelte icon="s" theme={null}
  import { inertia } from '@inertiajs/svelte'

  <a href="/users" use:inertia={{ prefetch: true, cacheTags: 'users' }}>Users</a>
  <a href="/dashboard" use:inertia={{ prefetch: true, cacheTags: ['dashboard', 'stats'] }}>Dashboard</a>
  ```
</CodeGroup>

Khi prefetch bằng lập trình, hãy truyền `cacheTags` trong đối số thứ ba của `router.prefetch`.

```js theme={null}
router.prefetch("/users", {}, { cacheTags: "users" });
router.prefetch("/dashboard", {}, { cacheTags: ["dashboard", "stats"] });
```

## Vô hiệu hóa cache

Bạn có thể xóa thủ công prefetch cache bằng cách gọi `router.flushAll` để xóa toàn bộ dữ liệu cache, hoặc `router.flush` để xóa cache của một trang cụ thể.

```js theme={null}
// Flush all prefetch cache
router.flushAll();

// Flush cache for a specific page
router.flush("/users", { method: "get", data: { page: 2 } });

// Using the usePrefetch hook
const { flush } = usePrefetch();

// Flush cache for the current page
flush();
```

Để kiểm soát chi tiết hơn, có thể flush cache theo tag bằng `router.flushByCacheTags`. Thao tác này xóa mọi cached response chứa *bất kỳ* tag được chỉ định.

```js theme={null}
// Flush all responses tagged with 'users'
router.flushByCacheTags("users");

// Flush all responses tagged with 'dashboard' OR 'stats'
router.flushByCacheTags(["dashboard", "stats"]);
```

### Tự động xóa cache

Mặc định, Inertia không tự động xóa prefetch cache khi bạn điều hướng sang trang mới. Dữ liệu cache chỉ bị loại bỏ khi hết hạn theo thời lượng cache. Nếu muốn xóa toàn bộ dữ liệu cache trong mỗi lần điều hướng, bạn có thể thiết lập một event listener.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.on("navigate", () => router.flushAll());
  ```

  ```js React icon="react" theme={null}
  import { router } from "@inertiajs/react";

  router.on("navigate", () => router.flushAll());
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.on("navigate", () => router.flushAll());
  ```
</CodeGroup>

### Vô hiệu hóa khi gửi request

Để tự động vô hiệu hóa cache khi gửi request, hãy truyền prop `invalidateCacheTags` vào component `Form`. Các tag được chỉ định sẽ bị xóa khi form được gửi thành công.

<CodeGroup>
  ```vue Vue icon="vuejs" theme={null}
  <script setup>
  import { Form } from "@inertiajs/vue3";
  </script>

  <template>
    <Form
      action="/users"
      method="post"
      :invalidate-cache-tags="['users', 'dashboard']"
    >
      <input type="text" name="name" />
      <input type="email" name="email" />
      <button type="submit">Create User</button>
    </Form>
  </template>
  ```

  ```jsx React icon="react" theme={null}
  import { Form } from "@inertiajs/react";

  export default () => (
    <Form
      action="/users"
      method="post"
      invalidateCacheTags={["users", "dashboard"]}
    >
      <input type="text" name="name" />
      <input type="email" name="email" />
      <button type="submit">Create User</button>
    </Form>
  );
  ```

  ```svelte Svelte icon="s" theme={null}
  <script>
      import { Form } from '@inertiajs/svelte'
  </script>

  <Form action="/users" method="post" invalidateCacheTags={['users', 'dashboard']}>
      <input type="text" name="name" />
      <input type="email" name="email" />
      <button type="submit">Create User</button>
  </Form>
  ```
</CodeGroup>

Khi dùng helper `useForm`, bạn có thể đưa `invalidateCacheTags` vào các tùy chọn visit.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { useForm } from "@inertiajs/vue3";

  const form = useForm({
    name: "",
    email: "",
  });

  const submit = () => {
    form.post("/users", {
      invalidateCacheTags: ["users", "dashboard"],
    });
  };
  ```

  ```js React icon="react" theme={null}
  import { useForm } from "@inertiajs/react";

  const { data, setData, post } = useForm({
    name: "",
    email: "",
  });

  function submit(e) {
    e.preventDefault();
    post("/users", {
      invalidateCacheTags: ["users", "dashboard"],
    });
  }
  ```

  ```js Svelte icon="s" theme={null}
  import { useForm } from "@inertiajs/svelte";

  const form = useForm({
    name: "",
    email: "",
  });

  function submit() {
    form.post("/users", {
      invalidateCacheTags: ["users", "dashboard"],
    });
  }
  ```
</CodeGroup>

Bạn cũng có thể vô hiệu hóa cache tag bằng các visit lập trình thông qua tùy chọn `invalidateCacheTags`.

```js theme={null}
router.delete(`/users/${userId}`, {
  invalidateCacheTags: ["users", "dashboard"],
});

router.post("/posts", postData, {
  invalidateCacheTags: ["posts", "recent-posts"],
});
```

## Stale-while-revalidate

Mặc định, Inertia fetch bản dữ liệu mới khi user truy cập page nếu cache cũ hơn thời lượng cache. Bạn có thể tùy chỉnh bằng cách truyền tuple vào prop `cacheFor`.

Giá trị đầu tiên trong mảng là số giây cache được xem là còn mới, còn giá trị thứ hai xác định khoảng thời gian dữ liệu cũ vẫn có thể được phục vụ trước khi bắt buộc phải lấy dữ liệu mới từ server.

<CodeGroup>
  ```vue Vue icon="vuejs" theme={null}
  import { Link } from '@inertiajs/vue3'

  <Link href="/users" prefetch :cacheFor="['30s', '1m']">Users</Link>
  ```

  ```jsx React icon="react" theme={null}
  import { Link } from "@inertiajs/react";

  <Link href="/users" prefetch cacheFor={["30s", "1m"]}>
    Users
  </Link>;
  ```

  ```svelte Svelte icon="s" theme={null}
  import { inertia } from '@inertiajs/svelte'

  <a href="/users" use:inertia={{ prefetch: true, cacheFor: ['30s', '1m'] }}>Users</a>
  ```
</CodeGroup>

Nếu request được thực hiện trong khoảng dữ liệu còn mới (trước giá trị thứ nhất), cache được trả về ngay mà không gửi request đến server.

Nếu request được thực hiện trong khoảng stale (giữa hai giá trị), giá trị cũ được trả cho người dùng đồng thời một request chạy nền sẽ làm mới dữ liệu cache. Khi dữ liệu mới được trả về, nó được gộp vào trang để người dùng có dữ liệu cập nhật nhất.

Nếu request được thực hiện sau giá trị thứ hai, cache được xem là hết hạn và page cùng dữ liệu được fetch từ server như request bình thường.

***

## Tài liệu chính thức

Bài dịch này được đối chiếu từ [tài liệu Inertia.js v3 chính thức](https://inertiajs.com/docs/v3/data-props/prefetching). Nếu có khác biệt do phiên bản hoặc cập nhật mới, hãy ưu tiên tài liệu chính thức làm nguồn tham chiếu.
