Transient API – Lưu cache cho đối tượng trong WordPress

Thường thì chúng ta sử dụng WordPress và muốn tăng tốc cho website của mình sẽ sử dụng cách là cài thêm các plugin hỗ trợ tăng tốc như WP Super Cache, W3 Total Cache và một số ứng dụng khác vào máy chủ nếu có quyền.

Tuy nhiên, chúng ta cần phải biết rằng bản thân WordPress đã có những thuật toán riêng của nó để xử lý và lưu cache dữ liệu sinh ra từ các đoạn mã PHP, nhưng nó sẽ chỉ áp dụng vào một số chức năng chính trong WordPress mà thôi. Cách đơn giản nhất để thử đó là bạn hãy sử dụng chức năng tìm kiếm theme WordPress trong bảng quản trị, lần thứ nhất thì nó sẽ xử lý hơi lâu nhưng các lần thứ hai trở đi nó sẽ xử lý nhanh hơn, đó là nhờ WordPress đã lưu lại cache truy vấn của bạn đã tìm trước đó.

Trong khuôn khổ bài này, mình sẽ hướng dẫn đến các bạn một tính năng rất hữu dụng trong WordPress mà nếu bạn thường xuyên làm việc với code trong đây, nó sẽ rất hữu ích cho bạn trong việc tối ưu lại quy trình xử lý, đó là Transient API.

Transient API là gì?

Transient API là một kỹ thuật lưu cache dữ liệu đã được xử lý trong WordPress và nó sẽ tự động lưu vào database trong một thời hạn nhất định, chúng ta có thể thiết lập thời gian hết hạn cho dữ liệu đã được lưu này.

Sau khi lưu dữ liệu vào database với tên là _transient_[tên-transient-key] trong table wp_options, thì thay vì đợi dữ liệu trả về khi code xử lý, nó sẽ lấy thẳng dữ liệu đã lưu trong database và hiển thị ra ngoài website, lúc đó bạn đã tiết kiệm được khâu xử lý mã PHP.

Do nó sẽ lưu dữ liệu vào database nên nó sẽ có một nhược điểm là làm database nặng hơn (tùy thuộc vào độ lớn của cái transient của bạn). Vậy nên hiện nay có rất nhiều website lớn đã sử dụng Memcached, APC, XCache để lưu các dữ liệu cache này vào RAM thay vì vào Database, dĩ nhiên nó sẽ tốn RAM hơn.

Khi nào nên sử dụng Transient API

Do nó sẽ lưu cache kết quả truy vấn nên sẽ chỉ có ích nếu bạn cần xử lý một dữ liệu gì đó có thời gian thay đổi lâu. Chẳng hạn như một đoạn loop tự tạo, lấy dữ liệu từ Facebook (số like, thông tin của user chẳng hạn),…Tóm lại là chỉ nên sử dụng để lưu các dữ liệu mà website sẽ không cần bắt buộc gọi ra khi tải trang, chẳng hạn như sử dụng để lưu option của theme/plugin là không nên.

Hướng dẫn Transient API

Trước khi sử dụng Transient API, chúng ta cần có một code để làm mẫu trong bài này. Ở bài này, mình sẽ viết một code lấy số like trên Facebook của bài này chẳng hạn.

Bạn có thể tạo một file tên test-transient.php trong thư mục theme với nội dung bên dưới để tạo một Custom Page Template để test. Tạo xong hãy vào Pages -> Add New tạo một trang mới và thiết lập Page Template vừa tạo.


<?php
/*
* Template Name: Facebook JSON
*/
$url = 'https://thachpham.com/wordpress/wordpress-tutorials/serie-hoc-wordpress-co-ban-2013.html';
$source = wp_remote_retrieve_body( wp_remote_get( &quot;https://graph.facebook.com/&quot; . $url ) );
$data = json_decode( $source );

echo $data->shares;

Kết quả sẽ trả về là số like của bài viết kia đúng không nào. Hãy xem ta mất bao nhiêu thời gian để tải trang này nhé (Chuột phải -> Inspect Element -> Network và F5).

before_transient

Nghĩa là mình đã tải trang nội dung này hết 500 milliseconds. Bây giờ mình sẽ tiến hành thiết lập Transient cho đoạn code trên và xem nó sẽ thay đổi như thế nào nhé.

<?php
/*
 * Template Name: Facebook JSON
 */
 $my_transient = get_transient ( 'facebook-like' ); // Gọi dữ liệu từ key 'facebook-like' trong Transient

// Kiểm tra, nếu chưa có thì tạo dữ liệu cho Transient mang tên 'facebook-like'
if ( empty( $my_transient) ) {

	$url = 'https://thachpham.com/wordpress/wordpress-tutorials/serie-hoc-wordpress-co-ban-2013.html';
	$source = wp_remote_retrieve_body( wp_remote_get( 'https://graph.facebook.com/' . $url ) );
	$data = json_decode( $source );

	// Lưu dữ liệu cần hiển thị vào Array
	$output = array(
		'shares' =>; $data->shares
	);

	// Tạo key transient với tên là 'facebook-like'
	set_transient( 'facebook-like', $output, 60*60*12 ); // 60*60*12 nghĩa là mỗi 12 giờ (giây*phút*giờ)
} else {
	echo $my_transient['shares'];
}

Các đoạn code ở trên mình xin giải thích như sau (mình đánh số dựa theo số dòng trong code):

  • 05: Tạo một biến để làm công việc gọi dữ liệu trong transient, nếu dữ liệu trong transient này chưa có thì kết quả trả về là false.
  • 08 đến 21: Kiểm tra nếu biến $my_transient chưa có dữ liệu thì sẽ tiến hành tạo một transient key và chứa các dữ liệu nhận về.
  • 15 đến 17: Do transient chỉ được phép lưu dữ liệu theo biến nên mình tạm thời đưa các dữ liệu nhận được vào một biến mảng $output để tiện lấy dữ liệu nếu bạn có nhiều dữ liệu.
  • 20: Dùng hàm set_transient để tạo ra một transient key với tên là facebook-like mà mình đã gọi ở trên.
  • 22: Nếu transient đã có dữ liệu thì mình sẽ hiển thị dữ liệu đó ra.

Bây giờ bạn hãy chạy code, lưu ý một điều là lần đầu tiên chạy code nó sẽ không hiển thị gì cả vì database chưa có transient, cùng lúc đó nó sẽ tiến hành tạo transient key trong database. Hãy tải lại trang một lần nữa thì bạn sẽ thấy dữ liệu trả về.

after_transient

Vậy là chúng ta đã tiết kiệm hơn tới 77% tốc độ tải với phương thức này, một con số rất tuyệt vời phải không nào.

Nếu bạn muốn biết nó lưu thế nào thì cứ vào database, mở table wp_options lên và tìm tên key là _transient_facebook-like, ngoài ra nó còn một key tên là _transient_timeout_facebook-like chứa thời gian hết hạn của transient.

transient-database

Và như mình nói ở trên, nếu bạn có sử dụng Memcached, XCache hay APC để lưu object cache trong WordPress thì database sẽ không lưu lại thông tin này.

Lời kết

Như vậy là bạn đã vừa tìm hiểu qua tính năng Transient API rồi đó, nếu bạn đã và đang sử dụng nhiều Query & Loop trong website mà nó chưa được cache thì đây là cơ hội để bạn thử nghiệm sự ưu việt của nó rồi đấy. 😀

Thạch Phạm

Đam mê với web và lập trình, thích viết và chia sẻ, nghiện cà phê và xăm mình, hứng thú với nhạc dân ca và nhạc không lời.

Xem thêm bài viết Subscribe
Do mình về Việt Nam có công việc nên tạm đóng bình luận tới ngày 28/02/2017 vì trong thời gian này mình không hỗ trợ được. Chân thành cáo lỗi về sự bất tiện này.
menu
menu
Hãy ấn nút chia sẻ nếu bạn thấy bài viết có ích!