Optimize Hugo build based on context7 docs review

Performance improvements:
- Use partialCached for footer and accessibility-panel
- Use js.Build with ESBuild for better JS minification
- Remove duplicate FOUC prevention code from accessibility.js
- Move footer link handler into main JS bundle

Security improvements:
- Add crossorigin="anonymous" to CSS link for SRI compliance
- Add integrity hash and crossorigin to script tag

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-21 08:55:43 +00:00
parent 89fa8e4262
commit 04797e7c9f
4 changed files with 21 additions and 68 deletions

View File

@@ -585,11 +585,22 @@
} }
} }
function initFooterLink() {
const footerLink = document.getElementById('footer-accessibility-link');
if (footerLink) {
footerLink.addEventListener('click', function(e) {
e.preventDefault();
document.getElementById('accessibility-toggle')?.click();
});
}
}
function onDOMReady() { function onDOMReady() {
bindEvents(); bindEvents();
initPanelToggle(); initPanelToggle();
initHeaderScroll(); initHeaderScroll();
initMobileNav(); initMobileNav();
initFooterLink();
updateControlStates(); updateControlStates();
// Show first-visit animation // Show first-visit animation
@@ -601,60 +612,6 @@
} }
} }
// ============================================ // Start - FOUC prevention handled by inline script in head.html
// Critical Styles (Prevent Flash)
// ============================================
(function applyCriticalStyles() {
try {
const stored = localStorage.getItem(STORAGE_KEY);
if (stored) {
const prefs = JSON.parse(stored);
// Apply theme immediately
if (prefs.theme && prefs.theme !== 'light') {
if (prefs.theme === 'system') {
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
if (prefersDark) {
html.setAttribute('data-theme', 'dark');
}
} else {
html.setAttribute('data-theme', prefs.theme);
}
}
// Apply font scale
if (prefs.fontSize && FONT_SIZES[prefs.fontSize]) {
html.setAttribute('data-font-size', prefs.fontSize);
}
// Apply dyslexia font
if (prefs.dyslexiaFont) {
html.setAttribute('data-dyslexia', 'true');
}
// Apply other critical preferences
if (prefs.lineSpacing) {
html.setAttribute('data-line-spacing', prefs.lineSpacing);
}
if (prefs.readingWidth) {
html.setAttribute('data-reading-width', prefs.readingWidth);
}
if (prefs.enhancedFocus) {
html.setAttribute('data-enhanced-focus', 'true');
}
if (prefs.reducedMotion && prefs.reducedMotion !== 'system') {
html.setAttribute('data-reduced-motion', prefs.reducedMotion);
}
}
} catch (e) {
// Silent fail
}
})();
// Start
init(); init();
})(); })();

View File

@@ -12,16 +12,20 @@
{{- block "main" . }}{{- end }} {{- block "main" . }}{{- end }}
</main> </main>
{{- partial "footer.html" . -}} {{- partialCached "footer.html" . "footer" -}}
</div> </div>
{{- partial "accessibility-panel.html" . -}} {{- partialCached "accessibility-panel.html" . "a11y-panel" -}}
{{/* Backdrop for panel */}} {{/* Backdrop for panel */}}
<div id="accessibility-backdrop" class="accessibility-backdrop" aria-hidden="true"></div> <div id="accessibility-backdrop" class="accessibility-backdrop" aria-hidden="true"></div>
{{/* Load JavaScript */}} {{/* Load JavaScript */}}
{{ $js := resources.Get "js/accessibility.js" | minify | fingerprint }} {{ with resources.Get "js/accessibility.js" }}
<script src="{{ $js.RelPermalink }}" defer></script> {{ $opts := dict "minify" true }}
{{ with . | js.Build $opts | fingerprint }}
<script src="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous" defer></script>
{{ end }}
{{ end }}
</body> </body>
</html> </html>

View File

@@ -45,11 +45,3 @@
</div> </div>
</div> </div>
</footer> </footer>
<script>
// Footer accessibility link opens panel
document.getElementById('footer-accessibility-link')?.addEventListener('click', function(e) {
e.preventDefault();
document.getElementById('accessibility-toggle')?.click();
});
</script>

View File

@@ -54,7 +54,7 @@
{{ $main := resources.Get "css/main.css" }} {{ $main := resources.Get "css/main.css" }}
{{ $allCSS := slice $variables $reset $typography $dark $highContrast $header $footer $article $accessibilityPanel $focus $print $main | resources.Concat "css/bundle.css" | minify | fingerprint }} {{ $allCSS := slice $variables $reset $typography $dark $highContrast $header $footer $article $accessibilityPanel $focus $print $main | resources.Concat "css/bundle.css" | minify | fingerprint }}
<link rel="stylesheet" href="{{ $allCSS.RelPermalink }}" integrity="{{ $allCSS.Data.Integrity }}"> <link rel="stylesheet" href="{{ $allCSS.RelPermalink }}" integrity="{{ $allCSS.Data.Integrity }}" crossorigin="anonymous">
{{/* Favicon */}} {{/* Favicon */}}
<link rel="icon" type="image/svg+xml" href="/favicon.svg"> <link rel="icon" type="image/svg+xml" href="/favicon.svg">