ObsiViewer/server/performance-config.mjs

96 lines
2.0 KiB
JavaScript

/**
* Performance configuration for Phase 1 optimization
*/
export const PERFORMANCE_CONFIG = {
// Metadata cache TTL (5 minutes)
METADATA_CACHE_TTL: 5 * 60 * 1000,
// Preload nearby notes (number of notes before/after)
PRELOAD_NEARBY: 5,
// Pagination size for large vaults
PAGINATION_SIZE: 100,
// Maximum notes to load in metadata endpoint
MAX_METADATA_ITEMS: 10000,
// Enable performance logging
ENABLE_PERF_LOGGING: process.env.PERF_LOGGING === 'true',
};
/**
* Simple in-memory cache for metadata
*/
export class MetadataCache {
constructor(ttl = PERFORMANCE_CONFIG.METADATA_CACHE_TTL) {
this.cache = null;
this.ttl = ttl;
this.timestamp = null;
}
set(data) {
this.cache = data;
this.timestamp = Date.now();
}
get() {
if (!this.cache || !this.timestamp) {
return null;
}
if (Date.now() - this.timestamp > this.ttl) {
this.cache = null;
this.timestamp = null;
return null;
}
return this.cache;
}
invalidate() {
this.cache = null;
this.timestamp = null;
}
isValid() {
return this.cache !== null && (Date.now() - this.timestamp) < this.ttl;
}
}
/**
* Performance logger
*/
export class PerformanceLogger {
static log(operation, duration, metadata = {}) {
if (!PERFORMANCE_CONFIG.ENABLE_PERF_LOGGING) {
return;
}
const level = duration > 1000 ? 'warn' : 'info';
const message = `[PERF] ${operation}: ${duration.toFixed(0)}ms`;
if (level === 'warn') {
console.warn(message, metadata);
} else {
console.log(message, metadata);
}
}
static mark(label) {
if (typeof performance !== 'undefined' && performance.mark) {
performance.mark(label);
}
}
static measure(label, startMark, endMark) {
if (typeof performance !== 'undefined' && performance.measure) {
try {
performance.measure(label, startMark, endMark);
} catch (e) {
// Ignore if marks don't exist
}
}
}
}