专栏名称: AleCC
善良的小美工
目录
相关文章推荐
新华社  ·  夜读|沉得住气,才能成大器 ·  8 小时前  
中国新闻周刊  ·  汾酒凭什么圈粉年轻人? ·  昨天  
河北交通广播  ·  【992 | 交管】车牌 "穿帮"、车道 ... ·  2 天前  
河北交通广播  ·  石家庄都市圈获批!包括5市 ·  2 天前  
51好读  ›  专栏  ›  AleCC

Tinder渐进式网页应用性能案例学习

AleCC  · 掘金  ·  · 2018-01-28 05:13

正文

原文出处 A Tinder Progressive Web App Performance Case Study

Tinder最近对移动端“右滑”了。他们最近出品的响应式的 渐进式网页应用 —— Tinder Online ——已经可以在桌面和移动端使用了,应用采用了新技术做 JavaScript性能优化 ,并用 Service Workers Push Notification 分别做了网络弹性和对话约会。今天我们来简单过一遍他们的性能学习之路。

踏上渐进式网页应用的旅程

Tinder Online的目标是在新市场站稳脚跟,力争达到在其它平台上Tinder V1版本的使用体验。

PWA的MVP花了三个月,采用了 React 构架UI库和 Redux 做状态管理。 这些努力的结果就是,渐进式网页应用只使用了10%的流量消耗就达到了Tinder核心的应用体验,这对流量费用昂贵或连接速度慢的地区的人来讲尤为重要:

上图是Tinder Online和原生应用的流量消耗对比。值得注意的是,这并不是横向的比较。PWA只会按需从新路由上加载代码,这些额外的代码加载分散在应用的整个生命周期里面。后续导航消耗流量依旧比下载整个app的要少。

早期征兆显示,对比原生应用,PWA表现出了流畅的滑动体验,更多的消息操作和更长的会话时间。在PWA上:

  • 用户的滑动操作更多
  • 用户之间发送的消息更多
  • 用户的购买量与原生应用持平
  • 用户对个人资料的编辑更为频繁
  • 用户的会话时间更长

性能

Tinder Online的移动端用户使用最多的设备包括:

  • Apple iPhone和iPad
  • Samsung Galaxy S8
  • Samsung Galaxy S7
  • Motorola Moto G4

通过使用 Chrome用户体验报告 (CrUX),我们了解到大部分的用户在浏览Tinder Online的时候使用的是4G网络:

注:Rick Viscomi最近在 PerfPlanet 中加入了CrUX,Inian Parameshwaran使用了 rUXt 将数据变得更加可视化。

在使用 WebPageTest Lighthouse (4G下使用Galaxy S7)测试后,我们看到用户在 五秒钟之内 即可加载完毕并进入可交互状态。

当然,在受CPU约束的 中端移动设备 (比如Moto G4)上,仍然存在很多可优化空间:

Tinder正在努力优化他们的体验,未来我们也希望能看到他们在网页性能优化上所做的工作。

性能优化

Tinder使用了很多技术来提升加载速度和减少进入可交互状态之前的时间。他们使用了基于路由的代码分割,并引入了性能预算和资源的长期缓存。

基于路由的代码分割

Tinder网页端最初包含了庞大的JavaScript代码包,这延长了应用的加载时间。这些包中包含了很多并不需要立即加载的代码,因此这些代码可以通过使用 代码分割 打碎。 只加载用户首屏使用的代码,其它的在需要的时候懒加载,这种办法非常有用。

为了达到这一点,Tinder使用了 React Router React Loadable 。他们的应用把路由和渲染信息集中在了一个配置里面,他们发现可以直接在顶层做代码分割。

简介: React Loadable的的作者是James Kyle,他的初衷是简化以组件为中心的React应用的 代码分割 Loadable 是一个高阶组件(一个创建组件的函数),能够在组件层使得 分割 代码包更加简单。

比如我们有两个组件,“A”和“B”。在做代码分割之前,Tinder静态地将所有东西(A、B等等)都引入到主包里面。这种方式很低效,因为我们并不立刻且同时需要A和B两个组件:

在做了代码分割之后,组件A和组件B会在需要的时候再加载。Tinder在JS中引入了React Loadable, 动态导入 webpack的魔法注释 (针对命名动态代码块):

针对“vendor”(库),Tinder使用了 CommonsChunkPlugin 将频繁使用的公共库单独打包,这样可以有效利用长缓存:

接着,Tinder使用 React Loadable的预加载支持 来预加载下一页可能会使用到的资源:

Tinder也使用了 Service Workers 来预缓存所有路由层的代码包,并把用户最有可能访问的路由在未做分割的情况下加进了主包中。当然他们也使用了最常用的优化手段,例如通过UglifyJS最小化JavaScript文件的体积:

new webpack.optimize.UglifyJsPlugin({
    parallel: true,
    compress: {
    warnings: false,
        screw_ie8: true
    },
    sourceMap: SHOULD_SOURCEMAP
}),

影响

在引入了基于路由的代码分割之后,他们的主包的大小从166KB降至了101KB,DCL从5.46秒降至4.69秒:

资源的长期缓存

通过使用webpack的[chunkhash]向文件名中加入独一无二的字段,这保证了静态资源的 长期缓存

Tinder在依赖中使用了很多开源的库。vendor的[chunkhash]会随着对这些库作出的改变而改变,这就会使缓存失效。为了解决这个问题,Tinder定义了一个 外部库白名单 ,并将他们的manifest文件从主代码块中分离出来,以改善缓存。现在两个代码包的大小大约都是160KB。

预加载后期使用资源

作为一名新手, <link rel="preload"> 是一个声明式的命令,指导浏览器预先加载关键的、后续会用到的资源。在一个单页面应用里面,这些资源可能会是JavaScript包。







请到「今天看啥」查看全文