Performance optimizations: lazy rendering, row memoization, and data processing loops

This commit is contained in:
Christian Vidal Wolf
2026-01-27 21:43:25 +01:00
parent f521dd2921
commit 6b4bef66ec
4 changed files with 284 additions and 194 deletions
+32 -30
View File
@@ -511,13 +511,14 @@ export const mergeSalesAndAdsData = (
const createKey = (asin: string, customer: string, year: number, week: number) =>
`${asin.trim().toUpperCase()}|${customer.trim().toUpperCase()}|${year}|${week}`;
// Build traffic lookup map
// Build traffic lookup map - Use a more efficient key
const trafficMap = new Map<string, number>();
if (trafficData) {
trafficData.forEach(t => {
const key = createKey(t.asin, t.country, t.year, t.week);
trafficMap.set(key, (trafficMap.get(key) || 0) + t.glanceViews);
});
for (let i = 0; i < trafficData.length; i++) {
const t = trafficData[i];
const key = `${t.asin.trim().toUpperCase()}|${t.country.trim().toUpperCase()}|${t.year}|${t.week}`;
trafficMap.set(key, (trafficMap.get(key) || 0) + (t.glanceViews || 0));
}
}
// 1. Initialize metadata lookup map with provided global map if available, otherwise build from current sales
@@ -537,23 +538,24 @@ export const mergeSalesAndAdsData = (
month: string;
}>();
salesData.forEach(sale => {
for (let i = 0; i < salesData.length; i++) {
const sale = salesData[i];
const weekNum = sale.week || 0;
if (weekNum === 0) return;
if (weekNum === 0) continue;
const key = createKey(sale.asin, sale.customer, sale.year, weekNum);
const asinUpper = sale.asin.trim().toUpperCase();
const key = `${asinUpper}|${sale.customer.trim().toUpperCase()}|${sale.year}|${weekNum}`;
// If no global map provided, build it on the fly
if (!asinMetadataMap) {
const metaKey = sale.asin.trim().toUpperCase();
const existingMeta = asinMetadata.get(metaKey);
const existingMeta = asinMetadata.get(asinUpper);
if (!existingMeta || (sale.title && sale.title.length > (existingMeta.title?.length || 0))) {
asinMetadata.set(metaKey, { sku: sale.sku, title: sale.title, line: sale.line });
asinMetadata.set(asinUpper, { sku: sale.sku, title: sale.title, line: sale.line });
}
}
if (salesMap.has(key)) {
const existing = salesMap.get(key)!;
const existing = salesMap.get(key);
if (existing) {
existing.sellOut += sale.sellOut;
existing.units += sale.units;
if (sale.title && sale.title.length > (existing.title?.length || 0)) {
@@ -576,14 +578,15 @@ export const mergeSalesAndAdsData = (
month: sale.month
});
}
});
}
// 3. Aggregate Ads by ASIN|Customer|Year|Week
const adsMap = new Map<string, AdsRecord>();
adsData.forEach(ad => {
const key = createKey(ad.asin, ad.country, ad.year, ad.week);
if (adsMap.has(key)) {
const existing = adsMap.get(key)!;
for (let i = 0; i < adsData.length; i++) {
const ad = adsData[i];
const key = `${ad.asin.trim().toUpperCase()}|${ad.country.trim().toUpperCase()}|${ad.year}|${ad.week}`;
const existing = adsMap.get(key);
if (existing) {
existing.cost += ad.cost;
existing.clicks += ad.clicks;
existing.impressions += ad.impressions;
@@ -593,7 +596,7 @@ export const mergeSalesAndAdsData = (
} else {
adsMap.set(key, { ...ad });
}
});
}
const mergedData: CombinedKPIs[] = [];
const processedKeys = new Set<string>();
@@ -1492,13 +1495,14 @@ export const pivotWeeklySalesData = (data: CombinedKPIs[]): {
const map = new Map<string, WeeklyPivotRow>();
data.forEach(record => {
// Use ASIN as primary key since mergeSalesAndAdsData outputs one record per ASIN/week
for (let i = 0; i < data.length; i++) {
const record = data[i];
const key = record.asin || record.sku || `${record.title}-${record.line}`;
if (!key) return;
if (!key) continue;
if (!map.has(key)) {
map.set(key, {
let row = map.get(key);
if (!row) {
row = {
id: key,
sku: record.sku || '',
title: record.title || '',
@@ -1508,19 +1512,17 @@ export const pivotWeeklySalesData = (data: CombinedKPIs[]): {
unitsByWeek: {},
spendByWeek: {},
gvByWeek: {}
});
};
map.set(key, row);
}
const row = map.get(key)!;
if (record.week) {
const weekKey = `${record.year}-${String(record.week).padStart(2, '0')}`;
row.unitsByWeek[weekKey] = (row.unitsByWeek[weekKey] || 0) + record.unitsTotal;
// Only add cost if we haven't already added it for this ASIN/week
// Since mergeSalesAndAdsData now outputs one record per ASIN/week, this should be clean
row.unitsByWeek[weekKey] = (row.unitsByWeek[weekKey] || 0) + (record.unitsTotal || 0);
row.spendByWeek[weekKey] = (row.spendByWeek[weekKey] || 0) + (record.cost || 0);
row.gvByWeek[weekKey] = (row.gvByWeek[weekKey] || 0) + (record.glanceViews || 0);
}
});
}
return {
rows: Array.from(map.values()),