Faster first load; demo date tags stay current
First load: - Draw the Overview as soon as the data arrives instead of on its next 2-second timer tick (about 2.5 s to 0.6 s on a typical connection). - Start on DOMContentLoaded instead of window.onload. - Load the ~900 KB PDF library only when someone exports a PDF. - Fetch the startup files side by side, and build the docs search index after the dashboard has drawn (unless the visit starts on /docs). - Show a loading placeholder on the Overview until the data arrives. Demo: the date-batch tags sit on fixed working-day offsets from today. The seed records them in Demo-Dates.json and the worker relabels them when the day changes, so a long-running container never looks stale.
This commit is contained in:
8 files changed
+105
-21
No files matched your search
+32
-12
@@ -8,7 +8,6 @@
|
||||
<link rel="icon" href="/favicon.png" type="image/png">
|
||||
|
||||
<script src="/vendor/marked/marked.min.js"></script>
|
||||
<script src="/vendor/html2pdf/html2pdf.bundle.min.js"></script>
|
||||
<link rel="stylesheet" href="/vendor/highlight/styles/atom-one-dark.min.css">
|
||||
<script src="/vendor/highlight/highlight.min.js"></script>
|
||||
<script src="/vendor/highlight/languages/powershell.min.js"></script>
|
||||
@@ -1784,7 +1783,22 @@
|
||||
}
|
||||
}
|
||||
|
||||
window.onload = async () => {
|
||||
// PDF export library (~900 KB): fetched the first time someone exports, not on every visit
|
||||
function loadHtml2Pdf() {
|
||||
if (window.html2pdf) return Promise.resolve();
|
||||
return window._html2pdfLoading || (window._html2pdfLoading = new Promise((resolve, reject) => {
|
||||
const s = document.createElement('script');
|
||||
s.src = '/vendor/html2pdf/html2pdf.bundle.min.js';
|
||||
s.onload = resolve;
|
||||
s.onerror = () => { window._html2pdfLoading = null; reject(new Error('Could not load the PDF library')); };
|
||||
document.head.appendChild(s);
|
||||
}));
|
||||
}
|
||||
|
||||
// Start as soon as the page is parsed (not after every image and script has finished, as
|
||||
// window.onload would); the timeout lets every module's own DOMContentLoaded setup run first
|
||||
document.addEventListener('DOMContentLoaded', () => setTimeout(initDashboard, 0));
|
||||
async function initDashboard() {
|
||||
updateThemeBtn();
|
||||
initMasterTables();
|
||||
|
||||
@@ -1812,9 +1826,9 @@
|
||||
document.getElementById('btn-edit-mode').innerHTML = EDIT_SVG;
|
||||
document.getElementById('btn-save-doc').innerHTML = `${SAVE_SVG} Save`;
|
||||
|
||||
await loadBlacklist();
|
||||
await loadDocsList();
|
||||
await loadAllTags();
|
||||
// Load side by side; the device data doesn't wait for the article list
|
||||
const docsReady = loadDocsList();
|
||||
await Promise.all([loadBlacklist(), loadAllTags()]);
|
||||
|
||||
const savedTech = localStorage.getItem('usmt_tech_id');
|
||||
if (savedTech) {
|
||||
@@ -1822,15 +1836,16 @@
|
||||
await loadTechRoster();
|
||||
}
|
||||
|
||||
startDashboard();
|
||||
|
||||
// Check if we were opened in a new tab specifically to view a document
|
||||
await docsReady;
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const targetDoc = urlParams.get('doc');
|
||||
if (targetDoc && availableDocs.includes(targetDoc)) {
|
||||
await openDoc(targetDoc);
|
||||
}
|
||||
|
||||
startDashboard();
|
||||
};
|
||||
}
|
||||
|
||||
// Code spans and fenced blocks are set aside while the [[Badge:..]] / [[Copy:..]] / UNC
|
||||
// path rewrites run, so an article can show that syntax literally inside `code`
|
||||
@@ -2088,7 +2103,7 @@
|
||||
btn.disabled = true;
|
||||
btn.innerHTML = btn.innerHTML.replace('PDF', 'Exporting...');
|
||||
|
||||
html2pdf().set(opt).from(clone).save().finally(() => {
|
||||
loadHtml2Pdf().then(() => html2pdf().set(opt).from(clone).save()).finally(() => {
|
||||
btn.disabled = false;
|
||||
btn.innerHTML = btn.innerHTML.replace('Exporting...', 'PDF');
|
||||
});
|
||||
@@ -4307,7 +4322,8 @@
|
||||
|
||||
async function pullData() {
|
||||
try {
|
||||
// 1. FAST STATE POLLING
|
||||
// 1. FAST STATE POLLING (the tracked list is fetched alongside it)
|
||||
const trackFetch = fetch('Tracked-Devices.json?t=' + Date.now()).catch(() => null);
|
||||
const stateRes = await fetch('Worker-State.json?t=' + Date.now());
|
||||
if (!stateRes.ok) return;
|
||||
const state = await stateRes.json();
|
||||
@@ -4353,7 +4369,7 @@
|
||||
document.getElementById('syncBreakdown').innerHTML = DeviceInfo.syncBreakdownHtml(state);
|
||||
|
||||
// Check if Tracked-Devices was updated by you or a teammate
|
||||
const trackRes = await fetch('Tracked-Devices.json?t=' + Date.now()).catch(() => null);
|
||||
const trackRes = await trackFetch;
|
||||
let currentTrackedHash = "";
|
||||
let trackData = null;
|
||||
if (trackRes && trackRes.ok) {
|
||||
@@ -4374,6 +4390,7 @@
|
||||
globalTrackedHash = currentTrackedHash;
|
||||
|
||||
// 2. FETCH CORE DATA AND ADVANCED DATA
|
||||
const advFetch = fetch('Advanced-Cache.json?t=' + Date.now()).catch(() => null);
|
||||
const dataRes = await fetch('Data.json?t=' + Date.now()).catch(() => null);
|
||||
if (dataRes && dataRes.ok) {
|
||||
const payload = await dataRes.json();
|
||||
@@ -4387,7 +4404,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
const advRes = await fetch('Advanced-Cache.json?t=' + Date.now()).catch(() => null);
|
||||
const advRes = await advFetch;
|
||||
if (advRes && advRes.ok) {
|
||||
advancedDataCache = await advRes.json();
|
||||
}
|
||||
@@ -4496,6 +4513,8 @@
|
||||
renderSoftwareTable(); // <-- Forces the Software tab to update instantly!
|
||||
renderCustomTable();
|
||||
refreshOpenDialogs();
|
||||
document.dispatchEvent(new Event('usmt:data'));
|
||||
if (window.Overview) Overview.refresh(); // draw the Overview now, not on its next timer tick
|
||||
|
||||
// 3. LAZY LOAD SOFTWARE LAST
|
||||
fetch('Software-Cache.json?t=' + Date.now())
|
||||
@@ -4528,6 +4547,7 @@
|
||||
renderSoftwareTable();
|
||||
renderCustomTable();
|
||||
refreshOpenDialogs(true);
|
||||
if (window.Overview) Overview.refresh();
|
||||
}
|
||||
}
|
||||
}).catch(() => null);
|
||||
|
||||
Reference in new issue
Block a user