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>
可以通过使用 single-item
和 items
属性进行调整。
<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>
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>
如果使用多个 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>
如果未指定 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>
在 从状态初始化 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>
更改 amp-list 组件中显示的内容可能需要更改大小。使用 [is-layout-container]
可绑定属性 将布局更改为 container
,从而允许 amp-list 的子项定义其大小。
无需用户互动即可更新实时内容
amp-live-list
组件提供了一个包装器和最少的 UI 来实时更新内容。某些实时渲染内容的情况可能需要比 amp-live-list 提供的更多自定义。在这些情况下,amp-script
允许复杂的逻辑,并且可以使用其他 UI 库,例如 Preact 或 Vue.js 和 WebSocket API。
但是,使用 amp-script 渲染实时内容有一些限制。这种方法允许创建任何非 AMP 元素,但只能创建 amp-img
和 amp-layout
组件。您可以通过将更新写入 amp-state 并通过 amp-list 渲染来解决此问题。
使用 amp-access 进行个性化设置
amp-access
组件允许个性化页面内容。此数据通过 JSON 端点提供,该端点使用 amp-mustache 来更新页面内容。
amp-access
的最大优势在于没有布局限制。这提供了很大的灵活性,但您必须确保它不会导致内容跳转。这可能会损害您的 Web Vital 分数。
渲染表单响应
amp-form
组件允许客户端渲染 JSON 响应。与 amp-mustache
一起使用时,表单能够传达提交成功和失败。
-
由 @CrystalOnScript 撰写
并由 @sbenz 提供贡献