10 điểm bởi xguru 2024-10-10 | Chưa có bình luận nào. | Chia sẻ qua WhatsApp
  • 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
    • setFilterlistTodos 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.

Chưa có bình luận nào.