Cách sử dụng Cache Rules cho blog WordPress trong Cloudflare (tìm hiểu cơ chế)

Lưu ý nhỏ: Bài này dành cho người dùng muốn hiểu cơ chế của Cache Rules, nếu muốn thực sự dùng nên cài các plugin chuyên như Super Page Cache để việc xóa cache tự động diễn ra mà không cần thao tác thủ công nào (ví dụ khi bạn cập nhật bài viết, thay đổi theme, plugin). Ngoài ra hướng dẫn bên dưới chỉ áp dụng cho trang WordPress dạng blog hoặc tin tức, KHÔNG áp dụng cho trang thương mại điện tử.

Với người dùng phổ thông, không muốn đau đầu với các chi tiết kỹ thuật, bạn chỉ cần chọn VPS gần Việt Nam, và sử dụng plugin Cache Enabler là đủ để trang web blog tải nhanh…

Các thao tác dưới đây nên được tạo trong lúc bạn KHÔNG đăng nhập WordPress (để tránh hiển thị sai). Nếu việc tạo các rule có vấn đề gì khi bạn test, bạn luôn có thể thử xóa toàn bộ cache để xem lại bằng cách vào tên miền tương ứng trên Cloudflare, vào Caching > Configuration rồi nhấn Purge Everything để xóa toàn bộ cache của website.


Cache Rules trong Cloudflare là tính năng cache cấp độ CDN/Edge, đặc biệt hữu ích trong 2 trường hợp:

  • VPS của bạn ở xa người dùng mục tiêu: Ví dụ người dùng chủ yếu ở Việt Nam nhưng VPS đặt ở Hoa Kỳ hoặc châu Âu.
  • Bạn muốn giảm tối đa tải cho VPS: Cache Rules sẽ giúp website của bạn tải dữ liệu từ các cụm máy chủ của Cloudflare khi dữ liệu đó đã được cache, thay vì phải liên tục lấy data từ VPS của bạn => Nếu VPS của bạn không đủ mạnh cho số lượng người dùng rất lớn, dùng Cloudflare cache là giải pháp rất tiện lợi & tiết kiệm.

Bây giờ chúng ta sẽ đi vào các rule đặc thù dành cho WordPress Blog. Cloudflare cung cấp 10 rule cho gói người dùng free, chúng ta sẽ tận dụng trong số lượng đó để tối ưu WordPress.

Để vào Cache Rules bạn truy cập vào tên miền, vào phần Caching > Cache Rules.


Có 2 nguyên tắc trong cache:

  • KHÔNG được cache nội dung không nên cache.
  • Nếu một nội dung được cache thì cần phải biết nó nên cache NHƯ THẾ NÀO?

Thế nào là ‘không được cache nội dung không nên cache’? Chúng ta phải quay về bản chất cache là dành cho nội dung mà ‘tương lai gần của nó không khác với hiện tại’, ví dụ như ảnh trên website, hay một bài blog như bài này. Tương lai gần của một bài post là không đổi, với ảnh thậm chí còn ít thay đổi hơn rất nhiều (đa số là không bao giờ thay đổi).

Nói cách khác, những cái thay đổi thường xuyên, liên tục là cái không bao giờ được phép cache, nội dung điển hình là trang admin, bạn vào đây để viết bài, cập nhật plugin, các thứ này đều liên tục thay đổi, hành vi cache giống như làm đông cứng một trạng thái để sử dụng lại trong tương lai sẽ làm mất đi tính sống động liên tục mà trang như admin cần phải có.

Ví dụ khác: Một trang mà người dùng vừa comment xong cũng không được phép cache, nếu không nó sẽ chỉ hiển thị nội dung tĩnh, thay vì thông báo xác nhận cho người dùng là họ vừa mới bình luận.

Một điều chúng ta cần nhớ là ‘trang không nên cache không được phép nhầm lẫn‘, nghĩa là thà không cache trang được phép cache còn hơn cache nhầm trang không được phép cache!‘ Vì cái hại đầu tiên chỉ làm giảm hiệu suất, còn cái hại thứ hai hỏng luôn chức năng của website. Nói một cách dân dã, dễ nhớ thì ‘thà bỏ sót cache còn hơn cache nhầm‘.

Thế nào là ‘Nếu một nội dung được cache thì cần phải biết nó nên cache như thế nào?’ Ở đây có một thông số rất cơ bản là thời gian sống của cache, nghĩa là sau bao lâu thì nó nên cập nhật mới. Thời gian sống của cache cho ảnh có thể rất lâu, vì nội dung ảnh trong phần lớn trường hợp là không bao giờ thay đổi. Nhưng thời gian sống của cache cho một bài post có thể phải ngắn hơn nhiều, vì bài post hay cập nhật hơn.

Với Cloudflare có 2 chỉ số liên quan đến thời gian sống của cache, là thời gian sống của cache ở cụm máy chủ (Edge TTL) của Cloudflare, và thời gian sống của cache ở trình duyệt (Browser TTL) người dùng. Kết hợp cả hai sẽ cho hiệu suất tốt nhất. Ví dụ ảnh có thể để thời gian sống ở máy chủ Cloudflare lên đến 1 năm, trong khi tại trình duyệt người dùng có thể để 1 tháng.


Một điều quan trọng trong cache rules là các quy tắc theo kiểu xếp chồng (stackable) & ‘last match wins’, nghĩa là nếu có nhiều rule cho một đối tượng thì các rule sẽ kết hợp nhau, còn cài đặt cụ thể cuối cùng (nếu chúng mâu thuẫn nhau) sẽ được áp dụng (tham khảo thêm ở đây). Điều này khác biệt các rule liên quan đến bảo mật, các rule này thường theo kiểu ‘first match wins’ (va phải rule nào đúng là áp dụng luôn, không cần check các rule còn lại nữa). Hỏi vui: Bạn thử nghĩ xem tại sao lại thế?

Vì các quy tắc trên của cache rules nên về nguyên lý các rule càng xuất hiện sớm sẽ là các rule càng có tính tổng quát cao, các rule về sau sẽ đi vào chi tiết hơn, và rule cuối cùng thường sẽ là rule quan trọng nhất, chốt chặn cuối cùng để hạn chế tối đa sai sót.


Quy tắc 1: Quy tắc cache chung

Quy tắc cache cơ bản áp dụng cho toàn website. Mục tiêu nhắm đến chủ yếu là cache html các bài post, page, category, tag nói chung, trang chủ.

Nhấn vào Create rule để tạo rule mới.

Ở phần Rule name (required) đặt tên tùy ý, nhưng nên là tên gợi ra quy tắc, ví dụ: ‘Quy tắc cache chung.’

Chỗ If incoming requests match… để như mặc định là Custom filter expression nghĩa là bạn sẽ tùy chỉnh các quy tắc cụ thể.

Click Edit expression rồi paste đoạn mã dưới đây vào:

(not http.request.uri.path contains "/wp-login.php" and not http.request.uri.path contains "/wp-admin" and not http.cookie contains "wordpress_logged_in_" and not http.request.uri.path.extension in {"css" "js" "woff" "woff2" "ttf" "otf" "eot" "map" "jpg" "png" "jpeg" "webp" "avif" "ico" "svg" "gif" "pdf" "mp3" "mp4" "webm"})

Kéo xuống phía dưới ở phần Cache eligibility, chọn Eligible for cache (cho phép cache).

Ở phần Edge TTL, chọn Ignore cache-control header and use this TTL rồi chọn Input time-to-live (TTL) (required) là 1 day (một ngày).

Ở phần Browser TTL, chọn Bypass cache (bỏ qua không cache phía trình duyệt, để tránh bạn cập nhật bài mới nhưng trình duyệt vẫn hiển thị nội dung cũ do nó lưu trước đây).

Bypass cache ở phần này tuy chắc chắn nhưng nó sẽ giảm ít nhiều hiệu suất (khi người dùng quay lại trang đã vào vài phút sau đó), nên nếu có thể hãy để phần này có thời gian ngắn đủ để không nguy hiểm đến tính cập nhật, chẳng hạn như 5 hoặc 10 phút. Tuy nhiên hiện Cloudflare không có tùy chọn đặt ngắn như vậy cho cache trình duyệt (ít nhất dựa trên gói free mà tôi đang dùng), thời gian ngắn nhất họ cho phép là 2 tiếng. Nếu không đặt nặng tính cập nhật là tiêu chí hàng đầu, và ưu tiên hiệu suất hơn, thì 2 tiếng cũng là lựa chọn ổn.

Nếu bạn để ý Edge TTL tôi để khá ngắn, chỉ có 1 ngày, nguyên nhân là vì chúng ta đang không có plugin tự động xóa cache trên Cloudflare mỗi khi cập nhật bài viết, nên để 1 ngày sẽ rất an toàn, chậm nhất thì 24 tiếng sau người đọc của bạn sẽ thấy bài mới cập nhật. Nếu bạn dùng plugin chuyên, ví dụ cái Super Page Cache đầu bài có nói thì thường Edge TTL cho phần này họ sẽ thiết lập cao hơn đáng kể (plugin sẽ tự động thiết lập rule cho bạn), vì nó có cơ chế báo xóa cache trên Cloudflare khi cập nhật.

PS: Nếu website của bạn có yêu cầu cập nhật nhanh hơn thì hoặc là dùng plugin Super Page Cache, hoặc là để Edge TTL thấp xuống, ví dụ 8 hours (tiếng) hoặc 4 hours.

Rule 1 này sẽ không sai nếu viết ngắn thế này:

(not http.request.uri.path contains "/wp-login.php" and not http.request.uri.path contains "/wp-admin" and not http.cookie contains "wordpress_logged_in_")

vì:

not http.request.uri.path.extension in {"css" "js" "woff" "woff2" "ttf" "otf" "eot" "map" "jpg" "png" "jpeg" "webp" "avif" "ico" "svg" "gif" "pdf" "mp3" "mp4" "webm"})

sẽ được các rule 2 và rule 3 xử lý nhờ quy tắc ‘last match wins’. Tuy nhiên việc viết cụ thể hơn như vậy làm rule này rõ ràng hơn. Mục đích của rule này được chốt chắc chắn ngay từ đầu là chỉ tạo cache cho các trang post, page, cat, tag, homepage, và không liên quan gì đến các file tĩnh (css, js, font chữ, ảnh, nhạc, video,…)

Giải thích thêm phần này:

(not http.request.uri.path contains "/wp-admin" and not http.request.uri.path contains "/wp-login.php" and not http.cookie contains "wordpress_logged_in_")

Nó có nghĩa là nếu trang đó không có đường dẫn bao gồm wp-admin, không có đường dẫn bao gồm /wp-login.php và không có cookie là wordpress_logged_in_ thì được phép cache. Các dấu hiệu trên là của trang đã đăng nhập của người quản trị nên chắc chắn không được phép cache.


Quy tắc 2: Cache CSS, JS và font

Xong rule đầu tiên ở trên, bạn lại tiếp tục nhấn vào Create rule để tạo rule mới. Tên rule cũng cần mới, ví dụ ‘Cache CSS, JS và font‘. If incoming requests match… cũng để như mặc định là Custom filter expression.

Click Edit expression rồi paste đoạn mã dưới đây vào:

(http.request.uri.path.extension in {"css" "js" "woff" "woff2" "ttf" "otf" "eot" "map"})

Kéo xuống bên dưới ở phần Cache eligibility, chọn: Eligible for cache

Ở phần Edge TTL chọn Ignore cache-control header and use this TTL, rồi chọn 1 month (một tháng).

Ở phần Browser TTL chọn Override origin and use this TTL, rồi chọn 8 hour (8 tiếng).

Kéo xuống cuối nhấn Save để lưu.

Plugin và theme là các thành phần rất hay được cập nhật trên website, điều đó sẽ kéo theo CSS, JS, font cũng thường xuyên thay đổi. Hiện tại hầu hết các CSS, JS đều có cơ chế phiên bản ở cuối đường dẫn file, nên mỗi bản cập nhật dù địa chỉ file vẫn vậy nhưng nhờ phiên bản nên cache cũ sẽ không che phiên bản mới nhất.

Đây là lý do bạn có thể tự tin để Edge TTL là một tháng. Riêng Browser TTL vẫn nên để ngắn cho an toàn, 8 tiếng là giá trị ổn.

Ở đây nếu bạn để ý sẽ thấy tính năng xếp chồng và ‘last match wins’ sẽ phát huy tác dụng. Vì quy tắc của CSS & JS nằm sau quy tắc chung đầu tiên, nên Edge TTL & Browser TTL cụ thể cho CSS, JS, font được áp dụng, chứ không phải rule chung => Rule cụ thể hơn luôn phải xếp phía dưới rule chung.

  • “css” “js”: các file css, js cho hiển thị & chức năng của website.
  • “woff” “woff2” “ttf” “otf” “eot” “map”: các định dạng liên quan đến font chữ.
  • http.request.uri.path.extension có nghĩa là định dạng của file.

Quy tắc 3: Cache ảnh và file PDF

Bạn lại tiếp tục nhấn vào Create rule để tạo rule mới. Tên rule có thể đặt là ‘Cache ảnh, pdf, media‘. If incoming requests match… cũng để như mặc định là Custom filter expression.

Click Edit expression rồi paste đoạn mã dưới đây vào:

(http.request.uri.path.extension in {"jpg" "png" "jpeg" "webp" "avif" "ico" "svg" "gif" "pdf" "mp3" "mp4" "webm"})

Kéo xuống bên dưới ở phần Cache eligibility, chọn: Eligible for cache

Ở phần Edge TTL chọn Ignore cache-control header and use this TTL, rồi chọn 1 year (một năm).

Ở phần Browser TTL chọn Override origin and use this TTL, rồi chọn 1 month (một tháng).

Kéo xuống cuối nhấn Save để lưu.

Giải thích thêm: Bạn có thể thấy sự khác biệt lớn về thời gian sống của cache cho ảnh. Sở dĩ chúng ta có cơ sở để làm điều này là vì ảnh rất hiếm khi thay đổi. Và khi thay đổi chúng ta thường sử dụng ảnh mới với tên mới nên vấn đề cache cũ che nội dung mới không xảy ra. File PDF cũng tương tự.

Để rule này phát huy hiệu quả tốt nhất, hãy luôn đổi tên file ảnh hoặc pdf khi cập nhật. Ví dụ logo website đang tên là logo-web.png, khi cập nhật hãy đổi tên nó thành logo-web2.png chẳng hạn.

PS: ngay cả bạn không đổi tên, WordPress tự phát hiện trùng và sẽ đổi tên nó bằng cách thêm hậu tố số vào tương tự như cách trên. Ngoài ra thường khi sửa đổi là thời điểm vài tháng sau đó thì kể cả trùng tên thì ảnh đó sẽ được cho vào thư mục tháng khác => địa chỉ ảnh thực tế thay đổi (vì địa chỉ ảnh phân theo thư mục năm, tháng) => không bị vấn đề cache cũ làm hỏng nội dung mới.

Tất cả giải thích dài dòng phía trên chỉ để nói một điều, cache ảnh, pdf bạn thoải mái để thời gian sống của cache dài, vì khi bạn cập nhật nó luôn tạo ra địa chỉ mới dù bạn có chủ động đổi tên hay không.

  • “jpg” “png” “jpeg” “webp” “avif” “ico” “svg” “gif”: các định dạng dành cho ảnh (thường luôn có).
  • “pdf”: định dạng file pdf (một số website sẽ có).
  • “mp3” “mp4” “webm”: định dạng của file âm thanh và video (hiếm khi có).

Quy tắc 4: Cache ngắn cho sitemap & feed

Nhấn Create rule để tạo rule mới. Tên rule có thể đặt là ‘Cache ngắn cho sitemap & feed‘. If incoming requests match… cũng để như mặc định là Custom filter expression.

Click Edit expression rồi paste đoạn mã dưới đây vào:

(http.request.uri.path contains "sitemap")
or (http.request.uri.path contains "/feed/")

Kéo xuống bên dưới ở phần Cache eligibility, chọn: Eligible for cache

Ở phần Edge TTL chọn Ignore cache-control header and use this TTL, rồi chọn 8 hours.

Ở phần Browser TTL chọn Override origin and use this TTL, rồi chọn 8 hours.

Nhấn Save để lưu.

Giải thích: sitemap & feed là nội dung cần có tính cập nhật tương đối cao, vì đây là nơi các bot (như máy tìm kiếm, công cụ cập nhật tin) dùng để phát hiện bài mới trên website. Tuy nhiên nó cũng không cần kíp đến mức bypass cache mà nên để cache ngắn, tránh ảnh hưởng hiệu suất mà bot vẫn thu thập được nội dung cập nhật nhanh (chậm nhất chỉ 8 tiếng sau khi bài đăng).


Quy tắc 5: Bỏ qua không cache các trang admin, người dùng đã đăng nhập, API

Create rule để tạo rule mới. Tên rule có thể đặt là ‘Bỏ qua không cache (admin, login, API)‘. If incoming requests match… để như mặc định là Custom filter expression.

Click vào Edit expression rồi paste đoạn mã dưới đây vào:

(http.request.uri.path contains "/wp-admin")
or (http.request.uri.path contains "/wp-login.php")
or (http.request.uri.path contains "/wp-json/")
or (http.request.uri.query contains "rest_route=")
or (http.request.uri.path contains "/xmlrpc.php")
or (http.request.uri.path contains "/wp-cron.php")
or (http.request.uri.query contains "doing_wp_cron=")
or (http.cookie contains "wordpress_logged_in_")
or (http.cookie contains "wp-postpass_")
or (http.cookie contains "wordpress_sec_")
or (http.cookie contains "comment_author_")
or (http.request.uri.query contains "replytocom=")
or (http.request.uri.query contains "unapproved=")
or (http.request.uri.query contains "moderation-hash=")
or (http.request.uri.query contains "preview=")
or (http.request.uri.query contains "preview_id=")
or (http.request.uri.query contains "preview_nonce=")
or (http.request.uri.query contains "customize_changeset_uuid")
or (http.request.uri.query contains "customize_preview=")
or (http.request.uri.query contains "customize=")
or (http.request.uri.query contains "_wpnonce")
or (http.request.uri.query contains "s=")
or (http.request.uri.query contains "action=")
or (http.request.uri.query contains "elementor-preview")
or (http.request.uri.query contains "fl_builder")
or (http.request.uri.query contains "et_fb")
or (http.request.uri.query contains "vc_editable")
or (http.request.uri.query contains "bricks=")
or (http.request.uri.query contains "tve=")
or (http.request.uri.query contains "brizy-edit")

Kéo xuống dưới ở phần Cache eligibility, chọn: Bypass cache

Nghĩa là các trang, nội dung thỏa mãn các đặc điểm ở trên thì không cache.

Kéo xuống cuối, nhấn Save để lưu.

Đây chính là rule cho phần ‘các trang, nội dung không được cache thì không nên cache’. Người mới thử cài đặt cache rules theo cách thủ công rất hay bỏ sót cái này dẫn đến trang WordPress hiển thị lỗi (ví dụ nó hiển thị cả admin bar cho người dùng thông thường, do trang đó được cache), hoặc chính chủ website không thao tác được với admin (vì trang luôn hiển thị thông tin cũ đã cache trước đây, dù quá trình thao tác có thành công hay không).


Lưu ý quan trọng: Do đặc tính xếp chồng của các rules và quy tắc ‘last match wins’, bạn cần phải sắp xếp các rule theo đúng thứ tự như hình dưới đây:

Thứ tự các rule
Thứ tự các rule

Bạn làm theo hướng dẫn của bài thì nó sẽ tự động sắp xếp đúng như vậy, nếu không bạn có thể dùng con trỏ chuột di chuyển vào gần các con số để kéo lên, xuống các rule cho đúng thứ tự như hình.


Quy tắc 6: Xóa query tracking

Cái này liên quan đến việc URL có query tracking, chẳng hạn như link chia sẻ từ Facebook hay có dạng thế này:

https://blog.wpsila.com/cache-rules-trong-cloudflare/?fbclid=IwAR2a1b3c4d5

Điều này sẽ tạo ra 2 vấn đề:

  • Nó tạo ra cache thừa thãi cho query tương ứng đó.
  • Nó không tối ưu hiệu suất, vì thực tế trang đó đã được cache rồi.

Quy tắc này sẽ giúp khi người dùng truy cập:

https://blog.wpsila.com/cache-rules-trong-cloudflare/?fbclid=IwAR2a1b3c4d5

họ sẽ được cấp nội dung từ:

https://blog.wpsila.com/cache-rules-trong-cloudflare/

Nghĩa là không tạo thêm cache thừa & hiệu suất vẫn cao.

Cái này không thuộc Cache Rules, để bổ sung, bạn làm như sau:

Rules > Overview. Tìm đến mục URL Rewrite Rules. Nhấn Create Rule để tạo rule mới.

Rule name (required) có thể nhập là Xóa tất cả query tracking.

If incoming requests match… chọn Custom filter expression.

Nhấn Edit expression rồi nhập mã dưới đây vào:

(http.request.uri.query contains "fbclid") or 
(http.request.uri.query contains "utm_") or 
(http.request.uri.query contains "gclid") or 
(http.request.uri.query contains "ttclid") or 
(http.request.uri.query contains "wbraid") or 
(http.request.uri.query contains "gbraid") or 
(http.request.uri.query contains "msclkid") or 
(http.request.uri.query contains "yclid") or 
(http.request.uri.query contains "mc_cid") or 
(http.request.uri.query contains "_hsenc") or 
(http.request.uri.query contains "dclid")

Kéo xuống dưới, chỗ Path để mặc định là Preserve.

Còn chỗ Query, tick chọn Rewrite to…, bên dưới để Static, bên phải để rỗng.


Lưu ý cuối: Cloudflare chỉ giúp người dùng truy cập website nhanh hơn. Nhưng nó không giúp được trang admin nhanh hơn nếu VPS ở xa bạn, vì trang admin vẫn phải động.