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 ``;
});