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 有效,您必须预定义呈现内容的高度。这可以通过以下布局来完成
响应式
填充
固定高度
固定
flex-item
最佳做法是在 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 从 state 初始化的价值 博客文章中详细了解此实现。
通过 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 协助编写