Cache Product Objects в WooCommerce 10.5 – какво прави и как да го включите

Какъв проблем решава Cache Product Objects

Всяко извикване на wc_get_product() създава нов WC_Product обект. WordPress вече кешира суровите данни – post data, meta, taxonomy terms – през собствения си object cache и стандартните post caching механизми. Проблемът не е в базата данни, а в процеса на хидрация: конструиране на обекта, задаване на свойства, зареждане на мета полета в структурата на класа. Тази операция отнема между 0.5 и 0.9 ms на продукт.

На product page с variable продукт и пет-шест активни разширения, един и същи продукт може да се зареди 8-12 пъти в рамките на единична HTTP заявка. Всяко зареждане минава през пълния цикъл на хидрация – дори данните вече да стоят в кеширащия слой на WordPress. За магазин с bundle продукти или subscription добавки, числото расте допълнително.

Cache Product Objects елиминира точно този overhead. Първото извикване на wc_get_product($id) минава по нормалния път и записва готовия обект в in-memory масив. Всяко следващо извикване за същото ID връща clone на кеширания обект вместо да минава отново през datastore-а.

Как работи на ниско ниво

Механизмът се намесва в WC_Product_Factory::get_product(). Преди да делегира към datastore, фабриката проверява вътрешен runtime масив (не persistent storage, не Redis, не база данни). Ако намери съвпадение по product ID, прави clone на обекта и го връща.

// Опростена илюстрация на логиката в WC_Product_Factory
$cached = ProductInstanceCache::get( $product_id );
if ( $cached ) {
    return clone $cached;
}

$product = $datastore->read( $product_id );
ProductInstanceCache::set( $product_id, $product );
return $product;

clone е критичен детайл тук. Без него всяка модификация на обекта от един плъгин би се отразила навсякъде в request-а, което би довело до трудни за диагностициране бъгове. С clone всеки caller получава собствено копие на обекта, което може да модифицира свободно без странични ефекти.

Инвалидирането на кеша се задейства автоматично при стандартни WordPress и WooCommerce действия: clean_post_cache, updated_post_meta, added_post_meta, deleted_post_meta, woocommerce_updated_product_stock, woocommerce_updated_product_sales и при save() операции през product datastore. Ако данните минават през официалните API-та, кешът се изчиства коректно.

Активиране и конфигурация

Функцията е изключена по подразбиране и се включва от WooCommerce > Settings > Advanced > Features с отметка на Cache Product Objects. Налична е от WooCommerce 10.5 нагоре – ако не я виждате, проверете версията на плъгина.

# Проверка на WooCommerce версията от WP-CLI
wp option get woocommerce_version
# Очакван резултат: 10.5.0 или по-нова

Програмно може да се активира и чрез филтър:

// Програмно активиране (за staging/testing среда)
add_filter( 'woocommerce_feature_product_instance_caching_enabled', '__return_true' );

Разширенията на трети страни декларират съвместимост с тази функция по начина, познат от HPOS прехода в WooCommerce. Дори без изрична декларация от страна на плъгина, функцията се прилага глобално за всички product loads в магазина.

Реални бенчмаркове от WooCommerce екипа

Официалните тестове са направени с активен WooCommerce All Products for Subscriptions, който предизвиква допълнително зареждане на продукти при различни операции. Резултатите варират в зависимост от типа продукт и действието на потребителя.

Variable Product - View Product Page:   -160ms до -227ms (~9-12%)
Variable Product - Add to Cart:         -235ms до -250ms (~12-13%)
Bundle Product  - Place Order:          -165ms до -234ms (~6-12%)
Simple Product  - Place Order:          -22ms  до -56ms  (~2-6%)

Simple продуктите показват по-скромно подобрение, защото се зареждат по-рядко повторно в рамките на checkout. Variable и bundle продуктите печелят повече – variations и bundled items предизвикват множество wc_get_product() извиквания за едни и същи ID-та. Магазин само с прости продукти и без тежки разширения може изобщо да не забележи промяна.

Магазин с WooCommerce бисквитки, subscription добавки и custom pricing логика ще види осезаемо подобрение на checkout и product page response time. За магазини с над 500 variable продукта и 10+ активни разширения, спестените милисекунди се натрупват – особено при checkout, където WooCommerce зарежда продуктите от количката, прилага отстъпки, валидира наличности и калкулира данъци в рамките на един request.

Кога кешът може да доведе до проблеми

Директните SQL заявки са основният рисков фактор.

Ако разширение обновява product meta с $wpdb->update() без да извика clean_post_cache() или wp_cache_delete(), кешираният обект остава неактуален за остатъка от заявката. Следващото извикване на wc_get_product() ще върне стария обект от кеша, не обновените данни. При стандартен продуктов поток (admin save, REST API update, WooCommerce import) проблемът не възниква.

// ГРЕШЕН подход - кешът няма да се инвалидира
$wpdb->update(
    $wpdb->postmeta,
    array( 'meta_value' => '29.99' ),
    array( 'post_id' => $product_id, 'meta_key' => '_price' )
);

// ПРАВИЛЕН подход - тригерира WordPress hooks
update_post_meta( $product_id, '_price', '29.99' );
// Или поне ръчно инвалидиране след директен SQL
clean_post_cache( $product_id );

WeakMap зависимости са друг ъглов случай, който засяга по-специфични разширения. Ако плъгин съхранява допълнителни данни за продуктов обект чрез WeakMap, clone операцията създава нов обект, който няма съответстващ запис в тази WeakMap. Към момента няма hook, който да се задейства при клониране от кеша, така че разработчиците на подобни плъгини трябва да преработят подхода си.

Взаимодействие с persistent object cache

Cache Product Objects и persistent object cache (Redis, Memcached) работят на различни слоеве и не се конкурират. Persistent кешът съхранява сурови данни между заявки – post rows, meta rows, option стойности. Product instance cache-ът работи само в рамките на единична заявка и пази вече конструирани PHP обекти.

Заявка 1:
  wc_get_product(42)
    -> WordPress object cache (Redis) -> post data, meta    [HIT/MISS]
    -> WC_Product hydration                                 [~0.7ms]
    -> Product Instance Cache: SET

  wc_get_product(42)  // второ извикване
    -> Product Instance Cache: HIT -> clone                 [~0.05ms]
    // Спестява 0.7ms хидрация

Заявка 2 (нов HTTP request):
  // Product Instance Cache е празен
  wc_get_product(42)
    -> WordPress object cache (Redis) -> post data, meta    [HIT]
    -> WC_Product hydration                                 [~0.7ms]

За оптимална производителност двата кеширащи слоя се допълват. Redis елиминира SQL заявки между page loads, а product instance cache елиминира повторна хидрация в рамките на единична заявка. Сайтове, които разчитат на page-level кеширане, ще имат по-малко полза от тази функция, защото PHP изобщо не се изпълнява при пълен cache hit на ниво Nginx или Varnish.

Transients и product data – различен механизъм

WooCommerce използва transients за различни продуктови данни: цени на вариации, свързани продукти, product counts по категории. Тези transients са persistent – записват се в wp_options таблицата (или в Redis, ако има external object cache). Изчистват се ръчно от WooCommerce > Status > Tools > Clear Transients или програмно с wc_delete_product_transients().

// Изчистване на transients за конкретен продукт
wc_delete_product_transients( $product_id );

// Автоматично изчистване при промяна на свойства
add_action( 'woocommerce_product_object_updated_props', function( $product ) {
    wc_delete_product_transients( $product->get_id() );
});

Product instance cache-ът няма нищо общо с transients. Не записва данни в базата, не персистира между заявки и не изисква ръчно изчистване. Двата механизма решават различни проблеми и не конфликтуват помежду си при стандартна конфигурация. WooCommerce 10.5 подобрява и transient кеширането за вариационни цени с нов алгоритъм за хеширане, който намалява ненужните инвалидации.

Диагностика с Query Monitor

За да проверите дали кешът работи на вашия сайт, инсталирайте Query Monitor. В секцията Object Cache ще видите броя cache hits и misses за различни групи. По-конкретно, следете за повторни извиквания на wc_get_product() с еднакви ID-та в рамките на една page load.

// Debug log за проследяване на product loads
add_action( 'woocommerce_before_single_product', function() {
    add_filter( 'woocommerce_product_class', function( $classname, $product_type, $product_id ) {
        error_log( sprintf(
            '[ProductCache] Loading product #%d (%s) at %.4f',
            $product_id, $product_type, microtime( true )
        ));
        return $classname;
    }, 10, 3 );
});

Ако след активиране на функцията видите, че определен продукт се зарежда само веднъж в лога (вместо 5-6 пъти), кешът работи коректно. Следващите зареждания минават през clone операцията, която не тригерира product_class филтъра и съответно не генерира допълнителни записи.

Стъпки за безопасно активиране в production

Активирайте функцията първо на staging среда. Проверете основните потоци: product page, add to cart, checkout, order confirmation. Обърнете внимание на цените – ако custom pricing плъгин разчита на директни SQL заявки, цените може да се покажат неактуални.

За WP-CLI потребители, бърз тест на производителността преди и след:

# Измерване на response time преди активиране
wp eval 'update_option("woocommerce_feature_product_instance_caching_enabled","no");'
ab -n 50 -c 1 https://yoursite.com/product/your-variable-product/

# Активиране и повторен тест
wp eval 'update_option("woocommerce_feature_product_instance_caching_enabled","yes");'
ab -n 50 -c 1 https://yoursite.com/product/your-variable-product/

Сравнете средните стойности на Time per request. Разликата ще е най-видима при variable продукти с много вариации и при bundle продукти с десетки подпродукти. Ако видите регресия или грешки при checkout, деактивирайте функцията и проверете за несъвместими разширения чрез debug log-а.

Често задавани въпроси

  1. Какво точно кешира Cache Product Objects в WooCommerce?

    Функцията кешира напълно инстанцираните WC_Product обекти в паметта за времето на текущата HTTP заявка. Самите данни от базата (post data, meta, taxonomy terms) вече се кешират от WordPress – тази функция спестява повторната хидрация на обектите.

  2. Трябва ли ми Redis или Memcached, за да работи Cache Product Objects?

    Не. Кешът е in-memory и живее само в рамките на единична заявка. Не зависи от persistent object cache като Redis или Memcached и не записва нищо в базата данни.

  3. Как да включа Cache Product Objects?

    Отидете в WooCommerce > Settings > Advanced > Features и активирайте опцията Cache Product Objects. Функцията е налична от WooCommerce 10.5 нагоре.

  4. Може ли Cache Product Objects да счупи плъгини от трети страни?

    Ако плъгин променя продуктови данни с директни SQL заявки без да извика clean_post_cache(), кешираният обект ще остане неактуален до края на заявката. Повечето плъгини, които използват стандартните WooCommerce API-та, няма да имат проблем.

  5. Колко подобрение на производителността да очаквам от Cache Product Objects?

    Зависи от броя разширения и колко пъти се зарежда един и същи продукт в рамките на заявка. Официалните бенчмаркове показват между 2% и 13% ускорение при различни операции – от прост checkout до зареждане на variable product страница.

Какво представляват бисквитките? „Бисквитките“ са малки парчета данни, съхранявани в текстови файлове, които се съхраняват на вашия компютър или друго устройство, когато уебсайтове се зареждат в браузър. Това позволява на…

WooCommerce MCP е нативна интеграция на Model Context Protocol в WooCommerce, която позволява на AI клиенти като Claude и Cursor да работят директно с продукти и поръчки. Статията покрива архитектура,…

С наближаващото приемане на еврото като официална валута в България от 1 януари 2026 г., е време да се уверите, че вашият онлайн магазин е готов. Websycraft предлага безплатен WordPress…

Laravel 13 излезе на 17 март 2026 г. с нулев брой breaking changes спрямо Laravel 12. Тази статия разглежда конкретните разлики между двете версии – от PHP 8.3 изискването и…
Full-Text Search индексите в HPOS превръщат бавното LIKE търсене на поръчки в MySQL MATCH…AGAINST заявки. Разликата при магазини с над 50 000 поръчки е от 4-7 секунди на под 0.5…
WooCommerce MCP е нативна интеграция на Model Context Protocol в WooCommerce, която позволява на AI клиенти като Claude и Cursor да работят директно с продукти и поръчки. Статията покрива архитектура,…