TL; DR. Требуется , чтобы уровень запасов был отображен на странице с перечнем продуктов категории с минимальными дополнительными запросами / памятью, учитывая производительность, соответствующую структуре Magento.
После прочтения статьи Винай Копп о предварительной загрузке для масштабируемости .
Каков наилучший способ включить уровни запасов на страницах со списком продуктов категории ( list.phtml ) с минимальным количеством дополнительных запросов / загрузок для повышения производительности?
Мне известны несколько подходов:
afterLoad (), кажется, хорошо работает сmedia_gallery
включением без дополнительных запросов, однако я не смог реализовать тот же подход с инвентарем.
$attributes = $_product->getTypeInstance(true)->getSetAttributes($_product);
$media_gallery = $attributes['media_gallery'];
$backend = $media_gallery->getBackend();
$backend->afterLoad($_product);
Прямой SQL для сбора необходимых данных параллельно с коллекцией с product_id
ключом, например. Но ищу больше средств через рамки.
В настоящее время я просто загружаю stock_item
объект через:
$_product->load('stock_item')->getTotalQty();
Что работает, но я замечаю добавление дополнительных запросов, чтобы получить итоговые данные инвентаризации всех продуктов в коллекции.
...
__EAV_LOAD_MODEL__ (Mage_Catalog_Model_Product, id: stock_item, attributes: NULL)
__EAV_LOAD_MODEL__ (Mage_Catalog_Model_Product, id: stock_item, attributes: NULL)
__EAV_LOAD_MODEL__ (Mage_Catalog_Model_Product, id: stock_item, attributes: NULL)
...
странно, это работает. Волшебство происходит при загрузке Mage_Eav_Model_Entity_Abstract-> ($ object, $ entityId, $ attribute). Если $ attribute пуст, он вызовет loadAllAttribute ($ object). Таким образом, $ product-> load ('blah') загрузит все недостающие атрибуты, включая 'media_gallery' - Уильям Тран 19 ноября '14 в 4:45
Добавьте необходимые значения в уже загруженную коллекцию.
Очевидный простой подход добавления необходимых данных к производственному набору верхнего уровня в слое / фильтре, казалось бы, лучший подход.
Я заметил наблюдателя addInventoryDataToCollection () в Mage_CatalogInventory_Model_Observer, который звучит так, как будто этого можно достичь, но добавление метода в наблюдатель пользовательских модулей не представляется совместимым.
<events>
<catalog_product_collection_load_after>
<observers>
<inventory>
<class>cataloginventory/observer</class>
<method>addInventoryDataToCollection</method>
</inventory>
</observers>
</catalog_product_collection_load_after>
</events>
Что приводит к:
Предупреждение: неверный аргумент указан для foreach () в /app/code/core/Mage/CatalogInventory/Model/Resource/Stock/Item/Collection.php в строке 71
Ответы:
Реальная проблема здесь не в предварительной загрузке, а в точности. Относительно легко получить сумму запаса для коллекции продуктов:
Теперь с двумя запросами у вас есть вся необходимая информация. Их просто трудно связать друг с другом, что можно исправить с помощью ассоциативного массива
'product_id' => 'stock'
и написания геттера. Кроме того, addProductsFilter может быть оптимизирован:Это избавит вас от проверки типа и клонирования массива.
Проблема сейчас в блоке HTML кеша. Эта страница категории должна быть очищена, когда любой запас обновляется на продукт, содержащийся в нем. Насколько я знаю, это не является стандартным, поскольку только изменение состояния запаса очищает страницу категории, содержащую продукт (или, точнее, изменение видимости). Таким образом, вы должны будете наблюдать хотя бы
cataloginventory_stock_item_before_save
и, возможно, несколько других и очищать html-кэш блока (и кэш FPC) для этой страницы категории.источник
Я вижу, что вы уже приняли и, без сомнения, что-то уже реализовали, однако я хотел бы указать, насколько вы были близки,
addInventoryDataToCollection()
но похоже, что вы неверно процитировали файл конфигурации или мы используем совершенно разные версии magento. Моя копияCatalogInventory/etc/config.xml
имеет другой метод дляcatalog_product_collection_load_after
addInventoryDataToCollection()
называется в<sales_quote_item_collection_products_after_load>
Источник для
addStockStatusToCollection()
:Вы можете либо установить флаг
require_stock_items
для коллекции перед ее загрузкой, возможно, это не так просто для блока за списком категорий, или вы можете вызватьMage::getModel('cataloginventory/stock')->addItemsToProducts($productCollection)
вручную коллекцию после того, как она уже загружена.addItemsToProducts()
получает все StockItems для вас и прикрепляет их к вашей ProductCollectionисточник
Вы используете Varnish или FPC вообще или планируете в будущем?
Мы обнаружили, что по количеству дырок и запросов ESI, которые требуются в списках продуктов, почти не стоит использовать кэширование, поэтому выбрали другой подход.
Мы внедрили решение на одном веб-сайте, который использует запрос AJAX к пользовательскому контроллеру для получения данных о запасах продуктов, а javascript обрабатывает обновления DOM. Дополнительный запрос данных о запасе занимает ~ 100 мс, что никак не влияет на общее (видимое) время загрузки страницы. В сочетании с тем, что FPC снизит количество запросов страниц до 100 мс, у вас будет один быстрый сайт с низкими издержками производительности для отображения данных о запасах в списках продуктов.
Все, что вам нужно сделать по шаблону, это добавить productId в каждый html-упаковщик продуктов, чтобы ваш javascript знал, какие данные о запасах следует применять к каждому продукту.
Если вы посмотрите на дополнительные методы кэширования для фактических данных о запасах, вы можете опустить их намного ниже 100 мс, если бы не нужно было инициировать Mage / попадать в базу данных при каждом запросе.
Извините, если это не соответствует тому, что вы ищете, но мы нашли, что это лучший подход для масштабируемости и производительности в соответствии с нашими требованиями.
источник