htmx 预加载扩展
preload 扩展程序允许你在用户请求 HTML 片段之前将其加载到浏览器的缓存中,这样用户几乎可以立即加载其他页面。作为开发人员,你可以自定义其行为以满足你的应用程序需求和用例。
重要提示:谨慎地预加载内容可以提高 Web 应用程序的感知性能,但预加载过多资源可能会启动过多未使用的请求,从而对访问者的带宽和服务器性能产生负面影响。请谨慎使用此扩展!
安装
<script src="https://unpkg.com/[email protected]/preload.js"></script>
用法
使用 hx-ext 属性向 htmx 注册扩展。然后,preload 向要预加载的任何超链接和元素添加 hx-get 属性。默认情况下,资源将在 mousedown 事件开始时立即加载,从而使你的应用程序在提供响应方面领先大约 100-200 毫秒。有关其他选项,请参阅下面的配置。
<body hx-ext="preload">
<h1>What Works</h2>
<a href="/server/1" preload>WILL BE requested using a standard XMLHttpRequest() and default options (below)</a>
<button hx-get="/server/2" preload>WILL BE requested with additional htmx headers.</button>
<h1>What WILL NOT WORK</h1>
<a href="/server/3">WILL NOT be preloaded because it does not have an explicit "preload" attribute</a>
<a hx-post="/server/4" preload>WILL NOT be preloaded because it is an HX-POST transaction.</a>
</body>
所有预加载请求都包含一个附加 "HX-Preloaded": "true" 头。
继承预加载设置
你可以将属性添加到包含多个 <a href=""> 或 hx-get="" 元素的 preload 顶级元素 ,这样所有这些元素都会被预加载。请谨慎使用此设置,因为如果你预加载的资源比你需要的多,最终可能会浪费带宽。
<body hx-ext="preload">
<ul preload>
<li><a href="/server/1">This will be preloaded because of the attribute in the node above.</a>
<li><a href="/server/2">This will also be preloaded for the same reason.</a>
<li><a href="/server/3">This will be preloaded, too. Lorem ipsum.</a>
</ul>
</body>
预加载表单
如果表单包含 hx-get 属性或使用 method="get" ,则扩展可以预加载某些表单元素。preload 可以将属性添加到表单或其某些选定元素。 目前可以预加载以下表单元素:
- <input type="radio"> 将会预加载,就像单击单选按钮并提交表单一样
- <input type="checkbox"> 将会预加载,就像复选框被选中并且表单被提交一样
- <input type="checkbox" checked> 将会预加载,就像复选框未选中并且表单已提交一样
- <select> 将发送多个预加载请求,就像选择了每个未选择的选项并提交了表单一样
- <input type="submit"> 将会像提交表单一样进行预加载
图片的预加载
预加载 HTML 页面(或页面片段)后,此扩展程序还可以预加载链接的图像资源。但它不会加载或运行链接的 Javascript 或 CSS 内容,无论是链接的还是嵌入在预加载的 HTML 中都不支持。要预加载图像,请使用以下语法。
<div hx-ext="preload">
<a href="/my-next-page" preload="mouseover" preload-images="true">Next Page</a>
</div>
配置
此扩展的默认设置旨在平衡用户感知的性能与未使用的请求对服务器造成的潜在负载。作为开发人员,你可以修改两个设置以根据特定用例自定义此行为。
preload=“mousedown” (默认)
此扩展的默认行为是在用户按下鼠标时开始加载资源。这是一个保守的设置,可确保用户确实想要使用链接的资源。由于用户点击事件通常需要 100-200 毫秒才能完成,因此与常规点击相比,此设置可让你的服务器获得显著的优势。
<a href="/server/1" preload="mousedown">This will be preloaded when the user begins to click.</a>
preload=“mouseover”
为了更积极地预加载链接,你可以改为在用户的鼠标悬停在链接上时触发预加载。为了防止在用户滚动或将鼠标移过大量对象列表时加载许多资源,此操作内置了 100 毫秒的延迟。如果用户的鼠标在此超时到期之前离开元素,则不会预加载资源。
通常,用户在点击链接之前会将鼠标悬停在链接上几百毫秒,这比上面的 mousedown 选项给你的服务器更多的时间来响应请求。 在此处测试你自己的悬停时间。但是,使用此选项时要小心,因为它可能会通过不必要地请求资源来增加服务器负载。
<a href="/server/1" preload="mouseover">This will be preloaded when the user's mouse remains over it for more than
100ms.</a>
preload=“custom-event-name”
preload 还可以监听系统内的任何自定义事件,触发资源预加载(如果它们尚未被浏览器缓存)。扩展本身会生成一个名为 preload:init 的事件,可用于在对象被 htmx 处理后立即触发预加载。
<body hx-ext="preload">
<button hx-get="/server" preload="preload:init" hx-target="idLoadMore">Load More</a>
<div id="idLoadMore">
Content for this DIV will be preloaded as soon as the page is ready.
Clicking the button above will swap it into the DOM.
</div>
</body>
preload=“always”
默认情况下,扩展将预加载每个元素一次。如果你希望始终预加载元素,则可以添加 preload="always" 属性。如果不是元素本身,这将很有用。此属性可以与其他配置属性结合使用,例如: hx-targetpreload="always mouseover"
关于触摸事件
为了适应触摸屏设备,每当你指定 mouseover 或 mousedown 触发器时,都会添加一个额外的 ontouchstart 事件处理程序。每当用户触摸屏幕时,这个额外的触发器会立即触发(无等待期),从而在 Android 上为你节省 300 毫秒的等待时间,在 iOS 上为你节省 450 毫秒的等待时间。
限制
- 链接必须标有 preload 属性,或者具有带 preload 属性的父节点。
- 仅可预加载 GET 请求(包括 <a href=""> 和 hx-get="")。根据 REST 原则, 假定事务不会对资源做出任何重大更改。在任何情况下,都不会预加载可能做出更改的事务(例如:POST、PUT 和 DELETE)。
- 在监听 mouseover 事件时,preload 会等待 100ms 后才下载链接的资源。如果鼠标在此超时时间之前离开资源,则不会预加载该资源。
- 仅当响应头允许时,预加载的响应才会缓存在浏览器中。例如,响应头Cache-Control: private, max-age=60 允许浏览器缓存响应,而响应头 Cache-Control: no-cache 则阻止浏览器缓存响应。
致谢
该插件的行为受到 Alexandre Dieulot 在 InstantClick上 所做的工作的启发,该插件根据 MIT 许可证发布。