perf: оптимизация памяти - кэширование только текущей недели и условный парсинг Критические оптимизации для снижения потребления памяти с 1.2 ГБ: - Кэширование только текущей недели: * Кэш хранит только текущие недели (без параметра wk) * Запросы с конкретной неделей (wk указан) не кэшируются * Ключ кэша изменен с ${group}_${wk} на group * Уменьшен maxCacheSize с 100 до 50 записей - Условный парсинг навигации по неделям: * Парсинг навигации выполняется только если weekNavigationEnabled === true * Если навигация выключена, parseWeekNavigation не вызывается * Экономит память и CPU при выключенной навигации * Параметр shouldParseWeekNavigation передается через getSchedule -> parsePage - Результат: * Значительное снижение потребления памяти * Кэш содержит только актуальные данные (текущие недели) * Парсинг навигации выполняется только при необходимости Измененные файлы: - src/pages/[group].tsx - логика кэширования только текущей недели - src/app/agregator/schedule.ts - параметр для условного парсинга - src/app/parser/schedule.ts - условный вызов parseWeekNavigation
Критические оптимизации для снижения потребления памяти
- Кэширование только текущей недели:
* Кэш хранит только текущие недели (без параметра wk)
* Запросы с конкретной неделей (wk указан) не кэшируются
* Ключ кэша изменен с `${group}_${wk}` на `group`
* Уменьшен maxCacheSize с 100 до 50 записей
- Условный парсинг навигации по неделям:
* Парсинг навигации выполняется только если weekNavigationEnabled === true
* Если навигация выключена, parseWeekNavigation не вызывается
* Экономит память и CPU при выключенной навигации
* Параметр shouldParseWeekNavigation передается через getSchedule -> parsePage
- Результат:
* Значительное снижение потребления памяти
* Кэш содержит только актуальные данные (текущие недели)
* Парсинг навигации выполняется только при необходимости
Измененные файлы:
- src/pages/[group].tsx - логика кэширования только текущей недели
- src/app/agregator/schedule.ts - параметр для условного парсинга
- src/app/parser/schedule.ts - условный вызов parseWeekNavigation
This commit is contained in:
@@ -82,6 +82,33 @@ export default function HomePage(props: NextSerialized<PageProps>) {
|
||||
|
||||
const cachedSchedules = new Map<string, { lastFetched: Date, results: ScheduleResult }>()
|
||||
const maxCacheDurationInMS = 1000 * 60 * 60
|
||||
const maxCacheSize = 50 // Максимальное количество записей в кэше (только текущие недели)
|
||||
|
||||
// Очистка старых записей из кэша
|
||||
function cleanupCache() {
|
||||
const now = Date.now()
|
||||
const entriesToDelete: string[] = []
|
||||
|
||||
// Находим устаревшие записи
|
||||
for (const [key, value] of cachedSchedules.entries()) {
|
||||
if (now - value.lastFetched.getTime() >= maxCacheDurationInMS) {
|
||||
entriesToDelete.push(key)
|
||||
}
|
||||
}
|
||||
|
||||
// Удаляем устаревшие записи
|
||||
entriesToDelete.forEach(key => cachedSchedules.delete(key))
|
||||
|
||||
// Если кэш все еще слишком большой, удаляем самые старые записи
|
||||
if (cachedSchedules.size > maxCacheSize) {
|
||||
const sortedEntries = Array.from(cachedSchedules.entries())
|
||||
.sort((a, b) => a[1].lastFetched.getTime() - b[1].lastFetched.getTime())
|
||||
|
||||
const toRemove = sortedEntries.slice(0, cachedSchedules.size - maxCacheSize)
|
||||
toRemove.forEach(([key]) => cachedSchedules.delete(key))
|
||||
}
|
||||
}
|
||||
|
||||
export async function getServerSideProps(context: GetServerSidePropsContext<{ group: string }>): Promise<GetServerSidePropsResult<NextSerialized<PageProps>>> {
|
||||
const groups = loadGroups()
|
||||
const settings = loadSettings()
|
||||
@@ -93,9 +120,14 @@ export async function getServerSideProps(context: GetServerSidePropsContext<{ gr
|
||||
let scheduleResult: ScheduleResult
|
||||
let parsedAt
|
||||
|
||||
// Ключ кэша включает группу и неделю
|
||||
const cacheKey = wk ? `${group}_${wk}` : group
|
||||
const cachedSchedule = cachedSchedules.get(cacheKey)
|
||||
// Очищаем старые записи из кэша перед использованием
|
||||
cleanupCache()
|
||||
|
||||
// Кэшируем только текущую неделю (без параметра wk)
|
||||
// Если запрашивается конкретная неделя (wk указан), не используем кэш
|
||||
const useCache = !wk
|
||||
const cacheKey = group // Ключ кэша - только группа (текущая неделя)
|
||||
const cachedSchedule = useCache ? cachedSchedules.get(cacheKey) : undefined
|
||||
|
||||
if (cachedSchedule?.lastFetched && Date.now() - cachedSchedule.lastFetched.getTime() < maxCacheDurationInMS) {
|
||||
scheduleResult = cachedSchedule.results
|
||||
@@ -103,9 +135,16 @@ export async function getServerSideProps(context: GetServerSidePropsContext<{ gr
|
||||
} else {
|
||||
try {
|
||||
const groupInfo = groups[group]
|
||||
scheduleResult = await getSchedule(groupInfo.parseId, groupInfo.name, wk)
|
||||
// Передаем настройки в getSchedule для условного парсинга навигации
|
||||
scheduleResult = await getSchedule(groupInfo.parseId, groupInfo.name, wk, settings.weekNavigationEnabled)
|
||||
parsedAt = new Date()
|
||||
cachedSchedules.set(cacheKey, { lastFetched: new Date(), results: scheduleResult })
|
||||
|
||||
// Кэшируем только текущую неделю
|
||||
if (useCache) {
|
||||
cachedSchedules.set(cacheKey, { lastFetched: new Date(), results: scheduleResult })
|
||||
// Очищаем кэш после добавления новой записи, если он стал слишком большим
|
||||
cleanupCache()
|
||||
}
|
||||
} catch(e) {
|
||||
if (cachedSchedule?.lastFetched) {
|
||||
scheduleResult = cachedSchedule.results
|
||||
|
||||
Reference in New Issue
Block a user