Cải thiện tốc độ web thông qua tối ưu load CSS – cách áp dụng với WordPress

1. Tại sao cần load async CSS với wordpress

Bình thường các browser sẽ load các file CSS theo cách synchronous (đồng bộ) và trong lúc download và đọc các file style này, browser sẽ ngừng page rendering.

Điều này làm cho người đọc web sẽ không nhìn thấy bất cứ nội dung nào trong khoảng thời gian đầu tiên khi vào web. Các file CSS càng lớn thì khoảng thời gian này càng dài và làm cho những người đọc không đủ kiên nhẫn sẽ rời đi. Vì vậy, chúng ta cần áp dụng kỹ thuật load CSS file asynchorous (bất đồng bộ) để rút ngắn khoảng thời gian này.

Lưu ý: Với tổng dung lượng css files < 20kb thì bạn không cần phải áp dụng phương thức tải file css bất đồng bộ vì sự khác biệt đối với tốc độ tải website không chênh lệch nhiều. 

* Điều kiện để áp dụng tải file css bất đồng bộ (Load CSS asynchronously): 

Nếu chúng ta áp dụng phương thức Load CSS async cho toàn bộ css files của webpage thì trong khoảng thời gian CSS chưa được tải và đọc, nội dung của page sẽ được hiển thị unstyled và có thể tạo ra trải nghiệm người dùng không tốt (Hình dưới là FOUC – Flash of Uncontented Style của CNN)

FOUC

Để tránh hiện tượng này, có 2 giải pháp được sử dụng:

+ Thêm attribute “preload” vào các file stylesheet kết hợp với inline critical CSS vào <head> => Để làm được điều này, toàn bộ CSS của webpage cần được chia ra làm 2 phần: Critical CSS và non-Critical CSS => Công cụ tạo Critical CSS cho webpage: công cụ Critical CSS generator

+ Thêm attribute “media” & “onload”

2. Các cách load async CSS với WordPress:

2.1 Sử dụng “preload”: 

Khi sử dụng tag “rel=preload” thay cho phương thức tải đồng bộ “rel=stylesheet”, các web browser sẽ tải bất động bộ non-critical CSS. Tuy nhiên phương thức “preload” này cũng có một số nhược điểm: 

+ Có những web browser không hỗ trợ “preload”, vì vậy chúng ta cần áp dụng thêm kỹ thuật “polyfill” để đảm bảo các web browser này sẽ vẫn tải CSS theo phương thức bất đồng bộ. 

+ “Preload” có thể làm cho web browser ưu tiên tải non-critical CSS hơn những các tài nguyên khác, có thể cần tải trước. 

Các browser hỗ trợ “preload”: Xem tại đây

2.2 Sử dụng attribute “media” & attribute “onload”:

<br />
&lt;link rel=&quot;stylesheet&quot; href=&quot;/path/to/my.css&quot; media=&quot;print&quot; onload=&quot;this.media='all'&quot;&gt;<br />

+ Attribute “media” = “print”: áp dụng stylesheet rule vào màn hình hiển thị cho người dùng (giống như khi visitor chọn in webpage) => Browser sẽ tải phần CSS tương ứng với nội dung hiển thị đầu tiên, phần css còn lại sẽ được tải async và giảm thời gian page rendering.

 + Attribbute “onload” = this.media =all: áp dụng stylesheet rule cho toàn bộ các màn hình khi css file được tải xong. 

3. Ứng dụng Load async CSS vào WordPress:

Để thêm attribute vào tag <style> html trong wordpress, chúng ta sử dụng hook “style_loader_tagcủa WordPress. 

3.1 Cách thêm attribute media & onload vào các file stylesheet:

+ list các css file có thể load async => get $handle của tất cả các file css cần load async

Cách get handle của tất cả các style và script chạy trong wordpress: 

a. Thêm đoạn code sau vào functions.php của theme đang sử dụng:

  function crunchify_print_scripts_styles() {<br />
// Print all loaded Scripts<br />
global $wp_scripts;<br />
foreach( $wp_scripts-&gt;queue as $script ) :<br />
echo $script . ' ** ';<br />
endforeach;</p>
<p>// Print all loaded Styles (CSS)<br />
global $wp_styles;<br />
foreach( $wp_styles-&gt;queue as $style ) :<br />
echo $style . ' || ';<br />
endforeach;<br />
}</p>
<p>add_action( 'wp_print_scripts', 'crunchify_print_scripts_styles' );     

b. Copy toàn bộ script và style handle: 

Copy lại toàn bộ các handle hiển thị (tên script 1 | tên style 1 ….)

c. Xóa đoạn code: 

Sau khi đã lấy được list các style & script thì chúng ta nên xóa/uncomment code đi để làm sạch <head>

+ viết function add attribute vào tất cả các file css áp dụng kỹ thuật load async:

Thay thế đoạn media=’all’ thành media=”print” onload=”this.media=’all'”> trong các stylesheet bằng function dưới đây:

 function add_attributes_to_all_styles( $html, $handle ) {<br />// add style handles to the array below<br />$styles = array( 'font-awesome-5',<br />'another-style',<br />'bootstrap-css' );<br />foreach ( $styles as $style ) {<br />if ( $style === $handle ) {<br />return preg_replace( &quot;/media='all'/&quot;, &quot;/media='print' onload='this.media='all'/&quot;, $html ); }</p>
<p>}<br />
return $html;<br />
}<br />
add_filter( 'style_loader_tag', 'add_attributes_to_all_styles', 10, 2 );

+ gắn code vào function.php

+ test lại website trên các web browser mục tiêu.

Xem thêm:

+ Style được register trong wordpress thông qua hàm wp_enqueue_style

 wp_enqueue_style( $handle, $src, $deps, $ver, $media );

3.2 Thêm attribute preload vào file stylesheet:

Để thêm attribute “preload”, tham khảo cách làm tại đây: Namehero defer CSS

Source:
+ https://www.filamentgroup.com/lab/load-css-simpler/
+ https://joshuatz.com/posts/2019/wordpress-script-and-style-tags-adding-defer-async-and-lazy-load/
+ https://stackoverflow.com/questions/28158492/add-attribute-to-link-tag-thats-generated-through-wp-register-style
+ Str_replace: https://freetuts.net/php-function/str_replace.html