perf: reduce 3 API calls to 1 when expanding grouped packet row

Expanding a grouped row fired: packets?hash=X&expand=observations,
packets?hash=X&limit=1, and packets/HASH — all returning the same
data. Now uses single /packets/HASH call and passes prefetched data
to selectPacket() to skip redundant fetches.
This commit is contained in:
you
2026-03-21 21:17:24 +00:00
parent 6f350bb785
commit ebc72fa364
2 changed files with 15 additions and 11 deletions

View File

@@ -84,7 +84,7 @@
<script src="hop-resolver.js?v=1774126708"></script>
<script src="app.js?v=1774126708"></script>
<script src="home.js?v=1774042199"></script>
<script src="packets.js?v=1774126708"></script>
<script src="packets.js?v=1774127844"></script>
<script src="map.js?v=1774126708" onerror="console.error('Failed to load:', this.src)"></script>
<script src="channels.js?v=1774127388" onerror="console.error('Failed to load:', this.src)"></script>
<script src="nodes.js?v=1774126708" onerror="console.error('Failed to load:', this.src)"></script>

View File

@@ -742,7 +742,7 @@
return '';
}
async function selectPacket(id, hash) {
async function selectPacket(id, hash, prefetchedData) {
selectedId = id;
if (hash) {
history.replaceState(null, '', `#/packets/${hash}`);
@@ -779,8 +779,7 @@
}
try {
const endpoint = hash ? `/packets/${hash}` : `/packets/${id}`;
const data = await api(endpoint);
const data = prefetchedData || await api(hash ? `/packets/${hash}` : `/packets/${id}`);
// Resolve path hops for detail view
const pkt = data.packet;
try {
@@ -1209,12 +1208,15 @@
renderTableRows();
return;
}
// Load children (observations) for this hash
// Single fetch — gets packet + observations + path + breakdown
try {
const data = await api(`/packets?hash=${hash}&limit=1&expand=observations`);
const pkt = (data.packets || [])[0];
const data = await api(`/packets/${hash}`);
const pkt = data.packet;
if (!pkt) return;
const group = packets.find(p => p.hash === hash);
if (group && pkt) group._children = (pkt.observations || []).map(o => ({...pkt, ...o, _isObservation: true}));
if (group && data.observations) {
group._children = data.observations.map(o => ({...pkt, ...o, _isObservation: true}));
}
// Resolve any new hops from children
const childHops = new Set();
for (const c of (group?._children || [])) {
@@ -1224,13 +1226,15 @@
if (newHops.length) await resolveHops(newHops);
expandedHashes.add(hash);
renderTableRows();
// Also open detail panel — no extra fetch needed
selectPacket(pkt.id, hash, data);
} catch {}
}
async function pktSelectHash(hash) {
// When grouped, find first packet with this hash
// When grouped, select packet — reuse cached detail endpoint
try {
const data = await api(`/packets?hash=${hash}&limit=1`);
if (data.packets?.[0]) selectPacket(data.packets[0].id, hash);
const data = await api(`/packets/${hash}`);
if (data?.packet) selectPacket(data.packet.id, hash, data);
} catch {}
}