---
type: "Blog post"
title: "Astro giữ cho website marketing nhanh như thế nào"
description: "Phần lớn website marketing gửi cả một framework chỉ để hiển thị đoạn văn bản không bao giờ thay đổi. Đây là cách Astro làm khác đi, cùng vài thiết lập vẫn đáng chỉnh khi bạn đã qua phần mặc định."
resource: "https://new.cuongthach.com/vi/blog/astro-performance/"
tags:
  - "blog"
  - "vi"
  - "Kỹ thuật"
  - "astro"
  - "hiệu năng"
  - "islands"
status: stable
generated:
  by: "process:cuongthach-okf-export"
  at: "2026-06-12T00:00:00Z"
---
# Astro giữ cho website marketing nhanh như thế nào

Một trang marketing chủ yếu là văn bản, vài hình ảnh, và hai ba thứ thực sự cần
phản hồi khi người dùng bấm. Bộ công nghệ phổ biến lại gửi kèm runtime, router
và một lượt hydrate cho tất cả, rồi bỏ sáu tháng sau đó để cố lấy lại từng mili
giây.

Astro bắt đầu từ mặc định ngược lại. Mọi component được render thành HTML lúc
build và gửi đi **không kèm JavaScript** trừ khi bạn yêu cầu. Bạn không phải tối
ưu dần để trang nhanh lên. Bạn quyết định, từng component một, cái nào xứng đáng
được tương tác.

## Component render trên server rồi dừng lại

Một component `.astro` trông như một trang và hoạt động như một hàm. Phần
frontmatter chạy một lần lúc build, còn template trở thành markup thuần. File
này không có client bundle, vì không còn gì để chạy.

```astro
---
const posts = await fetch("https://api.example.com/posts/").then((res) =>
  res.json(),
);
---

<ul class="post-list">
  {posts.map((post) => (
    <li>
      <a href={post.href}>{post.title}</a>
    </li>
  ))}
</ul>
```

Dòng `await` ở đầu file làm việc thật sự trong lúc build, không phải trong trình
duyệt của người truy cập. Khi trang được yêu cầu, danh sách đã là HTML nằm sẵn
trong một file.

## Islands là tùy chọn, bật từng directive một

Khi một component thực sự cần state, bạn gắn directive `client:*`. Chỉ component
đó và phần phụ thuộc của nó đến được trình duyệt. Mọi thứ xung quanh vẫn tĩnh.

```astro
---
---

{/* Rendered to HTML at build time. Ships nothing. */}

{/* Hydrates only once it scrolls into view. */}
```

Directive cũng là quyết định về thời điểm:

- **`client:load`** hydrate ngay lập tức. Dành cho thứ nằm ở màn hình đầu tiên và
  hỏng nếu thiếu JavaScript.
- **`client:visible`** đợi component cuộn vào tầm nhìn. Đây là câu trả lời đúng
  thường xuyên hơn người ta nghĩ.
- **`client:idle`** đợi main thread rảnh, nhờ đó không cản lần paint đầu tiên.
- **`client:media`** chỉ hydrate khi media query khớp, nên widget chỉ dành cho
  desktop không tốn gì của điện thoại.

> Component nhanh nhất là component không bao giờ hydrate. Nhanh thứ hai là
> component hydrate sau khi người dùng đã nhìn thấy trang.

## Bốn thiết lập đáng bật

Mặc định đã tốt, nhưng một website marketing được lợi từ vài lựa chọn tường
minh. Prefetch là thứ người ta thấy rõ nhất: liên kết được tải trước khi click,
nên điều hướng có cảm giác tức thì mà không cần client-side router.

```js

  site: "https://example.com/",
  compressHTML: true,
  trailingSlash: "always",
  prefetch: {
    prefetchAll: true,
    defaultStrategy: "viewport",
  },
  integrations: [sitemap()],
});
```

### Hình ảnh là một phần của build, không phải việc làm sau

Pipeline ảnh chuyển định dạng, đổi kích thước và tạo srcset ngay lúc build. Thứ
duy nhất nó cần từ bạn là kích thước hiển thị, vì đó là điều nó không thể suy ra
từ file.

```astro
---
---

<Image
  src={hero}
  alt="Product dashboard"
  widths={[640, 1024, 1536]}
  sizes="(min-width: 64rem) 1024px, 100vw"
  loading="eager"
  fetchpriority="high"
/>
```

Bỏ qua `widths` và `sizes`, trình duyệt sẽ vui vẻ tải ảnh gốc 2400 pixel để vẽ
ở 380. Đó là lý do phổ biến nhất khiến một site Astro vốn sạch sẽ bị điểm thấp.

## Build thực sự tạo ra gì

Điểm hay là bạn có thể kiểm tra. Nếu trang không có island, sẽ không có thư mục
JavaScript nào để soi, và sự vắng mặt đó chính là mục đích.

```bash
$ npm run build

09:41:02 [build] 14 page(s) built in 1.83s
09:41:02 [build] Complete!

$ ls dist/_astro/*.js
ls: cannot access 'dist/_astro/*.js': No such file or directory
```

## Công sức đi đâu thay vào đó

Không điều nào ở trên loại bỏ công việc dựng một website tốt. Nó chỉ chuyển công
việc đi chỗ khác. Bạn dành thời gian cho bố cục, nội dung và hai ba tương tác
xứng đáng với số byte của chúng, thay vì kiểm toán một bundle mình không chọn
gửi đi. Đó là cuộc đổi chác tốt hơn nhiều, và nó vẫn đúng khi site lớn lên.
