Trống Đồng Đông Sơn

Việc tối ưu tốc độ wordpress cloudflare và kết hợp hạ tầng web server OpenLiteSpeed là bài toán sống còn cho các website doanh nghiệp năm 2026. Bài viết này đúc kết lại một case study thực tế: tối ưu tốc độ tải trang cho một website WordPress chạy trên OpenLiteSpeed (CyberPanel) + Cloudflare, và song song đó là dọn dẹp, kiểm tra lại hệ thống tracking (GA4, Facebook Pixel, Microsoft Ads) khi chuyển sang chạy server-side qua Cloudflare Zaraz.

Nếu bạn là marketer cần hiểu vì sao trang load chậm hoặc vì sao công cụ kiểm tra tag báo lỗi, hoặc là dev cần một checklist tuning cụ thể — bài viết này dành cho bạn.

1. Vấn đề ban đầu: một file font “nhẹ tênh” nhưng mất 2 giây để tải

Mọi chuyện bắt đầu từ một quan sát rất cụ thể trên tab Network của Chrome DevTools: file font Gilroy-Regular.woff2 chỉ nặng 26KB nhưng mất tới 2 giây để hiển thị, trong khi VPS chạy 8 core / 16GB RAM gần như không tải gì cả.

Đây là bài học đầu tiên cho cả marketer lẫn dev: “tài nguyên server còn dư” không đồng nghĩa với “web nhanh”. Tốc độ tải một tài nguyên phụ thuộc vào cách trình duyệt xếp hàng, phát hiện và ưu tiên tài nguyên đó — chứ không chỉ phụ thuộc vào CPU/RAM còn trống.

Đọc bảng Timing để biết thời gian “biến mất” ở đâu

Khi click vào một request trong tab Network, tab Timing cho biết thời gian bị tiêu tốn ở giai đoạn nào:

  • Stalled: Trình duyệt đã sẵn sàng gửi request nhưng phải xếp hàng chờ (do giới hạn số kết nối/luồng đồng thời).
  • Waiting for server response (TTFB): Thời gian chờ server phản hồi byte đầu tiên.
  • Content Download: Thời gian tải nội dung thực tế.

Trong case study này, file font chỉ mất 0.3ms để tải nội dung — toàn bộ 2 giây nằm ở StalledTTFB, tức là vấn đề nằm ở việc xếp hàngphát hiện muộn, không phải ở dung lượng file hay băng thông server.

Hai nguyên nhân gốc rễ

Thứ nhất, trang gọi quá nhiều request cùng lúc (234 request cho một trang chủ, thay vì mức khuyến nghị 30–60). Kết nối HTTP/2 có giới hạn số luồng đồng thời (concurrent streams), nên khi có hàng trăm file ảnh/JS/CSS đổ về cùng lúc, các file đến sau — như file font — bị đẩy vào hàng đợi.

Thứ hai, font không được khai báo sớm. Trình duyệt chỉ biết đến file font sau khi: tải xong HTML → tải xong CSS của plugin quản lý font → parse CSS → thấy @font-face → mới gửi request lấy font. Vì “biết muộn”, request này luôn bị xếp cuối hàng đợi.

Bài học cho marketer: khi brief cho designer/dev về “web load chậm”, đừng chỉ nói “chậm quá” — hãy đính kèm ảnh chụp tab Network và cột Timing, đó là ngôn ngữ chung giúp dev chẩn đoán đúng thay vì đoán mò.

2. Sửa nhanh: Preload font và font-display: swap

Cách xử lý trực tiếp nhất để tối ưu tốc độ wordpress cloudflare ở khâu hiển thị font là “nói trước” cho trình duyệt biết về file font ngay từ khi nhận HTML, thay vì để nó tự phát hiện qua CSS.

Thẻ này chèn vào , báo cho trình duyệt tải font song song với HTML thay vì chờ CSS.

Kết hợp thêm font-display: swap trong khai báo @font-face:

@font-face{ 
  font-family: 'Gilroy-Regular';
  src: url('font.woff2') format('woff2');
  font-display: swap;
 }

swap giúp chữ hiển thị ngay bằng font hệ thống trong lúc chờ font custom tải xong, tránh hiện tượng chữ “biến mất” (FOIT — Flash of Invisible Text).

Trên WordPress dùng LiteSpeed Cache, có thể làm việc này không cần đụng code: vào LiteSpeed Cache → Page Optimization → Preload, dán URL file font vào ô Preload Fonts.

Lưu ý thực tế: bước này giúp giảm thời gian tải riêng file font, nhưng nếu tổng số request của trang vẫn ở mức hàng trăm, cảm nhận tốc độ tổng thể sẽ chưa cải thiện rõ. Đây chỉ là bước 1 trong một chuỗi tối ưu.

tối ưu tốc độ wordpress cloudflare

3. Giảm tổng số request: nguyên nhân gốc của nghẽn hàng đợi

Chuẩn tối ưu chung của Google cho một trang là khoảng 30–60 request. Một trang có 234 request gần như chắc chắn sẽ gặp hiện tượng nghẽn hàng đợi bất kể server mạnh cỡ nào.

Việc cần làm trong LiteSpeed Cache → Page Optimization:

Thiết lập Tác dụng
CSS Combine Gộp hàng chục file CSS nhỏ thành 1–2 file
JS Combine Gộp các file JS lẻ (slider, animation, plugin…) thành 1 file
JS Deferred Trì hoãn JS không thiết yếu đến sau khi trang đã hiển thị
Lazy Load Images Chỉ tải ảnh khi cuộn tới, đặc biệt với ảnh below-the-fold
Font Display Optimization Chọn Swap

Ngoài ra, các icon nhỏ dạng .png nên chuyển sang SVG inline hoặc SVG sprite thay vì gọi hàng trăm file ảnh riêng lẻ — mỗi file ảnh là một request, và request nào cũng có chi phí (DNS, TCP/TLS handshake, hàng đợi).

4. Tuning tầng Cloudflare: những gì nên bật

Trên Cloudflare Dashboard (kể cả gói Free) có một số thiết lập ảnh hưởng trực tiếp đến tốc độ:

Network:

  • HTTP/3 (with QUIC) — loại bỏ hiện tượng Head-of-Line Blocking vốn có ở TCP/HTTP2.
  • 0-RTT Connection Resumption — giảm độ trễ bắt tay (handshake) khi người dùng quay lại trang.

Speed → Optimization:

  • Early Hints (103) — Cloudflare gửi gợi ý preload cho trình duyệt ngay khi request vừa tới, trước cả khi server WordPress xử lý xong HTML.
  • Auto Minify (JS, CSS, HTML) — nếu chưa bật ở LiteSpeed Cache.
  • HTTP/2 Prioritization.

Caching → Configuration:

  • Browser Cache TTL: chọn “Respect Existing Headers” hoặc đặt 1 tháng/1 năm cho tài nguyên tĩnh.
  • Development Mode: đảm bảo đang OFF (bật nhầm sẽ vô hiệu hoá toàn bộ cache).

Đây đều là các thiết lập một lần, không cần theo dõi liên tục — phù hợp để marketer/quản trị viên tự làm mà không cần dev can thiệp.

5. Cạm bẫy dễ gặp: Rocket Loader xung đột với plugin cache

Đây là phần đáng chú ý nhất cho những site đã dùng plugin cache mạnh như LiteSpeed Cache hoặc Super Page Cache for Cloudflare.

Rocket Loader là tính năng của Cloudflare giúp hoãn tải JavaScript để tăng tốc render ban đầu. Nghe hợp lý, nhưng khi website đã có plugin cache tự lo việc gộp/hoãn JS, Rocket Loader lại chèn thêm một lớp trung gian (rocket-loader.min.js) để chặn và điều phối lại toàn bộ script — gây ra hiện tượng:

  • Toàn bộ file JS bị dồn lại chờ ~800ms trước khi bắt đầu tải (xuất hiện dưới dạng “Pending” đồng loạt trong Network tab).
  • Xung đột thứ tự thực thi script với plugin cache, có thể gây lỗi giao diện: slider không chạy, menu bị đơ, icon lệch vị trí.

Nguyên tắc chung: nếu website đã dùng một plugin cache toàn diện (LiteSpeed Cache, Super Page Cache, WP Rocket…), nên tắt Rocket Loader trên Cloudflare (Speed → Optimization → Rocket Loader → OFF) và để plugin cache tự đảm nhiệm việc gộp/defer JS. Hai công cụ cùng “sửa” một việc thường tạo ra xung đột chứ không cộng dồn hiệu quả.

6. Tuning sâu tầng server: OpenLiteSpeed (dành cho dev)

Nếu đã tối ưu ở tầng WordPress và Cloudflare mà vẫn còn độ trễ, bước tiếp theo là tinh chỉnh chính OpenLiteSpeed (qua WebAdmin Panel, thường ở cổng :7080 trên CyberPanel).

Server Configuration → Tuning → Connection:

  • Max Connections / Max SSL Connections: nâng lên mức đủ lớn (ví dụ 10.000–30.000) để không nghẽn ở tầng kết nối.
  • Max Keep-Alive Requests: nâng từ mặc định (thường 100–1000) lên 10.000 — giúp trình duyệt giữ nguyên một kết nối để tải toàn bộ tài nguyên của trang mà không phải mở/đóng SSL liên tục.
  • Keep-Alive Timeout: 5–10 giây là hợp lý.

HTTP3/QUIC:

  • Max Concurrent Streams Per Connection: đây là thiết lập then chốt — mặc định thường giới hạn ở 100 luồng, có thể nâng lên 300–500 để trình duyệt tải nhiều tài nguyên song song hơn mà không bị “Stalled”.

Static File Delivery Optimization — phần hay bị bỏ sót nhất:

  • Max Cached Small File Size: mặc định 16KB. Nếu file font/CSS/JS của bạn lớn hơn ngưỡng này, OLS sẽ không cache vào RAM mà phải đọc từ đĩa mỗi lần — dù RAM còn dư hàng chục GB. Nên nâng lên 128KB.
  • Total Small File Cache Size: nâng từ 128M lên 512M–1G.
  • Max MMAP File Size / Total MMAP Cache Size: nâng tương ứng để chứa được nhiều file tĩnh hơn trong bộ bộ nhớ.

External App (lsphp):

  • PHP_LSAPI_CHILDREN: số tiến trình PHP con xử lý song song, có thể đặt 150 nếu RAM còn dư nhiều.
  • PHP_LSAPI_MAX_REQUESTS: 10.000.

Sau khi chỉnh xong, luôn nhớ Graceful Restart để OLS nạp lại cấu hình mà không làm gián đoạn kết nối đang có.

Lưu ý quan trọng: các thiết lập này chỉ phát huy tác dụng đầy đủ sau khi đã giảm số lượng request và tắt các nguồn gây xung đột (như Rocket Loader) ở bước trước. Tuning server không thay thế được việc tối ưu ở tầng ứng dụng.

7. Chuyển tracking sang server-side với Cloudflare Zaraz: vì sao và cần lưu ý gì

Song song với tối ưu tốc độ, một hướng đi phổ biến hiện nay là chuyển các tag tracking (Google Analytics 4, Facebook Pixel, Microsoft Ads UET…) từ chạy client-side (nhúng script gtag.js, fbevents.js, bat.js trực tiếp vào trình duyệt người dùng) sang chạy server-side qua Cloudflare Zaraz. Bạn có thể tham khảo tài liệu hướng dẫn Cloudflare Zaraz chính thức để nắm rõ kiến trúc vận hành.

Lợi ích cho marketer: dữ liệu vẫn được ghi nhận đầy đủ về các nền tảng quảng cáo, nhưng trình duyệt người dùng không phải tải thêm hàng loạt script bên thứ ba — trang nhẹ hơn, nhanh hơn, ít bị chặn bởi ad-blocker hơn.

Điều dev/marketer cần biết khi vận hành:

  • Sau khi chuyển sang Zaraz, các script client-side truyền thống (như bat.js của Microsoft Ads) sẽ không còn xuất hiện trong mã nguồn trang, vì dữ liệu được Cloudflare Edge gửi thẳng server-to-server tới nền tảng quảng cáo.
  • Vì vậy, các công cụ kiểm tra tag kiểu cũ — ví dụ công cụ “Test your UET tag” của Microsoft Ads — vốn được thiết kế để tìm mã JavaScript trong trình duyệt, sẽ báo lỗi dạng “Tag not found” dù tracking vẫn hoạt động bình thường. Đây không phải lỗi, mà là hệ quả tất yếu của mô hình server-side.
  • Cách xác nhận tracking vẫn chạy đúng: kiểm tra trạng thái trực tiếp trên dashboard của từng nền tảng (ví dụ Microsoft Advertising hiển thị “Tracking Status: Active”), đối chiếu với biểu đồ hoạt động (pageview, event) trên chính Zaraz Dashboard — thay vì dựa vào công cụ kiểm tra client-side đã lỗi thời với mô hình này.

Gợi ý cho marketer: khi báo cáo hiệu quả tracking cho team hoặc agency, nên nói rõ hệ thống đang chạy server-side qua Zaraz, để tránh việc bị nghi ngờ “mất tag” chỉ vì một công cụ kiểm tra không tương thích với kiến trúc mới.

8. Truy tìm nguồn gốc script lạ trong tab Network

Một tình huống thường gặp: mở tab Network và thấy các request tới domain lạ, ví dụ dạng api.example-tracking.ai/beacon hoặc cdn.example-tracking.ai/core.min.js, mà không rõ ai chèn vào.

Quy trình xác minh nhanh, marketer và dev đều có thể tự làm:

  1. Kiểm tra cột Initiator trong DevTools Network — cột này cho biết chính xác request được khởi tạo bởi file/nguồn nào (một script trên trang, hoặc một extension của trình duyệt).
  2. Mở trang bằng cửa sổ ẩn danh (Incognito) và tắt hết extension. Nếu script lạ biến mất, nguyên nhân đến từ extension trình duyệt (thường là các tiện ích SEO, kiểm tra rank, AI tool) chứ không phải từ chính website.
  3. Nếu script vẫn còn trong chế độ ẩn danh, kiểm tra tiếp trong mã nguồn server (view-source) và danh sách plugin WordPress đang active — nhiều plugin tự chèn script theo dõi riêng của nhà cung cấp dịch vụ (như plugin quản lý LLMs.txt tích hợp theo dõi lượt giới thiệu từ AI).
  4. Nếu xác định được plugin là nguồn gốc, thường plugin đó sẽ có tuỳ chọn “Disconnect” hoặc “Remove tracking script” ngay trong phần cài đặt — dùng tuỳ chọn này thay vì xoá plugin thủ công, để đảm bảo gỡ sạch cả script phía server lẫn phía trình duyệt. Sau đó nhớ Purge Cache để thay đổi có hiệu lực ngay.

Riêng với script của chính Cloudflare (ví dụ static.cloudflareinsights.com/beacon.min.js), đây là Cloudflare Web Analytics — công cụ đo lượt truy cập miễn phí, tự động chèn ở tầng CDN. Có thể tắt tại Cloudflare Dashboard → Analytics → Web Analytics → Settings → JS Snippet nếu không cần dùng.

9. Về header Report-To / NEL — không phải điều đáng lo

Nếu bạn thấy một header dạng:

{"group":"cf-nel","max_age":604800,"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v4?s=..."}]}

Đây là NEL (Network Error Logging) — một chuẩn HTTP header do Cloudflare tự động thêm vào cho mọi website dùng Cloudflare proxy. Tác dụng: nếu trình duyệt gặp sự cố kết nối (rớt mạng, lỗi DNS…), nó sẽ âm thầm gửi báo cáo lỗi về Cloudflare để chẩn đoán hạ tầng.

Header này không ảnh hưởng đến tốc độ tải trang — chỉ là một dòng thông tin trong HTTP header, và trình duyệt chỉ gửi báo cáo khi có sự cố. Có thể tắt tại Cloudflare → Network → Network Error Logging nếu muốn dọn gọn header, nhưng không bắt buộc.

Lưu ý phân biệt: NEL là dịch vụ chính chủ Cloudflare, khác hoàn toàn với các script tracking bên thứ ba — Cloudflare không bao giờ tự ý chèn script của nhà cung cấp khác vào website của bạn.

Checklist tổng kết quy trình tối ưu

Việc cần làm Vị trí thao tác Phân quyền xử lý
Preload font, font-display: swap trang / LiteSpeed Cache → Preload Dev, hoặc marketer có quyền admin
Gộp CSS/JS, Lazy load, JS Deferred LiteSpeed Cache → Page Optimization Dev, hoặc marketer có quyền admin
Bật HTTP/3, 0-RTT, Early Hints, Auto Minify Cloudflare → Network / Speed Marketer / Quản trị viên
Tắt Rocket Loader nếu đã có plugin cache Cloudflare → Speed → Optimization Marketer / Quản trị viên
Tuning Max Keep-Alive, Concurrent Streams, Static File Cache OpenLiteSpeed WebAdmin Dev / Server Admin
Xác minh tracking server-side qua dashboard nền tảng Zaraz Dashboard + dashboard từng nền tảng quảng cáo Marketer
Xác định nguồn gốc script lạ qua Initiator + Incognito Chrome DevTools Marketer, Dev

Tối ưu một website không phải là bật một công tắc duy nhất, mà là xử lý đúng từng tầng: ứng dụng (WordPress/plugin) → CDN (Cloudflare) → server (OpenLiteSpeed). Bỏ qua một tầng, hoặc bật chồng chéo các tính năng làm cùng một việc (như Rocket Loader và JS Combine), thường gây ra hiệu ứng ngược thay vì cộng hưởng.

Tương tự, khi hệ thống tracking chuyển sang mô hình server-side, cách kiểm tra và báo cáo hiệu quả tracking cũng cần thay đổi theo — dựa vào dữ liệu thực tế trên dashboard nền tảng thay vì các công cụ kiểm tra được thiết kế cho mô hình client-side cũ.

Để tìm hiểu thêm các giải pháp tối ưu tổng thể và dịch vụ kỹ thuật số toàn diện, bạn có thể tham khảo dịch vụ Digital Marketing toàn diện của DPS.MEDIA để được hỗ trợ hạ tầng web xé gió và chuyển đổi cao nhất.

Ý kiến bạn đọc (9)

DPS SECURITY

Đăng nhập để bình luận

Đăng nhập nhanh 1-chạm bằng Google để chia sẻ ý kiến của bạn về bài viết.