Tối ưu WordPress với wp_cache: công thức đơn giản, hiệu quả và an toàn

wp_cache là lớp cache ở tầng ứng dụng của WordPress, đặc biệt mạnh khi dùng kèm Object Cache Pro/Redis. Bài viết tổng hợp kinh nghiệm triển khai thực chiến: khi nào nên cache, cách đặt key, TTL, nên cache dữ liệu gì, và quan trọng nhất — cách clear cache đúng lúc khi dữ liệu cập nhật để vừa nhanh vừa chính xác.

Tối ưu WordPress với wp_cache: công thức đơn giản, hiệu quả và an toàn

Khi nào nên dùng wp_cache

  • Truy vấn lặp lại nhiều lần: WP_Term_Query, WP_Query, get_terms().
  • Các khối dữ liệu ít thay đổi: danh sách “top”, “full”, “hot”.
  • Widget hoặc section xuất hiện ở nhiều trang, chi phí truy vấn cao.

Nguyên tắc chung: key, group, TTL

  • Key: băm (md5) theo tham số đầu vào để tránh xung đột và gọn nhẹ.
  • Group: đặt tên rõ ràng theo chức năng, dễ quản lý và xóa.
  • TTL: dữ liệu cập nhật thường xuyên ⇒ 5–15 phút; dữ liệu ổn định ⇒ 6 giờ.

Ví dụ cache kết quả truy vấn CPT manga

<?php
/**
 * Lấy danh sách manga mới nhất (cached 6h)
 */
function get_new_manga($per, $page, $exclude = array()) {
    $per     = max(1, (int) $per);
    $page    = max(1, (int) $page);
    $exclude = array_filter(array_map('intval', (array) $exclude));

    $group = 'get_new_manga';
    $key   = md5("per:{$per}|page:{$page}|ex:" . implode(',', $exclude));

    $cached = wp_cache_get($key, $group);
    if ($cached !== false) {
        return $cached;
    }

    $args = array(
        'post_type'      => 'manga',
        'post_status'    => 'publish',
        'posts_per_page' => $per,
        'offset'         => ($page - 1) * $per,
        'orderby'        => 'date',
        'order'          => 'DESC',
        'post__not_in'   => $exclude,
    );

    $query = new WP_Query($args);
    $posts = $query->have_posts() ? $query->posts : array();

    wp_cache_set($key, $posts, $group, 6 * HOUR_IN_SECONDS);
    return $posts;
}
?>

Nên cache danh sách ID thay vì HTML

Cache HTML giúp tăng tốc nhưng tốn bộ nhớ và khó đồng bộ khi theme thay đổi. Đối với các danh sách động, nên cache ID hoặc mảng post object và render HTML mỗi request. Cách này cân bằng giữa hiệu năng và tính linh hoạt.

Clear cache khi có cập nhật

Cache chỉ có giá trị khi dữ liệu hiển thị chính xác. Với danh sách “manga mới cập nhật”, cần clear cache ngay khi có bài viết mới publish. Cách hiệu quả là sử dụng biến last_changed trong group cache và “bump” mỗi khi dữ liệu thay đổi.

Ví dụ cache 15 phút + auto-invalidate khi publish manga

<?php
/**
 * Lấy manga mới cập nhật (cached 15m + auto-invalidate)
 */
function get_latest_update_manga($per, $page, $exclude = array()) {
    $per     = max(1, (int) $per);
    $page    = max(1, (int) $page);
    $exclude = array_filter(array_map('intval', (array) $exclude));

    $args = array(
        'post_type'      => 'manga',
        'post_status'    => 'publish',
        'posts_per_page' => $per,
        'offset'         => ($page - 1) * $per,
        'orderby'        => 'meta_value_num',
        'meta_key'       => 'last_chapter_time',
        'order'          => 'DESC',
        'post__not_in'   => $exclude,
    );

    $group        = 'get_latest_update_manga';
    $last_changed = wp_cache_get('last_changed', $group);
    if (!$last_changed) {
        $last_changed = microtime();
        wp_cache_set('last_changed', $last_changed, $group);
    }

    $key = md5("v{$last_changed}|per:{$per}|page:{$page}|ex:" . implode(',', $exclude));

    $cached = wp_cache_get($key, $group);
    if ($cached !== false) {
        return $cached;
    }

    $query = new WP_Query($args);
    $posts = $query->have_posts() ? $query->posts : array();

    wp_cache_set($key, $posts, $group, 15 * MINUTE_IN_SECONDS);
    return $posts;
}

/**
 * Bump cache khi có manga publish
 */
function bump_latest_update_manga_on_publish($post_id, $post, $update) {
    if ($post->post_type !== 'manga') {
        return;
    }
    if (wp_is_post_autosave($post_id) || wp_is_post_revision($post_id)) {
        return;
    }
    if (get_post_status($post_id) !== 'publish') {
        return;
    }
    wp_cache_set('last_changed', microtime(), 'get_latest_update_manga');
}
add_action('wp_insert_post', 'bump_latest_update_manga_on_publish', 10, 3);
?>

Chiến lược TTL

  • 5–15 phút: danh sách manga mới, most viewed trong vài ngày.
  • 6 giờ: manga full bộ, top follow, dữ liệu ít thay đổi.

Lỗi thường gặp

  • Sử dụng wp_cache nhưng không có persistent object cache ⇒ dữ liệu chỉ sống trong request.
  • Đặt key không gắn tham số đầu vào ⇒ dữ liệu lẫn nhau giữa các biến thể.
  • Cache HTML thay vì ID/post object ⇒ khó bảo trì khi thay đổi theme.
  • Bỏ quên cơ chế invalidate ⇒ danh sách “latest manga” hiển thị sai.

Kết luận

wp_cache là công cụ mạnh trong WordPress nếu được sử dụng đúng cách. Key rõ ràng, TTL hợp lý và đặc biệt là clear cache khi có update sẽ giúp website manga vừa nhanh vừa chính xác. Cách tiếp cận dùng last_changed kết hợp hook wp_insert_post là phương pháp an toàn và gọn gàng để invalidate toàn bộ cache ngay khi có manga mới.

Bình luận


  • Không có bình luận.

Init Toolbox

Nhấn Ctrl + \ trên máy tính, hoặc vuốt sang trái ở bất kỳ đâu trên mobile.

Đăng nhập





Đang tải...