优化AEM站点缓存

优化AEM架构中的缓存是显着提升性能的最快速的方法之一。 本文重点介绍如何优化AEM架构中可用的各种缓存。

描述 description

环境

Adobe Experience Manager

问题/症状

如何优化AEM站点缓存?

AEM架构和缓存

在所有AEM体系结构中,用户访问您的站点时会遇到多个缓存层。 在标准AEM架构中,有4个缓存层需要考虑。 这包括Web浏览器、CDN、调度程序和AEM实例。

screenshot_2018-03-25160541

解决方法 resolution

A.浏览器缓存

用户在重复访问您的网站时遇到的第一个缓存级别是他们自己的浏览器。 通常,浏览器级别的缓存是通过 Cache-Control: max-age=… 响应 标题. 此 max-age 设置可告知浏览器,在尝试“重新验证”或再次从站点申请缓存之前,应当缓存文件的时间长度(以秒为单位)。 这个缓存的概念 max-age 通常称为“缓存过期时间”或TTL(“生存时间”)。

中提供了各种选项(或“指令”), Cache-Control 影响缓存方式的标头。 以下是一些常见的指令:

  1. private - Cache-Control标头中的private指令只允许将文件缓存在浏览器,而非类似CDN这样的中间缓存中。 这项指令的实用场合:您的页面包含个性化/特定于用户的内容。

    用法示例: Cache-Control: max-age=300, private

  2. s-maxage - Cache-Control标头中的s-maxage指令允许您为类似CDN这样的共享缓存,设置不同的TTL。 当设置了该值后,浏览器将运用max-age中设置的内容,而其他缓存则改为遵循s-maxage设置。

    用法示例: Cache-Control: max-age=600, s-maxage=300

现代浏览器都支持 Cache-Control 但是,标头HTTP/1.0中存在一些旧的已弃用标头,仍可能会对缓存产生影响。 这些标头包括 过期Pragma. 如果您不需要支持非常旧的浏览器,那么请不要发送这些响应标头。

除了缓存之外,“重新验证”也是一个重要的概念。 重新验证依赖于 上次修改时间(响应) / If-Modified-Since (请求)标头,以及 ETag (响应) / If-None-Match (请求)标头。

测试浏览器时请小心:

在Google Chrome中测试缓存时,如果您通过https进行测试,并且您具有自签名证书,则不会缓存任何内容。 当存在不受信任或无效的证书时,Chrome将不会缓存响应或执行重新验证。

关于Dispatcher的注释:

AEM Dispatcher v4.2.3及更早版本存在一个问题,该问题会导致 /enableTTL 仅缓存使用 max-age 指令。 这意味着,即使 私有s-maxage 设置指令后,如果符合以下条件,它仍会缓存 max-age 设置。 这个问题会在Dispatcher 4.2.4及更高版本中得以解决。

B. CDN缓存

A CDN或“内容分发网络”,是一种Web服务器的分布式网络,旨在从距离用户最近的位置缓存和提供内容。 这会减少网络跃点数以及用户计算机与您的内容之间的距离,从而减少 《往返时间》 (RTT). RTT是浏览器向您的站点发送请求并接收响应所花费的时间。 由于CDN提供商领域中的竞争,CDN变得非常经济高效。 因此,可以轻松决定使用CDN来访问您的站点。 如果您尚未使用CDN,则务必应该在您的站点中融入CDN。

有许许多多的CDN提供商,每一家提供商提供的特征和配置各不相同。

CDN缓存的工作原理

CDN会按照与浏览器类似的规则缓存内容。 他们依靠 Cache-Control HTTP 响应 标题,通常回退到 过期 标头(如果否) Cache-Control 标头已找到。

大多数CDN都提供了触发手动刷新缓存的方法。  在很多情况下,当涉及传播到包含您的文件的所有边缘服务器时,缓存刷新会存在一些延迟(例如15分钟)。

优化CDN使用

为了确保在CDN中以最佳方式缓存文件,需执行以下操作:

  1. 使用支持 stale-while-revalidatestale-if-error 中的指令 Cache-Control 标题。

    • stale-while-revalidate — 当缓存文件已过期且CDN在检索新的缓存文件时,该指令可告知CDN提供此文件的旧(即,已缓存的)版本。
    • stale-if-error — 同样,在重新验证期间,如果源缓存文件的响应包含错误,该指令可告知CDN提供此文件的旧(即,已缓存的)版本。
  2. 对于所有未经过预压缩的文件类型,GZip压缩会做出响应。

    您应该从调度程序级别执行这项操作。 这将确保减少发送到CDN的字节数。 CDN通常按传输的字节数收费,因此压缩响应可降低成本。

    • 在Dispatcher级别启用GZip压缩: Apache - 使用mod_deflate. 当mod_deflate使用Vary标头时,应务必小心。 在某些情况下,Vary标头可能会导致CDN和浏览器完全跳过缓存。

    • Microsoft IIS — 使用 动态压缩.

    • 不允许对大型文件或已压缩的文件执行gzip压缩。 请注意,大多数的图像和视频格式均已预先压缩。 在Web服务器级别上动态压缩这些文件,会付出高昂的性能成本。

      • 在Apache上,这项操作可通过AddOutputFilterByType指令来完成: AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript
      • 在IIS上,这可以通过以下进行控制 < dynamicType> 配置。
    • 如果您的CDN提供商支持 Edge-side Include (ESI)然后利用此功能。 可以使用ESI对AEM组件进行分组。 为此,请使用Apache \[ Sling Dynamic包含\] 或实施自定义解决方案。 当您拥有许多静态页面,但却需要在页面的某些部分提供更多的动态内容时,这项功能会比较有用。 对于这些情况,您实际上是要将页面分组为多个CDN文件。 这样一来,您便可以在不同的时间段缓存页面的不同部分。

受欢迎的CDN提供商

以下是一些流行的CDN提供商的列表:

还有好几种,每一种都有不同的功能。

注意:

当心 Vary 响应标头。 在某些情况下, Vary 可能会导致CDN和浏览器完全跳过缓存。 作为一项常规经验,请避免添加 Vary 除了 Vary: Accept-Encoding (仅当响应经过gzip压缩后应用)。 换言之,如果您需要“变换”响应的输出,请使用不同的URL。

例如,如果适用于移动设备与桌面设备的不同HTML版本不同,则使用不同的URL。 这将允许CDN和浏览器更有效地进行缓存。

C. AEM Dispatcher缓存

如果CDN缓存已过期,则请求将发送到AEM Dispatcher缓存。 在此级别,可以执行许多操作来优化缓存。

由于这是一个较大的主题,请参阅 本文 有关如何优化Dispatcher缓存的详细信息。

D. AEM Publish实例

在AEM级别,应当执行几项操作来优化各种缓存层:

  1. 设置以下AEM默认未设置的HTTP响应标头。

    1. Cache-Control: max-age=… — 要设置此标头,请执行以下操作: ACS Commons - Dispatcher TTL 或者,您可以实施自定义代码来进行设置。
    2. 上次修改时间 — 如果页面内容保持相对静态(例如,一篇文章),则可以将其last-modified标头设置为“cq:lastModified date/time”(即,最近一次修改这篇文章的时间)。 但是,如果页面是动态的,并且组件内容中包含JCR查询结果,则最好将其设置为使用当前的日期/时间。
    3. ETag — 如果您决定使用此选项而不是 上次修改时间,您可以编写一个 ReplicationEventListener 侦听页面激活并生成页面内容的md5哈希值。 可将其设置为author实例上该页面jcr:content节点上的属性。 在复制页面时,它会发送到发布实例。 对于内容相对静态的页面组件,这个标头可以正常工作;但是,如果页面包含动态内容或引用了大量内容,则必须忽略(或计算)ETag。
  2. 如果站点包含个性化/动态内容:

    1. 使用 Apache Sling Dynamic包含 对内容进行分组,以便可以在不同时段缓存页面的不同部分。

      1. 可以使用以下技术完成缓存:

        • CDN上的Edge-side Include (ESI)
        • Web服务器上的服务器端包含(SSI)
        • 浏览器中的异步Javascript和XML (AJAX)
      2. 可将页面上的组件分组为单独的请求,以便在不同时间段进行缓存。 相对静态的页面部分可以缓存较长的时段。

    2. 考虑使用 ACS Commons的HTTP缓存功能.

  3. 优化客户端库。

    1. 在客户端库上启用压缩。

    2. 如果客户端库中的文件已预先缩小,则在该客户端库上禁用压缩。 编辑cq:ClientLibraryFolder节点:

      1. 将属性jsProcessor设置为字符串类型[ ] 值为min:none
      2. 并将属性cssProcessor设置为String类型[ ] 值为min:none
      3. 查看更多详细信息, 此处.
    3. 嵌入客户端库 以缩小并减少js和css文件。

    4. 实施 ACS Commons的versioned-clientlibs 以允许CDN和Dispatcher较长的时段缓存js和css文件。

recommendation-more-help
3d58f420-19b5-47a0-a122-5c9dab55ec7f