Replaced timings in the footer with a visual for the Server-Timing header.

This commit is contained in:
flash 2025-04-03 19:40:10 +00:00
parent ceb6bece09
commit 83068a4183
Signed by: flash
GPG key ID: 2C9C2C574D47FE3E
17 changed files with 246 additions and 65 deletions
assets

View file

@ -22,3 +22,4 @@ html, body {
}
@include loading.css;
@include perf.css;

100
assets/common.css/perf.css Normal file
View file

@ -0,0 +1,100 @@
.msz-perfs {
position: fixed;
bottom: 4px;
left: 4px;
display: flex;
gap: 2px;
flex-direction: column-reverse;
align-items: flex-start;
opacity: .5;
}
.msz-perfs-right {
left: initial;
right: 4px;
}
.msz-perfs:hover {
opacity: 1;
}
.msz-perf {
background-color: #111d;
color: #fff;
font-family: monospace;
font-size: 12px;
line-height: 20px;
padding: 4px 8px;
border-radius: 6px;
}
.msz-perfs:hover .msz-perf {
backdrop-filter: blur(10px);
}
.msz-perf-number {
color: #fff;
}
.msz-perf-unit {
color: #888;
}
.msz-perf-header {
display: flex;
flex: 0 0 auto;
gap: 4px;
}
.msz-perf:hover .msz-perf-header {
border-bottom: 1px solid #888;
margin-bottom: 2px;
}
.msz-perf-type {
flex: 0 0 auto;
font-weight: 700;
min-width: 60px;
}
.msz-perf-type-navigation {
color: #f0f;
}
.msz-perf-type-other {
color: #0ff;
}
.msz-perf-target {
flex: 1 0 auto;
min-width: 200px;
}
.msz-perf-target-host,
.msz-perf-target-path,
.msz-perf-target-query {
display: inline-block;
}
.msz-perf-target-host,
.msz-perf-target-query {
color: #888;
}
.msz-perf-total {
flex: 0 0 auto;
min-width: 80px;
text-align: right;
}
.msz-perf-timings {
display: none;
border-collapse: collapse;
width: 100%;
}
.msz-perf:hover .msz-perf-timings {
display: table;
}
.msz-perf-timing-name {
font-weight: 700;
min-width: 60px;
}
.msz-perf-timing-comment {
color: #888;
}
.msz-perf-timing-duration {
min-width: 80px;
text-align: right;
}

View file

@ -2,6 +2,7 @@
#include csrf.js
#include html.js
#include meta.js
#include perf.jsx
#include uniqstr.js
#include xhr.js

72
assets/common.js/perf.jsx Normal file
View file

@ -0,0 +1,72 @@
#include html.js
(() => {
const perfs = <div class="msz-perfs"/>;
perfs.ondblclick = () => {
perfs.classList.toggle('msz-perfs-right');
};
const appendReal = elem => {
$appendChild(perfs, elem);
};
let append = elem => {
append = appendReal;
$appendChild(document.body, perfs);
appendReal(elem);
};
(new PerformanceObserver(list => {
for(const entry of list.getEntries()) {
if(entry.serverTiming.length < 1)
break;
const url = new URL(entry.name);
let total = 0;
let queries = -1;
const timings = <table class="msz-perf-timings"/>;
for(const timing of entry.serverTiming) {
if(timing.name === 'msz-queries') {
queries = Math.ceil(timing.duration);
continue;
}
total += timing.duration;
$appendChild(timings, <tr class="msz-perf-timing">
<td class="msz-perf-timing-name">{timing.name}</td>
<td class="msz-perf-timing-comment">{decodeURIComponent(timing.description)}</td>
<td class="msz-perf-timing-duration">
<span class="msz-perf-number">{timing.duration}</span>
<span class="msz-perf-unit">ms</span>
</td>
</tr>);
}
append(<div class="msz-perf">
<div class="msz-perf-header">
<div class={`msz-perf-type msz-perf-type-${entry instanceof PerformanceNavigationTiming ? 'navigation' : 'other'}`}>
{entry instanceof PerformanceNavigationTiming ? entry.type : (
entry.initiatorType === 'xmlhttprequest' ? 'xhr' : entry.initiatorType
)}
</div>
<div class="msz-perf-target">
{url.host !== location.host ? <div class="msz-perf-target-host">{url.host}</div> : null}
<div class="msz-perf-target-path">{url.pathname}</div>
{url.search !== '' ? <div class="msz-perf-target-query">{url.search}</div> : null}
</div>
{queries > 0 ? <div class="msz-perf-total">
<span class="msz-perf-number">{queries}</span>
{' '}
<span class="msz-perf-unit">{queries === 1 ? 'query' : 'queries'}</span>
</div> : null}
<div class="msz-perf-total">
<span class="msz-perf-number">{total.toFixed(5)}</span>
<span class="msz-perf-unit">ms</span>
</div>
</div>
{timings}
</div>);
}
})).observe({ entryTypes: ['navigation', 'resource'] });
})();