Takim przypadkiem jest chociażby element jak przycisk koszyka z liczbą dodanych produktów.

Przycisk koszyka z liczbą produktów na stronie opartej o Woocommerce

Jeżeli cache'ujemy całe strony, gdy użytkownik odwiedza np. stronę główną (jest scache'owana), a następnie przechodzi na stronę produktu, dodaje go do koszyka i później wraca na stronę główną - licznik produktów w koszyku się nie zaktualizował. 

Dlaczego? Dlatego, bo wciąż załadowała się strona sprzed operacji dodania produktu do koszyka zapamiętana wcześniej.

Jak rozwiązać problem cache na stronach WP z Woocommerce?

Większość developerów rezygnuje z agresywnego cache'owania w takich momentach. Niesłusznie.

Możemy zastosować pewien trick.

Nadal cache'ujmy agresywnie, ale oprócz tego uruchamiajmy żądanie XHR/Ajax do stworzonego przez nas API endpointu (niecache'ujący odpowiedzi), który zwracał będzie liczbę produktów w koszyku. Dzięki kilku liniom kodu JS możemy wtedy dynamicznie podmienić liczbę produktów w koszyku w takim elemencie, gdy strona się ładuje.

Przykład kodu endpointu API:

<?php

add_action('wp_loaded', function() {
    if (!empty($_REQUEST['get_cart_info'])) {
        $cart = WC()->cart;
        $cart_contents_count = $cart ? $cart->get_cart_contents_count() : 0;
    
        $response = [
            'products_count' => $cart_contents_count,
        ];
    
        echo json_encode($response);
        exit;
    }
});

Powyższy snippet kodu powinien zostać dodany do functions.php (lub innego jeśli korzystasz z Bedrocka). Próbowałem stworzyć customowy route API (poprzez register_rest_route()), jednak Woocommerce nie zwraca danych o koszyku (który bazuje na sesji) w RESTfulowych endpointach.

A tutaj kod odpowiadający za wysyłanie żądania do tego API i podmianę wartości produktów w koszyku w przycisku na frontendzie.

Taki kod można dodać np. przed znacznikiem zamykającym </body>.

document.addEventListener("DOMContentLoaded", function() {
    function updateProductsCounter() {
        const apiUrl = '/?get_cart_info=1';

        fetch(apiUrl)
            .then(response => {
                if (!response.ok) {
                    throw new Error('Network response was not ok');
                }
                return response.json();
            })
            .then(data => {
                if (data.hasOwnProperty('products_count')) {
                    const counterElement = document.getElementById('products-counter');
                    
                    if (counterElement) {
                        counterElement.textContent = data.products_count;
                    } else {
                        console.error('Element with ID #products-counter not found.');
                    }
                } else {
                    console.error('Invalid data format received from API.');
                }
            })
            .catch(error => {
                console.error('There was a problem with the fetch operation:', error);
            });
    }

    updateProductsCounter();
});

Dzięki temu sposobowi możemy ów problem rozwiązać. Globalne cache'owanie całej strony, a element strony jak licznik produktów w koszyku aktualizuje się na bieżąco, czyniąc żądanie do końcówki API, która zwraca obecną liczbę produktów (i podmienia liczbę w przycisku dynamicznie).

W ramach ciekawostki - textContent jest dużo szybszy niż innerText czy też innerHTML w JS. Tutaj możesz sobie samodzielnie przetestować. Metody .innerHTML i .innerText powodują rekalkulację stylów i reflow.

Demo:

  1. Wejdź na jeden z naszych projektów (Wordpress z Woocommerce, pełne cache'owanie).
  2. Przejdź na stronę produktu (np. ten).
  3. Powróć na stronę główną - u góry widoczna będzie aktualna liczba produktów w koszyku, zaktualizowana poprzez odpowiedź z naszego API (pomimo tego, że w dokumencie HTML nadal liczba wskazywać będzie na 0 z powodu cache'u strony sprzed dodania produktu do koszyka).

Demo koszyka Woocommerce po optymalizacji

Pełne cache'owanie przynosi wiele korzyści na powyższej stronie. Zerknij na dane z CrUX jak wspaniałe czasy TTFB odnotowuje ten projekt (stronę uruchomiliśmy w październiku 2023).

Polecany artykuł:

Technika Window Shopping Caching
Polega na cache'owaniu stron produktów do momentu, gdy użytkownik nie doda jakiegoś produktu do koszyka - ciekawe, aczkolwiek opisana przeze mnie technika nie będzie sprawiać potencjalnych problemów z pluginami oraz zawsze cache'uje strony produktów, nawet gdy coś się już znajduje w koszyku.

Jeśli chcesz więcej treści związanych z optymalizacją wydajności Wordpressa - zapisz się na bezpłatny newsletter.

Zoptymalizowany Wordpress

Zapisz się