翻译 | Progressive Web AMPs

842 阅读8分钟
原文链接: mp.weixin.qq.com

傅姝丽(沪江前端开发工程师)

本文原创翻译,有不当的地方欢迎指出。转载请指明出处。‍


如果你在过去几个月一直关注web开发社区,你很可能已经阅读了 progressive web apps,下面简称PWAs (中文有译作渐进式web应用).它是一个术语,统称那些拥有 离线支持可安装,“Retina”,满屏显示,个性化支持,流畅的浏览效果,推送通知和强大的UI等可以和原生媲美的web应用。

www.smashingmagazine.com/2016/08/a-b…



这是一些谷歌Progressive Web APPs示范

虽然当你网站一加载,Service Work API就会帮你缓存所有网站资源,但就像你初次见一个人第一眼印象很重要,最新DoubleClick study的数据表明,如果首次加载花费的时间超过3秒,超过53%的用户会离开。


3秒,在现实中是一个非常残酷的目标。移动端连接,平均有300毫秒的延迟,还受制于带宽、弱信号,所以实际上你只有不到1秒的时间去下载你app所需要初始化所需要的资源。




以上显示了用户请求的延时


当然,我们有办法去减少首次加载的时间,比如服务端预渲染基本布局、按需懒加载等等,但是我们能做到的是有限的,还必须专门有个人去做性能优化。所以,既要迅速加载又要有原生的体验,我们该怎样做?

AMP, For Accelerated Mobile Pages 

codelabs.developers.google.com/codelabs/yo…


网站一个巨大的优势在于无摩擦的入口——它不需要安装,用户总是只需点击一下即可立即加载。


为了享受这么轻松、瞬间的浏览体验,你所有要做的是让你的网站跑的飞快,但是如何让你的网站跑到飞快?我们可以适当的减少开销,没有兆级别容量的图片,没有阻塞渲染的广告,不超过10万行的js代码,所有的只是纯内容的展示。


Accelerated Mobile Pages, 简称AMPs, 就非常擅长做这些,事实这也是它们的宗旨。通过它精心设计的规则能保证优先显示页面的主要内容。通过创建要严格的 静态布局,它能使平台像google Search通过首屏预加载达到瞬间加载的效果。

www.ampproject.org/

www.ampproject.org/learn/how-a…

www.ampproject.org/learn/how-a…



这个AMP 的hero image 和 headline会预加载, 以保证用户可以立马看到它

AMP 还是 PWA? 


为了快速加载你引入了AMP, 但你引入AMP的同时你很多功能会受限。AMP并不适用一些高级的功能 比如通知推送,网页支付或者一切需要引入其它js的功能。以及因为AMP的页面是受AMP Cache控制的,你享受不到PWA的的优势,因为你自己的Service Worker不能运行。另一方面PWA并不能像AMP在第一次加载那么快,并且能安全且容易的嵌入。



所以AMP还是渐进式的app?是一次性加载还是选择性的加载,是最新的平台特性还是轻巧的应用代码?我们是不是有可能结合两者,综合两个的好处?

PWAMP 结合模式


你可以通过以下方式结合AMPs和progressive web apps

  • AMP AS PWA

当你能接受AMP的局限性

  • AMP TO PWA

当你希望在两者之间无缝过度

  • AMP IN PWA

当你希望AMP作为一个资源在你的PWA里面可复用, 现在让我们来单独的谈谈它们。


AMP AS PWA


很多网站在AMPs范围不需要别的功能。例如,Amp by Example既是一个AMP APP,也是PWA APP。

ampbyexample.com/

  • 它有一个service worker,因此它允许离线访问等。

  • 它有一个manifest,所以支持“添加到主屏幕”。


当用户在google search页面点击Amp by Example,然后点击该网站上的另一个链接时,他们将脱离AMP Cache去远程拉数据。网站仍然使用AMP库,当然,但是因为它依赖远程,所以它可以使用service worker,然后安装及激活等等。


你可以使用此技术让你的AMP网站支持离线访问,然后在线时及时更新你的网页,因为在线时您可以通过service workor的fetch事件修改响应,返回你想要返回的内容:



AMP TO PWA


如果上面的不能满足你,你需要非凡的PWA体验围绕你的内容,这是你可以考虑为高级的模式

  • 所有的内容子页面(那些指定的内容,不是全局的页面)作为AMP发布,享受立即加载

  • 这些AMP页面用AMP特定的元素<amp-install-serviceworker>在用户阅读你内容的时候为缓存和PWA脚本做准备

  • 当用户点击你网站的另外一个链接(比如唤起类似原生app的操作),这时候service worker截取请求,接管页面控制权加载PWA脚本


你可以实施这三部,如果你熟悉Service Works的是怎样运行的(如果你不熟悉,我强烈推荐你阅读我同事 Jake’s Udacity 的课程)。

www.udacity.com/course/offl…


首先在你所有AMP引入入Service Worker.




第二步, 在Service Worker安装事件中,缓存PWA需要的所有数据




最后, 还是在Service Worker里面, 用返回PWA取代原有的AMP导航请求

(下面的代码只是为了展示原理所以简化了,高级的例子在最后的Demo里)



现在,当用户在你从AMP Cache返回的页面里面点击一个链接,Service Worker会注册这个navigate 请求然后接管, 变成一个完全成型的已经缓存的PWA。




这个技术有意思的在于它是渐进增强的从AMP转变成PWA. 这也意味着,如果你的浏览器不支持Service Worker,它将不会被导航到PWA, 而是AMP跳AMP

AMP通过shell url rewriting实现这种渐进增强。通过在<amp-install-serviceworker>添加一个回调属性, 如果检测到不支持Service Worker,AMP会用shell Url重写所有匹配所有连接,所有的后续的点击不再会导航到PWA.

www.ampproject.org/docs/refere…




AMP IN PWA


在此模式中,用户已经在一个渐进式的app里面了,你正好用AJAX获取获取数据,但是你的真实需求是得到两种后端返回的数据,一种是AMP内容,另一种是你Progressive Web App所需要的JSON格式数据。


当然,一种简单方式是在iframes里面加载 AMP内容。但是iframe比较慢,而且你需要一次又一次重新编译和重新初始化AMP Library。今天cutting-edge 技术提供一个更好的办法: shadow-dom




AMP 可以安全的被嵌入其他网站, mp liabrary在整个PWA只会被编译和加载一次。


整个过程是这样


  1. PWA劫持任何导航点击

  2. 然后它发一个XMLHttpRequest 去fetch AMP页面

  3. 拉到后它把内容放到一个新的shadow root

  4. 然后它通知 main AMP Library, “这里有个新的document,请检查”(运行的时候叫 attachShadowDoc)


用这个技术,AMP Library在PWA只编译和加载一次,它会响应每个你绑定的shadow document。并且因为你是通过XMLHttpRequests去fetch页面,你可以在插入到新的 shadow document之前更改AMP 资源。打个比方你可以用来:

  • 过滤掉不需要的信息,比如headers 和footers

  • 插入额外的内容, 比如广告和工具

  • 用更动态的内容替换某些内容


现在你把你的渐进式Web APP变得稍微复杂点了,你可以减轻后端的复杂度。


准备好了,走你~


为了阐述 shadow dom的这个方法(PWA包含AMP),AMP团队已经制作了React-based demo called The Scenic, ---- 一个虚拟的旅游杂志.





这个Demo在GitHub

github.com/ampproject/…


来点干货


我们看看 Mic’s new PWA(in beta)这个以及上线的例子: 如果你强刷任意一个页面(会暂时忽略Service Worker),然后你看你请求返回的结果,你会发现是AMP页面资源。现在你单价“hamburger menu”: 它会重新加载当前页面,然而因为<amp-install-serviceworker>已经加载在PWA app shell, 这个重新加载几乎是瞬间的,菜单在刷新后打开,看上去好像根本没有刷新过。

beta.mic.com/


最后的想法


我对这种新的结合方式很兴奋,这种结合带来了它们各自的好处, 再强调下:

  • 总是很快

  • 内置大型分布(通过AMP平台套件)渐进式增强

  • 一种后端返回规则

  • 减少客户端的复杂程度

  • 更少的整体投入


但是我们只是探索了不同方式的差异,打造2016年及未来的最好的Web体验还仍需努力,为开辟Web新篇章继续前行。