Download - Truck js 高性能移动web开发解决方案
truckJS⾼高性能移动web开发解决⽅方案
关于我
•巩守强
•移动前端开发⼯工程师
• 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