HTMX Is So Cool I Rolled My Own (2024)

HTMX Is So Cool I Rolled My Own (2024)

HTMX 太酷了,所以我自己写了一个 (2024)

HTMX is hot right now. HTMX rejects modern JavaScript UI in favour of server-rendered HTML. It’s not a new concept it’s an evolution of old ideas. It builds on how we did things before the front-end got all bloated with React. HTMX 现在非常火。它摒弃了现代 JavaScript UI,转而推崇服务器端渲染的 HTML。这并不是什么新概念,而是旧思想的演进。它建立在我们前端还没被 React 等框架搞得臃肿不堪之前的那套做法之上。

Popular HTMX examples are infinite scroll, live search results, etc. I must have implemented those a 100 different ways. I wish I had HTMX ten years ago. HTMX does not solve all of the problems that React et al. try to solve. It even appears rather limiting to me. But within those limits HTMX is gold. HTMX 的常见用例包括无限滚动、实时搜索结果等。我以前肯定用过一百种不同的方法来实现这些功能。真希望十年前就有 HTMX。HTMX 并不能解决 React 等框架试图解决的所有问题,甚至在我看来还有些局限性。但在这些局限之内,HTMX 简直是金子。

I like how Carson Gross — HTMX author — talks about HTMX on the recent PodRocket podcast episode. He says HTMX is not a “magic bullet” and: “I think some of the ideas behind HTMX are probably more important than HTMX.” I think so too. 我很喜欢 HTMX 作者 Carson Gross 在最近一期 PodRocket 播客中谈论 HTMX 的方式。他说 HTMX 不是“灵丹妙药”,并表示:“我认为 HTMX 背后的某些理念可能比 HTMX 本身更重要。” 我也深有同感。

The Experiment

实验

I wanted to give HTMX a fair try. Reading documentation only goes so far. Actually using code is the real test and I found a good use for HTMX. 我想给 HTMX 一个公平的尝试机会。光看文档是不够的,实际编写代码才是真正的考验,而我找到了一个适合使用 HTMX 的场景。

I recently refactored the server for my self-hosted podcast web app. The previous iteration used SvelteKit. I’m a big fan of SvelteKit but it can be overwhelming for smaller websites. 我最近重构了我的自托管播客 Web 应用的服务器。之前的版本使用的是 SvelteKit。我很喜欢 SvelteKit,但对于小型网站来说,它可能显得过于繁重了。

I replaced SvelteKit with my own janky DinoSsr project I’ve been hacking away on. I also use it to build my static site and serve my bookmark blog. DinoSsr is primarily server-side. It can serve components as front-end “islands” but they do not provide full page interactivity. This is a problem for my audio player component. It needs to persist as I navigate between pages otherwise the listening experience is swiftly ended. 我用自己折腾的 DinoSsr 项目替换了 SvelteKit。我还用它来构建静态网站和托管书签博客。DinoSsr 主要运行在服务器端。它可以将组件作为前端“孤岛”提供,但无法提供全页面的交互性。这对我的音频播放器组件来说是个问题,因为它需要在页面跳转时保持运行,否则听歌体验会立刻中断。

I recognised an opportunity to use HTMX here. I have a handful of pages that differ in the <main> section. With HTMX I can progressively enhance links and update this section without reloading the page. Thus keeping the audio component intact. I tried HTMX and it worked great! Then I immediately removed HTMX and decided to roll my own. 我意识到这里正是使用 HTMX 的好机会。我有几个页面,它们只有 <main> 部分不同。通过 HTMX,我可以对链接进行渐进式增强,并在不重新加载页面的情况下更新这部分内容,从而保持音频组件的连续性。我试用了 HTMX,效果非常好!然后我立刻移除了它,决定自己写一个。

A Few Thoughts on HTMX

关于 HTMX 的几点想法

In my case HTMX is a replacement for front-end Svelte. But not a ‘drop-in’ replacement like React would be. It’s a dramatic shift in thinking. I find that refreshing. 在我的案例中,HTMX 是前端 Svelte 的替代品。但它不像 React 那样是“即插即用”的替代品,而是一种思维上的巨大转变。我觉得这很令人耳目一新。

Although HTMX ships as a JavaScript library to progressively enhance the front-end, most of the HTMX implementation is done on the back-end. HTMX does not prescribe code for the back-end. You must bring your own server templates and configuration. 虽然 HTMX 作为 JavaScript 库发布以增强前端,但大部分 HTMX 的实现是在后端完成的。HTMX 并没有规定后端代码的写法,你必须自己准备服务器模板和配置。

Minor nitpick but I’m not keen on the hx-* prefixed HTML attributes where data-* should be used (with dataset). Why use non-standard when a standard exists? 一个小小的吐槽:我不喜欢 hx-* 前缀的 HTML 属性,明明应该使用 data-*(配合 dataset)。既然有标准,为什么要用非标准的呢?

Larger nitpick: HTMX documentation has a lot of <div> examples. Did I mistake this for a React tutorial? Users should not be clicking <div> elements. In my opinion some of the more advanced HTMX examples using inline JavaScript get a bit nasty. Those show the limits of declarative attribute templating. 更大的吐槽:HTMX 文档中有很多 <div> 示例。我是不是误入了 React 教程?用户不应该去点击 <div> 元素。在我看来,一些使用内联 JavaScript 的高级 HTMX 示例显得有些糟糕。这暴露了声明式属性模板的局限性。

Criticisms aside, I think HTMX offers a limited but useful feature set that can enhance many common web design patterns. If I hated it I wouldn’t take the time to blog about it! 抛开批评不谈,我认为 HTMX 提供了一套有限但实用的功能,可以增强许多常见的网页设计模式。如果我讨厌它,我就不会花时间写博客来讨论它了!

Rolling My Own

自己动手

So anyway, immediately after successfully adding HTMX I removed it! I had so much fun I decided to write my own mini version using the same ideas. 总之,在成功添加 HTMX 后,我立刻把它删了!我玩得很开心,于是决定用同样的思路写一个迷你版本。

I used the same last-modified and if-modified-since HTTP headers and 304 response to allow caching fetch requests. I used pushState and popstate for basic history integration. I added a bit of code to extract and replace <title> elements. Inspired by the HTMX preload extension I built in preloading using pointer events. This gives a little performance boost by starting the fetch request before the click event is fired. 我使用了相同的 last-modifiedif-modified-since HTTP 头部以及 304 响应来实现 fetch 请求的缓存。我使用了 pushStatepopstate 来实现基础的历史记录集成。我还添加了一些代码来提取和替换 <title> 元素。受 HTMX 预加载扩展的启发,我通过指针事件(pointer events)实现了预加载功能。这通过在点击事件触发前就开始 fetch 请求,带来了一定的性能提升。

Source code for my experiment is on my Git forge. It’s very basic but it demonstrates how little JavaScript is actually needed in the browser. By using HTMX — or “we have HTMX at home” — my codebase has become much smaller and simpler. 我的实验源代码在我的 Git 仓库里。它非常基础,但证明了浏览器中实际上只需要很少的 JavaScript。通过使用 HTMX(或者说“家里有 HTMX”),我的代码库变得更小、更简单了。

Front-end JavaScript

前端 JavaScript

Templates and ‘components’ are practically necessary to organise and reuse code for all but the smallest of websites. That can be done server-side using PHP, Ruby, Go, anything, even JavaScript. Does that need to be replicated in the browser? Or worse, only in the browser? With the popularity of React et al. many of us have stopped asking that question. This project has reminded me the answer is an emphatic No. 对于除了最小型网站之外的所有网站,模板和“组件”几乎是组织和复用代码的必需品。这可以在服务器端使用 PHP、Ruby、Go 或任何语言(甚至是 JavaScript)来完成。这有必要在浏览器中重复实现吗?或者更糟的是,只在浏览器中实现?随着 React 等框架的流行,我们许多人已经不再问这个问题了。而这个项目提醒我,答案是坚决的“不”。

Front-end JavaScript fatigue is real. I’m guilty myself of over-engineering JS UI despite preferring good old server templates. I don’t even think HTMX is that good but the philosophy behind it embarrasses the modern JavaScript developer. For that I appreciate it very much. 前端 JavaScript 的疲劳感是真实存在的。尽管我更喜欢传统的服务器模板,但我自己也曾过度设计过 JS UI。我甚至不觉得 HTMX 有多完美,但它背后的哲学让现代 JavaScript 开发者感到汗颜。就这一点而言,我非常欣赏它。