Truck js 高性能移动web开发解决方案

Preview:

DESCRIPTION

@meituan

Citation preview

truckJS⾼高性能移动web开发解决⽅方案

关于我

•巩守强

•移动前端开发⼯工程师

• shouqiang.gong@gmail.com

• https://github.com/StuPig

•前端⼯工程化、性能优化

讲些什么

• truckJS是什么?

• 为什么使⽤用truckJS?

• 实际应⽤用• 实战效果• 接下来...

truckJS是什么?

• 狭义上说,truckJS就是个模块化加载器

模块化

• 什么是模块化?• 有那些好处?• 有那些标准?• 有哪些流⾏行的模块化加载器?

什么是模块化开发?

随着业务的发展

代码越积越多

冗余越来越多

维护越来越困难

bug越来越多

稳定性越来越差

效率越来越低

KPI越来越烂

奖⾦金越来越少

回家跪主板的频率越来越⾼高

整个⼈人都不好了〜~

Controlling complexity is the essence of computer programming.

——Brian Kernighan

有哪些好处?

• 按需加载• 避免全局变量• 模块间相互透明• 依赖管理• 性能优化更专注在开发本⾝身上

有哪些标准?

• CommonJS Modules规范

• AMD规范

模块化加载器

RequireJSr.js almond.js…

Sea.jsspmplugins…

为什么要开发truckJS?

• 现有各种模块化加载器• 功能全,但体积⼤大• 简单的依赖浏览器缓存• ⽂文件单个请求,不⽀支持依赖预解析

不适合移动端使⽤用

truckJS到底是什么?

• truckJS不只是⼀一个浏览器端的模块化加载器,

是⼀一整套移动web开发解决⽅方案

truckJS基础架构Browser

Server依赖预解析版本号⽣生成 Combo服务

Combo URL

DeCombo

URL utils模块系统

加载系统

缓存管理Persistence

LS utils

为什么使⽤用truckJS?

先看⼀一个典型的场景〜~

做个简单的详情⻚页应该加个商家电话

还需要个相册

再加个tab吧对了,tab也可能没有

哦,这个⻚页⾯面还需要分享

不要复杂,就安卓系统那样的

就左右滑的那种

好多模块都做过……

明天搞定没问题吧……

• 组件数量会变化

• 组件会有模块依赖

• 模块依赖存在嵌套

• 组件间可能有重复模块

• 组件动态加载

加载组件哪家强?

• 如何更快、更省流量、更省电量的动态加载?

• 为什么这些是传统模块化加载器根本做不到的呢?

• 为什么说turckJS不只是⼀一个模块化加载器,⽽而是⼀一个完整的解决⽅方案?

• truckJS在背后都做了哪些事呢?

本地缓存

• CDN + 浏览器缓存• 缓存容易失效,304浪费请求

• Application Cache

• 全量更新,2次⽣生效

• localStorage

• 速度快,空间⼤大,有先河

传统⽅方式

版本校验

模块完整性

加载模块

请求结果XHR

localStorage

存在缓存

Combo加载

• 什么是Combo加载?

CSS

JS

Combo加载

• 为什么要做Combo加载?

⺴⽹网络延时AT

&T

late

ncie

s fo

r dep

loye

d 2G

–4G

net

wor

ks

GPRS/EDGE

HSPA

HSPA+

LTE

0 200 400 600 800

50

200

400

750

40

100

150

600

最低 最⾼高

Combo加载

• 时间开销RTT + DNS

• domain请求阈值

• 请求最佳传输量~14KB

版本校验

模块完整性

加载模块

请求结果XHRCombo

DeCombo

tag

localStorage

存在缓存

依赖预解析

• 传统的依赖解析list.js加载完成

filter加载完成

依赖预解析

• 上线任务中,通过扫描源码获取抽象语法树(AST)

• 从抽象语法树中获取到该模块的依赖模块

• 获取到每个模块对应的依赖关系

JavaScript AST

require(['zepto.js', 'album.js'], function ($, album) { // ...})

define(['msg.js'], function (msg) { // ...})

JavaScript AST

拓扑排序

a : b, c, db : c, ec :d : b, ee :

依赖关系:a

b d

ec

拓扑排序

• 避免重复依赖,节省请求、带宽、电量和时间

• 有效率⽤用⺴⽹网络缓存、提⾼高CDN缓存命中率

• 发现循环依赖

新的加载⽅方案

“增量”更新

• 以⽂文件为粒度• 给予缓存和依赖预解析,找到“待更新”⽂文件

• 将所有“待更新”⽂文件Combo进⼀一个请求

localStorage

版本校验

模块完整性

加载模块

请求结果XHRCombo

DeCombo

tag依赖排序

存在缓存

短⼩小精悍

• 专注⾼高级浏览器• 没有代码兼容问题

• “约定⼤大于配置”

• define(id?, dependencies?, factory)

• define(dependencies?, factory)

• 简单易⽤用

requirejs.config( { baseUrl: 'http://ms0.meituan.net/', // [String] 基本路径 http|https|ftp

revision: {"a.js":"b2f80e87"}, // [Object] ⽂文件名对应版本号 prefix: 'touch/js/amd/', // [String] ⽂文件的路径前缀 combo: { url: 'http://mc.meituan.net/combo/?f=' // [String] combo 服务地址 }} )

• 不⽤用写什么paths/maps对应路径关系

• 不⽤用写什么preload配置,⾃自动⽽而且动态Combo

短⼩小精悍

gzip后⼤大⼩小(KB)

0

4

8

12

16

truckJS Sea.js RequireJS

14.9

5.93.3

对⽐比

truckJS RequireJS/Sea.js

模块化加载

兼容Node/IE

第三⽅方类库兼容

本地强缓存

动态Combo

依赖预解析

依赖排序

增量更新

体积更⼩小

插件扩展

✔✔

✔✔✔✔✔✔

✔ ✔

实际应⽤用

• 模块化加载• web 组件化

web组件化

• HTML5 web components

• 如何加载

• 如何解决依赖

• 阻塞渲染,SPOF

• 组件数量会变化

• 组件会有模块依赖

• 模块依赖存在嵌套

• 组件间可能有重复模块

• 组件动态加载

配合truckJS, 您只需要简单⼏几⾏行HTML就能搞定〜~

web组件化

<!-- 相册组件‚ --><div class="album" data-com="album" data-pics="http://p1.meituan.net/a.jpg,http://p0.meituan.net/b.jpg,http://p1.meituan.net/c.jpg"> <div class="dealcard-img imgbox" data-src="http://p1.meituan.net/low.jpg" data-src-high="http://p1.meituan.net/high.jpg" data-com="unveil" data-page="0"> <span class="img-count">共3张</span> </div></div>

web组件化

<!-- 选项卡组件 --><ul class="taba" data-com="tab"> <li tab-target="hotel_goupon"><a class="react"><span class="dealtype-icon">团</span> 团购<small>(1)</small></a></li> <li class="active" tab-target="hotel_quick"><a class="react"><span class="dealtype-icon dealcard-magiccard">订</span> 快订<small>(7)</small></a></li></ul>

web组件化

<!-- 拨打电话组件 --><a class="react" data-com="phonecall" data-tele="010-87526100"> <div class="kv-line-r"> <h6><i class="text-icon">✆</i> 010-87526100</h6><p>拨打电话</p> </div></a>

<!-- 分享组件 --><a class="btn btn-block btn-weak btn-margin" gaevent="imt/deal/share" data-com="share" data-share-text="这家店不错哦,⼀一起去吧!010-87526100。http://www.meituan.com/shop/4984058 @美团" data-share-pic="http://p1.meituan.net/300.0/deal/__31728669__7967104.jpg"><i class="text-icon icon-share"></i> 分享</a>

实战效果

• 平均每天JS加载量为35390346,localStorage缓存命中量为29012492,缓存率为

• CDN请求平均时间为1340ms,localStorage时间为

• 每天JS加载⼤大⼩小为160.7G,CDN请求⼤大⼩小为27.94G,节省流量为

⾸首屏加载时间、完全加载时间分别下降了10%、25%

82%

33.75ms

132.76G

接下来

• ⽀支持⽆无差异化加载• 构建组件/模块⽣生态环境

• ⽀支持对tag加载⽅方式的缓存

• 引⼊入插件机制

美团移动前端期待你的加⼊入!

Q&A