Skip to content

Commit a412b60

Browse files
Closes #7243: preload fonts frontend rockethead (PR #7320)
Co-authored-by: WordPressFan <[email protected]>
1 parent daa4504 commit a412b60

File tree

10 files changed

+119
-73
lines changed

10 files changed

+119
-73
lines changed

inc/Engine/Media/PreloadFonts/Context/Context.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,15 @@ public function is_allowed( array $data = [] ): bool {
3636

3737
return wpm_apply_filters_typed( 'boolean', 'rocket_preload_fonts_optimization', (bool) $this->options->get( 'rocket_preload_fonts', 1 ) );
3838
}
39+
40+
/**
41+
* Determines if the page is mobile and separate cache for mobile files is enabled.
42+
*
43+
* @return bool
44+
*/
45+
public function is_mobile_allowed(): bool {
46+
return $this->options->get( 'cache_mobile', 0 )
47+
&& $this->options->get( 'do_caching_mobile_files', 0 )
48+
&& wp_is_mobile();
49+
}
3950
}

inc/Engine/Media/PreloadFonts/Frontend/Controller.php

Lines changed: 48 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,13 @@
88
use WP_Rocket\Engine\Media\PreloadFonts\Database\Queries\PreloadFonts as PFQuery;
99
use WP_Rocket\Engine\Media\PreloadFonts\Context\Context;
1010
use WP_Rocket\Engine\Optimization\UrlTrait;
11+
use WP_Rocket\Engine\Support\CommentTrait;
12+
use WP_Rocket\Engine\Common\Head\ElementTrait;
1113

1214
class Controller implements ControllerInterface {
1315
use UrlTrait;
16+
use CommentTrait;
17+
use ElementTrait;
1418

1519
/**
1620
* Options instance
@@ -55,13 +59,10 @@ public function __construct( Options_Data $options, PFQuery $query, Context $con
5559
* @return string
5660
*/
5761
public function optimize( string $html, $row ): string {
58-
if ( ! $row->has_preload_fonts() ) {
62+
if ( ! $this->context->is_allowed() || ! $row->has_preload_fonts() ) {
5963
return $html;
6064
}
61-
62-
$html = $this->preload_fonts( $html, $row );
63-
64-
return $html;
65+
return $this->add_meta_comment( 'auto_preload_fonts', $html );
6566
}
6667

6768
/**
@@ -72,6 +73,10 @@ public function optimize( string $html, $row ): string {
7273
* @return array
7374
*/
7475
public function add_custom_data( array $data ): array {
76+
if ( ! $this->context->is_allowed() ) {
77+
return $data;
78+
}
79+
7580
$system_fonts = [
7681
'serif',
7782
'sans-serif',
@@ -121,45 +126,6 @@ public function add_custom_data( array $data ): array {
121126
return $data;
122127
}
123128

124-
/**
125-
* Preload Fonts in HTML.
126-
*
127-
* @param string $html HTML content.
128-
* @param object $row Corresponding DB row.
129-
*
130-
* @return string
131-
*/
132-
private function preload_fonts( string $html, $row ): string {
133-
if ( 'completed' !== $row->status || empty( $row->fonts ) || '[]' === $row->fonts ) {
134-
return $html;
135-
}
136-
137-
if ( ! preg_match( '#</title\s*>#', $html, $matches ) ) {
138-
return $html;
139-
}
140-
$title = $matches[0];
141-
142-
$preload = $title;
143-
144-
$fonts = json_decode( $row->fonts, true );
145-
146-
if ( empty( $fonts ) ) {
147-
return $html;
148-
}
149-
150-
foreach ( $fonts as $font ) {
151-
$preload .= $this->preload_tag( $font );
152-
}
153-
154-
$replace = preg_replace( '#' . $title . '#', $preload, $html, 1 );
155-
156-
if ( null === $replace ) {
157-
return $html;
158-
}
159-
160-
return $replace;
161-
}
162-
163129
/**
164130
* Checks if the font URL is from a third party.
165131
*
@@ -180,26 +146,46 @@ private function is_third_party_font( string $font_url ): bool {
180146
}
181147

182148
/**
183-
* Generates the preload tag for a font.
184-
*
185-
* @param string $font Font URL.
149+
* Adds the preload fonts to the head tag.
186150
*
187-
* @return string
151+
* @param array $items added to the head.
152+
* @return array Items to be added to the head.
188153
*/
189-
private function preload_tag( string $font ): string {
190-
if ( ! $this->is_relative( $font ) ) {
191-
$crossorigin = $this->is_third_party_font( $font ) ? ' crossorigin' : '';
192-
$tag = sprintf(
193-
'<link rel="preload" data-rocket-preload as="font" href="%s"%s>',
194-
esc_url( $font ),
195-
$crossorigin
196-
);
197-
} else {
198-
$tag = sprintf(
199-
'<link rel="preload" data-rocket-preload as="font" href="%s">',
200-
$font
201-
);
154+
public function add_preload_fonts_in_head( $items ) {
155+
if ( ! $this->context->is_allowed() ) {
156+
return $items;
157+
}
158+
159+
global $wp;
160+
161+
$url = untrailingslashit( home_url( add_query_arg( [], $wp->request ) ) );
162+
$is_mobile = $this->context->is_mobile_allowed();
163+
164+
$row = $this->query->get_row( $url, $is_mobile );
165+
if ( empty( $row ) || 'completed' !== $row->status || empty( $row->fonts ) || '[]' === $row->fonts ) {
166+
return $items;
167+
}
168+
169+
$fonts = json_decode( $row->fonts, true );
170+
171+
if ( empty( $fonts ) ) {
172+
return $items;
202173
}
203-
return $tag;
174+
175+
foreach ( $fonts as $font ) {
176+
$item_args = [
177+
// 'id' => 'preload-font-' . md5( $font ), // Unique ID based on font URL.
178+
'href' => esc_url( $font ),
179+
'as' => 'font',
180+
];
181+
182+
if ( ! $this->is_relative( $font ) && $this->is_third_party_font( $font ) ) {
183+
$item_args[2] = 'crossorigin';
184+
}
185+
186+
$items[] = $this->preload_link( $item_args );
187+
}
188+
189+
return $items;
204190
}
205191
}

inc/Engine/Media/PreloadFonts/Frontend/Subscriber.php

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,26 @@
44
namespace WP_Rocket\Engine\Media\PreloadFonts\Frontend;
55

66
use WP_Rocket\Event_Management\Subscriber_Interface;
7+
use WP_Rocket\Engine\Media\PreloadFonts\Frontend\Controller as PreloadFonts;
78

89
class Subscriber implements Subscriber_Interface {
910

11+
/**
12+
* Preload Fonts controller instance.
13+
*
14+
* @var PreloadFonts
15+
*/
16+
private $preload_fonts;
17+
18+
/**
19+
* Subscriber constructor.
20+
*
21+
* @param PreloadFonts $preload_fonts Preload Fonts controller instance.
22+
*/
23+
public function __construct( PreloadFonts $preload_fonts ) {
24+
$this->preload_fonts = $preload_fonts;
25+
}
26+
1027
/**
1128
* Returns an array of events that this subscriber wants to listen to.
1229
*
@@ -15,6 +32,18 @@ class Subscriber implements Subscriber_Interface {
1532
* @return array
1633
*/
1734
public static function get_subscribed_events(): array {
18-
return [];
35+
return [
36+
'rocket_head_items' => [ 'add_preload_fonts_in_head', 30 ],
37+
];
38+
}
39+
40+
/**
41+
* Add preload fonts into head.
42+
*
43+
* @param array $items Head items.
44+
* @return array
45+
*/
46+
public function add_preload_fonts_in_head( $items ) {
47+
return $this->preload_fonts->add_preload_fonts_in_head( $items );
1948
}
2049
}

inc/Engine/Media/PreloadFonts/ServiceProvider.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public function register(): void {
5656
$this->getContainer()->add( 'preload_fonts_query', PreloadFontsQuery::class );
5757
$this->getContainer()->add( 'preload_fonts_context', Context::class )
5858
->addArgument( $options );
59-
$this->getContainer()->add( 'preload_fonts_front_controller', FrontendController::class )
59+
$this->getContainer()->addShared( 'preload_fonts_front_controller', FrontendController::class )
6060
->addArguments(
6161
[
6262
$this->getContainer()->get( 'options' ),
@@ -73,7 +73,12 @@ public function register(): void {
7373
]
7474
);
7575

76-
$this->getContainer()->addShared( 'preload_fonts_frontend_subscriber', FrontendSubscriber::class );
76+
$this->getContainer()->addShared( 'preload_fonts_frontend_subscriber', FrontendSubscriber::class )
77+
->addArguments(
78+
[
79+
$this->getContainer()->get( 'preload_fonts_front_controller' ),
80+
]
81+
);
7782

7883
$this->getContainer()->addShared( 'preload_fonts_factory', Factory::class )
7984
->addArguments(

inc/Plugin.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,15 @@ class Plugin {
9090
*/
9191
private $is_valid_key;
9292

93+
/**
94+
* Instance of the Options.
95+
*
96+
* @since 3.6
97+
*
98+
* @var Options
99+
*/
100+
private $options_api;
101+
93102
/**
94103
* Instance of the Options_Data.
95104
*

tests/Fixtures/inc/Engine/Common/PerformanceHints/Frontend/Subscriber/HTML/output_preload_fonts.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<html>
22
<head>
3-
<title>Test</title><link rel="preload" data-rocket-preload as="font" href="http://example.org/assets/fonts/font1.woff2"><link rel="preload" data-rocket-preload as="font" href="http://example.org/assets/fonts/font2.ttf">
3+
<title>Test</title>
4+
<link data-rocket-preload as="font" href="http://example.org/assets/fonts/font1.woff2" rel="preload">
5+
<link data-rocket-preload as="font" href="http://example.org/assets/fonts/font2.ttf" rel="preload">
46
<link rel="stylesheet" href="http://example.org/assets/fonts/font1.woff2">
57
<link rel="stylesheet" href="http://example.org/assets/fonts/font2.ttf">
68
</head>

tests/Fixtures/inc/Engine/Common/PerformanceHints/Frontend/Subscriber/HTML/output_preload_fonts_w_crossorigin.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<html>
22
<head>
3-
<title>Test</title><link rel="preload" data-rocket-preload as="font" href="http://external.domain/assets/fonts/font1.woff2" crossorigin><link rel="preload" data-rocket-preload as="font" href="http://example.org/assets/fonts/font2.ttf">
3+
<title>Test</title>
4+
<link crossorigin data-rocket-preload as="font" href="http://external.domain/assets/fonts/font1.woff2" rel="preload">
5+
<link data-rocket-preload as="font" href="http://example.org/assets/fonts/font2.ttf" rel="preload">
46
<link rel="stylesheet" href="http://external.domain/assets/fonts/font1.woff2">
57
<link rel="stylesheet" href="http://example.org/assets/fonts/font2.ttf">
68
</head>

tests/Fixtures/inc/Engine/Common/PerformanceHints/Frontend/Subscriber/HTML/output_preload_fonts_w_relative_path.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<html>
22
<head>
3-
<title>Test</title><link rel="preload" data-rocket-preload as="font" href="/assets/fonts/font1.woff2"><link rel="preload" data-rocket-preload as="font" href="/assets/fonts/font2.ttf">
3+
<title>Test</title>
4+
<link data-rocket-preload as="font" href="/assets/fonts/font1.woff2" rel="preload">
5+
<link data-rocket-preload as="font" href="/assets/fonts/font2.ttf" rel="preload">
46
<link rel="stylesheet" href="/assets/fonts/font1.woff2">
57
<link rel="stylesheet" href="/assets/fonts/font2.ttf">
68
</head>

tests/Fixtures/inc/Engine/Common/PerformanceHints/Frontend/Subscriber/maybe_apply_optimizations.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@
214214
],
215215
],
216216
'lrc' => $lrc,
217-
'preload_fonts' => $preload_fonts_empty
217+
'preload_fonts' => $preload_fonts_empty,
218218
],
219219
'expected' => $html_output_with_preload,
220220
],
@@ -240,7 +240,7 @@
240240
],
241241
],
242242
'lrc' => $lrc,
243-
'preload_fonts' => $preload_fonts_empty
243+
'preload_fonts' => $preload_fonts_empty,
244244
],
245245
'expected' => $html_output,
246246
],

tests/Integration/inc/Engine/Common/PerformanceHints/Frontend/Subscriber/maybe_apply_optimizations.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public function set_up() {
3838

3939
add_filter( 'rocket_disable_meta_generator', '__return_true' );
4040

41-
$this->unregisterAllCallbacksExcept( 'rocket_buffer', 'maybe_apply_optimizations', 17 );
41+
$this->unregisterAllCallbacksExceptMulti('rocket_buffer', [17 => 'maybe_apply_optimizations', 100000 => 'insert_rocket_head']);
4242
}
4343

4444
public function tear_down() {
@@ -97,8 +97,8 @@ public function testShouldReturnAsExpected( $config, $expected ) {
9797
add_filter( 'pre_get_rocket_option_cache_logged_user', [ $this, 'get_cache_user' ] );
9898

9999
$this->assertSame(
100-
trim($expected),
101-
trim(apply_filters( 'rocket_buffer', $config['html'] ))
100+
$this->format_the_html($expected),
101+
$this->format_the_html(apply_filters( 'rocket_buffer', $config['html'] ))
102102
);
103103
}
104104

0 commit comments

Comments
 (0)