我為何選擇擁抱 Alpine.js,並漸漸遠離 HTMX

大家好。今天,我將以一名主要負責後端開發的 Django 開發者身份,來聊聊最近在前端生態系中,引領「減少 JavaScript 使用」風潮的兩大主角:Alpine.jsHTMX

對於像我這樣熟悉 Django 和 Python 的開發者來說,這些工具簡直是天賜的禮物。它們讓我們無需複雜的 React 或 Vue 設定,也能打造出相當不錯的現代化網站。然而,這兩個工具的用途和特性截然不同:HTMX 專注於伺服器通訊,而 Alpine.js 則擅長處理瀏覽器內部的 UI 操作。

開門見山地說,我已經成為 Alpine.js 的忠實擁護者,並逐漸與 HTMX 保持距離。接下來,我將毫無保留地分享我的理由。

htmx 與 Alpine.js 的比較圖


1. 事前知識:HTMX 與 Alpine.js 一覽

在進入正題之前,為了不熟悉這兩個概念的朋友們,我簡單整理了比較表。

類別 HTMX Alpine.js
核心目的 伺服器通訊 (AJAX 請求後替換 HTML) 客戶端狀態管理 (UI 互動)
哲學 HTML 的延伸 (伺服器中心) Vue/React 的輕量化 (瀏覽器中心)
資料形式 HTML 片段 (Snippet) JSON 資料
主要優勢 無限捲動、即時搜尋 (SSR 方式) 模態框、下拉選單、分頁切換 (CSR 方式)

2. 我漸漸迴避 HTMX 的四大原因

HTMX 乍看之下非常方便。然而,當我實際將其深入應用於專案時,卻發現它與我的開發習慣產生了一些衝突點。

① 「非得在伺服器端產生 HTML 片段嗎?」(維護的兩難)

若要使用 HTMX,伺服器 (Django) 必須回傳 HTML 片段而非 JSON。這一點不太符合我的開發習慣。 * 我的觀點:「伺服器只負責提供乾淨的資料,而渲染工作則由客戶端處理,這樣職責分工不是更明確嗎?」 * HTMX 的立場:「接收 JSON 再重新渲染是一種浪費。由伺服器提供最終結果才是單一事實來源 (SSOT)。」

在 Django 模板中加入 if request.htmx: 這樣的條件判斷,總讓我覺得 View 邏輯變得支離破碎且雜亂無章。

② AJAX 邏輯,難道還不夠簡單嗎?

HTMX 的 hx-gethx-target 確實是出色的「語法糖」。然而,對於已經習慣使用 Vanilla JS 或自定義工具函數來實現 AJAX 的人來說,這些並非不可或缺。 現今瀏覽器的 fetch API 功能非常強大。在 Alpine.js 的 x-init 中,只需一行 fetch 程式碼,就能實現足夠宣告式且簡潔的邏輯,這讓我不太覺得有必要再遵循其他函式庫的規則。

③ 致命的「行為局部性 (Locality of Behavior, LoB)」斷裂

我非常喜歡 Alpine.js,因為它能讓程式碼的行為 當場一目了然。但 HTMX 則不然。 * Alpine.js: 行為 (Behavior) 定義在 HTML 中,結果也立即在瀏覽器記憶體中發生。 * HTMX: 行為定義在 HTML 中,但若要查看結果 (HTML 片段),則必須回頭翻閱伺服器端程式碼 (views.py)。

我認為這個過程中上下文 (Context) 的斷裂非常低效。在閱讀程式碼時,總是要不斷地開啟後端檔案,這種不便正是我迴避 htmx 的關鍵原因之一。

④ 微妙的延遲 (Latency) 帶來的不適

HTMX 的所有互動都建立在網路往返的基礎上。

無論伺服器速度再快,也無法比擬 Alpine.js 在瀏覽器內部即時反應的速度。點擊時感受到的那 0.1 到 0.2 秒的微小延遲,對我而言,在使用者體驗方面是相當惱人的因素。


總結:您有什麼看法?

總結來說,我偏好這樣的架構:資料透過 API(JSON) 流動,而 UI 則在瀏覽器內部即時反應。因此,我最喜歡 Alpine.js 和 DRF(Django REST Framework) 的組合。

有趣的是,最近在 Reddit 等社群上,我發現許多人持有與我截然不同的觀點。不少人認為 Alpine.js 過於複雜,轉而使用 HTMX,甚至回歸 jQuery + HTMX 的組合。無論如何,目前 HTMX 的人氣確實顯得壓倒性。

當然,HTMX 是一個非常出色的工具。它只是不符合我的開發風格和系統設計方式罷了。我認為 「沒有標準答案,只有最適合自己的選擇」

那麼您呢?您是否滿意 HTMX 以伺服器為中心的哲學,還是像我一樣,更偏好 JSON 回應和 Alpine.js 的即時反應性呢?歡迎在評論區分享您的看法!

或許,我是否在尚未真正領略 HTMX 的強大之處前,就過早地與它保持了距離呢?