AMP

AMP 中的客户端渲染

本指南概述了 AMP 中客户端渲染的可能性。默认情况下,AMP 页面是在服务器端渲染的。但是,在某些情况下,需要动态渲染数据,例如文章列表或用户购物车中的商品。

页面加载时渲染

虽然其名称可能具有误导性,但 amp-list 是 AMP 中客户端渲染的首选解决方案。amp-list 组件适用于各种客户端渲染需求。它可以渲染单个项目,也可以提供无限滚动和分页。它允许在页面加载时动态渲染内容,并且可以在 用户与页面交互后更新该内容。使用默认的加载指示器,或者构建自己的加载指示器,以获得最佳的用户体验,尤其是在从远程端点获取内容时。

amp-list 组件使用远程 JSON 端点、本地 amp-state 元素或本地 amp-script 元素,以在页面加载时渲染动态内容。默认使用 amp-list 要求每个 JSON 都具有 items 数组。

<amp-state id="weekdays">
    <script type="application/json">
    {
      "items": [
        "Monday",
        "Tuesday",
        "Wednesday",
        "Thursday",
        "Friday",
        "Saturday",
        "Sunday"
      ]
    }
    </script>
  </amp-state>
  <amp-list layout="fixed-height" 
            height="126" 
            src="amp-state:weekdays" 
            binding="no">    
    <template type="amp-mustache">
      {{.}}
    </template>
  </amp-list>
在 playground 中打开此代码段

可以通过使用 single-itemitems 属性进行调整。

  <amp-list layout="fixed-height" 
            height="18" 
            src="/documentation/examples/api/time" 
            binding="no" 
            single-item 
            items=".">
<template type="amp-mustache">
      The time is: {{time}}
    </template>  </amp-list>
在 playground 中打开此代码段

AMP 使用 amp-mustache 模板渲染内容。

为了获得最佳用户体验并保持 AMP 有效性,您必须预先定义渲染内容的高度。这可以通过以下布局完成

  • 响应式
  • 填充
  • 固定高度
  • 固定
  • 弹性项目

最佳做法是在 amp-list 元素上使用 fixed-height 布局属性。

为避免在加载内容时出现空白,请在 amp-list 组件中显示占位符

<amp-list height="32" width="80"
    src="/login-button"
    binding="no"
    items="."
    single-item>
    <template type="amp-mustache">
    {{#loggedIn}}
    <button>Logout</button>
    {{/loggedIn}}
    {{^loggedIn}}
    <button>Login</button>
    {{#loggedIn}}
  </template>
  <button disabled placeholder>Login</button>
</amp-list>
在 playground 中打开此代码段

如果使用多个 amp-list 实现,最佳做法是使用单个提取并共享数据。

从 JSON 端点渲染

当从 JSON 端点渲染而不是本地 amp-state 元素渲染时,请包含 binding 属性并将其设置为 no

<amp-list layout="fixed-height"
  height="100"
  src="/static/samples/json/examples.json"
  binding="no">
  <template type="amp-mustache">
    <div><a href="{{url}}">{{title}}</a></div>
  </template>
</amp-list>
在 playground 中打开此代码段

如果未指定 binding="no",amp-list 默认为 binding="always"。这意味着绑定在页面加载时执行,导致 AMP 阻止渲染并减慢页面速度。

从 amp-state 在页面加载时渲染

使用 amp-list 可以从页面加载时的 amp-bind 进行状态渲染。通过使用 src 属性值中的 amp-state 前缀,可以在页面加载时渲染来自本地 amp-state 元素的数据。

  <amp-state
    id="hikes">
    <script type="application/json">
          {
        "items": [
          {
            "title": "Coastal Sights",
            "city": "San Francisco",
            "length": "9.3 Miles",
            "hikeUrl": "/coast",
            "credit": "Photo by Joseph Barrientos",
            "imageUrl": "https://images.unsplash.com/photo-1449034446853-66c86144b0ad?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=800&q=60",
            "altDescription": "Photo of the Golden Gate Bridge."
          },
          {
            "title": "Through the Park",
            "city": "San Francisco",
            "length": "5 Miles",
            "hikeUrl": "/park",
            "credit": "Photo by Claudia Lorusso",
            "imageUrl": "https://images.unsplash.com/photo-1565086565717-351194b2488b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2850&q=80",
            "altDescription": "Photo of the Academy of Sciences in Golden Gate Park."
          },
          {
            "title": "Historic Brownstones",
            "city": "New York City",
            "length": "1.2 Miles",
            "hikeUrl": "#",
            "credit": "Photo by Rachel Martin",
            "imageUrl": "https://images.unsplash.com/photo-1542042238232-3a0b14425b71?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2850&q=80",
            "altDescription": "Photo of Brownstone building in New York City."
          },
          {
            "title": "Big Apple, Big Bites",
            "city": "New York City",
            "length": "3.2 Miles",
            "hikeUrl": "#",
            "credit": "Photo by Peter Bond",
            "imageUrl": "https://images.unsplash.com/photo-1515711127392-4c62a99c3393?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2854&q=80",
            "altDescription": "Photo of a diner."
          }
        ]
      }
    </script>
  </amp-state>
  <amp-list
    width="auto"
    height="300"
    layout="fixed-height"
    src="amp-state:hikes"
    [src]="hikes"
    binding="always"
    reset-on-refresh>

    <template type="amp-mustache">
      <div class="hike-display">
        <amp-img src="{{imageUrl}}" width="300" height="225" alt="{{altDescription}}"></amp-img>
        <br />
        <span class="image-credit">{{credit}}</span>
        <br />
        <a class="hike-title" href="{{hikeUrl}}">{{title}}</a>
        <br />
        <span class="image-credit">{{city}}</span>
      </div>
    </template>
    <div overflow class="list-overflow" style="background-color:red;">
      See more
    </div>
  </amp-list>
在 playground 中打开此代码段

从状态初始化 amp-list 的价值 这篇博文中阅读有关此实现的更多信息。

使用 amp-script 的自定义解决方案

对于需要自定义逻辑的客户端渲染,可以使用 amp-script。它允许自定义 JavaScript,并支持使用额外的 UI 库。与 amp-list 类似,只有在预先知道布局高度的情况下,才能使用 amp-script 在页面上渲染内容。

用户互动后渲染

在用户通过 amp-bind 互动后,您可以更改 amp-list 组件的 JSON 端点或 amp-state 变量。这允许在用户与您的页面互动后渲染新内容。

  <button on="tap:AMP.setState({
                colors: ['red', 'blue', 'green', 'yellow']
              })">Add list content</button>

  <amp-list width="0"
            height="0"
            [src]="colors" 
            [is-layout-container]="true" 
            items="." 
            binding="no">

    <template type="amp-mustache">
      {{.}}
    </template>
  </amp-list>
在 playground 中打开此代码段

更改 amp-list 组件中显示的内容可能需要更改大小。使用 [is-layout-container] 可绑定属性 将布局更改为 container,从而允许 amp-list 的子项定义其大小。

无需用户互动即可更新实时内容

amp-live-list 组件提供了一个包装器和最少的 UI 来实时更新内容。某些实时渲染内容的情况可能需要比 amp-live-list 提供的更多自定义。在这些情况下,amp-script 允许复杂的逻辑,并且可以使用其他 UI 库,例如 PreactVue.jsWebSocket API

但是,使用 amp-script 渲染实时内容有一些限制。这种方法允许创建任何非 AMP 元素,但只能创建 amp-imgamp-layout 组件。您可以通过将更新写入 amp-state 并通过 amp-list 渲染来解决此问题。

使用 amp-access 进行个性化设置

amp-access 组件允许个性化页面内容。此数据通过 JSON 端点提供,该端点使用 amp-mustache 来更新页面内容。

amp-access 的最大优势在于没有布局限制。这提供了很大的灵活性,但您必须确保它不会导致内容跳转。这可能会损害您的 Web Vital 分数。

渲染表单响应

amp-form 组件允许客户端渲染 JSON 响应。与 amp-mustache 一起使用时,表单能够传达提交成功和失败。