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

bởi Nguyễn Đức Anh
tìm hiểu về WordPress Caching

Vài năm qua khi thực hiện công việc hỗ trợ sản phẩm của chúng tôi tại Delicious Brains (đặc biệt là 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:

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

Trong bài viết này, tôi hy vọng 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 đề caching trên WordPress vốn rất phức tạp.

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

Tại sao Caching 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 là phải hiểu được lợi ích của caching là gì. Caching đó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 lưu lượng truy cập hơn.

Ngoài ra, caching 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 là 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).

Các lớp caching

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 là 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 (out-of-the-box) 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 đến, và đây là việc lãng phí hiệu quả 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

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, caching 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:

  • Caching phía trình duyệt / Browser caching
  • Page caching
  • Object caching

WordPress sau cache

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à caching phía trình duyệt.

Caching phía trình duyệt

Mặc dù caching 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 là trong vương quốc của WordPress), 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 nói đến việc hiểu về bộ nhớ đệm trình duyệt, tab network trong bộ công cụ cho nhà phát triển trên trình duyệt là người bạn thân thiết.  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ả mạo lượt tải 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ểntổ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 CSS

Ảnh của bài viết trên thực ra 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

Đ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 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 là gzip và brotli).

Vì lý do đó, nếu caching 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 giảm hẳn

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! 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-controlexpires cái được bổ sung vào đáp ứng 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.

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

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.

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. 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 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 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 headers 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 Không được 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ẽ gia hạn thời gian hết hạn được chỉ định trong cache-control: max-age=<seconds>.

Page Caching

Page Caching 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 cho việc cung cấp hosting WordPress.  Các kết quả không cache là cho WordPress không được cấu hình caching (ngoại trừ PHP OPcache, sử dụng các giá trị mặc định 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 hơn (traffic).

trang đã được cache

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.

thời gian phản hồi khi có cache và không có cache

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à đá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 caching 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ữ, 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 khó khăn.
  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 caching (cái sẽ được nói ở phần bên dưới) vẫn được khuyến khích dùng.

Object Caching

Như đã đề cập ở phần trên, không phải tất cả các trang có thể được cached. Đ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 caching đượ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 caching 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 caching được bật sẽ tạo ra 32 truy vấn cơ sở dữ liệu:

không bật object cache

Khi object caching đượ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:

khi object cache được bật

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 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.

Tổng kết

Tôi mới chỉ lướt qua những vấn đề căn bản của caching khi nó liên quan đến WordPress. Hy vọng là bạn đã hiểu rõ hơn cách nhiều lớp caching 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ề caching 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 caching? 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)

0 bình luận

Khu vực bình luận

avatar