乐趣区

关于小程序:钉钉小程序快照技术初窥

作者:孙然(煮虾)

对于小程序技术来说,容器加载和前端异步渲染的过程中诚然不可避免的会有白屏或 loading 页的展现,短则一瞬间,长则须要数秒能力展现首屏。如果白屏工夫长,将十分影响用户的体验。依据 Google 的统计,如果页面加载耗时超过了 3s,那么有 53% 的用户会抉择间接退出该页面了。

为减速小程序首页的展现,支付宝和手淘使用了基于 HTML 的 快照 技术,次要思路都是缓存首页 HTML 供下次启动时与数据一起优先渲染以提前首屏展现的工夫,实用于传统 WebView 渲染的小程序场景。这种基于 HTML 的快照技术可能极大缩短启动时的白屏工夫,但首屏展现的速度还是不够快,期间用户依然会有可见的白屏感触。并且快照展现的依然是无奈点击操作的页面,须要期待 JS 局部 ready 后才可点击交互。

为了谋求极致的体验成果,咱们提出了一种全新的小程序快照技术,指标是既做到彻底消除白屏景象,同时也要可能响应用户交互。

外围思路

不同于现有的基于 HTML 的快照技术,咱们提出了一种 native 的图像级别的快照技术,次要由以下三个步骤:

  • 步骤 1:在小程序启动后适合的机会将小程序首页保留为图片,咱们称之为 快照
  • 步骤 2:下次关上小程序时先展现上次保留的快照,再启动小程序
  • 步骤 3:当小程序启动完后的适合机会,暗藏快照,展现出实在的小程序首页,并保留以后界面视图作为下次的快照(同步骤 1)

成果

当初钉钉中的新建 DING 日程页面就使用了快照技术,前后成果比照如下:

before after

能够看出,通过快照技术,该页面实现了首屏秒开的成果,启动白屏的景象彻底隐没,页面的首屏渲染耗时从 1700ms 左右升高到了 300ms 以下。

上面我会对快照技术的几个要害思考点进行具体介绍。

场景和机会

现实中的快照,该当是可能和首屏页面齐全重合,并且在快照暗藏时不会产生任何视觉变动的。那么生成快照的 机会 和使用快照的 场景 就间接决定了快照技术可能达到的优化成果。

什么页面适宜用快照?

并不是所有的小程序都适宜应用快照技术来晋升首屏体验。如果使用不当,快照可能还会成为体验的减分项。为达到最佳成果,个别首屏页面满足上面几个条件是比拟适宜应用快照的:

  • 首屏页面较为固定。如果首屏不固定,很难找到适合的快照机会来保障快照与下次的首屏重合
  • 首屏页面不含用户隐衷数据。用户的隐衷数据不该当被快照下来

什么时候生成快照?

如果快照的机会过早,快照可能展现的也是白屏或者未渲染残缺的首页框架。

如果快照的机会过晚,可能用户曾经对首屏有了交互(滚动、点击等),容易生成无奈和首屏重合的快照。

所以须要依据不同的首屏场景来确定最佳的快照机会。个别咱们思考快照的机会有:

  • 小程序首屏 Page 的 onReady 生命周期回调里。但此时页面很可能依然没有渲染实现,能够思考适当延时后进行快照
  • 小程序首屏的数据如果须要近程拉取,能够在近程获取到首屏数据后进行
  • 用户产生滚动时、点击等交互后不再进行快照

什么时候暗藏快照?

咱们个别思考在 生成快照时 去暗藏以后曾经展现的快照。二者的程序个别是在暗藏快照后立刻生成快照,能力实现快照和实在页面的无缝连接。

当然,也须要思考小程序启动可能失败的场景。这里须要对展现快照的工夫设置一个展现的下限,如果展现工夫达到下限时小程序首屏依然没有启动胜利,那么快照将间接暗藏,以防造成首屏对用户可见但始终不响应的难堪场面。

这里咱们在还暗藏快照时做了一个小小的视觉优化。思考到在暗藏快照时,如果间接暗藏快照,一旦快照和实在页面稍有差异,在视觉上可能就会有闪动的体感产生。

所以在暗藏快照时,咱们会做一个 200ms 的淡出动画,来缓解这种快照和实在页面差别导致的闪动感。因为有时快照的机会可能会稍提前于首页网络数据加载胜利、图片加载胜利等这些异步事件胜利的机会,导致快照比实在页面元素短少或者数据不精确,而淡出动画可能无效淡化这些过错造成的视觉异样感。上面的 demo 比照了这两种状况:

直出 淡出

可交互

因为快照和实在的首屏页面根本是雷同的,从用户体感上用户会以为首屏曾经胜利展示,也应该是个可交互的页面。所以 单纯展现死的快照页面是远远不够的,做到可交互是咱们快照的重要能力

咱们的快照反对响应用户的点击行为,具体方法就是在用户点击快照时先暂存用户的点击事件,待快照暗藏时将此次事件散发到实在页面下来。

此过程中如果用户有屡次点击事件,咱们只会响应最初一次点击事件。

从用户体感上来说,可能用户会感觉到此次点击的响应会比较慢,但不会让用户感知到它点击的是快照还是实在首页。

如果是小程序启动较慢的场景,还能够思考在用户点击后展现 loading:

为进一步提高快照层的可交互性,咱们甚至还能够容许开发者设定一些快照层的点击区域和简略操作,使用户在点击快照层的时候疾速响应点击事件。例如钉钉的工作台就非常适合这种场景:工作台中的各个利用个别不会频繁变动,并且有很明确的分块区域:

能够配置好不同的点击区域以及对应的 action(例如:跳转到其它页面 / 利用),形如:

[{
  area: {
    left: 100, 
    top: 100, 
    width: 100, 
    height: 100
  },
  action: {
    type: 'openLink', 
    params: {url: 'http://xxx'}
  }
}, ...]

这样用户在点击快照指定区域时就能间接实现跳转,而无需期待到小程序启动实现。

存储与平安

快照属于敏感数据,并且只保留在客户端本地不能进行上传,治理其存储必须分外小心,否则很容易酿成一起公关事件。

对于快照的存储,咱们思考了以下几点:

加密存储

快照数据必须进行 加密存储,这里加密形式用的是团体无线保镖里的加密办法。

隐衷爱护

快照里不能含有用户的隐衷数据。也就是说,快照该当只含有一些 UI 元素或者无意义的默认数据,而不应该含有用户隐衷数据。

不含用户隐衷数据 含用户隐衷数据

那么如何做到获取到不含用户隐衷数据的首页快照呢?能够思考在前端从网络、缓存中获取数据之前进行快照。但这样的快照必然是不残缺的,会损失肯定的体验,这也是咱们不举荐在有用户数据的首屏场景应用快照的起因。

快照清理

快照被存储在客户端中,须要有存储下限。当快照数据达到一定量后,须要淘汰一些老的快照数据。\
其次,在小程序版本更新、用户登出切换用户时都应该思考将现存的对应快照数据清理掉。

准确性

当快照上线后,咱们须要对快照的用户体验进行感知。最佳的体验是用户基本就没有感知到快照的存在,也就是快照和实在页面齐全重合;而如果快照和实在页面相差较大,则会让用户体验大大降落,这是咱们须要感知到的。

这里咱们次要关注快照的 准确性 指标,也就是快照和实在页面的类似(重合)水平。准确性越高,则阐明快照与实在页面的过渡约天然,体验越好;反之岂但不会晋升体验,可能还会对用户带来困惑。

如何判断快照准确性

在每次生成快照时,咱们会将本次快照与上一次快照进行比照,得出量化的指标进而反映快照的准确性。那么下一步的问题就变成了如何判断两张图片的 类似度 了。

这里可能首先会想到间接应用像素一一比照的形式来计算出两张快照中不同像素点的比例,比例越高则快照越精确,但实际上这种办法无奈体现出真正的类似度和用户的体感。例如,当两张快照地位只有稍有偏移,得进去的类似度值可能很低;或者是两张色差很小的快照,也可能失去很差的后果。并且,快照的像素数可能达到上百万量级,测试发现一一的像素比照工作一次可能就会耗时数秒钟。

咱们当初应用了 Google 以图搜图中用到的“感知哈希算法”来量化快照的准确性。算法自身流程大抵是将图片压缩后得出一些“指纹”信息,而后通过比照不同图片的指纹信息计算出“差别指数”。差别指数越高,则阐明二者类似度越低。此算法可能体现出两次快照的类似水平,并且其效率比像素一一比对的办法有了极大晋升,线上数据统计到整个算法的耗时不超过 3ms。

咱们对一些场景进行了试验并得出差别指数。能够看出,对于渺小字符扭转的场景,差别指数非常低;而有显著视觉差距的场景中,差别指数会变高。这样得出的量化值可能体现快照对用户带来的实在体感的影响。

场景差别指数视觉效果
大量字符变动 1
整体偏移 6

如何还原谬误快照场景

可能感知快照的准确性后,对于准确性较差的快照,咱们还须要晓得快照和实在页面相差在什么中央,进而改良快照的机会。

这里,咱们是通过获取快照时前端页面 DOM 树的形式来追究以后的实在页面状况。具体操作是在生成快照时获取以后小程序 HTML 页面 脱敏 后的 DOM 树信息,而后再依赖小程序框架的 CSS 文件,最初间接用浏览器就能够复原出快照时的界面了

其它能力

部分快照

快照的一个比拟大的局限性就是无奈适应多变的首屏场景,这种场景应用快照很容易导致每次快照都无奈跟实在首页重合,反而升高了用户体验。所以咱们思考提供一种能力,只对首页中每次都根本不变的局部进行快照,而其它多变的局部不进行快照,这样也可能每次使首屏局部内容实现秒出。

例如钉钉里的人脉首页,上半局部是绝对固定的展现,而下半局部 feed 流可能每次关上都会展现不同的信息。那么在这种场景下咱们就没必要每次都对整个首页第一屏进行快照,能够指定肯定高度的局部进行快照,让首页的一部分实现秒出。

超一屏快照

当首页可滚动时,咱们甚至能够思考超过一屏长度的快照,并且下次小程序启动时展现快照时让快照可滚动。此计划须要留神两个问题:

  1. 快照大小 \
    线上统计显示,一屏的快照文件均匀大小在 100K 左右。如果是超一屏的快照,大小可能会达到几百 K。须要在生成快照时预估一个长度下限或快照大小下限,以防快照应用时在低端机中呈现 OOM 等异常情况。
  2. 快照滚动 \
    如果快照在展现时用户进行了滚动操作,那么在暗藏快照时须要记录以后滚动的偏移量,以便将实在首页也滚动到指定地位,能力让快照和实在页面重合。

性能

对于快照的性能体现,咱们进行了实验室测试和线上的数据统计。

实验室测试中咱们结构了一个超大的快照(5.2M)的极限场景,并在低端机上与失常快照进行了比照:

一般场景极其场景
快照大小 262K 5.2M
内存占用 1840K 3245K
加载视觉体验 间接呈现 有极短暂延时

快照加载过程并没有影响失常的页面切换,只是在过大快照的加载可能有短暂的延时。

线上数据显示,带快照的页面加载耗时在 280ms 左右,快照的均匀大小约 110K。

快照的生成和准确性检测等工作都是在异步线程中进行的,此时用户交互并未开始,并且在用户滚动、交互后不会进行快照,不会对性能造成太多影响。

这里还有个比拟乏味的数据:用户对快照的均匀点击次数是 0.6 次,首次点击工夫约为 1500ms。也就是说,当快照展现 1.5s 后,有一半多的人会开始首次的交互。这也足矣阐明让快照具备可交互能力的重要性。

瞻望

快照技术尽管缘起是为解决小程序启动性能问题,但理论使用场景能够扩大到更多中央。

实践上来说,任何模式的异步渲染场景,不论是当初 WebView 还是 weex 渲染的小程序,或者就是一般的 H5 网页,甚至是一些 native 的场景(须要 loading 的场景),只有是一块可能在客户端中展现的视图,都可能使用快照技术解决其过程中的白屏或 loading 问题,并且都能做到秒出、可交互。因为快照是一个纯 native 的技术,它的实现原本就不依赖于实在页面的渲染形式,它更须要关怀的是更适合的快照机会和利用场景从而获取更佳的体验。

总结

咱们提出了一种全新的小程序快照技术,实现了小程序首页的秒开和可交互。它可能彻底消除小程序关上过程中的 loading 或白屏景象,让小程序关上达到了 native 的体验,还能够响应用户点击交互。

它是一种纯 native 的技术,不依赖于小程序容器和前端的渲染,只有有视图就能快照,只有有快照数据就能立刻展现,甚至可扩大使用于其它非小程序场景。

而其局限性次要是依赖首屏款式和快照机会抉择,多变、含用户隐衷数据的首屏不适宜快照,而且优质快照的生成的机会要求比拟刻薄。在快照准确性保障方面,快照的类似度比照办法上也依然有很大的优化空间,这些都还须要在今后一直打磨。

退出移动版