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 fetchData = async (apiURL, apiKey, endpoint, ticker) => {
const response = await fetch(`${apiURL}${endpoint}`, { try {
method: "POST", const response = await fetch(`${apiURL}${endpoint}`, {
headers: { method: "POST",
"Content-Type": "application/json", headers: {
"X-API-KEY": apiKey, "Content-Type": "application/json",
}, "X-API-KEY": apiKey,
body: JSON.stringify({ ticker }), },
}); body: JSON.stringify({ ticker }),
return response.json(); });
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) => { const fetchWatchlist = async (pb, userId) => {
@ -46,52 +57,68 @@ export const load = async ({ params, locals }) => {
const { apiURL, apiKey, pb, user } = locals; const { apiURL, apiKey, pb, user } = locals;
const { tickerID } = params; const { tickerID } = params;
const endpoints = [ try {
"/etf-profile", const endpoints = [
"/etf-holdings", "/etf-profile",
"/etf-sector-weighting", "/etf-holdings",
"/stock-dividend", "/etf-sector-weighting",
"/stock-quote", "/stock-dividend",
"/pre-post-quote", "/stock-quote",
"/wiim", "/pre-post-quote",
"/one-day-price", "/wiim",
"/stock-news", "/one-day-price",
]; "/stock-news",
];
const promises = [ const promises = [
...endpoints.map((endpoint) => ...endpoints.map((endpoint) =>
fetchData(apiURL, apiKey, endpoint, tickerID), fetchData(apiURL, apiKey, endpoint, tickerID),
), ),
fetchWatchlist(pb, user?.id), fetchWatchlist(pb, user?.id),
]; ];
const [ const [
getETFProfile, getETFProfile,
getETFHoldings, getETFHoldings,
getETFSectorWeighting, getETFSectorWeighting,
getStockDividend, getStockDividend,
getStockQuote, getStockQuote,
getPrePostQuote, getPrePostQuote,
getWhyPriceMoved, getWhyPriceMoved,
getOneDayPrice, getOneDayPrice,
getNews, getNews,
getUserWatchlist, getUserWatchlist,
] = await Promise.all(promises); ] = await Promise.all(promises);
return {
getETFProfile: getETFProfile || [],
return { getETFHoldings: getETFHoldings || [],
getETFProfile, getETFSectorWeighting: getETFSectorWeighting || [],
getETFHoldings, getStockDividend: getStockDividend || [],
getETFSectorWeighting, getStockQuote: getStockQuote || [],
getStockDividend, getPrePostQuote: getPrePostQuote || [],
getStockQuote, getWhyPriceMoved: getWhyPriceMoved || [],
getPrePostQuote, getOneDayPrice: getOneDayPrice || [],
getWhyPriceMoved, getNews: getNews || [],
getOneDayPrice, getUserWatchlist: getUserWatchlist || [],
getNews, companyName: cleanString(getETFProfile?.at(0)?.name),
getUserWatchlist, getParams: params.tickerID,
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); rawData = prepareDataset(data?.getData, timePeriod);
originalData = rawData; originalData = rawData;
stockList = rawData?.slice(0, 50); stockList = rawData?.slice(0, 50);
console.log(rawData);
isLoaded = true; isLoaded = true;
} }
} }

View File

@ -17,16 +17,47 @@ const cleanString = (input) => {
return input?.replace(pattern, "").trim(); 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 fetchData = async (apiURL, apiKey, endpoint, ticker) => {
const response = await fetch(`${apiURL}${endpoint}`, { const cacheKey = `${endpoint}-${ticker}`;
method: "POST", const cached = cache.get(cacheKey);
headers: {
"Content-Type": "application/json", if (cached && Date.now() - cached.timestamp < CACHE_DURATION) {
"X-API-KEY": apiKey, return cached.data;
}, }
body: JSON.stringify({ ticker }),
}); const controller = new AbortController();
return response.json(); 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) => { const fetchWatchlist = async (pb, userId) => {
@ -58,40 +89,48 @@ export const load = async ({ params, locals }) => {
"/stock-news", "/stock-news",
]; ];
const promises = [ if (!tickerID) {
...endpoints.map((endpoint) => return { error: 'Invalid ticker ID' };
fetchData(apiURL, apiKey, endpoint, tickerID), }
),
fetchWatchlist(pb, user?.id),
];
const [ try {
getStockDeck, const [
getAnalystRating, getStockDeck,
getStockQuote, getAnalystRating,
getPrePostQuote, getStockQuote,
getWhyPriceMoved, getPrePostQuote,
getOneDayPrice, getWhyPriceMoved,
getNextEarnings, getOneDayPrice,
getEarningsSurprise, getNextEarnings,
getNews, getEarningsSurprise,
getUserWatchlist, getNews,
] = await Promise.all(promises); 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 {
return { getStockDeck,
getStockDeck, getAnalystRating,
getAnalystRating, getStockQuote,
getStockQuote, getPrePostQuote,
getPrePostQuote, getWhyPriceMoved,
getWhyPriceMoved, getOneDayPrice,
getOneDayPrice, getNextEarnings,
getNextEarnings, getEarningsSurprise,
getEarningsSurprise, getNews,
getNews, getUserWatchlist,
getUserWatchlist, companyName: cleanString(getStockDeck?.companyName),
companyName: cleanString(getStockDeck?.companyName), getParams: params.tickerID,
getParams: params.tickerID, };
}; } catch (error) {
return { error: 'Failed to load stock data' };
}
}; };