- vừa được xem lúc

Phát triển web hiện đại với HMPL và HTMX: Hai con đường, một đích đến?

0 0 5

Người đăng: Nam Phạm

Theo Viblo Asia

Bạn đang phân vân giữa việc dùng template language hay HTML thuần với attribute đơn giản mà hiệu quả cho trang web hiện đại của mình? Trong bài viết này, chúng ta sẽ mổ xẻ điểm mạnh – điểm yếu của HMPL và HTMX, hai công cụ đang được cộng đồng dev quan tâm vì sự "khác biệt mà giống nhau" của chúng.

⚖️ Khi nào nên dùng HMPL để kiểm soát mọi thứ bằng JavaScript hiện đại? ⚡ Khi nào HTMX sẽ giúp bạn tăng tốc dự án chỉ với vài dòng HTML?

Ảnh mô tả HMPL vs HTMX

Triết lý thiết kế

HMPL: Là một template language độc lập, được phát triển như một ngôn ngữ riêng biệt với cú pháp riêng (.hmpl). Mục tiêu của HMPL là hỗ trợ tốt cho tooling (như linter, syntax highlight, formatter...), từ đó giúp quy trình phát triển web trở nên rõ ràng và cấu trúc hơn.

HTMX: Là một thư viện HTML-centric giúp mở rộng tính năng của HTML bằng cách thêm các attribute đặc biệt để xử lý hành vi động (interactive behavior) mà không cần đến JavaScript phức tạp. HTMX giữ mọi thứ “gần với HTML” nhất có thể.

Cách định nghĩa hành vi

HMPL: Cho phép mô tả hành vi thông qua các object JSON nhúng trực tiếp vào template. Đây là một cách tiếp cận cấu trúc, dễ kiểm soát logic xử lý từ phía client hoặc server.

<div> {{ "src": "http://localhost:8000/api/test" }}
</div>

HTMX: Sử dụng các attribute như hx-get, hx-post, hx-target... để định nghĩa hành vi trực tiếp lên HTML element. Mọi logic tương tác được định nghĩa ngay trong thuộc tính của thẻ HTML thay vì viết trong JavaScript.

<button hx-get="/click"> Click Me! <img class="htmx-indicator" src="/spinner.gif" />
</button>

Tích hợp với JavaScript

HMPL: Được thiết kế để tích hợp sâu với JavaScript. Một template .hmpl có thể được gọi như một function trong code JavaScript:

const templateFn = require("./main.hmpl");
const elementObj = templateFn();

Cách tiếp cận này giúp lập trình viên sử dụng lại component, truyền props, hoặc xử lý động linh hoạt bằng JavaScript.

HTMX: Cố gắng loại bỏ hoặc giảm thiểu sự phụ thuộc vào JavaScript. Tuy nhiên, bạn vẫn có thể mở rộng behavior thông qua hook,* custom events*, hoặc kết hợp với các thư viện JavaScript khác nếu cần.

<script src="https://unpkg.com/htmx.org"></script>
<!-- have a button POST a click via AJAX -->
<button hx-post="/clicked" hx-swap="outerHTML">Click Me</button>

Làm việc với DOM

HMPL: Không phụ thuộc trực tiếp vào DOM thực. Template trả về một object có thể được render thành DOM node hoặc chuỗi HTML, phù hợp với cả SSR (server-side rendering) lẫn xử lý động phía client.

HMPL tạo ra các phần tử độc lập với nhau. Khi bạn khởi tạo một HMPLInstance, nó chứa một tập hợp các node riêng biệt, không liên kết với các instance khác hoặc với DOM thực tế. Khi sử dụng thuộc tính after, nó chỉ tìm kiếm trong bản sao HTML được tạo trong quá trình biên dịch chứ không phải toàn bộ DOM.

Ví dụ trên minh họa cách HMPL xử lý yêu cầu: import { compile } from "hmpl-js";

const templateFn = compile( `<div> <button class="getHTML">Get HTML!</button> { { "src":"/api/test", "after":"click:.getHTML" } } </div>`
); const elementObj1 = templateFn();
const elementObj2 = templateFn();
  • compile() biên dịch một template HTML độc lập.
  • elementObj1elementObj2 là hai bản sao riêng biệt, không liên quan đến nhau.
  • Khi sự kiện click được kích hoạt trên .getHTML, nó chỉ tìm trong bản sao HTML được tạo trước đó.

HTMX: Tương tác trực tiếp với DOM. Khi người dùng tương tác, HTMX gửi request HTTP và thay thế (hoặc chèn) kết quả trả về vào DOM hiện tại. Các thuộc tính như hx-target tìm kiếm và tương tác trên toàn bộ tài liệu HTML. Ví dụ:

<button hx-post="/clicked" hx-trigger="click" hx-target="#parent-div" hx-swap="outerHTML"
> Click Me!
</button>
  • <button> sử dụng hx-post để gửi yêu cầu đến /clicked.
  • hx-target="#parent-div" giúp tìm kiếm phần tử mục tiêu trong toàn bộ DOM.
  • hx-swap="outerHTML" thay thế nội dung của phần tử #parent-div với kết quả từ server.

Cơ chế gửi request

HMPL: Sử dụng fetch – API hiện đại và mạnh mẽ trong JavaScript, đi kèm với Promiseasync/await. Tuy nhiên, không tương thích với trình duyệt quá cũ nếu không có polyfill.

HTMX: Dựa trên XMLHttpRequest – đảm bảo tương thích tốt hơn với trình duyệt cũ, nhưng kém linh hoạt hơn so với fetch trong các use-case hiện đại.

Kết luận

Tiêu chí HMPL HTMX
Cách tiếp cận Template-based, cấu trúc rõ ràng HTML-extended, trực tiếp trên DOM
Khả năng mở rộng Cao với JavaScript Hạn chế, ưu tiên đơn giản
Tooling Hỗ trợ tốt cho editor, linter, theme Dựa trên HTML tiêu chuẩn
Tương thích trình duyệt Tốt với trình duyệt hiện đại Tốt hơn với trình duyệt cũ
Cơ chế request fetch XMLHttpRequest

Nếu bạn muốn phát triển web theo hướng có cấu trúc rõ ràng, dễ tái sử dụng và tận dụng khả năng lập trình mạnh mẽ của JavaScript, HMPL sẽ là lựa chọn phù hợp.

Ngược lại, nếu bạn cần thêm tương tác nhanh cho HTML hiện có mà không cần viết nhiều logic phức tạp, HTMX là một giải pháp nhẹ nhàng và hiệu quả.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Hướng dẫn finetune mô hình LLM đơn giản và miễn phí với Unsloth

Chào mừng các bạn đến với bài viết hướng dẫn chi tiết cách finetune (tinh chỉnh) một mô hình ngôn ngữ lớn (LLM) một cách đơn giản và hoàn toàn miễn phí sử dụng thư viện Unsloth. Trong bài viết này, ch

0 0 7

- vừa được xem lúc

SERIES INDEX NÂNG CAO - BÀI 1: PHÂN TÍCH NHỮNG SAI LẦM PHỔ BIẾN KHI SỬ DỤNG INDEX TRONG MYSQL

Nếu anh em thấy hay thì ủng hộ tôi 1 follow + 1 upvote + 1 bookmark + 1 comment cho bài viết này tại Mayfest 2025 nhé. Còn nếu bài viết chưa hữu ích thì tôi cũng hi vọng anh em để lại những góp ý thẳn

0 0 8

- vừa được xem lúc

"Hack" Não Số Lớn Với Digit DP!

Xin chào anh em, những chiến binh thuật toán kiên cường. Phản ứng đầu tiên của nhiều anh em (có cả tôi): "Ối dào, dễ! Quất cái for từ 1 đến 101810^{18}1018 rồi check thôi!".

0 0 10

- vừa được xem lúc

So Sánh StatelessWidget và StatefulWidget & Các Widget Nâng Cao

Chào mọi người! Hôm nay chúng ta sẽ tiếp tục hành trình khám phá Flutter và đến với bài học về StatelessWidget và StatefulWidget. Trong bài này, mình sẽ giúp các bạn phân biệt sự khác nhau giữa hai lo

0 0 7

- vừa được xem lúc

React Lifecycle & Hooks Cơ Bản

React cung cấp các phương thức lifecycle và hooks để quản lý các giai đoạn khác nhau trong vòng đời của component. Việc hiểu rõ các phương thức này giúp bạn có thể tối ưu hóa ứng dụng React của mình.

0 0 7

- vừa được xem lúc

Kafka Fundamental - Bài 4: Consumers, Deserialization, Consumer Groups & Consumer Offsets

Xin chào, lại là mình - Đức Phúc, anh chàng hơn 6 năm trong nghề vẫn nghèo technical nhưng thích viết Blog để chia sẻ kiến thức bản thân học được trong quá trình “cơm áo gạo tiền” đây. Các bạn có thể

0 0 5