Trang chủ

Website này không gửi đi framework JavaScript nào, một cách có chủ đích

Website này là một bản build tĩnh bằng Astro. Không React, không Vue, không router phía client, không thư viện quản lý trạng thái. Thứ được gửi tới trình duyệt của bạn là HTML, một lượng nhỏ JavaScript thuần viết nội tuyến, một shader mảnh WebGL, và một bộ chữ được tự host.

Đó là một ràng buộc có chủ đích chứ không phải một sở thích, và sau bốn tháng thì đáng ghi lại xem nó thật sự tốn gì.

Ràng buộc đó là gì

Được ghi thẳng trong tài liệu hướng dẫn của chính dự án:

Bản build phát ra HTML, một ít JS thuần nội tuyến, và một shader mảnh WebGL. Không framework phía client, không CSS framework, không hệ thống class tiện ích, không thư viện component.

Phần cuối mới là phần cần kỷ luật. Giữ vững lập trường với React thì dễ, rồi lặng lẽ thêm Tailwind, một thư viện UI không giao diện, và một bộ định dạng ngày, để rồi có 300KB phụ thuộc phục vụ mười một trang chữ.

Nó tốn gì

Không có trạng thái theo component. Bộ chọn ngôn ngữ, menu di động và hộp thoại QR mỗi cái khoảng bốn mươi dòng JavaScript thuần nói chuyện thẳng với DOM. Trong React mỗi cái sẽ là năm dòng. Đó là một cái giá thật và tôi trả nó ba lần.

Trùng lặp giữa các ngôn ngữ. Mọi trang tồn tại hai lần — about.astro và vi/about.astro — mang cùng markup và CSS với phần chữ khác nhau. Một thay đổi bố cục phải được áp lên cả hai bản. Đây là một quyết định kiến trúc có chủ đích chứ không phải giới hạn của cách làm, nhưng nó cộng dồn với quy tắc không-framework: chẳng có lớp trừu tượng rẻ nào để giấu nó vào.

Những thứ tương tác thật sự khó hơn. Một danh sách lọc và sắp xếp được sẽ là một lần gửi form và tải lại trang, hoặc một trăm dòng code DOM. Tôi đã tránh xây một cái, và đó là phiên bản thành thật của câu “nó không phải vấn đề”.

Nó đem lại gì

Chẳng có gì phải cập nhật. Bốn tháng, một lần nâng phụ thuộc — chính Astro. Không cảnh báo bảo mật, không thay đổi phá vỡ tương thích trong một thư viện trạng thái, không buổi sáng nào bị nướng vào một phụ thuộc gián tiếp.

Nó nhanh mà chẳng cần cố. Không hydration, không gói cần phân tích, không nhảy bố cục trong lúc một framework khởi động. Thứ nặng nhất trên bất kỳ trang nào là bộ chữ, thứ được tự host và cắt bớt.

Toàn bộ nó vừa trong đầu bạn. Mười một file trang, sáu component, ba file CSS. Tôi mở bất kỳ file nào cũng hiểu được mà không phải lần theo một đồ thị phụ thuộc. Khi có gì đó trông sai, nguyên nhân nằm trong khoảng hai mươi file.

Nó vẫn sẽ build được sau năm năm. Đây là lập luận tôi thấy thuyết phục nhất và cũng khó chứng minh nhất. Một bộ sinh trang tĩnh phát ra HTML thì có một bề mặt rất nhỏ để hệ sinh thái làm vỡ nó từ bên dưới.

Mẹo

Bộ chữ tự host đáng được gọi tên như một khoản lợi cụ thể. API font của Astro tải các file về lúc build rồi phục vụ chúng từ chính domain này, nên đọc một trang không gửi request nào đến một font CDN — bớt một bên thứ ba, và bớt một thứ phải ghi trong chính sách bảo mật.

Chỗ duy nhất tôi phá luật

Trang chủ có một shader WebGL — một bãi biển đêm chuyển động chạy liên tục. Đó là thứ phức tạp nhất trên website này theo một khoảng cách xa và nó được viết dựa trên API WebGL thô, không thư viện nào.

Three.js sẽ khiến việc viết nó dễ hơn. Nó cũng sẽ tốn khoảng 600KB cho một cảnh chỉ gồm một tam giác quá khổ và một shader mảnh, trên một trang mà nhiệm vụ duy nhất là nói tôi là ai. Bản thô chỉ vài kilobyte.

Nó cũng phải biết cư xử: nó dừng khi visibilitychange, dừng khi cuộn ra khỏi tầm nhìn nhờ một IntersectionObserver, và tôn trọng prefers-reduced-motion bằng cách vẽ ra một khung tĩnh. Một vòng lặp chạy mãi trên pin laptop của ai đó không phải một nét hoa mỹ, nó là một con bug, và framework cũng đã chẳng giải quyết được chuyện đó.

Khi nào tôi sẽ không làm thế này

Tôi muốn nói rõ rằng đây không phải một lời khuyên chung.

Nếu website là một ứng dụng, hãy dùng framework. Bất cứ thứ gì có biểu mẫu, trạng thái đã xác thực, cập nhật thời gian thực hay một mô hình dữ liệu phía client phức tạp đều đúng là thứ framework sinh ra để làm, và tự viết tay nó là cách bạn rốt cuộc viết ra một React tệ hơn.

Nếu một đội đang bảo trì nó, hãy dùng thứ mà đội đó biết. Lập luận “tất cả vừa trong đầu bạn” của tôi chạy được vì chỉ có một cái đầu.

Nếu tính tương tác chính là sản phẩm, thì đây là ràng buộc sai.

Thứ tôi sẽ giữ lại

Sau bốn tháng, quyết định tôi mừng nhất không phải cái framework vắng mặt — mà là quy tắc nhỏ hơn nằm dưới nó: mọi phụ thuộc đều phải tự biện minh trước phiên bản không có nó.

Website này có ba: Astro, phần tích hợp MDX của nó, và phần tích hợp sitemap của nó. Mỗi cái đều xứng đáng có mặt. Đó là một danh sách tôi rà lại trong một phút, và là lý do chẳng có gì ở đây hỏng kể từ lúc tôi dựng nó.