据统计,40%的人会放弃使用加载时间超过3秒的网站。对于加载慢的页面我也是没耐心等待的,同类型网站那么多,为什么不选择加载速度更快体验更好的呢。为了解决网页加载慢的问题,Google联合数十家技术机构和企业等推出了移动网页加速项目(Accelerated Mobile Pages, AMP)。

据<AMP官网统计目前已有很多新闻类网站和科技类网站开始使用AMP,包括Wordpress、YouTube、Twitter、LinkedIn、BBC等。

不明觉厉,接下来让我们一起来揭开AMP神秘的面纱吧。

一、什么是AMP?

Accelerated Mobile Pages (AMP)直译过来就是在移动设备上快速加载的网页。它是由 Google 发起的一个开源项目,主要目的是缩短静态内容的渲染时间从而有效提升网站的加载速度。

那么问题来了,AMP的加载速度到底有多快?

根据 Google 官方说明,AMP 在模拟 Nexus 5 并模拟 3G 网络的测试情况下,首屏展现速度有 15% ~ 85% 的提升。

这么NB,让我们来看看AMP到底什么鬼。

AMP主要由三个部分组成:

1.AMP HTML

1).AMP HTML 规范

AMP HTML 在 HTML 的基础上加了一些使用限制,并且添加了AMP自定义的组件。

AMP 禁用部分 HTML 标签如 <frame><form><input> 等。

部分 HTML 标签必须使用 AMP 自定义的组件来替换如 <img> 、 <video> 用 <amp-img> 、 <amp-video>替换。

AMP在HTML基础上也提供一些扩展组件,如 <amp-carousel> 、 <amp-iframe> 、 <amp-youtube> 等,但是使用扩展组件时必须引入相应的JS文件。

一个简单的 AMP HTML 示例:

将上面的代码保存为 .html 文件,在浏览器中就可以正常运行,从这个示例可以看出,AMP HTML 的写法和HTML差不多,但是又有自己的规范要求:

  • DTD 必须是: <!doctype html>
  • 顶层标签必须包含 AMP 属性如: <html amp>,方便其他程序识别 AMP HTML;
  • 必须在 HEAD 区域中放置 <link rel="canonical" href="$SOME_URL" /> 标签,指定该页面普通版本的 URL;如果只有一个版本,则使用当前 URL;
  • 必须将 <meta charset="utf-8"> 放置在 HEAD 区域最开始的位置;
  • 必须在 HEAD 区域包含这个 ViewPort:
    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,minimal-ui">
  • 必须将 <script async src="https://cdn.ampproject.org/v0.js"></script> 作为 HEAD 区域最后的元素;
  • 必须在 HEAD 区域包含上面示例所示的 <style amp-boilerplate> 和 <noscript> 的相关代码;

更多 AMP HTML 相关说明,可移步 AMP HTML官方文档

2)AMP HTML 组件

    • 自定义组件

AMP HTML 自定义5个组件: amp-adamp-embedamp-imgamp-pixelamp-video

组件直接以标签的形式进行使用,如页面中需要加载video、img 使用相应的组件即可,如下:

amp-video amp-img 组件实际是使用HTML原生 <video> <img> 标签来实现,所以在页面上的展示效果和原生HTML一致。

amp-adamp-embed 组件主要用于引入广告类信息,使用iframe的方式来实现。

    • 扩展组件

AMP HTML的一个重要特性就是可扩展性,它提供扩展组件来实现丰富的功能。

官网目前提供的扩展有youtube视频组件、twitter组件、轮播、滚动、instagramd等等。

使用扩展组件需要在页面头部引入依赖的JS文件,如使用twitter组件:

twitter组件的显示效果如图:

扩展组件使用iframe来实现,定义扩展组件必须严格遵循AMP的3p contribution guidelines(为了保证性能,定义扩展组件的要求非常多)。

2.AMP JS

AMP JS 是 AMP 技术的核心。

AMP JS 负责协调资源的加载时机和优先级,让外部资源按不同顺序加载使得页面的主要内容优先加载;AMP JS 的resources模块根据元素优先级(amp-img的优先级高于amp-ad的优先级)、操作优先级、可视优先级给资源评分,根据评分调整资源加载优先级。

它还负责页面的性能优化,例如在资源加载完成前对页面元素布局预处理,禁用慢的CSS选择器,对 iframe 进行沙盒处理,提供对自定义元素的支持。

AMP JS 也负责提供验证器等调试功能,在URL最后加 #development=1 就会开启调试模式,AMP会自动加载验证器,并在控制台显示本页不符合AMP规范的报错信息。

3.Google AMP Cache

Google AMP Cache是一个基于代理机制的内容分发网络(CDN),它会分发所有合格的AMP文件,它会抓取AMP页面并进行缓存,自动提升页面的性能。使用Google AMP Cache,页面、JS文件、图片等都是从同一个源获取,并且使用HTTP2.0来优化性能。

这个缓存机制还带有的验证系统,以确保网页不受外部资源的限制,能随时随地正常运行。它能自动验证网页是否符合AMP HTML的规范。

二、AMP HTML 和 HTML 比较

简单了解了 AMP 的相关规范,我们来验证下 AMP 是不是如传说中那么NB。。。

分别用 AMP HTML 和 HTML 写了两个一样的页面,页面中有33个HTTP请求,包含一个video、28张图片等资源。不多说,直接上图:

3G(1Mbps 40ms RTT)网络状态下,HTML页面:

3G(1Mbps 40ms RTT)网络状态下,AMP页面:


从上图对比可看出,3G网络下,AMP页面的onload时间比HTML页面快50%以上,当然这是在HTML页面图片没做lazy-load优化的情况下。

3G(1Mbps 40ms RTT)网络状态下,HTML页面:

3G(1Mbps 40ms RTT)网络状态下,AMP页面:


从上面两图对比可看出,3G网络下AMP页面的渲染时间明显快于HTML页面。

AMP页面优化资源加载,自动对资源做延迟加载,首屏完整展现的速度明显快于HTML页面。

上面的测试页面是静态内容页面,不涉及到服务器数据拉取和复杂的页面交互,所以有一定的局限性。要深入了解AMP页面和HTML的差异,还需要更多的测试。

三、AMP如何提升性能?

在静态内容页面测试数据中,AMP页面的加载速度确实更快,那么AMP提升页面加载速度的秘诀是什么捏,我们一起来看看。

1.只允许异步加载script

HTML 解析器遇到 script 标签,它会暂停构建 DOM,并移交控制权给 JavaScript 引擎;等 JavaScript 引擎执行完毕,浏览器从中断的地方恢复 DOM 构建。执行内联脚本会阻塞 DOM 构建,也就延缓了首次渲染。为了减少JS对页面渲染的延迟,AMP不允许直接使用内联脚本,只允许异步加载JS。

AMP页面不允许直接包含任何内联JS,页面交互可在AMP组件中处理,AMP组件是经过精心设计的保证不会影响页面性能。第三方JS只允许在 iframe 中使用,这样就不会阻塞主页面的渲染。

2.静态资源指定宽高

扩展资源如图片、iframe等必须在标签中指定他们的宽高,AMP可以在这些资源下载完成以前就决定每一个元素的宽高和位置,AMP在所有资源加载完之前就开始页面布局。

AMP把文档和资源分开布局,避免样式重新计算和布局,资源加载完成后不会重新布局。

3.避免扩展机制影响渲染

AMP支持一些扩展组件如:`<amp-lightboxes>`,`<amp-tweets>`,使用这些组件需要加载相应的JS文件,会增加额外的HTTP请求,但是这些请求不会阻塞页面的布局和渲染。

任何页面用原生的script标签,必须要通知AMP系统,即在`script`中加 `custome-element`属性。

4.关键路径禁用第三方JS

AMP 只能在 sandboxed iframe 中加载第三方 JS。把他们当做 iframes,因此不会阻塞主页面。如果第三方JS触发多个样式重计算,iframe中也只有很少一部分DOM,重新布局不会消耗很多性能。

5.CSS必须内联,内联样式表最大50kb

CSS会阻塞页面渲染,阻塞页面加载。在AMP页面中,只允许内联样式,这会在关键渲染路径上比一般的页面减少1或多个HTTP请求。

CSS使用内联,内联样式表(inline stylesheet)最大不超过50kb。

6.字体必须有效触发

Web字体非常大,因此Web字体对性能优化是至关重要的。在一个普通的页面中有一些script和样式表,浏览器需要等待这些资源加载完成后开始加载这些大的字体资源。

在AMP中所有的JS都是异步加载而且只允许使用内联样式表,所以没有HTTP请求阻塞浏览器去加载字体资源。

7.减小样式重计算

修改元素样式时,会触发样式重新计算,这是非常高的性能消耗,因为浏览器需要重新布局整个页面。AMP页面在进行DOM写操作之前会先读取DOM,这样能确保样式重计算时一次最精确到每一帧的样式。

8.只运行经GPU加速的动画

AMP网页上的动画只允许变形和透明度调整,从而节省重新布局页面的时间。

9.优化资源加载次序

AMP控制所有的资源加载,优先加载必要的资源(如首屏需要展示的资源),预加载可以延迟加载的资源。

AMP加载资源时,最重要的资源最先被加载,images 和 ads 在他们可能被用户看到的情况下才加载,或者在用户快速滚动到他们的位置时加载。

10.使用 preconnect API

新的preconnect API用来确保HTTP请求尽可能快。页面可以在用户看到之前就渲染完成。通过即时加载,页面可能在用户选择它的时候就已经是可用的了。

虽然预渲染可以让页面更快,但是也会消耗大量的带宽和CPU。AMP对减少这两个因素进行了优化。预渲染只会下载被遮住的部分资源,而且不会渲染很耗CPU的内容。

四、总结与思考

AMP亮点:

  1. AMP有利于网站SEO,在网站内容差不多的情况下,使用AMP的网站在 Google 搜索中可以获得更靠前的排名。
  2. 延迟加载、按需加载使得首屏展现更快。
  3. 尤其对内容型页面性能优化明显。

AMP限制:

  1. 网络限制,如AMP JS、AMP Components 必须从 cdn.ampproject.org 加载;Web Font 必须从 fonts.googleapis.com 加载,这些源网站在国内访问速度很慢甚至直接被墙。
  2. 引入第三方资源受限。
  3. 需要遵循严格的代码规范指引。

AMP设计的初衷就是针对静态内容,用来加速新闻类网站,所以对其他交互较多的网站可能并不适用。但是,AMP 控制资源加载、处理响应式元素避免页面抖动、主动释放资源等策略可以作为我们对移动 Web 优化的参考。

参考资料:
1.https://www.ampproject.org/docs/get_started/about-amp.html
2.https://imququ.com/post/amp-project.html
3.https://github.com/ampproject
4.https://asknoypi.com/accelerated-mobile-pages-validator/#validator