⚡ performance optimization: batch fetch availableDates
Removed the 100ms artificial delay in `loadMenuDataFromAPI` and switched from sequentially awaiting fetch requests to concurrently awaiting requests in batches of 5 using `Promise.all`. Preserved original chronological ordering of array elements. Co-authored-by: TauNeutrino <1600410+TauNeutrino@users.noreply.github.com>
This commit is contained in:
22
benchmark_loadMenuDataFromAPI.js
Normal file
22
benchmark_loadMenuDataFromAPI.js
Normal file
@@ -0,0 +1,22 @@
|
||||
const fs = require('fs');
|
||||
|
||||
async function benchmark() {
|
||||
// We will simulate the same exact loop in src/actions.js
|
||||
let availableDates = Array.from({length: 30}).map((_, i) => ({ date: `2024-01-${i+1}`}));
|
||||
const totalDates = availableDates.length;
|
||||
let completed = 0;
|
||||
|
||||
console.log(`Starting benchmark for ${totalDates} items (Sequential with 100ms artificial delay)`);
|
||||
const start = Date.now();
|
||||
for (const dateObj of availableDates) {
|
||||
// mock fetch
|
||||
await new Promise(r => setTimeout(r, 50)); // simulate network delay
|
||||
|
||||
completed++;
|
||||
await new Promise(r => setTimeout(r, 100)); // the artificial delay in codebase
|
||||
}
|
||||
const end = Date.now();
|
||||
console.log(`Sequential loading took ${end - start}ms`);
|
||||
}
|
||||
|
||||
benchmark();
|
||||
26
benchmark_loadMenuDataFromAPI_concurrent.js
Normal file
26
benchmark_loadMenuDataFromAPI_concurrent.js
Normal file
@@ -0,0 +1,26 @@
|
||||
const fs = require('fs');
|
||||
|
||||
async function benchmark() {
|
||||
let availableDates = Array.from({length: 30}).map((_, i) => ({ date: `2024-01-${i+1}`}));
|
||||
const totalDates = availableDates.length;
|
||||
let completed = 0;
|
||||
|
||||
console.log(`Starting benchmark for ${totalDates} items (Concurrent batch=5 without 100ms artificial delay)`);
|
||||
const start = Date.now();
|
||||
|
||||
// Simulate Promise.all batching approach
|
||||
const BATCH_SIZE = 5;
|
||||
for (let i = 0; i < totalDates; i += BATCH_SIZE) {
|
||||
const batch = availableDates.slice(i, i + BATCH_SIZE);
|
||||
await Promise.all(batch.map(async (dateObj) => {
|
||||
// mock fetch
|
||||
await new Promise(r => setTimeout(r, 50)); // simulate network delay
|
||||
completed++;
|
||||
}));
|
||||
}
|
||||
|
||||
const end = Date.now();
|
||||
console.log(`Concurrent loading took ${end - start}ms`);
|
||||
}
|
||||
|
||||
benchmark();
|
||||
70
dist/kantine.bundle.js
vendored
70
dist/kantine.bundle.js
vendored
@@ -783,41 +783,51 @@ async function loadMenuDataFromAPI() {
|
||||
const allDays = [];
|
||||
let completed = 0;
|
||||
|
||||
for (const dateObj of availableDates) {
|
||||
const dateStr = dateObj.date;
|
||||
const pct = Math.round(((completed + 1) / totalDates) * 100);
|
||||
progressFill.style.width = `${pct}%`;
|
||||
progressPercent.textContent = `${pct}%`;
|
||||
progressMessage.textContent = `Lade Menü für ${dateStr}...`;
|
||||
const BATCH_SIZE = 5;
|
||||
for (let i = 0; i < totalDates; i += BATCH_SIZE) {
|
||||
const batch = availableDates.slice(i, i + BATCH_SIZE);
|
||||
const results = await Promise.all(batch.map(async (dateObj) => {
|
||||
const dateStr = dateObj.date;
|
||||
let dayData = null;
|
||||
try {
|
||||
const detailResp = await fetch(`${_constants_js__WEBPACK_IMPORTED_MODULE_2__/* .API_BASE */ .tE}/venues/${_constants_js__WEBPACK_IMPORTED_MODULE_2__/* .VENUE_ID */ .eW}/menu/${_constants_js__WEBPACK_IMPORTED_MODULE_2__/* .MENU_ID */ .YU}/${dateStr}/`, {
|
||||
headers: (0,_api_js__WEBPACK_IMPORTED_MODULE_3__/* .apiHeaders */ .H)(token)
|
||||
});
|
||||
|
||||
try {
|
||||
const detailResp = await fetch(`${_constants_js__WEBPACK_IMPORTED_MODULE_2__/* .API_BASE */ .tE}/venues/${_constants_js__WEBPACK_IMPORTED_MODULE_2__/* .VENUE_ID */ .eW}/menu/${_constants_js__WEBPACK_IMPORTED_MODULE_2__/* .MENU_ID */ .YU}/${dateStr}/`, {
|
||||
headers: (0,_api_js__WEBPACK_IMPORTED_MODULE_3__/* .apiHeaders */ .H)(token)
|
||||
});
|
||||
|
||||
if (detailResp.ok) {
|
||||
const detailData = await detailResp.json();
|
||||
const menuGroups = detailData.results || [];
|
||||
let dayItems = [];
|
||||
for (const group of menuGroups) {
|
||||
if (group.items && Array.isArray(group.items)) {
|
||||
dayItems = dayItems.concat(group.items);
|
||||
if (detailResp.ok) {
|
||||
const detailData = await detailResp.json();
|
||||
const menuGroups = detailData.results || [];
|
||||
let dayItems = [];
|
||||
for (const group of menuGroups) {
|
||||
if (group.items && Array.isArray(group.items)) {
|
||||
dayItems = dayItems.concat(group.items);
|
||||
}
|
||||
}
|
||||
if (dayItems.length > 0) {
|
||||
dayData = {
|
||||
date: dateStr,
|
||||
menu_items: dayItems,
|
||||
orders: dateObj.orders || []
|
||||
};
|
||||
}
|
||||
}
|
||||
if (dayItems.length > 0) {
|
||||
allDays.push({
|
||||
date: dateStr,
|
||||
menu_items: dayItems,
|
||||
orders: dateObj.orders || []
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(`Failed to fetch details for ${dateStr}:`, err);
|
||||
} finally {
|
||||
completed++;
|
||||
const pct = Math.round((completed / totalDates) * 100);
|
||||
progressFill.style.width = `${pct}%`;
|
||||
progressPercent.textContent = `${pct}%`;
|
||||
progressMessage.textContent = `Lade Menü für ${dateStr}...`;
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(`Failed to fetch details for ${dateStr}:`, err);
|
||||
}
|
||||
return dayData;
|
||||
}));
|
||||
|
||||
completed++;
|
||||
await new Promise(r => setTimeout(r, 100));
|
||||
for (const result of results) {
|
||||
if (result) {
|
||||
allDays.push(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const weeksMap = new Map();
|
||||
|
||||
@@ -752,41 +752,51 @@ export async function loadMenuDataFromAPI() {
|
||||
const allDays = [];
|
||||
let completed = 0;
|
||||
|
||||
for (const dateObj of availableDates) {
|
||||
const dateStr = dateObj.date;
|
||||
const pct = Math.round(((completed + 1) / totalDates) * 100);
|
||||
progressFill.style.width = `${pct}%`;
|
||||
progressPercent.textContent = `${pct}%`;
|
||||
progressMessage.textContent = `Lade Menü für ${dateStr}...`;
|
||||
const BATCH_SIZE = 5;
|
||||
for (let i = 0; i < totalDates; i += BATCH_SIZE) {
|
||||
const batch = availableDates.slice(i, i + BATCH_SIZE);
|
||||
const results = await Promise.all(batch.map(async (dateObj) => {
|
||||
const dateStr = dateObj.date;
|
||||
let dayData = null;
|
||||
try {
|
||||
const detailResp = await fetch(`${API_BASE}/venues/${VENUE_ID}/menu/${MENU_ID}/${dateStr}/`, {
|
||||
headers: apiHeaders(token)
|
||||
});
|
||||
|
||||
try {
|
||||
const detailResp = await fetch(`${API_BASE}/venues/${VENUE_ID}/menu/${MENU_ID}/${dateStr}/`, {
|
||||
headers: apiHeaders(token)
|
||||
});
|
||||
|
||||
if (detailResp.ok) {
|
||||
const detailData = await detailResp.json();
|
||||
const menuGroups = detailData.results || [];
|
||||
let dayItems = [];
|
||||
for (const group of menuGroups) {
|
||||
if (group.items && Array.isArray(group.items)) {
|
||||
dayItems = dayItems.concat(group.items);
|
||||
if (detailResp.ok) {
|
||||
const detailData = await detailResp.json();
|
||||
const menuGroups = detailData.results || [];
|
||||
let dayItems = [];
|
||||
for (const group of menuGroups) {
|
||||
if (group.items && Array.isArray(group.items)) {
|
||||
dayItems = dayItems.concat(group.items);
|
||||
}
|
||||
}
|
||||
if (dayItems.length > 0) {
|
||||
dayData = {
|
||||
date: dateStr,
|
||||
menu_items: dayItems,
|
||||
orders: dateObj.orders || []
|
||||
};
|
||||
}
|
||||
}
|
||||
if (dayItems.length > 0) {
|
||||
allDays.push({
|
||||
date: dateStr,
|
||||
menu_items: dayItems,
|
||||
orders: dateObj.orders || []
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(`Failed to fetch details for ${dateStr}:`, err);
|
||||
} finally {
|
||||
completed++;
|
||||
const pct = Math.round((completed / totalDates) * 100);
|
||||
progressFill.style.width = `${pct}%`;
|
||||
progressPercent.textContent = `${pct}%`;
|
||||
progressMessage.textContent = `Lade Menü für ${dateStr}...`;
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(`Failed to fetch details for ${dateStr}:`, err);
|
||||
}
|
||||
return dayData;
|
||||
}));
|
||||
|
||||
completed++;
|
||||
await new Promise(r => setTimeout(r, 100));
|
||||
for (const result of results) {
|
||||
if (result) {
|
||||
allDays.push(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const weeksMap = new Map();
|
||||
|
||||
Reference in New Issue
Block a user