Trong nhiều năm, Single Page Applications (SPA) được coi là tiêu chuẩn để xây dựng trải nghiệm web mượt mà. Nhưng giờ đây, sự phát triển của CSS hiện đại đã thay đổi hoàn toàn cuộc chơi.
Mục lục
Ảo Tưởng Về “Cảm Giác Như Ứng Dụng”
Hầu hết các dự án web hiện nay bắt đầu bằng một yêu cầu quen thuộc: “Hãy làm cho nó giống một ứng dụng”. Đây chính là lúc kiến trúc SPA được chọn, cùng với React, Vue hoặc Next.js đi kèm CMS headless và API GraphQL.
Nhưng thực tế, quyết định này thường không dựa trên nhu cầu kỹ thuật thực sự. Mà xuất phát từ mong muốn tạo hiệu ứng chuyển trang mượt mà – điều mà giờ đây đã có thể đạt được dễ dàng hơn nhiều.
Những Vấn Đề Không Tránh Khỏi Của SPA
Hầu hết SPA không thực sự mang lại trải nghiệm hoàn hảo như hứa hẹn. Thay vào đó, chúng thường kèm theo:
- Hiệu ứng chuyển trang giả tạo giữa hai trạng thái loading
- Khôi phục vị trí cuộn không ổn định
- Hành vi focus không nhất quán
- Navigation bị delay do script rehydrate
- Layout shift và nội dung “bật ra” đột ngột
- Hiệu suất giảm sút không tương xứng với lợi ích
Đây không phải là lý thuyết. Hãy nhìn vào hầu hết các trang được xây dựng bằng Next.js, Gatsby hay Nuxt. Họ đang gửi hàng MB JavaScript chỉ để mô phỏng chức năng điều hướng mà trình duyệt vốn đã làm tốt.
CSS Hiện Đại Đã Giải Quyết Vấn Đề
Trong khi các nhà phát triển bận rộn tái tạo điều hướng bằng JavaScript, nền tảng web đã âm thầm giải quyết vấn đề này.
1. View Transitions API
Với View Transitions API, bạn có thể tạo hiệu ứng chuyển trang giữa các documents mà không cần JavaScript:
@view-transition {
navigation: auto;
}
::view-transition-old(root),
::view-transition-new(root) {
animation: fade 0.3s ease both;
}
@keyframes fade {
from { opacity: 0; }
to { opacity: 1; }
}
2. Shared Element Transitions
Tạo hiệu ứng phóng to từ thumbnail sang ảnh sản phẩm chi tiết:
<!-- Trang danh sách -->
<a href="/product/red-shoes">
<img src="thumb.jpg" style="view-transition-name: product-image;" />
</a>
<!-- Trang chi tiết -->
<img src="large.jpg" style="view-transition-name: product-image;" />
3. Speculation Rules
Giúp trình duyệt preload/prerender trang tiếp theo dựa trên hành vi người dùng:
<script type="speculationrules">
{
"prerender": [
{
"where": {
"selector_matches": "a"
}
}
]
}
</script>
Sự Khác Biệt Về Hiệu Suất
Next.js Marketing Site | MPA + View Transitions |
---|---|
JS bundle: 1–3MB | JS bundle: 0KB |
TTI: ~3.5–5s | TTI: ~1s |
Chuyển trang mô phỏng | Chuyển trang native |
SEO phức tạp | SEO đơn giản |
Lời Khuyên Cho Nhà Phát Triển
- Hầu hết website không cần SPA – chúng không cần shared state hay client-side routing
- Sử dụng server rendering hiện đại
- Xây dựng bằng các trang thực sự thay vì mô phỏng
- Sử dụng CSS cho animation và hiệu ứng
- Giảm thiểu JavaScript không cần thiết
- Tận dụng các tính năng native mới nhất của trình duyệt
SPA từng là giải pháp thông minh cho một hạn chế tạm thời của web. Nhưng hạn chế đó giờ không còn nữa. Đã đến lúc quay trở lại với các nguyên tắc cơ bản của web: HTML mạnh mẽ, CSS linh hoạt và JavaScript chỉ khi thực sự cần thiết.