AMP是什么
Google 前沿的 AMP 「 Accelerated Mobile Pages 」技术,能使用户从搜索引擎当中进入我们页面的体验得到一个极大的提升。
AMP组成
AMP HTML
AMP HTML 本质上是使用自定义 AMP 属性扩展的 HTML。最简单的 AMP HTML 文件如下所示:
<!doctype html>
<html ⚡>
<head>
<meta charset="utf-8">
<link rel="canonical" href="hello-world.html">
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>
<script async src="https://cdn.ampproject.org/v0.js"></script>
</head>
<body>Hello World!</body>
</html>
复制代码
AMP 网页通过 HTML 标记被搜索引擎和其他平台的<link rel="">
发现。
AMP JS
AMP JS 库 可实现所有 AMP 的最佳性能做法、管理资源加载,并为您提供上面提到的自定义标记,所有这些都是为了确保快速渲染您的网页。
最重大的优化之一就是它可使来自外部资源的所有内容保持异步,让网页中的任何内容都能毫无阻碍地渲染。
其他性能技术还包括:将所有 iframe 沙盒化,加载资源之前对网页上每个元素的布局进行预先计算,以及禁用性能缓慢的 CSS 选择器。
AMP Cache
AMP 缓存是一种基于代理的内容传送网络 (CDN),用于传送有效的 AMP 文档。AMP 缓存旨在:
- 仅提供有效的 AMP 网页。
- 让 AMP 网页能够安全且高效地预加载。
- 对内容执行额外的性能优化措施,以提升用户体验。
谁会请求缓存的AMP页面?
缓存的 AMP 网页会被各类平台(如 Google 搜索、Google 新闻和 Cloudflare)和移动应用访问。移动应用可通过网址(请参阅 Google 的 AMP URL API)或通过渐进式网页应用中的跨源 XHR(详情请见嵌入 AMP 网页并将其用作数据源)关联到缓存的 AMP 内容。
如何实现?
平台可通过 <html ⚡>
或 <html amp>
标记发现您的 AMP 内容,进而缓存该内容。例如,Google 搜索会抓取内容;对于任何已被识别出的有效 AMP 网页,系统都会自动将相应内容添加到 Google AMP 缓存中。
AMP的好处
- 快速加载
- 减少页面复杂度
- Google搜索结果对AMP页面有预加载处理,更快地到达页面
AMP 如何提升性能
仅允许异步脚本(防止阻塞页面)
由于JavaScript也会阻塞 DOM 的构建,延缓页面渲染,AMP 仅允许异步 JavaScript。
AMP 页面不能包含作者自己编写的任何 JavaScript。 使用自定义 AMP 元素而不是 JavaScript 来处理互动页面功能。
例外: iframe 中允许第三方 JS,不过它不会阻塞渲染。
静态确定所有资源的大小(减少页面回流)
图片、广告或 iframe 等外部资源必须在 HTML 中声明其大小,以便 AMP 可以在资源下载前确定每个元素的大小和位置。
AMP 不必等待所有资源都下载完成就可以直接加载页面布局。
AMP 将文档布局与资源布局脱钩。 布局整个文档(包括字体)只需要一个 HTTP 请求。
由于 AMP 经过优化,可以在浏览器中避免会消耗大量资源的样式重新计算和布局,因此资源加载时不会存在任何重新布局。
不让扩展机制阻塞渲染(拓展组件不会阻塞渲染)
<script async custom-element="amp-iframe" src="https://cdn.ampproject.org/v0/amp-iframe-0.1.js"></script>
复制代码
CSS 必须内嵌并具有大小限值(减少http请求)
CSS 会阻碍所有渲染和页面加载,并且往往变得臃肿。 在 AMP HTML 页面中,只允许内嵌样式。 与大多数网页相比,这一限制可从关键渲染路径中移除 1 个或多个 HTTP 请求。
另外,内嵌样式表最大为 50 KB。 虽然此大小对非常复杂的页面来说已经足够大,页面作者仍需要践行良好的 CSS 风格。
设定资源加载的优先级(懒加载)
AMP 可以控制所有资源下载:它会设定资源加载的优先级、仅加载需要的内容,以及预提取具有延迟加载特性的资源。
下载资源时,AMP 会优化下载,以便优先下载当前最重要的资源。
图片和广告仅在位于首屏、用户可能会查看或者快速滚动到它们时下载。
AMP 还会预提取具有延迟加载特性的资源。 资源加载尽可能晚,但预提取则尽可能早。 这样一来,加载速度非常快,不过只有在资源实际向用户显示时才会使用 CPU。
瞬时加载页面(预渲染首屏)
大量使用全新的 preconnect API,从而确保 HTTP 请求的速度尽可能快。
这样,在用户明确指明想要前往某个页面之前,该页面就可以渲染完成;在用户实际选择页面之前,页面就可能已经准备就绪,进而实现瞬时加载。
所有网络内容都可以应用预渲染,但这一过程也需要使用一些带宽和 CPU。 AMP 已经过优化,可以减少这两种因素的消耗。预渲染仅下载首屏资源,并且不会渲染可能要消耗大量 CPU 的资源。
在 AMP 文档进行预渲染以实现瞬时加载时,实际上只会下载首屏资源。
在 AMP 文档进行预渲染以实现瞬时加载时,不会下载可能要使用大量 CPU 的资源(例如第三方 iframe)。
如何进行AMP页面开发
-
创建页面
<!doctype html> <html ⚡> <head> <meta charset="utf-8"> <script async src="https://cdn.ampproject.org/v0.js"></script> <title>Hello AMP world</title> <link rel="canonical" href="hello-world.html"> <meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1"> <style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript> </head> <body> <h1>Hello AMP World!</h1> </body> </html> 复制代码
- 以文档类型
<!doctype html>
开头 - 包含顶级
<html ⚡>
标记(也接受<html amp>
) - 包含
<head>
和<body>
标记(这些标记在 HTML 中是可选的) - 在
<head>
内包含一个<link rel="canonical" href="$SOME_URL">
标记,该标记指向 AMP HTML 文档的常规 HTML 版本,或在此类 HTML 版本不存在的情况下指向文档本身 - 包含
<meta charset="utf-8">
标记作为<head>
标记的第一个子项 - 在
<head>
标记内包含<meta name="viewport" content="width=device-width,minimum-scale=1">
标记。还建议包括initial-scale=1
- 包含
<script async src="https://cdn.ampproject.org/v0.js"></script>
标记作为<head>
中的最后一个元素(这样做将会包括并加载 AMP JS 库) - 在其
<head>
标记内包含以下内容:
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript> 复制代码
- 以文档类型
-
向网页添加组件
<amp-img src="https://www.ampproject.org/examples/images/amp.jpg" width="900" height="508" layout="responsive"></amp-img> 复制代码
<!-- this script is required for amp-youtube and must be in the <head> section --> <script async custom-element="amp-youtube" src="https://cdn.ampproject.org/v0/amp-youtube-0.1.js"></script> <amp-youtube data-videoid="9Cfxm7cikMY" layout="responsive" width="480" height="270"></amp-youtube> 复制代码
-
设计元素样式
要为 AMP 网页上的元素设计样式,请向文档的
<head>
中名为<style amp-custom>
的内嵌样式表添加 CSS:<style amp-custom> amp-img { margin: 0.5em; } body { max-width: 900px; } </style> 复制代码
-
添加分析工具
<amp-analytics type="googleanalytics">
<script type="application/json">
{
"vars": {
"account": "UA-YYYY-Y"
},
"triggers": {
"default pageview": {
"on": "visible",
"request": "pageview",
"vars": {
"title": "Name of the Article"
}
}
}
}
</script>
</amp-analytics>
复制代码
-
准备好页面分发
在某些情况下,您可能希望同时拥有同一页面(例如,新闻文章)的非 AMP 版本和 AMP 版本。请考虑此情况:如果 Google 搜索找到该页面的非 AMP 版本,它如何知道该页面有 AMP 版本?
双页面:
向非 AMP 页面中添加以下内容:
<link rel="amphtml" href="https://www.example.com/url/to/amp/document.html"> 复制代码
向 AMP 页面中添加以下内容
<link rel="canonical" href="https://www.example.com/url/to/full/document.html"> 复制代码
单页面:
如果您只有一个页面,并且该页面是 AMP 页面,则您仍必须向其中添加规范链接,该链接只是指向自身:
<link rel="canonical" href="https://www.example.com/url/to/amp/document.html">
复制代码
AMP的一些限制
!important
限定符 禁止使用该限定符。 这是 AMP 网页能够强制实施其元素尺寸设定规则的必要条件。<link rel=”stylesheet”>
禁止使用,但 自定义字体除外。script
标签.application/ld+json
除外 更多规范和限制 https://www.ampproject.org/zh_cn/docs/fundamentals/spec
注意事项
-
做好跨域请求处理
由于用户可能从AMP Cache访问你的网页, 所以访问的域名可能是某个cdn域名, 存在跨域的可能, 需要服务端做好相应配置 https://www.ampproject.org/zh_cn/docs/fundamentals/amp-cors-requests#verify-cors-header
function assertCors(req, res, opt_validMethods, opt_exposeHeaders) { var unauthorized = 'Unauthorized Request'; var origin; var allowedOrigins = [ "https://example.com", "https://example-com.cdn.ampproject.org", "https://example.com.amp.cloudflare.com", "https://cdn.ampproject.org" ]; var allowedSourceOrigin = "https://example.com"; //publisher's origin var sourceOrigin = req.query.__amp_source_origin; // If same origin if (req.headers['amp-same-origin'] == 'true') { origin = sourceOrigin; // If allowed CORS origin & allowed source origin } else if (allowedOrigins.indexOf(req.headers.origin) != -1 && sourceOrigin == allowedSourceOrigin) { origin = req.headers.origin; } else { res.statusCode = 401; res.end(JSON.stringify({message: unauthorized})); throw unauthorized; } res.setHeader('Access-Control-Allow-Credentials', 'true'); res.setHeader('Access-Control-Allow-Origin', origin); res.setHeader('Access-Control-Expose-Headers', ['AMP-Access-Control-Allow-Source-Origin'] .concat(opt_exposeHeaders || []).join(', ')); res.setHeader('AMP-Access-Control-Allow-Source-Origin', sourceOrigin); } 复制代码