feat: preload images
This commit is contained in:
@@ -17,6 +17,7 @@ templ Head(cfg config.Cfg, title string) {
|
||||
<script src="/js/htmx.min.js"></script>
|
||||
<script src="/js/head-support.min.js"></script>
|
||||
<script src="/js/preload.min.js"></script>
|
||||
<script src="/js/preload-links.min.js"></script>
|
||||
<script src={ cfg.Tracking.ScriptSrc } data-website-id={ cfg.Tracking.WebsiteID }></script>
|
||||
for _, h := range templer.GetHeader(ctx) {
|
||||
@templ.Raw(h)
|
||||
@@ -29,7 +30,7 @@ templ Base(cfg config.Cfg, title string) {
|
||||
<!DOCTYPE html>
|
||||
<html lang={ translate.Language(ctx) }>
|
||||
@Head(cfg, title)
|
||||
<body class="bg-black dark" hx-boost="true" hx-target="main" hx-ext="head-support,preload">
|
||||
<body class="bg-black dark" hx-boost="true" hx-target="main" hx-ext="head-support,preload,preload-links">
|
||||
<header
|
||||
class="fixed z-50 mix-blend-difference p-1 w-full flex justify-between items-start"
|
||||
>
|
||||
|
||||
@@ -13,7 +13,7 @@ templ Home(pages []page.PageHeader) {
|
||||
class="flex items-center justify-center h-full "
|
||||
href={ translate.Path(ctx, "/"+page.UID) }
|
||||
preload="mouseover"
|
||||
preload-images="true"
|
||||
hx-load-links="true"
|
||||
>
|
||||
<h2
|
||||
class="text-3xl font-bold text-white hover:underline text-shadow-lg"
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* @file preload-links.js
|
||||
* @description HTMX extension to extract <link rel="preload"> from preloaded HTML responses.
|
||||
* @generated By opencode (AI Agent)
|
||||
* @model gemini-3-flash-preview
|
||||
* @date Thu Mar 19 2026
|
||||
*/
|
||||
(function () {
|
||||
// Save the original XHR methods
|
||||
const originalOpen = XMLHttpRequest.prototype.open;
|
||||
const originalSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
|
||||
const originalSend = XMLHttpRequest.prototype.send;
|
||||
|
||||
// We need to track which XHRs are preloads
|
||||
XMLHttpRequest.prototype.open = function () {
|
||||
this._isHtmxPreload = false;
|
||||
return originalOpen.apply(this, arguments);
|
||||
};
|
||||
|
||||
XMLHttpRequest.prototype.setRequestHeader = function (header, value) {
|
||||
if (header.toLowerCase() === "hx-preloaded" && value === "true") {
|
||||
this._isHtmxPreload = true;
|
||||
}
|
||||
return originalSetRequestHeader.apply(this, arguments);
|
||||
};
|
||||
|
||||
XMLHttpRequest.prototype.send = function () {
|
||||
if (this._isHtmxPreload) {
|
||||
this.addEventListener("load", function () {
|
||||
// Parse the response text as HTML
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(this.responseText, "text/html");
|
||||
|
||||
// Find all preload links
|
||||
const links = doc.querySelectorAll('link[rel="preload"]');
|
||||
|
||||
links.forEach((link) => {
|
||||
const href = link.getAttribute("href");
|
||||
// Only inject if the current document doesn't already have it
|
||||
if (
|
||||
href &&
|
||||
!document.querySelector(`link[rel="preload"][href="${href}"]`)
|
||||
) {
|
||||
const newLink = document.createElement("link");
|
||||
newLink.rel = "preload";
|
||||
newLink.href = href;
|
||||
|
||||
// Copy relevant attributes
|
||||
["as", "type", "media", "fetchpriority", "crossorigin"].forEach(
|
||||
(attr) => {
|
||||
const val = link.getAttribute(attr);
|
||||
if (val) newLink.setAttribute(attr, val);
|
||||
},
|
||||
);
|
||||
|
||||
document.head.appendChild(newLink);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
return originalSend.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
File diff suppressed because one or more lines are too long
Vendored
+1
@@ -0,0 +1 @@
|
||||
(function(){const p=XMLHttpRequest.prototype.open,a=XMLHttpRequest.prototype.setRequestHeader,l=XMLHttpRequest.prototype.send;XMLHttpRequest.prototype.open=function(){return this._isHtmxPreload=!1,p.apply(this,arguments)},XMLHttpRequest.prototype.setRequestHeader=function(r,o){return r.toLowerCase()==="hx-preloaded"&&o==="true"&&(this._isHtmxPreload=!0),a.apply(this,arguments)},XMLHttpRequest.prototype.send=function(){return this._isHtmxPreload&&this.addEventListener("load",function(){new DOMParser().parseFromString(this.responseText,"text/html").querySelectorAll('link[rel="preload"]').forEach(n=>{const t=n.getAttribute("href");if(t&&!document.querySelector(`link[rel="preload"][href="${t}"]`)){const e=document.createElement("link");e.rel="preload",e.href=t,["as","type","media","fetchpriority","crossorigin"].forEach(s=>{const i=n.getAttribute(s);i&&e.setAttribute(s,i)}),document.head.appendChild(e)}})}),l.apply(this,arguments)}})();
|
||||
Reference in New Issue
Block a user