Adding Profiler module

This commit is contained in:
2026-03-21 18:08:34 +01:00
parent f887267362
commit 72d6cce6ff
5 changed files with 1566 additions and 0 deletions

View File

@@ -0,0 +1,87 @@
/**
* HTMX debug tracing — toggle with window.HTMX_DEBUG = true in the browser console.
*
* Each request gets a unique ID (#1, #2, ...). Timings are deltas from beforeRequest.
*
* Full event sequence (→ = network boundary):
* beforeRequest — request about to be sent
* beforeSend — XHR about to be sent (after HTMX setup)
* → network round-trip ←
* beforeOnLoad — response received, HTMX about to process it
* beforeSwap — DOM swap about to happen
* afterSwap — DOM swap done
* afterSettle — settle phase complete
* afterRequest — full request lifecycle complete
* sendError — network error
* responseError — non-2xx response
*/
window.HTMX_DEBUG = false;
(function () {
console.log('Debug HTMX: htmx.logAll();');
console.log('Perf HTMX: window.HTMX_DEBUG=true;');
})();
(function () {
const EVENTS = [
'htmx:beforeRequest',
'htmx:beforeSend',
'htmx:beforeOnLoad',
'htmx:beforeSwap',
'htmx:afterSwap',
'htmx:afterSettle',
'htmx:afterRequest',
'htmx:sendError',
'htmx:responseError',
];
let counter = 0;
const requests = new WeakMap();
function getInfo(detail) {
const key = detail?.requestConfig ?? detail?.xhr ?? null;
if (!key || !requests.has(key)) return null;
return requests.get(key);
}
EVENTS.forEach(eventName => {
document.addEventListener(eventName, (e) => {
if (!window.HTMX_DEBUG) return;
const short = eventName.replace('htmx:', '').padEnd(14);
const path = e.detail?.requestConfig?.path ?? e.detail?.pathInfo?.requestPath ?? '';
const isError = eventName === 'htmx:sendError' || eventName === 'htmx:responseError';
let prefix;
if (eventName === 'htmx:beforeRequest') {
const key = e.detail?.requestConfig ?? null;
if (key) {
const id = ++counter;
const now = performance.now();
requests.set(key, {id, start: now, last: now});
prefix = `#${String(id).padStart(3)} + 0.0ms (Δ 0.0ms)`;
} else {
prefix = `# ? + 0.0ms (Δ 0.0ms)`;
}
} else {
const info = getInfo(e.detail);
if (info) {
const now = performance.now();
const total = (now - info.start).toFixed(1);
const step = (now - info.last).toFixed(1);
info.last = now;
prefix = `#${String(info.id).padStart(3)} +${String(total).padStart(7)}ms (Δ${String(step).padStart(7)}ms)`;
} else {
prefix = `# ? + ?.?ms (Δ ?.?ms)`;
}
}
if (isError) {
console.warn(`[HTMX] ${prefix} ${short}`, path, e.detail);
} else {
console.debug(`[HTMX] ${prefix} ${short}`, path);
}
});
});
})();