perf: denormalize media_sort_date + pre-scale video thumbs
Schema (media_sort_date denormalization): - Add media_sort_date column to storage.files with DEFAULT created_at - Add trigger sync_media_sort_date: when file_metadata is upserted, copies COALESCE(captured_at, created_at) into files.media_sort_date - Add partial index idx_files_media_timeline on (user_id, media_sort_date DESC) WHERE NOT is_trashed AND media type -- enables Index Scan + Limit (no Sort) - copy_folder_tree now copies media_sort_date for copied files - Remove dead idx_file_metadata_captured (no longer needed) Query optimization (list_media_files): - Rewrite to use fi.media_sort_date instead of COALESCE(fm.captured_at,...) - Eliminates LEFT JOIN file_metadata -- one fewer table touch - Plan: Limit to Index Scan O(LIMIT) instead of Sort O(N) Video thumbnail pre-scaling (client + server): - JS: pre-scale canvas to max 400px before toBlob -- 22x less RAM, 15x less BW - Rust: fast-path in store_external_thumbnail -- if payload is already WebP with dims within max_dim, store as-is (zero decode, zero encode)
This commit is contained in:
@@ -257,11 +257,16 @@ const photosView = {
|
||||
}, { once: true });
|
||||
|
||||
video.addEventListener('seeked', () => {
|
||||
// Pre-scale to thumbnail size in the browser — saves ~22× RAM,
|
||||
// ~15× bandwidth, and lets the server skip resize entirely.
|
||||
const MAX_THUMB = 400; // must match ThumbnailSize::Preview
|
||||
const scale = Math.min(MAX_THUMB / video.videoWidth,
|
||||
MAX_THUMB / video.videoHeight, 1);
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = video.videoWidth;
|
||||
canvas.height = video.videoHeight;
|
||||
canvas.width = Math.round(video.videoWidth * scale);
|
||||
canvas.height = Math.round(video.videoHeight * scale);
|
||||
const ctx = canvas.getContext('2d');
|
||||
ctx.drawImage(video, 0, 0);
|
||||
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
|
||||
|
||||
// Try WebP first, fall back to JPEG
|
||||
const mimeType = typeof canvas.toBlob === 'function'
|
||||
|
||||
Reference in New Issue
Block a user