Cache a gclid: zapytanie z kliknięcia reklamy, klucz cache strony i zmierzony pierwszy bajt

Obsługa cache przy gclid polega na ignorowaniu zapytania gclid dodanego na końcu adresu kliknięcia reklamy i odpowiadaniu plikiem cache adresu bez zapytania. Pomiary pierwszego bajtu według zapytania i stanu cache na serwerze WordPress z Nginx + Apache pokazały, że gclid dodawał 0,014–0,015 sekundy, a opóźnienia rzędu kilku sekund występowały tylko wtedy, gdy nie dało się użyć cache.
Mierzony wewnątrz tego samego serwera pierwszy bajt przychodził po 0,014–0,015 sekundy bez zapytania i po 0,029–0,030 sekundy z dołączonymi zapytaniami kliknięcia reklamy. Gdy WordPress budował tę samą stronę od nowa bez cache, trwało to 3,639 i 3,260 sekundy.
1️⃣ Cache a gclid: adresy kliknięć reklam i klucz cache
Gdy w Google Ads działa automatyczne tagowanie, na końcu adresu odwiedzającego, który kliknął reklamę, dodawane jest [?gclid=wartość]. Ta wartość to parametr identyfikujący kliknięcie reklamy, więc różni się u każdego odwiedzającego, choć ta sama osoba klikająca ponownie tę samą reklamę może dostać tę samą wartość.
Prawdziwe adresy kliknięć reklam rzadko mają samo gclid. Często dochodzą gad_source, gad_campaignid i gbraid, a czasem także 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=EXAMPLEZ zapytaniem na końcu adresu przeglądarka nadal otwiera tę samą stronę, ale dla cache to inny adres. Standard cache HTTP (RFC 9111) definiuje klucz cache, czyli podstawę, na której cache wybiera zapisaną odpowiedź, jako złożony co najmniej z metody żądania i docelowego URI, a docelowy URI obejmuje też ciąg zapytania.
Jeśli ciąg zapytania trafia do klucza cache bez zmian, każde kliknięcie z inną wartością gclid staje się nowym adresem. CDN, nginx i WP Rocket, przez które przechodzi odpowiedź, obsługują to zapytanie każdy według innej zasady.
Jeśli CDN nie ma kopii albo jego klucz cache rozróżnia zapytania, żądanie idzie dalej do serwera źródłowego. Od tego miejsca szybkość zależy od tego, czy nginx i WP Rocket znajdą plik cache.
2️⃣ Statyczne serwowanie w nginx: żądania z zapytaniem trafiają do Apache
Nawet gdy plik cache jest na dysku, nginx w układzie Nginx + Apache nie serwuje go bezpośrednio na żądanie z zapytaniem. Dzieje się tak, bo poniższa konfiguracja, dzięki której nginx czyta pliki cache WP Rocket bezpośrednio, buduje ścieżkę pliku tylko wtedy, gdy ciąg zapytania jest pusty.
# nginx.conf — blok http: warunki pominięcia pliku 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; # 0 tylko przy pustym ciągu zapytania
}
# blok 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; # do Apache, gdy ścieżka jest pusta lub brak pliku
add_header X-Rocket-Nginx-Serving-File 'HIT' always; # oznacza odpowiedzi podane przez nginx prosto z pliku cache
}[$rocket_query] sprawdza tylko, czy cały ciąg zapytania jest pusty, więc gclid, które WP Rocket ignoruje, jest traktowane jak każde inne zapytanie. Jeśli kopie mobilne są trzymane osobno, dochodzi jeszcze jedno sprawdzenie, które dodaje [-mobile] do nazwy pliku.
Reguły [.htaccess], które WP Rocket zapisuje dla Apache, także wymagają pustego ciągu zapytania. Czy to nginx, czy Apache, krok serwujący plik cache bezpośrednio bez PHP dotyczy tylko żądań bez zapytania.
Żądania bez zapytania miały nagłówek [X-Rocket-Nginx-Serving-File: HIT], a sześć żądań z gclid i zapytaniami w stylu reklamowym go nie miało. Pierwszy bajt przy żądaniach z zapytaniem wydłużył się o 0,014–0,015 sekundy, bo do drogi doszły Apache i PHP, które czytają i zwracają plik cache.
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] to czas od żądania do nadejścia pierwszego bajtu. Aby mierzyć wewnątrz serwera bez przechodzenia przez CDN, dodaj [--resolve example.com:443:127.0.0.1].
3️⃣ Lista ignorowanych zapytań WP Rocket: ten sam plik cache
Niezapisywanie w cache adresów z zapytaniem to domyślne zachowanie WP Rocket, ale zapytania z kliknięć reklam są wyjątkiem. WP Rocket przed decyzją usuwa parametry ze swojej listy ignorowanych i jeśli nie zostaje żadne zapytanie, odpowiada plikiem cache adresu bez zapytania.
// wp-rocket/inc/classes/Buffer/class-tests.php (3.23.5.1)
public function get_query_params() {
// …
$params = array_diff_key( // najpierw usuń ignorowane zapytania
self::$get,
$this->config->get_config( 'cache_ignored_parameters' )
);
// …
}
public function can_process_query_string() {
// …
$params = $this->get_query_params();
if ( ! $params ) { // brak pozostałych zapytań: obsługa z cache
return self::memoize( __FUNCTION__, [], true );
}
// przechodzą tylko lang · s · permalink_name · lp-variation-id i zapytania dodane w [Cache Query String(s)]
// …
}Jeśli to, co [get_query_params] zwraca po usunięciu ignorowanych zapytań, jest puste, ścieżka pliku cache też zostaje ustawiona na adres bez zapytania. Żądanie z gclid przeszło przez Apache i PHP, ale komentarz cache na końcu HTML był taki sam jak przy żądaniu bez zapytania, a rozmiar odpowiedzi wyniósł 350 668 bajtów, tyle co plik cache (gzip).
Lista ignorowanych zapytań to domyślna lista, którą WP Rocket raz w tygodniu pobiera z własnych serwerów i zapisuje w [wp-content/wp-rocket-config/dynamic-lists.json]. Według stanu na 17 października 2026 lista zawiera gclid, gbraid, wbraid, gad_source i gad_campaignid.
Jeśli wmiesza się choćby jedno zapytanie spoza listy, WP Rocket nie używa cache: tę samą stronę z dowolnym zapytaniem spoza listy WordPress zbudował od nowa, bez komentarza cache. Jeśli do adresów swoich reklam dołączasz własne zapytania śledzące, te kliknięcia za każdym razem idą tą drogą.
Aby zmienić listę, użyj wtyczki pomocniczej wskazanej przez WP Rocket. Wtyczka dodaje lub usuwa zapytania filtrem [rocket_cache_ignored_parameters] i przy włączaniu oraz wyłączaniu ponownie tworzy plik konfiguracyjny WP Rocket.
// z WP Rocket | Ignore Query Strings 1.1.1 (wtyczka pomocnicza zespołu wsparcia WP Rocket)
function define_ignored_parameters( array $params ) {
$params['new_query_string'] = 1; // dodaj do ignorowanych zapytań
//unset ( $params['utm_source'] ); // usuń z ignorowanych zapytań
return $params;
}
add_filter( 'rocket_cache_ignored_parameters', __NAMESPACE__ . '\define_ignored_parameters', 999 );
register_activation_hook( __FILE__, __NAMESPACE__ . '\flush_wp_rocket' ); // przy włączaniu uruchamia rocket_generate_config_file()WP Rocket zapisuje tę listę w pliku konfiguracyjnym nazwanym od domeny w [wp-content/wp-rocket-config/] i czyta ten plik przy każdym żądaniu, więc jeśli dodasz tylko filtr bez ponownego utworzenia pliku konfiguracyjnego, nowa lista nie zadziała. Zapytania z listy niezależnie od wartości dzielą jeden plik cache adresu bazowego, więc nie dodawaj zapytań, których wartość zmienia to, co pokazuje strona.
Po dodaniu do wtyczki pomocniczej [uk_test], którego nie było na liście, i jej włączeniu plik konfiguracyjny został utworzony ponownie z tym zapytaniem na końcu listy. Następnie po kolei zażądano adresu bez zapytania i dwóch adresów z różnymi wartościami [uk_test].
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.027929Wszystkie trzy żądania zwróciły te same 21 390 bajtów w ciągu 0,03 sekundy, a koniec HTML żądania z [uk_test] otwarto, by sprawdzić czas 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 -->Czas cache w końcowym komentarzu zgadzał się z plikiem cache adresu bez zapytania. Przed włączeniem wtyczki pomocniczej to samo żądanie było budowane od nowa w 0,36–0,38 sekundy, bez komentarza cache.
Także po włączeniu żądanie, które miało dodatkowo [foo] spoza listy, nie użyło pliku cache i zostało zbudowane od nowa.
Przez minutę zaraz po ponownym utworzeniu pliku konfiguracyjnego żądania z [uk_test] też były budowane od nowa. Ponieważ PHP OPcache był ustawiony na ponowne sprawdzanie zmienionych plików co 60 sekund (revalidate_freq), odpowiedzi zaczęły przychodzić z pliku cache dopiero po minucie.
Nawet po wyłączeniu i usunięciu wtyczki pomocniczej wiersz z [uk_test] został w pliku konfiguracyjnym. Kod wyłączania próbuje usunąć filtr dodany z priorytetem 999 przy domyślnym priorytecie, więc plik konfiguracyjny jest tworzony ponownie, gdy filtr nadal działa. Dopiero ponowne utworzenie pliku konfiguracyjnego po usunięciu wtyczki usuwa zapytanie z listy.
4️⃣ Klucz cache w CDN: wykluczanie zapytań reklamowych i żądania do serwera źródłowego
Jeśli CDN wkłada ciąg zapytania do klucza cache bez zmian, każde kliknięcie z inną wartością gclid nie znajduje kopii, a żądanie idzie aż do serwera źródłowego. Pominięcie wszystkich zapytań to rozwiązuje, ale nie pasuje do stron z adresami, których treść zmienia się zależnie od zapytania, jak wyniki wyszukiwania, więc lepiej usuwać z klucza cache tylko zapytania reklamowe.
Po takim usunięciu zapytań reklamowych CDN odpowiada tą samą kopią co dla adresu bez zapytania nawet przy innej wartości gclid i tylko wtedy, gdy nie ma kopii, wysyła żądanie z dołączonym zapytaniem do serwera źródłowego.
# stan cache CDN dla dwóch żądań z różnymi wartościami gclid (nazwy nagłówków zależą od 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'Jeśli oba żądania z różnymi wartościami są HIT, a ich kopie zapisano w tym samym czasie co kopię adresu bez zapytania, ten CDN pomija gclid w kluczu cache. Pierwsza wizyta w lokalizacji bez kopii nadal przechodzi przez nginx i WP Rocket na serwerze źródłowym, nawet jeśli CDN usuwa zapytania reklamowe z klucza.
5️⃣ Co spowalnia kliknięcia reklam: pusty cache stron
Gdy pierwsza strona z reklamy ładuje się wolno, łatwo obwinić gclid o omijanie cache, ale jeśli plik cache istnieje, ten sam plik jest serwowany nawet z zapytaniem. Sekundy do pierwszego bajtu dokłada pusty plik cache, przez który WordPress musi zbudować stronę od nowa.
Pliki cache są usuwane po upływie czasu ustawionego w opcji Cykl trwania pamięci podręcznej; domyślnie w WP Rocket to 10 godzin. Zapisanie wpisu lub ustawień też usuwa powiązany cache, a gdy lista, którą WP Rocket pobiera raz w tygodniu, zostaje zastąpiona nową wersją i zapisana, opróżniany jest także cały cache strony.
Przy włączonym preloadzie WP Rocket ponownie otwiera opróżnione adresy i znów wypełnia cache, a odwiedzający, którzy przyjdą wcześniej, czekają, aż strona się zbuduje. Żądanie z samymi zapytaniami reklamowymi też tworzy plik cache pod adresem bez zapytania, więc kliknięcie reklamy, które jako pierwsze trafi na pusty cache, wypełnia go dla następnego odwiedzającego.
Zaraz po opróżnieniu cache pierwsze żądanie otwarte z zapytaniami w stylu reklamowym nie znalazło pliku cache i zostało zbudowane od nowa w 0,341–0,369 sekundy, a w tej samej sekundzie pojawił się plik cache adresu bez zapytania.
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
Razem 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.025379Wszystkie trzy razy przebiegły w tej samej kolejności, a następne żądanie bez zapytania dostało odpowiedź z nowego pliku cache w 0,023–0,025 sekundy. Ponieważ żądanie nie pochodziło z urządzenia mobilnego, powstały tylko dwa pliki dla komputerów.
W przypadku adresów, do których prowadzą twoje reklamy, sam sprawdź, czy istnieje plik cache i kiedy powstał; jeśli kopie mobilne są tworzone osobno, sprawdź zarówno plik dla komputerów, jak i mobilny.
ls -l --time-style='+%F %T' wp-content/cache/wp-rocket/example.com/sample-page/Razem 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 -->Odpowiedź z pliku cache ma w komentarzu na końcu HTML, po [Debug: cached@], czas utworzenia pliku w formacie Unix. Bez tego znacznika tę odpowiedź zbudował od nowa WordPress.
🔢 FAQ & polecane treści














ℹ️ Informacja o linkach partnerskich
Treści tej witryny zawierają linki partnerskie. Jeśli odwiedzający kupi produkt lub usługę przez taki link, witryna otrzymuje od sprzedawcy prowizję. Kwota płacona przy tym przez kupującego (podczas promocji spada↓) nie wzrasta. Podane ceny, rabaty i dostępność odnoszą się do chwili pisania i mogą różnić się od stanu faktycznego, dlatego przed zakupem sprawdź je u sprzedawcy. Produkty wybieramy i oceniamy według własnych kryteriów, a prowizja nie wpływa ani na kolejność prezentacji, ani na treść ocen.

