View on GitHub

Yinjie - GitHub.io

Welcome to the Yinjie's notes

AMP

什么是 AMP

####引言:

对许多人来说,在手机上看页面(webview)是一个很慢的、不靠谱的经历,但它不应该是这样的。加速移动端页面(AMP)项目是一个开源项目,它对移动端的页面进行了大幅的优化,开发人员可以借助它来构造网页。一旦拥有,瞬间加载—无处不在。

AMP (Accelerated Mobile Pages )是谷歌推动的一项专门针对移动端网页加速的项目。根据官方的测试报告,使用的 AMP 技术的页面在 3G 情况下,首屏显示时间会有 15% ~ 85% 的性能提升。

AMP 技术实现

AMP 主要由三部分构成,AMP HTML、AMP Runtime、AMP Components

AMP HTML

AMP 对应用此技术的页面 DOM 做出一些规定

页面必需的规范
  • doctype 必须是 <!doctype html>
  • 顶层 html 标签必须包含 AMP 属性: <html ⚡> (<html amp> 也可以)
  • 包含 <head><body> 标签
  • 在 head 中包含一个 <link rel="canonical" href="$SOME_URL" /> 标签,这个标签指出该页面普通版本的 URL,如果只有一个版本,使用当前的 URL 就可以。(告诉搜索引擎,这是同一个页面的不同版本,否则搜索引擎会认为此页面有两个 URL,会认为是作弊)
  • 必须将 <meta charset="utf-8"> 放置在 HEAD 的最上面
  • HEAD 中必须包含 <meta name="viewport" content="width=device-width,minimum-scale=1">,也可以在里添入initial-scale=1 (1)
  • 在 HEAD 中引入 AMP 核心 JS 文件 :<script async src="https://cdn.ampproject.org/v0.js"></script>
  • 在 HEAD 中写入以下代码
    <style>body {opacity: 0}</style><noscript><style>body {opacity: 1}</style></noscript>

(1) width=device-width,minimum-scale=1 需要打开GPU rasterization

DOM 元素规范
原生标签 AMP HTML 中的标签
script 除了类型是application/ld+json的 script 标签都被建议禁止使用。当然,AMP Runtime 和 AMP 扩展组件所需要的 JS 还是需要加载的
base 禁止
img amp-img
video amp-video
audio amp-audio
iframe amp-iframe
frame 禁止
frameset 禁止
object 禁止
param 禁止
applet 禁止
embed 禁止
form 禁止
input elements 禁止。 type="button" 的可以被使用
button 允许
link rel 为 canonical 的特定标签是可以放置的,stylesheet 则不被允许
meta http-equiv 属性不允许,其它的可以
a href 属性不能是 javascript:,如果必须是,那么 target 属性必须是 _blank

AMP Runtime

在上面的基础上,AMP Runtime(就是 HEAD 中最的引入的那个 JS)负责协调各个 DOM 与资源的加载时机与优先级,以及提供验证器等调试功能。

如果你不知道你的页面是否符合 AMP 的规范,你可以在访问的 URL 中加入 #development=1 来打开开发者模式。这时 AMP 会加载验证器,检测页面,并在控制台显示不符合 AMP 规范的位置信息

AMP Components

AMP 通过自定义元素提供了一些组件,分为两类:内置组件扩展组件

内置组件
组件 描述
amp-ad 广告位标签(受限
amp-img 对原生 img 标签的替换
amp-pixel 页面访问追踪标签,(受限
amp-video 对原生 video 标签的替换

内置组件是指在 AMP Runtime 中加入的一些自定义标签组件,用来替换 <img><video> 等常用标签,从页优化对资源的加载策略,

扩展标签
组件 描述
amp-anim 通过 AMP Runtime 管理加载的动图,一般为 gif
amp-audio 对原生 audio 标签的替换
amp-carousel 轮播图
amp-fit-text 一个可以自动调整大小的文本框,可以使文本始终充满文本框
amp-iframe 对原生 iframe 标签的替换
amp-image-lightbox 就是 “image lightbox” ,点击图后可以全屏特写
amp-lightbox 同上,不过不特定是 image
amp-instagram 引用 instagram 站点内容的自定义标签(受限
amp-twitter 引用 twitter 站点内容的自定义标签(受限
amp-youtube 引用 youtube 站点内容的自定义标签(受限
amp-pinterest 引用 pinterest 站点内容的自定义标签(受限

扩展组件并不存在于 AMP Runtime 中,使用时需要引入额外的 JS,如<script async custom-element="amp-audio" src="https://cdn.ampproject.org/v0/amp-audio-0.1.js"></script>注意:必须要有 async 和 custom-element=”amp-audio” 属性。

(受限是指,此类标签因中国的法律政策、网络环境、国际通用接口一致性等原因,在中国大陆内部基本没有实用价值)

AMP 的适用场景

定位:解决静态页面的性能问题

也许你会想,AMP 对页面做了这么多的限制,这还怎么让人以此开发页面??? 实际上,AMP 只关注于一件事 —— 提高静态页面的性能。

这个「静态」并不是指没有服务端参与的页面,而是指没有复杂交互、以内容展现为主的资源页,典型例子就是新闻详情页。现在的网站类型很多,游戏类、视频类、电商类等等,每一类网站都有着自己的特点,优化策略也各不相同,用一种方案去解决所有问题不切实际。所以 AMP 项目将关注点放在了更容易优化且效果最明显的内容型页面。

实现原理

AMP 对于页面优化的方式主要集中在资源的延迟加载按需加载。 将图片、视频等标签和第三方功能换成 AMP Components 后,AMP Runtime 可以将此资源延迟到页面彻底渲染之后,确保页面首屏性能。 对于大量图片,AMP 采用由上到下的串行加载,避免了同时加载多张图片时对移动设备带来的压力。 另外,一些资源非常消耗性能,例如 gif 和 video,AMP Runtime 可以在它们处于不可见时销毁元素,释放资源。

总结

AMP 的适用范围很窄,而且具有针对性,无法满足平时业务的需求。 而且在国内的使用环境就更加受限。AMP 要求 Runtime JS 必须从 cdn.ampproject.org 加载,这样做的出发点是为了更可控,以及更好的在各网站之间共享缓存,但是这些域名在国内很难访问甚至直接被墙。其次,从目前 AMP 目前已有的扩展组件来看,instagram、twitter、youtube 这类国外媒体常用的服务在国内都无法使用,内置的 ad 组件也不符合国情。

但是,AMP 项目对我们进行移动 Web 优化仍然很有借鉴意义。实际上,控制资源加载、处理响应式元素避免页面抖动、主动释放资源等策略,我们在项目中都有自己的尝试与经验,但我们的方案要么过分依赖服务端,要么没有抽象成通用模式,导致无法推广到更多产品,这些都是后续可以努力的方向,而 AMP 规范和代码实现,将会是最好的参考资料。