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:
kilyabin
2025-11-23 02:38:09 +04:00
parent 2893a9fd18
commit b1f892ca7d
4 changed files with 79 additions and 33 deletions

View File

@@ -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