optimize loading time

This commit is contained in:
MuslemRahimi 2025-02-09 18:02:41 +01:00
parent f330a64f82
commit ebfe0ed017
3 changed files with 162 additions and 97 deletions

View File

@ -18,15 +18,26 @@ const cleanString = (input) => {
};
const fetchData = async (apiURL, apiKey, endpoint, ticker) => {
const response = await fetch(`${apiURL}${endpoint}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-KEY": apiKey,
},
body: JSON.stringify({ ticker }),
});
return response.json();
try {
const response = await fetch(`${apiURL}${endpoint}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-KEY": apiKey,
},
body: JSON.stringify({ ticker }),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
console.error(`Error fetching ${endpoint}:`, error);
return [];
}
};
const fetchWatchlist = async (pb, userId) => {
@ -46,52 +57,68 @@ export const load = async ({ params, locals }) => {
const { apiURL, apiKey, pb, user } = locals;
const { tickerID } = params;
const endpoints = [
"/etf-profile",
"/etf-holdings",
"/etf-sector-weighting",
"/stock-dividend",
"/stock-quote",
"/pre-post-quote",
"/wiim",
"/one-day-price",
"/stock-news",
];
try {
const endpoints = [
"/etf-profile",
"/etf-holdings",
"/etf-sector-weighting",
"/stock-dividend",
"/stock-quote",
"/pre-post-quote",
"/wiim",
"/one-day-price",
"/stock-news",
];
const promises = [
...endpoints.map((endpoint) =>
fetchData(apiURL, apiKey, endpoint, tickerID),
),
fetchWatchlist(pb, user?.id),
];
const promises = [
...endpoints.map((endpoint) =>
fetchData(apiURL, apiKey, endpoint, tickerID),
),
fetchWatchlist(pb, user?.id),
];
const [
getETFProfile,
getETFHoldings,
getETFSectorWeighting,
getStockDividend,
getStockQuote,
getPrePostQuote,
getWhyPriceMoved,
getOneDayPrice,
getNews,
getUserWatchlist,
] = await Promise.all(promises);
const [
getETFProfile,
getETFHoldings,
getETFSectorWeighting,
getStockDividend,
getStockQuote,
getPrePostQuote,
getWhyPriceMoved,
getOneDayPrice,
getNews,
getUserWatchlist,
] = await Promise.all(promises);
return {
getETFProfile,
getETFHoldings,
getETFSectorWeighting,
getStockDividend,
getStockQuote,
getPrePostQuote,
getWhyPriceMoved,
getOneDayPrice,
getNews,
getUserWatchlist,
companyName: cleanString(getETFProfile?.at(0)?.name),
getParams: params.tickerID,
};
return {
getETFProfile: getETFProfile || [],
getETFHoldings: getETFHoldings || [],
getETFSectorWeighting: getETFSectorWeighting || [],
getStockDividend: getStockDividend || [],
getStockQuote: getStockQuote || [],
getPrePostQuote: getPrePostQuote || [],
getWhyPriceMoved: getWhyPriceMoved || [],
getOneDayPrice: getOneDayPrice || [],
getNews: getNews || [],
getUserWatchlist: getUserWatchlist || [],
companyName: cleanString(getETFProfile?.at(0)?.name),
getParams: params.tickerID,
};
} catch (error) {
console.error('Error in load function:', error);
return {
getETFProfile: [],
getETFHoldings: [],
getETFSectorWeighting: [],
getStockDividend: [],
getStockQuote: [],
getPrePostQuote: [],
getWhyPriceMoved: [],
getOneDayPrice: [],
getNews: [],
getUserWatchlist: [],
companyName: '',
getParams: params.tickerID,
};
}
};

View File

@ -267,7 +267,6 @@
rawData = prepareDataset(data?.getData, timePeriod);
originalData = rawData;
stockList = rawData?.slice(0, 50);
console.log(rawData);
isLoaded = true;
}
}

View File

@ -17,16 +17,47 @@ const cleanString = (input) => {
return input?.replace(pattern, "").trim();
};
const CACHE_DURATION = 5 * 60 * 1000; // 5 minutes in milliseconds
const REQUEST_TIMEOUT = 5000; // 5 seconds
const cache = new Map();
const fetchData = async (apiURL, apiKey, endpoint, ticker) => {
const response = await fetch(`${apiURL}${endpoint}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-KEY": apiKey,
},
body: JSON.stringify({ ticker }),
});
return response.json();
const cacheKey = `${endpoint}-${ticker}`;
const cached = cache.get(cacheKey);
if (cached && Date.now() - cached.timestamp < CACHE_DURATION) {
return cached.data;
}
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), REQUEST_TIMEOUT);
try {
const response = await fetch(`${apiURL}${endpoint}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-KEY": apiKey,
},
body: JSON.stringify({ ticker }),
signal: controller.signal
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
cache.set(cacheKey, { data, timestamp: Date.now() });
return data;
} catch (error) {
if (error.name === 'AbortError') {
throw new Error(`Request timeout for ${endpoint}`);
}
throw error;
} finally {
clearTimeout(timeoutId);
}
};
const fetchWatchlist = async (pb, userId) => {
@ -58,40 +89,48 @@ export const load = async ({ params, locals }) => {
"/stock-news",
];
const promises = [
...endpoints.map((endpoint) =>
fetchData(apiURL, apiKey, endpoint, tickerID),
),
fetchWatchlist(pb, user?.id),
];
if (!tickerID) {
return { error: 'Invalid ticker ID' };
}
const [
getStockDeck,
getAnalystRating,
getStockQuote,
getPrePostQuote,
getWhyPriceMoved,
getOneDayPrice,
getNextEarnings,
getEarningsSurprise,
getNews,
getUserWatchlist,
] = await Promise.all(promises);
try {
const [
getStockDeck,
getAnalystRating,
getStockQuote,
getPrePostQuote,
getWhyPriceMoved,
getOneDayPrice,
getNextEarnings,
getEarningsSurprise,
getNews,
getUserWatchlist,
] = await Promise.all([
...endpoints.map((endpoint) =>
fetchData(apiURL, apiKey, endpoint, tickerID).catch(error => ({ error: error.message }))
),
fetchWatchlist(pb, user?.id).catch(() => [])
]);
if (!getStockDeck || getStockDeck.error) {
return { error: 'Failed to fetch stock data' };
}
return {
getStockDeck,
getAnalystRating,
getStockQuote,
getPrePostQuote,
getWhyPriceMoved,
getOneDayPrice,
getNextEarnings,
getEarningsSurprise,
getNews,
getUserWatchlist,
companyName: cleanString(getStockDeck?.companyName),
getParams: params.tickerID,
};
return {
getStockDeck,
getAnalystRating,
getStockQuote,
getPrePostQuote,
getWhyPriceMoved,
getOneDayPrice,
getNextEarnings,
getEarningsSurprise,
getNews,
getUserWatchlist,
companyName: cleanString(getStockDeck?.companyName),
getParams: params.tickerID,
};
} catch (error) {
return { error: 'Failed to load stock data' };
}
};