diff --git a/_config.yml b/_config.yml index f23ced547b..881bcbdcec 100644 --- a/_config.yml +++ b/_config.yml @@ -347,6 +347,12 @@ calendar: # For more information: https://www.w3.org/TR/resource-hints/#preconnect preconnect: false +# Performance optimization +performance: + # Lazy-load non-critical CSS (FontAwesome, Fancybox, KaTeX) + # This improves Lighthouse scores by making these CSS files non-render-blocking + lazy_css: false + # Set the text alignment in posts / pages. text_align: # Available values: start | end | left | right | center | justify | justify-all | match-parent diff --git a/layout/_partials/head/head.njk b/layout/_partials/head/head.njk index fabf711a00..c306f44007 100644 --- a/layout/_partials/head/head.njk +++ b/layout/_partials/head/head.njk @@ -48,14 +48,14 @@ {{ next_font() }} -{{ next_vendors('fontawesome') }} +{{ next_vendors('fontawesome', { lazy: true }) }} {%- if theme.motion.enable %} {{ next_vendors('animate_css') }} {%- endif %} {%- if theme.fancybox %} - {{ next_vendors('fancybox_css') }} + {{ next_vendors('fancybox_css', { lazy: true }) }} {%- endif %} {%- if theme.pace.enable %} diff --git a/layout/_third-party/math/katex.njk b/layout/_third-party/math/katex.njk index 62a64c2c9f..d9228297d7 100644 --- a/layout/_third-party/math/katex.njk +++ b/layout/_third-party/math/katex.njk @@ -1,4 +1,4 @@ -{{ next_vendors('katex') }} +{{ next_vendors('katex', { lazy: true }) }} {%- if theme.math.katex.copy_tex %} {{ next_data('katex', { copy_tex_js: theme.vendors.copy_tex_js diff --git a/scripts/helpers/engine.js b/scripts/helpers/engine.js index 6b2f703ac4..876d91d736 100644 --- a/scripts/helpers/engine.js +++ b/scripts/helpers/engine.js @@ -35,13 +35,26 @@ hexo.extend.helper.register('next_js', function(file, { return ``; }); -hexo.extend.helper.register('next_vendors', function(name) { +hexo.extend.helper.register('next_vendors', function(name, options = {}) { const { url, integrity } = this.theme.vendors[name]; const type = url.endsWith('css') ? 'css' : 'js'; + const { lazy = false } = options; + if (type === 'css') { + const integrityAttr = integrity ? ` integrity="${integrity}" crossorigin="anonymous"` : ''; + + // Lazy-load CSS using preload + onload technique + if (lazy && this.theme.performance?.lazy_css) { + return ` +`; + } + + // Default: render-blocking CSS if (integrity) return ``; return ``; } + + // JS handling unchanged (already uses defer) if (integrity) return ``; return ``; });