- Mọi người nói về htmx như thể nó sẽ cứu web khỏi SPA
- Tác giả của htmx, Carson Gross, đã dí dỏm mô tả động lực này là “phép biện chứng của Hegel”:
- chính đề (thesis): MPA truyền thống
- phản đề (antithesis): SPA
- tổng hợp (synthesis): ứng dụng được cấu thành từ các đảo tương tác dựa trên hypermedia
- Nhưng tôi lại không nhìn theo cách đó, và trước đây đã từng “xây một SPA bằng htmx”
- Đây là PoC của một ứng dụng danh sách việc cần làm đơn giản
- Sau khi trang được tải, nó không còn giao tiếp với máy chủ nữa
- Mọi thứ đều được xử lý cục bộ ở phía client
- Nếu htmx tập trung vào việc quản lý trao đổi hypermedia qua mạng, thì chuyện này vận hành như thế nào?
- Một mẹo đơn giản: mã “Server-Side” chạy trong Service Worker
Service Worker
- Hoạt động như một proxy giữa trang web và internet
- Có thể chặn và thao tác các yêu cầu mạng
- Có thể sửa đổi yêu cầu, cache phản hồi để dùng ngoại tuyến, và tạo phản hồi mới mà không cần gửi yêu cầu ra ngoài trình duyệt
- Tính năng cuối cùng chính là cốt lõi của ứng dụng một trang này
- Khi htmx gửi yêu cầu mạng, Service Worker sẽ chặn lại
- Sau đó Service Worker chạy business logic và tạo HTML mới
- htmx thay thế vào DOM bằng HTML mới
Ưu điểm so với SPA truyền thống
- Service Worker phải dùng IndexedDB làm nơi lưu trữ
- Điều này giúp giữ trạng thái qua nhiều lần tải trang
- Dù đóng trang rồi quay lại, ứng dụng vẫn nhớ dữ liệu
- Đây là một lợi ích phụ được “tặng kèm miễn phí” khi chọn kiến trúc này
- Cũng rất dễ làm cho nó hoạt động ngoại tuyến
Nhược điểm
- Hỗ trợ từ công cụ dành cho nhà phát triển còn kém
console.log đôi khi bị bỏ sót
- Việc báo cáo Service Worker đã được cài đặt hay chưa không đáng tin cậy
- Thiếu hỗ trợ ES module trên Firefox
- Phải nhét toàn bộ mã vào một file duy nhất
- Trải nghiệm phát triển nói chung là “không vui”
Dù vậy, htmx SPA vẫn hoạt động tốt
Chi tiết triển khai
- HTML cơ bản là bộ khung trống của ứng dụng một trang
- Thẻ
<body> thiết lập phần thân của ứng dụng bằng htmx
hx-boost="true": yêu cầu htmx thay phản hồi của thao tác nhấp liên kết và gửi form bằng Ajax mà không điều hướng toàn trang
hx-push-url="false": không cho htmx thay đổi URL theo thao tác nhấp liên kết và gửi form
hx-get="./ui": yêu cầu tải nội dung từ /ui khi trang được load và thay thế vào đó
hx-target="body": yêu cầu thay kết quả vào phần tử <body>
hx-trigger="load": yêu cầu thực hiện tất cả việc này khi trang được load
/ui endpoint
- Trả về phần markup thực sự của ứng dụng
- Sau đó htmx điều khiển các liên kết và form để biến nó thành giao diện tương tác
- Service Worker xử lý định tuyến request bằng một thư viện kiểu Express
setFilter và listTodos là các hàm đơn giản bọc quanh IDB Keyval
- Component
App gồm form lọc, danh sách việc cần làm và form thêm mới
/todos/add endpoint
- Sau khi lưu việc cần làm, nó trả về phản hồi đã render lại UI
- htmx thay phản hồi đó vào DOM
Component Todo
- Gồm checkbox, nút xóa và nội dung việc cần làm
- Checkbox kích hoạt request tới
/todos/${id}/update
- Nút xóa kích hoạt request xóa tới
/todos/${id}
- Phần nội dung việc cần làm có hai trạng thái: “normal” và “editing”
- htmx lắng nghe sự kiện nhấp đúp
- Gửi request tới
/ui/todos/${id}?editable=true
- Service Worker trả về HTML
Todo có chứa <input>
- htmx thay mục việc cần làm hiện tại bằng HTML trong phản hồi
Tóm tắt
- Về mặt kỹ thuật, nó hoạt động
- Nhưng đây có phải ý tưởng hay không? Có phải là đỉnh cao của ứng dụng dựa trên hypermedia không? Có nên bỏ React để làm kiểu này không?
- Với ứng dụng hoàn toàn cục bộ, tính gián tiếp của htmx tạo cảm giác nặng nề hơn là giải phóng
- Phần lớn ứng dụng không hoàn toàn cục bộ
- Tôi cho rằng mẫu “các đảo tương tác” tốt hơn việc chia mã “phía máy chủ” giữa Service Worker và máy chủ thật
- Đây là một thử nghiệm nhằm cho thấy có thể xây dựng một SPA hoàn toàn cục bộ bằng hypermedia
Chưa có bình luận nào.