渐进增强的 Web 体验(Progressive Web AMP)

本文讲的是渐进增强的 Web 体验(Progressive Web AMP),


如果你最近几个月一直关注着 Web 开发社区,可能你对渐进增强的 Web 应用(Progressive Web App 简称 PWA)已有所了解。它是应用体验能与原生应用媲美的 Web 应用的统称:不依赖网络连接易安装,支持视网膜屏幕,支持无边距图像,支持登录和个性化,快速且流畅的应用体验,支持推送通并且有一个好看的界面。

一些 Google 的渐进式 Web 应用示例。

虽然新的 Service Worker API 允许离线缓存所有的网站资源以便在后续加载中瞬时加载,就像陌生人的第一印象很关键一样。最新的 DoubleClick 研究 (译者注:DoubleClick 是谷歌旗下一家公司)表明,如果首次加载超过 3 秒,超过 53% 的用户将放弃访问。

老实说,3 秒已是一个相当严峻的目标。移动端连接通常有平均 300ms 延迟,而且附带有带宽限制和时不时信号弱等不利情况,你可能只剩下不到 1 秒时间留给应用初始化等事情。

用户和内容之间的延迟。

当然,有一些方法能缓解首次加载缓慢的问题 — 在服务器上预先渲染好一个基础结构,再懒加载各个功能模块等等 — 但是使用此种策略达到的优化程度也有限,而且不得不雇佣一个前端优化专家,或者自己成长为一个专家。

那么,我们有什么方法来做一个从根本上和原生应用不同的首次瞬时加载呢?

AMP,为移动页面加速

网站的最重要的优势之一是跨平台 — 无需安装和即刻加载,用户通常只需轻击一下鼠标即可。

要想轻松地从短浏览(ephemeral browsing)的机会中收益,所需的就是一个瞬时加载(crazy-fast-loading)的网站。让网站瞬时加载,你需要做些什么呢?你所需做的只是一个适当的节制:没有兆字节大小图片,阻塞渲染的广告,没有十万行 JavaScript,就只有这些要求。

AMPs,是加速移动网页(Accelerated Mobile Pages)的简称,它擅长于此,实际上,这是它们存在的原因(raison d’être)。它就像一个驾驶辅助功能,通过实行一套合理的规则,优化你的网页主体内容,让它们处于快车道。并通过创建这种严格的,静态的布局环境,使譬如谷歌搜索等平台仅预渲染首屏,得以进一步接近“瞬时”。

此 AMP 的首屏横幅图片(hero image)和标题将被提前渲染,以便访问者瞬时看到首屏内容。

AMP 还是 PWA?

AMP 可靠快速的体验,在实现时也伴随着一些限制。当你需要高度动态的功能时,AMP 是不适用的,譬如推送通知、网络支付和依靠额外 JavaScript 的功能。此外,因为 AMP 页面通常从 AMP 缓存中提供,你的 Service Worker 不能运行,首次访问享受不到渐进式 Web 应用的最重要的好处。另一方面,在首次访问的速度上,渐进式 Web 应用永远不及 AMP,因为平台能顺利且毫不费力地预渲染 AMP 页面 — 内嵌更简单(比如在内嵌浏览器中)。

一旦用户点击内部链接,离开 AMP 缓存,你就能通过安装 service worker 来增强网站,让网站支持离线和更多的功能。

那么,是 AMP 还是渐进式 Web 应用?瞬时交付还是优化交付,或是最先进的平台功能和灵活的应用代码?有没有一种结合两者的好处的方式呢?

完美的用户旅程(User Journey)

终究,重要的是针对用户旅程的理想体验。它大概是这样的:

  1. 用户发现了一个指向你的内容的链接,并且点击了它。
  2. 内容快速加载是一种愉快的体验。
  3. 用户被通知并进阶到有推送通知和支持离线的更流畅的体验。
  4. 立即重定向到一个类原生的体验,并且可将网站放在你的主屏幕上。用户惊呼:“怎么回事?好神奇!”。

访问网站的第一步应该让人感觉快速,其后的浏览体验应该越来越引人入胜。

听起来是不是好的难以置信?好吧,尽管乍看,它们解决不同的问题且不相关,要是我们结合两种技术会怎么样呢?

PWAMP 结合模式

要获得瞬时加载,渐进增强的体验,你所需做的是将 AMPs 和渐进式 Web 应用的丰富功能用下列之一(或多)的方式相结合:

  • AMP 作为 PWA 当你可以接受 AMP 的限制时。
  • AMP 转作 PWA 当你想要在两者之间平滑过渡时。
  • AMP 在 PWA 中 当你重用 AMP 为 PWA 的数据源时。

让我们每个都过一遍吧。

AMP 作为 PWA

许多网站其实用不到超出 AMP(功能)范围。Amp by Example 就是一个例子,它既是 AMP 也是一个渐进式 Web 应用。

  • 它有 service worker,因此允许包括离线访问等在内的其他功能。
  • 它有清单(manifest),在横幅(banner)上会提醒“添加到主屏幕“。

当用户从谷歌搜索访问 Amp by Example,然后点击网站上链接,它们将从 AMP 缓存页面转到源页面上。当然,网站仍在使用 AMP 库,但是现在由于它处于源页面上,它能使用 service worker 或提示安装等等。

你可以使用此项技术让你的 AMP 网站支持离线访问,一旦他们访问源页面就进行扩展,因为你可以通过 service worker 的fetch 事件来修改响应(response),并返回你想要的响应 (response)。

function createCompleteResponse (header, body) {

  return Promise.all([
    header.text(),
    getTemplate(RANDOM STUFF AMP DOESN’T LIKE),
    body.text()
  ]).then(html => {
    return new Response(html[0] + html[1] + html[2], {
      headers: {
        'Content-Type': 'text/html'
      }
    });
  });

}

这一技术也允许你在 AMP 后续访问中插入脚本,提供超出 AMP 范围外的更进阶的功能。

AMP 转作 PWA

当上述不能满足,并且你想让内容有一个完全不同的 PWA 体验时,是时候用一种更高级一点的模式了:

  • 为了接近瞬时加载的体验,所有内容“叶”页(指有特定内容,不是概述的页面)被发布成 AMP。
  • 这些 AMP 使用 AMP 的特殊元素 <amp-install-serviceworker> 来预备缓存,并且当用户喜欢你的内容时用 PWA 的外壳。
  • 当用户点击你网站上的另一个链接(比如,在底部的行为召唤(按钮),使其更像原生)service worker 拦截请求并接管页面,然后加载 PWA 外壳替代之。

假如你熟悉 service worker 的运作,你可以通过以上三个简单步骤来实现这种体验。(如果你不清楚的话,强烈推荐我的同事杰克在优达学城(Udacity)上的课程)。第一步,在你所有的 AMP 上放置 service worker。

<amp-install-serviceworker
      src="https://www.your-domain.com/serviceworker.js"
      layout="nodisplay">
</amp-install-serviceworker>

第二步,在 service worker 安装过程中,缓存 PWA 所需的所有资源。

var CACHE_NAME = 'my-site-cache-v1';
var urlsToCache = [
  '/',
  '/styles/main.css',
  '/script/main.js'
];

self.addEventListener('install', function(event) {
  // Perform install steps
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(function(cache) {
        console.log('Opened cache');
        return cache.addAll(urlsToCache);
      })
  );
});

最后,又回到 service worker,拦截 AMP 的导航请求,用 PWA 替代响应。(下面的代码是功能简化版本,后面还有一个更进阶的示例。)

self.addEventListener('fetch', event => {
    if (event.request.mode === 'navigate') {
      event.respondWith(fetch('/pwa'));

      // Immediately start downloading the actual resource.
      fetch(event.request.url);
    }
});

现在,每当用户点击从 AMP 缓存页面上的链接,service worker 注册 navigate 请求模式(request mode)并接管,然后用已缓存的成熟(full-brown)的 PWA 代替。

你可以通过在网站上安装一些 service worker 来实现渐进增强。对于不支持 service worker 的浏览器,它们仅会转移到 AMP 缓存页面。

此项技术很有意思之处在于从 AMP 渐进增强到 PWA。然而,这也意味着,暂时不支持 service worker 的浏览器将从 AMP 跳到 AMP 并且不会导航到 PWA。

AMP 通过 Shell URL 重写 来跳转。通过在 <amp-install-serviceworker> 标签中添加一个备用 URL 模式(URL pattern),如果检测到不支持 service worker,就指示 AMP 重写特定页面上所有匹配的链接,用另一个传统的 shell URL 替代(外壳(Shell)是应用的用户界面所需的最基本的 HTML、CSS 和 JavaScript,也是一个用来确保应用有好多性能的组件。它的首次加载将会非常快,加载后立刻被缓存下来。这意味着应用的外壳不需要每次使用时都被下载,而是只加载需要的数据。 ):

<amp-install-serviceworker
      src="https://www.your-domain.com/serviceworker.js"
      layout="nodisplay"
      data-no-service-worker-fallback-url-match=".*"
      data-no-service-worker-fallback-shell-url="https://www.your-domain.com/pwa">
</amp-install-serviceworker>

在有 service worker 的情况下具有了这些属性,AMP 上所有后续点击都将转到 PWA。挺巧妙的,是吧?

AMP 在 PWA 中

那么,现在用户处于渐进式 Web 应用中,你可能会使用一些 AJAX 驱动(AJAX-driven)的导航,通过 JSON 来获取内容。你当然可以这么做,但是现在有两个完全不同的内容后端和基础架构需求 — 一个生成 AMP 页面,另外一个为你的渐进式 Web 应用提供基于 JSON 格式的接口。

但请想一想 AMP 的本质是什么。它不只是一个网站,它被设计成一个超轻便的内容单元。AMP 是独立的且可以顺利地嵌入到其他网站。我们是否可以抛弃 JSON 接口,使用 AMP 作为我们渐进式 Web 应用的数据格式,从而大大降低后端复杂性呢?

AMP 页面能顺利地嵌入其他网站中 — PWA 的 AMP 库只会编译并加载一次。

当然,一个简单的方法是在 frames 中加载 AMP 页面。但是使用 iframes 比较慢,并且需要你一遍又一遍地重新编译和初始化 AMP 库。现在前沿的 Web 技术提供了一种更好的方式:Shadow DOM。

处理过程看起来是这样的:

  1. PWA 操纵所有的导航点击事件。
  2. 然后,用 XMLHttpRequest 获取请求的 AMP 页面。
  3. 将内容放入一个新的 shadow root 中。
  4. 然后返回给主 AMP 库,“嘿,我有一个新文档给你。请查收!”(在运行时调用 attachShadowDoc)。

使用此种技术,整个 PWA 只会编译和加载一次 AMP 库,并且然后,因为你是通过 XMLHttpRequest 获取的页面,你能在 AMP 源插入新的 shadow document 之前进行一些修改,你可以像这样做:

  • 去掉不必要的内容,比如页眉(header)和页脚(footer);
  • 插入额外的内容,比如令人反感的广告或信息提示;
  • 用更动态的内容替换特定内容。

现在,你使你的渐进式 Web 应用更简单了,而且大大简化了后端结构。

准备,配置,实行!

AMP 团队做了一个名为 The Scenic 的 React 示例 来演示 shadom DOM 方法(也就是:PWA 中的 AMP),它是一本假的旅行杂志: 

整个示例的代码在 Github 上,但关键代码在 React 组件 amp-document.js 中。

看点真东西

一个真实产品的例子是 Mic 新式 PWA(beta 阶段),研究一下 :如果你按住 shift 重新刷新(shift-reload)任意文章(这样暂时忽略 service worker)查看源代码, 你会注意到这是一个 AMP 页面。现在尝试点击一下菜单:它会重新加载当前页面, 但由于 <amp-install-serviceworker> 已存在于 PWA 应用外壳中,重载几乎是瞬间完成的,并且菜单在刷新后打开,使其看起来不像是重新加载过一样。但现在你处于拥有其他丰富功能的(内嵌 AMP 页面)PWA 中。狡猾,但很了不起。

结语

无需多说,我非常激动地憧憬着新结合的潜力。这个结合集两者之所长。

优点概括:

  • 不论什么情况,都很快;
  • 良好的内置支持(通过 AMP 的平台伙伴);
  • 渐进增强;
  • 只需一种后端接口;
  • 降低客户端复杂性;
  • 成本低;

但是我们才开始发掘这种模式的变型,也是全新的一种。除提供构建 2016 最好的 Web 体验之外,继续向前到达 Web 的新篇章。






原文发布时间为:2016年12月16日


本文来自合作伙伴掘金,了解相关信息可以关注掘金网站。

时间: 2024-10-30 20:54:45

渐进增强的 Web 体验(Progressive Web AMP)的相关文章

《渐进增强——跨平台用户体验设计》一第1章 为体验而设计1.1 优秀的代码,麻烦的设备

第1章 为体验而设计 渐进增强--跨平台用户体验设计"总有些人干过这种事,在网页顶部或底部搞一个小黄条,写上'请使用XX浏览器(如IE6)访问本网站以获得最佳访问效果'.要我说,这种人到底是多么想回到过去啊,回到Web诞生之前吗?那样你就不可能在别的电脑.别的文字处理器,或者别的网络来访问你这个不想让别人看的网站啦!" --Tim Berners Lee 互联网中,唯一不变的就是变化.四下观望,永远都有新的设计风格,新的语言.框架.工具.新的上网设备在博人眼球.乱花渐欲迷人眼,城头变幻

《渐进增强——跨平台用户体验设计》一1.7 提升Web的可访问性

1.7 提升Web的可访问性 Tim关于Web的看法是:任何Web页面,我们都可以把它看成一个文档.同样内容的文档,我们只需要保留一份就够了.不论用户通过何种浏览器或设备访问,内容是唯一的,不同的只是呈现形式.这样做的好处显而易见--Web世界是由"超媒体"[17]联系起来的庞大网络,我在一个页面中添加了一个超链接,却不能预料到用户是通过什么设备访问并点击的这个链接.如果文档是唯一的,那么入口链接也一定是唯一的.我只需要添加一个链接,用户无论从任何设备点击它,都能获得最佳的访问体验.

《渐进增强——跨平台用户体验设计》一1.3 技术实现和用户体验

1.3 技术实现和用户体验 早期的Web技术更新得非常快.比方说,HTML的标准还未统一,微软和Netscape两家公司争相往HTML里面添加新的元素和行为,以证明自家技术比对方更厉害.后来又有了Java applets[6].RealMedia.Shockwave.Flash和其他的私有技术,我们的网页变得很复杂,同时用户需要安装很多插件来支持这些技术. 各家标准和技术的不统一导致了"优雅降级"概念的诞生.所谓优雅降级,指的是在用户的浏览器不能完全支持某项功能的时候,为用户提供一个在

《渐进增强——跨平台用户体验设计》一1.9 渐进增强的设计思想

1.9 渐进增强的设计思想 渐进增强是一种设计思想.运用这种设计思想进行设计实践,会让每个设计师和开发者节省大量的时间和成本.这种设计思想帮助你了解你所面对的真实用户和设备环境,让他们获得最适合的用户体验,从而体现出Web与生俱来的适应性. 渐进增强是一种无间断,连续的设计思想,不是为了某些设备而特殊优化,而是面向不同类型的设备,累加地提供用户体验的提升.在接下来的章节中,你会学习到如何把这种思想应用到Web设计的实践当中. [1] 作者的分析代码详见https://perma.cc/4EAE-

《渐进增强——跨平台用户体验设计》一1.5 向后兼容,向前适应

1.5 向后兼容,向前适应 中学时代,我经常用MS-DOS系统上的Word文字编辑软件写作业.这是个特别专业的软件,因为打开它就只能写字,别的什么都干不了[11].那时的Word软件没有太多的编辑选项,却也能满足大部分的需要,对于我来说,足够用了. 然而,当时我写的作业,用现在的Word软件已经打不开了.二十多年过去,这个软件已经不再支持MS-DOS版本的DOC文件. 有人说,都20多年过去了,你还惦记那些中学写的作业啊--我不是这个意思.我相信除了我之外,很多人都用过MS-DOS下的Word软

《渐进增强——跨平台用户体验设计》一1.6 适应未知的设备

1.6 适应未知的设备 然而,还是有人认为,设计思想这东西看不见摸不着,扯那些没用的是在浪费时间.在Web设计师Tim Kadlec的博文"我们的设计并没有真正理解Web"的后面,有个读者的留言是这么说的[15]: "说得好听,但是不接地气.你得算一下捕捉用户的成本.如果一些用户根本不是你的目标用户,不能为你带来任何收益,那么,干嘛为他们进行优化?根据这种设计思想,本质上你是要为所有用户的体验负责,无形中会大量增加开发成本.但是,恕我打个比方--我们都知道成衣的尺码分大中小号

《渐进增强——跨平台用户体验设计》一1.8 分层次设计

1.8 分层次设计 渐进增强是一种设计的思考方式,关于这种思考方式,我经常拿M&M豆来打比方(图1-5).我特别喜欢吃M&M豆,所以我们想一下,是不是所有的M&M豆最里面都有一颗花生啊?M&M豆为什么要在最里面包含一颗花生,而不是别的什么东西呢?我猜,因为花生是一种普遍都能接受的食品,除了少数过敏者,很少有人不喜欢吃花生.所以,花生是M&M豆的核心,正如一个网页的内容是网页的核心.广告啊.导航啊,这些都是次要的,大家来到你的网页是来看内容的,别的都不重要. 发明M&

《渐进增强——跨平台用户体验设计》一1.2 早期的Web是什么样

1.2 早期的Web是什么样 最初,我们的电脑是没有图形界面的[3],我们看到的,只是黑色屏幕上的一行行绿色的命令行和文字[4](图1-1),上网的用户个个看起来都和程序员没什么区别. 命令行模式的浏览器仅支持一些基本的文本格式,如缩进.对齐等,但是在1990年,Web上传输的内容基本都是些文本和用于发表的内容,所以这样的内容渲染程度也是能够满足人们的需要的. 我是从1990年开始上网的,本来一直用着这种命令行模式的浏览器,用着用着,我发现情况有了一些变化.1993年,美国国家超级计算应用中心(

《渐进增强——跨平台用户体验设计》一1.4 你满足不了所有的人

1.4 你满足不了所有的人 在今天的Web环境中,按照PSD文件的像素去还原一个网页,然后在任何设备上都展示成一个模样的时代已经过去了.我们要考虑的因素越来越多. 在技术实现方面,屏幕尺寸.像素密度.CPU运算速度.内存大小.传感器的支持程度.功能差异.不同接口,乃至不同的操作系统.同一操作系统的不同版本.不同的浏览器,同一浏览器的不同版本.插件.插件版本.网速.网络延迟.防火墙.用户自己设置的代理.路由器,以及日新月异的技术发展,让我们的Web环境愈发复杂起来. 技术实现方面之外,我们还要考虑