Categories Cache

Cache trong WordPress: Tất cả những điều bạn cần biết

Cache trong WordPress

Vài năm qua khi chúng tôi thực hiện công việc hỗ trợ sản phẩm của mình tại Delicious Brains (đặc biệt với plugin WP Offload Media và gần đây nhất là SpinupWP), một điều chúng tôi thấy rõ ràng là:

Mọi người hiểu sai về Cache trong WordPress (và hệ quả là các trang chạy chậm hơn so với nó có thể đạt được).

Trong bài này, tôi hy vọng sẽ làm sáng tỏ một số ngộ nhận và cung cấp cái nhìn rõ ràng hơn (một chút) vào vấn đề cache trên WordPress, cái vốn rất phức tạp.

Hy vọng là đến cuối bài, bạn sẽ hiểu rõ hơn về vai trò của nhiều lớp cache trong tăng tốc WordPress.


#1. Tại sao Cache lại quan trọng?

Trước khi chúng ta đi sâu vào các cơ chế bộ đệm khác nhau, điều căn bản mà chúng ta phải hiểu là lợi ích của cache là gì? Cache đóng hai vai trò chính:

  1. Nó nâng cao hiệu suất (performance) của ứng dụng. Với các trang WordPress, điều này có nghĩa là trang của bạn tải nhanh hơn.
  2. Nó nâng khả năng chịu tải (throughput). Điều này có nghĩa là trang của bạn có thể xử lý được nhiều truy cập hơn.

Ngoài ra, cache có thể làm tăng cả hiệu suất và khả năng chịu tải mà không làm tăng chi phí hosting. Điều này có được do bạn cần ít tài nguyên hệ thống hơn (CPU và bộ nhớ) để lưu trữ trang đã được cache chính xác. Đây là chiến lược win-win / cùng thắng (khi được thực hiện chính xác).


#2. Các lớp cache

WordPress là hệ quản trị nội dung dựa trên cơ sở dữ liệu (database-driven CMS), điều này có nghĩa rằng có nhiều thành phần động khi nó phải xử lý một yêu cầu.

WordPress khi cài đặt theo kiểu thông thường, đơn giản phải truy vấn đến cơ sở dữ liệu và xuất trang (reder page) trước khi nó có thể gửi đến người dùng.

Điều này xảy ra với mọi yêu cầu, và đây là việc lãng phí hiệu suất rất lớn nếu nội dung của trang không thay đổi. Một yêu cầu điển hình trông giống như thế này:

WordPress trước khi caching
WordPress trước khi caching

Chú thích:

  • User: người dùng.
  • Web server: máy chủ web.
  • PHP: ngôn ngữ lập trình PHP.
  • Database: cơ sở dữ liệu.
  • Speed scale: thang đo tốc độ, fast (nhanh), slow (chậm).

Như một quy tắc chung, càng có nhiều thành phần động liên quan đến việc xử lý một yêu cầu, người dùng càng phải đợi lâu và tài nguyên hệ thống càng bị dùng nhiều hơn. Để chống lại điều này, cache thường được thực hiện trong nhiều lớp, từng layer (lớp) đứng ngay trước phần động. Ba lớp nổi bật trong WordPress thường được chia thành:

Các lớp cache của WordPress
Các lớp cache của WordPress

Hãy đi sâu vào từng lớp. Chúng ta sẽ làm việc này từ ngoài vào trong, đầu tiên là cache phía trình duyệt.


#3. Cache phía trình duyệt

Mặc dù cache phía trình duyệt không nhất thiết giúp cải thiện thời gian đáp ứng của ứng dụng hoặc khả năng chịu tải (ít nhất trong vương quốc của WordPress), nó vẫn là lớp quan trọng nhất khi nói đến việc giảm số lượng dữ liệu cần phải gửi đi từ máy chủ đến trình duyệt.

Điều này có thể giúp người dùng cảm thấy trang của bạn phản hồi nhanh hơn bởi vì các tài nguyên tĩnh như là CSS, JS và ảnh xuất hiện nhanh hơn nếu chúng được cache bởi trình duyệt.

Khi muốn tìm hiểu về bộ nhớ đệm trình duyệt, tab Network trong bộ công cụ cho nhà phát triển (DevTools) trên trình duyệt Chrome là người bạn thân thiết của chúng ta. Hãy xem bộ nhớ đệm trình duyệt hoạt động như thế nào, bằng cách tải website (ví dụ, chính trang bạn đang đọc, Kiến càng). Lần tải đầu tiên không có bất cứ thành phần nào được cache bởi trình duyệt (tôi bật tính năng “disable cache” để giả lập lượt tải lần đầu).

tải web lần đầu
Tải web lần đầu

Các thông số mà chúng ta đặc biệt quan tâm là số lượng dữ liệu lưu chuyển và tổng lượng tài nguyên.

  • 824 KB / 1,3 MB được lưu chuyển / transferred.
  • 2,2  / 2,7 MB tài nguyên / resources.

Đầu tiên, lưu ý rằng mỗi thông số có hai giá trị (824 KB / 1,3 MB) vì bạn có thể lọc kết quả theo loại tài nguyên. Điều này cho phép bạn dễ dàng thấy được loại tài nguyên nào chiếm phần lớn băng thông. Ví dụ ở đây là CSS:

thành phần tải
Thành phần tải

Thực ra, ảnh của bài viết trên mới là cái chiếm nhiều nhất, nhưng tôi đang để lazy load ảnh nên bạn không thấy, khi tải đầy đủ, nó sẽ trông như bên dưới (ảnh chiếm 1,5 MB trên tổng số 2,2 MB dữ liệu lưu chuyển):

dung lượng của ảnh
Dung lượng của ảnh

Điều thứ hai cần để ý là, giá trị lưu chuyển phải luôn luôn nhỏ hơn so với tổng giá trị tài nguyên, thậm chí ngay cả trong lần tải đầu tiên bởi trình duyệt (hoặc khi tính năng “vô hiệu hóa cache” được bật), có hai lý do cho điều này:

  1. Các dữ liệu (thành phần) lưu trong bộ nhớ cache của trình duyệt không cần tải qua mạng (lưu chuyển).
  2. Các dữ liệu (thành phần) như là HTML, CSS và JS được nén bởi máy chủ trước khi được chuyển đến cho trình duyệt. Chúng sau đó được giải nén bởi trình duyệt trước khi hiển thị đến người dùng (một số kiểu nén phổ biến là gzip và brotli).

Vì lý do đó, nếu cache trình duyệt được cấu hình chính xác, thì ở những lần tải sau, dữ liệu lưu chuyển sẽ ít đi. Bạn có thể thấy điều này khi thử tải lại trang.

dữ liệu lưu chuyển
Dữ liệu lưu chuyển khi được cache trình duyệt

Dữ liệu lưu chuyển giảm từ 824 KB xuống 34,6 KB, đây là lượng dữ liệu tiết kiệm được rất lớn (hơn 95%)! Thời gian tải trong ví dụ này không giảm xuống đáng kể vì lazy load image đã hỗ trợ giảm tải nhiều.

Hành vi của bộ nhớ đệm trình duyệt được điều khiển bởi 2 headers là cache-control và expires– cái được bổ sung vào phản hồi của tài nguyên tĩnh bởi máy chủ của bạn. Header cache-control sẽ được ưu tiên hơn header expires. Nhưng cả hai thường được áp dụng để đảm bảo tương thích với một số dịch vụ proxy (CDN).

Bạn có thể kiểm tra header của tài nguyên bằng cách sử dụng bộ công cụ cho nhà phát triển (developer tools), hoặc sử dụng cURL command:

cache control
Cache control

Thông thường, header cache-control sẽ có giá trị nằm ở phần max-age=<second>nó sẽ hướng dẫn trình duyệt biết được cần phải cache file đó trong thời gian tối đa là bao nhiêu giây và ngăn nó không tải lại trong các yêu cầu tiếp theo. Trong trường hợp trên, file sẽ được cache trong trình duyệt 1 năm (đây là thời gian tối đa, và thường áp dụng cho các tài nguyên rất ít khi thay đổi, ví dụ như ảnh, âm thanh, video).

PS: Nếu bạn muốn hiểu rõ hơn về header Cache-Control để cache phía máy khách, bạn có thể tham khảo bài viết Tìm hiểu sâu về HTTP Caching.

Một vài điều quan trọng cần biết:

  1. Vô hiệu hóa bộ đệm là khó khăn. Một khi trình duyệt đã cache thành phần nào đó sử dụng cache-control: max-age=<seconds> bạn không thể nói với trình duyệt không cache nó, ít nhất khi không thay đổi URL. Đây là lý do vì sao WordPress thêm một chuỗi query phiên bản vào các tài nguyên (để tài nguyên mới cập nhật được sử dụng, chứ không dùng tài nguyên cũ được cache trong bộ nhớ đệm trình duyệt). Lấy ví dụ: https://kiengcang.net/wp/wp-includes/css/dashicons.min.css?ver=5.2.2
  2. Các công cụ kiểm tra tốc độ website như Pingdom sẽ than phiền về header có thời gian hết hạn ngắn. Thông thường, những cảnh báo này được kích hoạt bởi các thành phần như là Google Analytics được gắn vào trong website của bạn. Điều này là bởi các dịch vụ bên ngoài sử dụng thời gian hết hạn ngắn để đảm bảo rằng tài nguyên của họ được cập nhật nhanh nhất, do có khó khăn về việc vô hiệu hóa bộ đệm.
  3. Các header cache-control và expires không phải là những header duy nhất mà trình duyệt sử dụng để biết được rằng tài nguyên có cần lấy từ máy chủ hay không. Lấy ví dụ, khi thời lượng cụ thể được điều chỉnh bởi cache-control: max-age<seconds> trôi qua thì tiêu đề etag sẽ được sử dụng. Nó chứa mã thông báo xác thực (tương tự với MD5 hash của tài nguyên được yêu cầu). Nếu giá trị etag giữ nguyên, tài nguyên trả về phản hồi “304 vẫn chưa sửa đổi”. Điều này nói với trình duyệt rằng tài nguyên cache không thay đổi và nó sẽ được gia hạn thời gian hết hạn chỉ định trong cache-control: max-age=<seconds>.

#4. Page Cache

Page Cache sẽ đem lại cho bạn nhiều lợi ích nhất khi đề cập đến việc cải thiện thời gian phản hồi và chịu tải trong WordPress. Bộ đệm trang (page cache) về cơ bản biến WordPress (một CMS dựa trên cơ sở dữ liệu) thành trang HTML tĩnh bằng cách loại bỏ cả PHP và MySQL ra ngoài khi xử lý yêu cầu.

Để chứng minh tầm quan trọng mà bộ nhớ đệm trang có thể làm được, tôi tiến hành kiểm tra (benchmark) một bản cài đặt WordPress 5.2.2 sử dụng ApacheBench. Trong các thử nghiệm này tôi sử dụng SpinupWP kết hợp với DigitalOcean Droplet 8GB, 4vCPUs để làm hosting WordPress. Các kết quả không cache là cho WordPress không được cấu hình cache (ngoại trừ PHP OPcache, sử dụng các giá trị mặc định trong PHP 7.3). Các kết quả cache là cho trang khi SpinupWP one-click được bật.

Hãy bắt đầu với số lượng yêu cầu trên mỗi giây (cao hơn thì tốt hơn), điều này có nghĩa là:

Nó làm tăng khả năng chịu tải của ứng dụng. Nói cách khác, trang web của bạn có thể xử lý nhiều lưu lượng truy cập (traffic) hơn.

số lượng request
So sánh số lượng request

Số lượng yêu cầu trên mỗi giây khác nhau đến 10 lần, điều này thật tuyệt vời! Nhưng số lượng yêu cầu cao mỗi giây không có ý nghĩa gì nhiều nếu các yêu cầu này mất nhiều thời gian để hoàn thành. Đấy là lý do tại sao điều quan trọng là đo cả thời gian phản hồi trung bình (thấp hơn thì tốt hơn), điều này có nghĩa là:

Nó cải thiện hiệu suất của ứng dụng. Nói cách khác, với website WordPress, trang của bạn tải nhanh hơn.

So sánh thời gian phản hồi
So sánh thời gian phản hồi

Thời gian phản hồi trung bình giảm một nửa khi cache trang được cấu hình, điều này là rất đáng chú ý khi chúng ta biết rằng trong tình huống này số lượng yêu cầu tăng lên gấp 10 lần mỗi giây.

Một số điểm cần lưu ý:

  1. Page cache là vô cùng khó khăn khi website hiển thị thông tin cá nhân hóa, chẳng hạn như trên trang thương mại điện tử hoặc một trang có tính động cao như forum (diễn đàn). Thường thì page cache sẽ cần vô hiệu hóa hoàn toàn hoặc các trang đặc biệt như trang thanh toán sẽ cần phải bỏ qua, không cho phép cache.
  2. Vô hiệu hóa bộ nhớ cache có thể khó khăn tùy thuộc vào cách nó được triển khai. Do tính chất năng động của WordPress, nó khó xác định được trang nào cần phải xóa khỏi bộ nhớ đệm khi nội dung được cập nhật (đặc biệt là khi các trang lưu trữ (ví dụ thư mục, tag), phân trang và widget có liên quan đến chuyện này). Đây là lý do vì sao xóa toàn bộ nội dung khỏi bộ nhớ đệm thường là cách tiếp cận được ưa thích khi nội dung thay đổi.
  3. Sử dụng nhiều biện pháp page cache cùng lúc không giúp cải thiện hiệu suất. Trong thực tế, có nhiều giải pháp page cache cùng lúc được triển khai sẽ gây phiền toái bởi vì nó có thể dẫn đến tính không liên tục của bộ nhớ cache (các phiên bản khác nhau của website được lưu trên từng phiên bản cache) và làm cho việc vô hiệu hóa cache trở nên rối rắm.
  4. Page cache thường được vô hiệu hóa với người dùng đăng nhập, đây là lý do vì sao object cache (cái sẽ được nói ở phần bên dưới) vẫn được khuyến khích dùng.

#5. Object Caching

Như đã đề cập ở phần trên, không phải tất cả các trang có thể được cache. Điều này đặc biệt đúng với các trang thương mại điện tử và các trang cho phép đăng ký thành viên, nơi chúng thường hiển thị thông tin được cá nhân hóa. Nó cũng đúng với khu vực quản trị của WordPress. Nếu các trang động như vậy được cache, người dùng sẽ thấy các nội dung cá nhân hóa không liên quan đến họ.

WordPress có object cache được xây dựng sẵn bên trong (bulit-in), cho phép thông tin như các truy vấn cơ sở dữ liệu được lưu trữ trong bộ nhớ. Đây là nguyên nhân mà dù có nhiều lệnh gọi đến các hàm như get_posts, nhưng nó chỉ dẫn đến một truy vấn cơ sở dữ liệu (những lời gọi khác đã được cache).

Mặc dù vậy, object cache không được tạo liên tục theo mặc định (nghĩa là nó không tồn tại khi không được yêu cầu). May mắn là, WordPress có thể tích hợp với phần mềm dữ liệu lưu trữ liên tục như Redis, đây là điều rất quan trọng để nhân rộng các trang động.

Object cache nằm giữa PHP và database (cơ sở dữ liệu) sẽ tăng tốc độ thực thi PHP và giảm tải lên cơ sở dữ liệu bằng cách cache truy vấn trong bộ nhớ. Bạn có thể thấy ảnh hưởng của object cache bằng cách cài đặt plugin Query Monitor. Tải trang giỏ hàng trên WooCommerce không có object cache được bật sẽ tạo ra 32 truy vấn cơ sở dữ liệu:

không bật object cache

Khi object cache được bật, con số này giảm xuống chỉ còn 2 truy vấn cơ sở dữ liệu và giảm thời gian tạo trang từ 0,085 giây xuống còn 0,053 giây:

bật object cache

Các bài kiểm tra được thực hiện trên nền PHP 7.3, WordPress 5.2.2, WooCommerce 3.6.3 và theme Storefront.

Một số điểm cần lưu ý:

  1. Việc bổ sung thêm các phần mềm máy chủ như Redis hoặc Memcached là cần thiết để tạo object cache liên tục. Điều này nên được quan tâm để ý nếu bạn đang sử dụng host WordPress loại tốt, hoặc bạn có thể tự cài đặt lấy nếu bạn tự quản trị máy chủ của riêng mình.
  2. Object cache không loại bỏ hoàn toàn sự phụ thuộc vào cơ sở dữ liệu, cái thường là nguyên nhân gây vấn đề nút thắt cổ chai lớn nhất trong WordPress. Lý do là vì các truy vấn SQL để xây dựng chỉ mục post sẽ luôn luôn được thực thi vì kết quả không được cache.

#6. Tổng kết

Tôi mới chỉ lướt qua những vấn đề căn bản về cache khi nó liên quan đến WordPress. Hy vọng là bạn đã hiểu rõ hơn cách nhiều lớp cache làm việc. Nếu bạn muốn đào sâu, tôi khuyên bạn đọc bài viết này về HTTP Caching để hiểu rõ hơn về cache phía trình duyệt. Một trang web khác bằng tiếng Anh là WordPress as Scale cũng là một nguồn thông tin tuyệt vời để bạn học hỏi nhiều hơn về chủ đề hiệu suất trong WP.

Bạn vẫn còn thắc mắc chưa được giải đáp về WordPress cache? Hãy đặt câu hỏi trong phần bên dưới nhé.

(Dịch từ bài viết: WordPress Caching: All You Need To Know, tác giả: Ashley Rich, website: SpinupWP)

Back to Top