网页加速特技之 AMP
据AMP官网统计目前已有很多新闻类网站和科技类网站开始使用AMP,包括Wordpress、YouTube、Twitter、LinkedIn、BBC等。不明觉厉,接下来让我们一起来揭开AMP神秘的面纱吧。
据统计,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-ad、amp-embed、amp-img、amp-pixel、amp-video
组件直接以标签的形式进行使用,如页面中需要加载video、img 使用相应的组件即可,如下:
amp-video amp-img 组件实际是使用HTML原生<video> <img>
标签来实现,所以在页面上的展示效果和原生HTML一致。
amp-ad、amp-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亮点:
-
AMP有利于网站SEO,在网站内容差不多的情况下,使用AMP的网站在 Google 搜索中可以获得更靠前的排名。
-
延迟加载、按需加载使得首屏展现更快。
-
尤其对内容型页面性能优化明显。
AMP限制:
网络限制,如AMP JS、AMP Components 必须从 cdn.ampproject.org 加载;Web Font 必须从 fonts.googleapis.com 加载,这些源网站在国内访问速度很慢甚至直接被墙。
引入第三方资源受限。
需要遵循严格的代码规范指引。
AMP设计的初衷就是针对静态内容,用来加速新闻类网站,所以对其他交互较多的网站可能并不适用。但是,AMP 控制资源加载、处理响应式元素避免页面抖动、主动释放资源等策略可以作为我们对移动 Web 优化的参考。
参考资料:
1.https://www.ampproject.org/docs/get_started/about-amp.html
2.https://imququ.com/post/amp-project.html
3.https://asknoypi.com/accelerated-mobile-pages-validator/#validator
4.https://github.com/ampproject