perf: fix N+1 query pattern across all modules + rack numbering
CRITICAL PERF BUG: Every hook did storage.list() (1 HTTP call fetching ALL items with values, discarding values, returning only keys) then storage.get() for EACH key (N individual HTTP calls re-fetching values one by one). With 6 entries + contacts + tags, Registratura page fired ~40 sequential HTTP requests on load, where 3 would suffice. Fix: Replace list()+N*get() with single exportAll() call in ALL hooks: - registratura/registry-service.ts (added exportAll to RegistryStorage interface) - address-book/use-contacts.ts - it-inventory/use-inventory.ts - password-vault/use-vault.ts - word-templates/use-templates.ts - prompt-generator/use-prompt-generator.ts - hot-desk/use-reservations.ts - email-signature/use-saved-signatures.ts - digital-signatures/use-signatures.ts - ai-chat/use-chat.ts - core/tagging/tag-service.ts (uses storage.export()) Additional fixes: - registratura/use-registry.ts: addEntry uses optimistic local state update instead of double-refresh; closeEntry batches saves with Promise.all + single refresh - server-rack.tsx: reversed slot rendering so U1 is at bottom (standard rack numbering, per user's physical rack) Performance impact: ~90% reduction in HTTP requests on page load for all modules
This commit is contained in:
@@ -68,6 +68,9 @@ export function ServerRack({ items }: ServerRackProps) {
|
||||
return result;
|
||||
}, [items]);
|
||||
|
||||
// Reverse so U1 is at the bottom (standard rack numbering)
|
||||
const displaySlots = useMemo(() => [...slots].reverse(), [slots]);
|
||||
|
||||
const rackItems = items.filter((i) => i.rackPosition);
|
||||
|
||||
if (rackItems.length === 0) {
|
||||
@@ -97,7 +100,7 @@ export function ServerRack({ items }: ServerRackProps) {
|
||||
|
||||
{/* Units */}
|
||||
<div className="p-1 space-y-px">
|
||||
{slots.map((slot) => {
|
||||
{displaySlots.map((slot) => {
|
||||
if (!slot.isStart && slot.item) return null;
|
||||
|
||||
const heightPx = slot.height * 24;
|
||||
|
||||
@@ -27,12 +27,11 @@ export function useInventory() {
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
setLoading(true);
|
||||
const keys = await storage.list();
|
||||
const all = await storage.exportAll();
|
||||
const results: InventoryItem[] = [];
|
||||
for (const key of keys) {
|
||||
if (key.startsWith(PREFIX)) {
|
||||
const item = await storage.get<InventoryItem>(key);
|
||||
if (item) results.push(item);
|
||||
for (const [key, value] of Object.entries(all)) {
|
||||
if (key.startsWith(PREFIX) && value) {
|
||||
results.push(value as InventoryItem);
|
||||
}
|
||||
}
|
||||
results.sort((a, b) => b.createdAt.localeCompare(a.createdAt));
|
||||
|
||||
Reference in New Issue
Block a user