默认情况下,Magento 中的所有页面都是可缓存的,但您可以在必要时禁用缓存(例如,付款方式返回页面、调试页面或 AJAX 数据源)。
缓存
如果您需要每秒刷新数据,请考虑使用缓存。 从缓存中请求内容比为每个请求生成内容要快。
只有 GET 和 HEAD 方法是可缓存的。
禁用或启用缓存
将 cacheable=”false” 属性添加到布局中的任何块以禁用缓存:
<block class="Magento\Paypal\Block\Payflow\Link\Iframe" template="payflowlink/redirect.phtml" cacheable="false"/>
如果布局中至少存在一个不可缓存的块,Magento 将禁用页面缓存。
在 default.xml 文件中使用 cacheable=”false” 可以禁用站点上所有页面的缓存。
您还可以禁用带有 HTTP 标头的缓存。 使用控制器返回一个包含操作缓存方法的对象。
定义缓存行为
您可以使用 Admin 来定义缓存策略,也可以在控制器中以编程方式定义它们:
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
class DynamicController extends Action
{
protected $pageFactory;
public function __construct(
Context $context,
PageFactory $resultPageFactory
) {
parent::__construct($context);
$this->pageFactory = $resultPageFactory;
}
/**
* This action render random number for each request
*/
public function execute()
{
$page = $this->pageFactory->create();
//We are using HTTP headers to control various page caches (varnish, fastly, built-in php cache)
$page->setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0', true);
return $page;
}
}
配置全页缓存
大多数缓存服务器和代理使用 URL 作为缓存记录的键。但是,Magento URL 的唯一性不足以允许仅通过 URL 进行缓存。 URL 中的 Cookie 和会话数据也可能导致不良副作用,包括:
缓存存储中的冲突
不需要的信息泄露(例如,法语网站在英语网站上部分可见,客户群的价格在公共场合可见等)
为了使每个缓存的 URL 完全唯一,我们使用 HTTP 上下文变量。上下文变量使 Magento 应用程序能够基于以下内容在同一 URL 上提供不同的内容:
客户群
选择的语言
选定的商店
选择的货币
客户是否登录
上下文变量不应特定于单个用户,因为变量用于公共内容的缓存键。换句话说,每个用户的上下文变量导致为每个用户缓存在服务器上的内容的单独副本。
Magento 根据所有上下文变量 (\Magento\Framework\App\Http\Context::getVaryString) 生成哈希。哈希值和当前 URL 用作缓存存储的键。
例如,让我们声明一个上下文变量,该变量仅向成人客户显示饮料目录和广告。以下代码片段将为 18 岁以下的用户创建 Magento 中每个页面的副本。
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
use Magento\Customer\Model\Session;
use Magento\Framework\App\Http\Context;
/**
* Plugin on \Magento\Framework\App\Http\Context
*/
class CustomerAgeContextPlugin
{
public function __construct(
Session $customerSession
) {
$this->customerSession = $customerSession;
}
/**
* \Magento\Framework\App\Http\Context::getVaryString is used by Magento to retrieve unique identifier for selected context,
* so this is a best place to declare custom context variables
*/
public function beforeGetVaryString(Context $subject)
{
$age = $this->customerSession->getCustomerData()->getCustomAttribute('age');
$defaultAgeContext = 0;
$ageContext = $age >= 18 ? 1 : $defaultAgeContext;
$subject->setValue('CONTEXT_AGE', $ageContext, $defaultAgeContext);
}
}
subject->setValue
参数指定新人上下文的值,用于在缓存密钥生成期间为新人和已经收到X-的用户保证奇偶校验Magento-Vary
cookie。
X-Magento-Vary
cookie
使用X-Magento-Vary
cookie 在 HTTP 层传输上下文。 HTTP 代理可以配置为根据 cookie 和 URL 计算缓存的唯一标识符。例如,使用以下内容:
sub vcl_hash {
if (req.http.cookie ~ "X-Magento-Vary=") {
hash_data(regsub(req.http.cookie, "^.*?X-Magento-Vary=([^;]+);*.*$", "\1"));
}
... more ...
}
使公开内容无效
您可以在实体更改后立即清除缓存内容。 Magento 使用 IdentityInterface 将应用程序中的实体与缓存内容链接起来,并知道在实体更改时要清除的缓存。
本节向您展示如何告诉 Magento 在您更改实体时要清除哪些缓存。
首先,您的实体模块必须实现 Magento/Framework/DataObject/IdentityInterface,如下所示:
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
use Magento\Framework\DataObject\IdentityInterface;
class Product implements IdentityInterface
{
/**
* Product cache tag
*/
const CACHE_TAG = 'catalog_product';
/**
* Get identities
*
* @return array
*/
public function getIdentities()
{
return [self::CACHE_TAG . '_' . $this->getId()];
}
}
其次,块对象还必须实现 Magento/Framework/DataObject/IdentityInterface 如下:
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
use Magento\Framework\DataObject\IdentityInterface;
class View extends AbstractProduct implements IdentityInterface
{
/**
* Return identifiers for produced content
*
* @return array
*/
public function getIdentities()
{
return $this->getProduct()->getIdentities();
}
}
Magento 使用缓存标签来创建链接。 缓存存储的性能直接依赖于每个缓存记录的标签数量,所以尽量减少标签数量,只将它们用于生产模式下使用的实体。 换句话说,不要对与商店设置相关的操作使用失效。
仅使用 HTTP POST 或 PUT 方法来更改状态(例如,添加到购物车、添加到心愿单等)并且不要期望看到这些方法的缓存。 使用 GET 或 HEAD 方法可能会触发缓存并阻止更新私有内容。
可缓存页面清单
页面使用 GET 请求
页面仅呈现可缓存的块
页面呈现时没有敏感的私人数据; 会话和客户 DTO 对象为空
特定于当前会话(客户)和页面的功能应使用 JavaScript 编写(例如,相关产品列表应排除购物车中已有的项目)
模型和块级别应该标识自己的失效支持
如果您计划使用相同的 URL 显示不同的公共内容,请声明一个自定义上下文变量
不可缓存的页面清单
使用 POST 请求修改 Magento 状态(例如,添加到购物车、愿望清单等)
无法缓存的块应在布局中标记为不可缓存。 但是,请注意,向页面添加不可缓存的块会阻止整页缓存缓存该页面。
不使用布局的控制器应该设置 no-cache HTTP headers
本文来源于:
Magento2.x企业级开发实战