Bộ nhớ đệm và gclid: truy vấn nhấp quảng cáo, khóa cache của trang và byte đầu tiên đo được

Xử lý cache với gclid là cách bỏ qua truy vấn gclid gắn ở cuối URL nhấp quảng cáo và phản hồi bằng tệp cache của URL không có truy vấn. Kết quả đo byte đầu tiên theo truy vấn và theo có hay không có cache trên máy chủ WordPress cấu hình Nginx + Apache cho thấy thời gian gclid thêm vào là 0,014–0,015 giây, và độ trễ tính bằng giây chỉ xảy ra khi không dùng được cache.
Byte đầu tiên đo bên trong cùng máy chủ là 0,014–0,015 giây khi không có truy vấn và 0,029–0,030 giây khi gắn truy vấn nhấp quảng cáo. Khi WordPress tạo mới cùng trang đó mà không có cache, mất 3,639 giây và 3,260 giây.
1️⃣ Cache và gclid: URL nhấp quảng cáo và khóa cache
Khi bật tính năng tự động gắn thẻ của Google Ads, [?gclid=giá trị] được thêm vào cuối URL của khách truy cập nhấp vào quảng cáo. Giá trị này là tham số nhận diện lượt nhấp quảng cáo nên khác nhau theo từng khách, dù đôi khi cùng một người nhấp lại cùng quảng cáo có thể nhận cùng giá trị.
URL nhấp quảng cáo thực tế hiếm khi chỉ có gclid. gad_source, gad_campaignid và gbraid thường được gắn kèm, đôi khi có thêm wbraid.
https://example.com/sample-page/?gad_source=1&gad_campaignid=1234567890&gbraid=EXAMPLE&gclid=EXAMPLE
https://example.com/sample-page/?gclid=EXAMPLE&gbraid=EXAMPLE&wbraid=EXAMPLEDù có truy vấn ở cuối URL, trình duyệt vẫn mở cùng trang, nhưng với cache thì đó là một địa chỉ khác. Tiêu chuẩn cache HTTP (RFC 9111) định nghĩa khóa cache, tức tiêu chí để cache chọn phản hồi đã lưu, tối thiểu gồm phương thức yêu cầu và URI đích, và URI đích có bao gồm chuỗi truy vấn.
Nếu chuỗi truy vấn được đưa nguyên vào khóa cache, mỗi lượt nhấp có giá trị gclid khác nhau đều thành một địa chỉ mới. CDN, nginx và WP Rocket mà phản hồi đi qua xử lý truy vấn này theo những tiêu chí khác nhau.
Nếu CDN không có bản sao hoặc khóa cache phân biệt truy vấn, yêu cầu được chuyển đến máy chủ gốc. Tốc độ sau đó phụ thuộc vào việc nginx và WP Rocket có tìm thấy tệp cache hay không.
2️⃣ Phục vụ tĩnh của nginx: có truy vấn thì chuyển sang Apache
Dù tệp cache có trên đĩa, nginx trong cấu hình Nginx + Apache không phản hồi trực tiếp bằng tệp đó cho yêu cầu có truy vấn. Lý do là thiết lập dưới đây, vốn cho nginx đọc trực tiếp tệp cache của WP Rocket, chỉ tạo đường dẫn tệp khi chuỗi truy vấn trống.
# nginx.conf — khối http: điều kiện bỏ qua tệp cache
map $http_cookie $rocket_cookie {
default 0;
'~*wordpress_logged_in' 1;
'~*wp-postpass' 1;
'~*comment_author' 1;
'~*woocommerce_items' 1;
}
map $request_method $rocket_method {
default 1;
GET 0;
HEAD 0;
}
map $query_string $rocket_query {
default 1;
'' 0; # chỉ là 0 khi chuỗi truy vấn trống
}
# khối server
set $rocket_bypass '';
if ($rocket_cookie = 1) { set $rocket_bypass '1'; }
if ($rocket_method = 1) { set $rocket_bypass '1'; }
if ($rocket_query = 1) { set $rocket_bypass '1'; }
set $rocket_file '/wp-content/cache/wp-rocket/example.com${request_uri}index-https.html';
if ($rocket_bypass = '1') { set $rocket_file ''; }
location / {
try_files $rocket_file @apache; # chuyển sang Apache nếu đường dẫn trống hoặc không có tệp
add_header X-Rocket-Nginx-Serving-File 'HIT' always; # dấu hiệu nginx đã phản hồi trực tiếp bằng tệp cache
}[$rocket_query] chỉ kiểm tra toàn bộ chuỗi truy vấn có trống hay không, nên gclid mà WP Rocket bỏ qua cũng bị xử lý giống mọi truy vấn khác. Nếu thiết lập lưu riêng bản sao cho di động, sẽ có thêm một bước kiểm tra gắn [-mobile] vào tên tệp.
Các quy tắc [.htaccess] mà WP Rocket tạo cho Apache cũng có điều kiện chuỗi truy vấn phải trống. Bước phản hồi trực tiếp bằng tệp cache mà không qua PHP, dù ở nginx hay Apache, chỉ áp dụng cho yêu cầu không có truy vấn.
Yêu cầu không có truy vấn có header [X-Rocket-Nginx-Serving-File: HIT], còn sáu yêu cầu gắn gclid và truy vấn kiểu quảng cáo thì không có header này. Byte đầu tiên của yêu cầu có truy vấn tăng 0,014–0,015 giây vì có thêm bước Apache và PHP đọc tệp cache rồi phản hồi.
curl -so /dev/null -H 'Accept-Encoding: gzip' -w '%{time_starttransfer}\n' \
'https://example.com/sample-page/'0.015127curl -so /dev/null -H 'Accept-Encoding: gzip' -w '%{time_starttransfer}\n' \
'https://example.com/sample-page/?gclid=test123'0.029525curl -sI 'https://example.com/sample-page/' | grep -i x-rocket-nginx-serving-filex-rocket-nginx-serving-file: HIT[time_starttransfer] là thời gian từ lúc gửi yêu cầu đến khi nhận byte đầu tiên. Khi đo bên trong máy chủ mà không qua CDN, hãy thêm cả [--resolve example.com:443:127.0.0.1].
3️⃣ Danh sách truy vấn bị bỏ qua của WP Rocket: phản hồi bằng cùng tệp cache
Không lưu cache URL có truy vấn là cách hoạt động mặc định của WP Rocket, nhưng truy vấn nhấp quảng cáo là ngoại lệ. WP Rocket bỏ các tham số có trong danh sách truy vấn bị bỏ qua trước khi xét, và nếu không còn truy vấn nào, nó phản hồi bằng tệp cache của URL không có truy vấn.
// wp-rocket/inc/classes/Buffer/class-tests.php (3.23.5.1)
public function get_query_params() {
// …
$params = array_diff_key( // bỏ trước các truy vấn bị bỏ qua
self::$get,
$this->config->get_config( 'cache_ignored_parameters' )
);
// …
}
public function can_process_query_string() {
// …
$params = $this->get_query_params();
if ( ! $params ) { // nếu không còn truy vấn nào, xử lý bằng cache
return self::memoize( __FUNCTION__, [], true );
}
// chỉ lang · s · permalink_name · lp-variation-id và truy vấn đưa vào [Cache Query String(s)] được đi qua
// …
}Nếu kết quả của [get_query_params] sau khi bỏ các truy vấn bị bỏ qua là rỗng, đường dẫn tệp cache cũng được đặt theo URL không có truy vấn. Yêu cầu gắn gclid đi qua Apache và PHP, nhưng chú thích cache ở cuối HTML giống với yêu cầu không có truy vấn, và kích thước phản hồi cũng bằng tệp cache (gzip) là 350.668 byte.
Danh sách truy vấn bị bỏ qua là danh sách mặc định mà WP Rocket tải từ máy chủ của mình mỗi tuần một lần và lưu vào [wp-content/wp-rocket-config/dynamic-lists.json]. Tính đến ngày 17 tháng 10 năm 2026, danh sách có gclid, gbraid, wbraid, gad_source và gad_campaignid.
Chỉ cần lẫn vào một truy vấn không có trong danh sách là WP Rocket không dùng cache: cùng trang đó gắn một truy vấn bất kỳ không có trong danh sách đã được WordPress tạo mới mà không có chú thích cache. Nếu URL quảng cáo của bạn gắn kèm truy vấn theo dõi tự tạo, các lượt nhấp đó lần nào cũng đi theo đường này.
Để thay đổi danh sách, hãy dùng plugin trợ giúp mà WP Rocket hướng dẫn. Plugin này thêm hoặc bớt truy vấn qua bộ lọc [rocket_cache_ignored_parameters] và tạo lại tệp cấu hình của WP Rocket khi được bật hoặc tắt.
// trích từ WP Rocket | Ignore Query Strings 1.1.1 (plugin trợ giúp của nhóm hỗ trợ WP Rocket)
function define_ignored_parameters( array $params ) {
$params['new_query_string'] = 1; // thêm vào truy vấn bị bỏ qua
//unset ( $params['utm_source'] ); // loại khỏi truy vấn bị bỏ qua
return $params;
}
add_filter( 'rocket_cache_ignored_parameters', __NAMESPACE__ . '\define_ignored_parameters', 999 );
register_activation_hook( __FILE__, __NAMESPACE__ . '\flush_wp_rocket' ); // chạy rocket_generate_config_file() khi bậtWP Rocket ghi danh sách này vào tệp cấu hình đặt theo tên miền trong [wp-content/wp-rocket-config/] và đọc tệp đó ở mỗi yêu cầu, nên nếu chỉ thêm bộ lọc mà không tạo lại tệp cấu hình, danh sách mới không có hiệu lực. Truy vấn trong danh sách dùng chung một tệp cache của URL gốc dù giá trị là gì, nên đừng đưa vào những truy vấn mà giá trị làm thay đổi nội dung trang.
Sau khi thêm [uk_test] chưa có trong danh sách vào plugin trợ giúp rồi bật plugin, tệp cấu hình được tạo lại và truy vấn đó được thêm vào cuối danh sách. Tiếp theo, URL không có truy vấn và hai URL có giá trị [uk_test] khác nhau được yêu cầu lần lượt.
curl -s -o /dev/null -w '%{size_download} %{time_starttransfer}\n' -H 'Accept-Encoding: gzip' 'https://example.com/sample-page/'
curl -s -o /dev/null -w '%{size_download} %{time_starttransfer}\n' -H 'Accept-Encoding: gzip' 'https://example.com/sample-page/?uk_test=abc'
curl -s -o /dev/null -w '%{size_download} %{time_starttransfer}\n' -H 'Accept-Encoding: gzip' 'https://example.com/sample-page/?uk_test=xyz'21390 0.025720
21390 0.025507
21390 0.027929Cả ba yêu cầu đều nhận cùng 21.390 byte trong vòng 0,03 giây, và phần cuối HTML của yêu cầu gắn [uk_test] đã được mở để kiểm tra thời điểm cache.
curl -s --compressed 'https://example.com/sample-page/?uk_test=abc' | tail -c 200ck=lazyLoadYoutubeIframe;}});</script></body>
</html>
<!-- This website is like a Rocket, isn't it? Performance optimized by WP Rocket. Learn more: https://wp-rocket.me - Debug: cached@1792248839 -->Thời điểm cache trong chú thích cuối trùng với tệp cache của URL không có truy vấn. Trước khi bật plugin trợ giúp, cùng yêu cầu đó được tạo mới không có chú thích cache trong 0,36–0,38 giây.
Ngay cả sau khi bật, yêu cầu gắn kèm [foo] không có trong danh sách cũng không dùng tệp cache mà được tạo mới.
Trong 1 phút ngay sau khi tạo lại tệp cấu hình, yêu cầu [uk_test] cũng được tạo mới. Vì PHP OPcache được cấu hình kiểm tra lại tệp thay đổi mỗi 60 giây (revalidate_freq), phản hồi chỉ đến từ tệp cache sau khi qua 1 phút.
Dù tắt và xóa plugin trợ giúp, dòng [uk_test] vẫn còn trong tệp cấu hình. Đoạn mã chạy khi tắt cố gỡ bộ lọc đã thêm với độ ưu tiên 999 bằng độ ưu tiên mặc định, nên tệp cấu hình được tạo lại khi bộ lọc vẫn còn. Phải tạo lại tệp cấu hình thêm một lần sau khi xóa plugin thì truy vấn đó mới ra khỏi danh sách.
4️⃣ Khóa cache của CDN: loại truy vấn quảng cáo và yêu cầu về máy chủ gốc
Nếu CDN đưa nguyên chuỗi truy vấn vào khóa cache, mỗi lượt nhấp có giá trị gclid khác nhau đều không có bản sao và yêu cầu đi thẳng đến máy chủ gốc. Bỏ toàn bộ truy vấn sẽ hết vấn đề này, nhưng không hợp với trang có URL thay đổi nội dung theo truy vấn như kết quả tìm kiếm, nên tốt hơn là chỉ loại truy vấn quảng cáo khỏi khóa cache.
Khi loại truy vấn quảng cáo như vậy, dù giá trị gclid khác nhau, CDN vẫn phản hồi bằng cùng bản sao với URL không có truy vấn, và chỉ gửi yêu cầu kèm truy vấn đến máy chủ gốc khi không có bản sao.
# Trạng thái cache CDN của hai yêu cầu có giá trị gclid khác nhau (tên header khác nhau tùy CDN)
curl -sI 'https://example.com/sample-page/?gclid=test1' | grep -i -E 'cache|age'curl -sI 'https://example.com/sample-page/?gclid=test2' | grep -i -E 'cache|age'Nếu cả hai yêu cầu có giá trị khác nhau đều là HIT và thời điểm lưu bản sao trùng với URL không có truy vấn, CDN đó đang loại gclid khỏi khóa cache. Lượt truy cập đầu tiên tại điểm chưa có bản sao vẫn đi qua xử lý của nginx và WP Rocket trên máy chủ gốc, dù CDN có loại truy vấn quảng cáo khỏi khóa.
5️⃣ Nguyên nhân lượt nhấp quảng cáo chậm: cache trang đang trống
Nếu trang đầu tiên vào từ quảng cáo chậm, dễ nghĩ là gclid đã bỏ qua cache, nhưng nếu có tệp cache thì dù có truy vấn vẫn phản hồi bằng cùng tệp cache. Thứ làm byte đầu tiên tăng thêm vài giây là khi tệp cache trống khiến WordPress phải tạo mới trang.
Tệp cache bị xóa khi hết Thời gian sống của cache (mặc định của WP Rocket là 10 giờ). Khi lưu bài hoặc cài đặt, cache liên quan cũng bị xóa theo, và khi danh sách mà WP Rocket tải về mỗi tuần một lần được thay bằng phiên bản mới rồi lưu lại, toàn bộ cache của trang cũng bị làm trống.
Nếu bật preload, WP Rocket sẽ mở lại các URL đã bị làm trống để điền lại cache, và khách đến trước đó phải chờ thời gian tạo mới trang. Yêu cầu chỉ có truy vấn quảng cáo cũng tạo tệp cache theo URL không có truy vấn, nên lượt nhấp quảng cáo đầu tiên gặp cache trống sẽ điền cache cho khách tiếp theo.
Ngay sau khi làm trống cache, yêu cầu đầu tiên mở bằng truy vấn kiểu quảng cáo không tìm thấy tệp cache và được tạo mới trong 0,341–0,369 giây, và tệp cache của URL không có truy vấn xuất hiện ngay trong giây đó.
curl -s -o /dev/null -w '%{size_download} %{time_starttransfer}\n' -H 'Accept-Encoding: gzip' 'https://example.com/sample-page/?gclid=EXAMPLE1'
ls -l --time-style='+%F %T' wp-content/cache/wp-rocket/example.com/sample-page/
curl -s -o /dev/null -w '%{size_download} %{time_starttransfer}\n' -H 'Accept-Encoding: gzip' 'https://example.com/sample-page/'21361 0.366881
Tổng cộng 116
-rw-r--r-- 1 example nobody 90908 2026-10-17 23:56:38 index-https.html
-rw-r--r-- 1 example nobody 21385 2026-10-17 23:56:38 index-https.html_gzip
21385 0.025379Cả ba lần đều diễn ra theo cùng trình tự, và yêu cầu không có truy vấn mở tiếp theo được phản hồi bằng tệp cache mới trong 0,023–0,025 giây. Vì yêu cầu không đến từ thiết bị di động nên chỉ có hai tệp cho PC được tạo.
Với URL đích của quảng cáo, hãy tự kiểm tra có tệp cache không và được tạo lúc nào, và nếu thiết lập tạo riêng bản sao cho di động, hãy kiểm tra cả tệp PC lẫn tệp di động.
ls -l --time-style='+%F %T' wp-content/cache/wp-rocket/example.com/sample-page/Tổng cộng 3520
-rw-r--r-- 1 example nobody 1445922 2026-10-17 14:07:44 index-https.html
-rw-r--r-- 1 example nobody 350668 2026-10-17 14:07:44 index-https.html_gzip
-rw-r--r-- 1 example nobody 1446862 2026-10-17 14:07:47 index-mobile-https.html
-rw-r--r-- 1 example nobody 351042 2026-10-17 14:07:47 index-mobile-https.html_gzipcurl -s --compressed 'https://example.com/sample-page/?gclid=test123' | tail -c 200n/1/wp-content/uploads/example-plugin/style.css' media='all' /></noscript></body>
</html>
<!-- Cached for great performance - Debug: cached@1792213663 -->Phản hồi đi ra từ tệp cache có thời điểm tạo tệp cache theo giờ Unix ghi sau [Debug: cached@] trong chú thích cuối HTML. Nếu không có dấu này, phản hồi đó do WordPress tạo mới.
🔢 FAQ & nội dung đề xuất














ℹ️ Thông báo tiếp thị liên kết
Nội dung trên trang này có chứa liên kết affiliate (tiếp thị liên kết). Khi khách truy cập mua sản phẩm hoặc dịch vụ qua các liên kết này, trang sẽ nhận hoa hồng từ bên bán. Trong quá trình đó, số tiền người mua phải trả (sẽ giảm khi có chương trình khuyến mãi ↓) không hề tăng lên. Giá, khuyến mãi và tình trạng hàng được đăng theo thời điểm viết bài và có thể khác với thực tế, vì vậy hãy kiểm tra lại lần cuối với bên bán trước khi mua. Việc chọn và đánh giá sản phẩm dựa trên tiêu chí riêng của trang; việc có nhận hoa hồng hay không không ảnh hưởng đến thứ tự giới thiệu hay nội dung đánh giá.

