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);
- }
复制代码
来源: https://juejin.im/post/5b6061a3f265da0f926b9992