Add Redis/Valkey caching with sessionStorage client-side cache and improved asset loading
This commit is contained in:
+46
-29
@@ -4,6 +4,11 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" maximum-scale="1" />
|
||||
<title>Job Info — Vanilla JS</title>
|
||||
<!-- Preload critical images for instant display -->
|
||||
<link rel="preload" href="assets/CCwhiteApp.png" as="image">
|
||||
<link rel="preload" href="assets/lightbulb.jpg" as="image">
|
||||
<link rel="preload" href="assets/PalmIsland.png" as="image">
|
||||
<link rel="preload" href="assets/DailyCheck.png" as="image">
|
||||
<script src="https://cdn.tailwindcss.com"></script> <!-- Suppress Tailwind CDN warning for now -->
|
||||
<script>
|
||||
if (window.tailwind) window.tailwind.config = { corePlugins: { preflight: true } }
|
||||
@@ -239,7 +244,8 @@
|
||||
// --- Utility ---
|
||||
const fetchNoCache = (url, options={}) => {
|
||||
const headers = { ...(options.headers||{}), ...authHeaders() };
|
||||
return fetch(url + `&_ts=${Date.now()}`, { ...options, headers });
|
||||
const separator = url.includes('?') ? '&' : '?';
|
||||
return fetch(url + `${separator}_ts=${Date.now()}`, { ...options, headers });
|
||||
};
|
||||
const GRAPH_TOKEN_KEY = 'graphAccessToken';
|
||||
const GRAPH_REAUTH_FLAG = 'graphReauthAttempted';
|
||||
@@ -368,17 +374,8 @@
|
||||
// Load version from backend /version endpoint so UI matches package.json
|
||||
async function loadVersion(){
|
||||
if(!versionLabel) return;
|
||||
try{
|
||||
const res = await fetch('/version');
|
||||
if(!res.ok) {
|
||||
console.warn(`Version endpoint returned ${res.status}. Using default version.`);
|
||||
return;
|
||||
}
|
||||
const data = await res.json().catch(()=>null);
|
||||
if(data?.version) versionLabel.textContent = `v${data.version}`;
|
||||
}catch(err){
|
||||
console.debug('Version load failed (non-critical):', err.message);
|
||||
}
|
||||
// Display "Redis" for the Redis implementation branch
|
||||
versionLabel.textContent = 'Redis';
|
||||
}
|
||||
loadVersion();
|
||||
|
||||
@@ -397,26 +394,46 @@
|
||||
async function fetchAllJobs(){
|
||||
startProgress();
|
||||
clearJobsCache('Loading…');
|
||||
let page=1, totalItems=0;
|
||||
const startTime = performance.now();
|
||||
try{
|
||||
while(true){
|
||||
const url = `${PB_COLLECTION_URL}?page=${page}&perPage=${perPage}&sort=-Job_Number`;
|
||||
const res = await fetchNoCache(url);
|
||||
if(!res.ok) throw new Error(`Fetch failed: ${res.status}`);
|
||||
const data = await res.json();
|
||||
const items = data.items || [];
|
||||
jobsCache.push(...items);
|
||||
totalItems = data.totalItems || (items.length + ((page-1)*perPage));
|
||||
|
||||
// Apply filters on the currently loaded pages so initial results reflect preferences immediately.
|
||||
// Check client-side cache first (sessionStorage)
|
||||
const cachedData = sessionStorage.getItem('jobsCache');
|
||||
const cacheTime = sessionStorage.getItem('jobsCacheTime');
|
||||
const cacheAge = cacheTime ? Date.now() - parseInt(cacheTime) : Infinity;
|
||||
|
||||
// Use client cache if less than 5 minutes old
|
||||
if (cachedData && cacheAge < 300000) {
|
||||
const data = JSON.parse(cachedData);
|
||||
jobsCache.push(...data);
|
||||
const loadTime = Math.round(performance.now() - startTime);
|
||||
console.log(`✓ Loaded ${data.length} jobs from CLIENT CACHE in ${loadTime}ms`);
|
||||
progressBar.style.width='95%';
|
||||
applyFiltersAndRender();
|
||||
|
||||
if(progTimer) clearInterval(progTimer);
|
||||
const realProg=Math.min(95, Math.floor((jobsCache.length / Math.max(1,totalItems)) * 95));
|
||||
progressBar.style.width=realProg+'%';
|
||||
if(jobsCache.length >= totalItems || items.length===0) break;
|
||||
page++;
|
||||
finishProgress();
|
||||
return;
|
||||
}
|
||||
|
||||
// Use single cached endpoint that returns all jobs at once
|
||||
const url = `/api/jobs-all`;
|
||||
const res = await fetchNoCache(url);
|
||||
if(!res.ok) throw new Error(`Fetch failed: ${res.status}`);
|
||||
const data = await res.json();
|
||||
const items = data.items || [];
|
||||
jobsCache.push(...items);
|
||||
|
||||
// Store in client-side cache
|
||||
sessionStorage.setItem('jobsCache', JSON.stringify(items));
|
||||
sessionStorage.setItem('jobsCacheTime', Date.now().toString());
|
||||
|
||||
const loadTime = Math.round(performance.now() - startTime);
|
||||
console.log(`✓ Loaded ${items.length} jobs from API in ${loadTime}ms`);
|
||||
|
||||
// Show results immediately
|
||||
progressBar.style.width='95%';
|
||||
const renderStart = performance.now();
|
||||
applyFiltersAndRender();
|
||||
const renderTime = Math.round(performance.now() - renderStart);
|
||||
console.log(`✓ Rendered jobs in ${renderTime}ms (Total: ${Math.round(performance.now() - startTime)}ms)`);
|
||||
finishProgress();
|
||||
}catch(err){ finishProgress(); alert('Failed to fetch jobs: '+err.message); console.error(err);}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user