diff --git a/assets/apps/customizer-controls/src/typography-extra/LocalGoogleFonts.js b/assets/apps/customizer-controls/src/typography-extra/LocalGoogleFonts.js
index ac499ecadd..7f6ba54fcd 100644
--- a/assets/apps/customizer-controls/src/typography-extra/LocalGoogleFonts.js
+++ b/assets/apps/customizer-controls/src/typography-extra/LocalGoogleFonts.js
@@ -20,7 +20,7 @@ const initLocalGoogleFonts = () => {
return;
}
- const toggleControl =
+ const localFontsToggle =
new wp.customize.controlConstructor.neve_toggle_control(
NeveReactCustomize.localGoogleFonts.key,
{
@@ -32,7 +32,24 @@ const initLocalGoogleFonts = () => {
}
);
- render(, section.container[0]);
+ const preloadFontsToggle =
+ new wp.customize.controlConstructor.neve_toggle_control(
+ NeveReactCustomize.preloadFonts.key,
+ {
+ section: section.id,
+ label: __('Preload fonts', 'neve'),
+ setting: NeveReactCustomize.preloadFonts.key,
+ priority: 6,
+ }
+ );
+
+ render(
+ <>
+
+
+ >,
+ section.container[0]
+ );
};
export { initLocalGoogleFonts };
diff --git a/inc/core/settings/config.php b/inc/core/settings/config.php
index b3b9b5db6a..ab5ba5369a 100644
--- a/inc/core/settings/config.php
+++ b/inc/core/settings/config.php
@@ -94,6 +94,7 @@ class Config {
const MODS_POST_TYPE_VSPACING = 'content_vspacing';
const OPTION_LOCAL_GOOGLE_FONTS_HOSTING = 'nv_pro_enable_local_fonts';
+ const MODS_PRELOAD_FONTS = 'neve_preload_fonts';
const OPTION_POSTS_PER_PAGE = 'posts_per_page';
const MODS_TPOGRAPHY_FONT_PAIRS = 'neve_font_pairs';
diff --git a/inc/customizer/loader.php b/inc/customizer/loader.php
index 605ad804d2..46f03fe1d9 100644
--- a/inc/customizer/loader.php
+++ b/inc/customizer/loader.php
@@ -144,6 +144,9 @@ public function enqueue_customizer_controls() {
'learnMore' => apply_filters( 'neve_external_link', 'https://docs.themeisle.com/article/1349-how-to-load-neve-fonts-locally', esc_html__( 'Learn more', 'neve' ) ),
'key' => Config::OPTION_LOCAL_GOOGLE_FONTS_HOSTING,
),
+ 'preloadFonts' => array(
+ 'key' => Config::MODS_PRELOAD_FONTS,
+ ),
'fontPairs' => get_theme_mod( Config::MODS_TPOGRAPHY_FONT_PAIRS, Config::$typography_default_pairs ),
'allowedGlobalCustomColor' => Colors_Background::CUSTOM_COLOR_LIMIT,
'constants' => [
@@ -291,6 +294,14 @@ public function register_setting_local_gf( $wp_customize ) {
'default' => false,
]
);
+
+ $wp_customize->add_setting(
+ Config::MODS_PRELOAD_FONTS,
+ [
+ 'sanitize_callback' => 'neve_sanitize_checkbox',
+ 'default' => false,
+ ]
+ );
}
/**
diff --git a/inc/views/font_manager.php b/inc/views/font_manager.php
index cc9d8b36d3..46769b35d3 100644
--- a/inc/views/font_manager.php
+++ b/inc/views/font_manager.php
@@ -93,6 +93,7 @@ public function init() {
add_action( 'enqueue_block_editor_assets', array( $this, 'register_google_fonts' ), 200 );
add_action( 'enqueue_block_editor_assets', array( $this, 'do_editor_styles_google_fonts' ), 210 );
add_action( 'wp_print_styles', array( $this, 'load_external_fonts_locally' ), PHP_INT_MAX );
+ add_filter( 'style_loader_tag', array( $this, 'add_rel_preload' ), 10, 2 );
}
/**
@@ -251,6 +252,46 @@ private function enqueue_google_font( $font, $weights = [], $skip_enqueue = fals
wp_enqueue_style( 'neve-google-font-' . str_replace( ' ', '-', strtolower( $font ) ), $url, array(), NEVE_VERSION );
}
+ /**
+ * Add onload, rel and as attributes for Google Font stylesheets.
+ * Implements lazy loading with preload for better performance.
+ *
+ * @param string $html Current html code.
+ * @param string $handle Current script handle.
+ *
+ * @return string
+ */
+ public function add_rel_preload( $html, $handle ) {
+ if ( is_admin() ) {
+ return $html;
+ }
+
+ $preload_enabled = get_theme_mod( Config::MODS_PRELOAD_FONTS, false );
+
+ /**
+ * Filters whether fonts should be preloaded.
+ *
+ * @param bool $preload_enabled Whether fonts should be preloaded. Default value is false.
+ *
+ * @since 3.9.0
+ */
+ $should_preload = apply_filters( 'neve_preload_fonts', $preload_enabled );
+
+ if ( ! (bool) $should_preload ) {
+ return $html;
+ }
+
+ // Only preload Google Font stylesheets
+ if ( strpos( $handle, 'neve-google-font-' ) === 0 ) {
+ // Lazy load with JS, but also add noscript in case no JS
+ $no_script = '';
+ // Add onload, rel="preload", as="style", and put together with noscript
+ $html = str_replace( 'rel=\'stylesheet\'', 'rel="preload" as="style" onload="this.rel=\'stylesheet\';"', $html ) . $no_script;
+ }
+
+ return $html;
+ }
+
/**
* Load Google Fonts locally.
*