Kỹ thuật 3 phút đọc

Astro giữ cho website marketing nhanh như thế nào

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.

Theo Park
Theo Park Kỹ sư cấp cao
Biểu đồ hiệu năng của một trang dựng bằng Astro
Mục lục
  1. Component render trên server rồi dừng lại
  2. Islands là tùy chọn, bật từng directive một
  3. Bốn thiết lập đáng bật
  4. Hình ảnh là một phần của build, không phải việc làm sau
  5. Build thực sự tạo ra gì
  6. Công sức đi đâu thay và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.

---
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.

---
import PriceTable from "@/components/PriceTable.astro";
import Newsletter from "@/components/Newsletter.tsx";
---

{/* Rendered to HTML at build time. Ships nothing. */}
<PriceTable plans={plans} />

{/* Hydrates only once it scrolls into view. */}
<Newsletter client:visible />

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.

import { defineConfig } from "astro/config";
import sitemap from "@astrojs/sitemap";

export default defineConfig({
  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.

---
import { Image } from "astro:assets";
import hero from "@/assets/hero.jpg";
---

<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.

$ 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.

  • astro
  • hiệu năng
  • islands
Chia sẻ
Theo Park

Theo Park

Kỹ sư cấp cao

Theo có sáu năm làm công cụ cho lập trình viên, hiện tập trung vào hiệu năng render và pipeline build.