Kiwi中js资源加载的优化
shellzhang
2013-12-6
开发与部署环境加载异同
- 808X端口上,全部独立<script>加载
- 80端口上:
- 通过combo_resource合并为一个请求或者
- spm提前打包合并成一个js文件加载
- 目标:
- 线上环境最大限度减少请求数
- 不足:
- 通用文件的更新,会导致各个合并文件均需要更新
- 栗子
栗子
- CommonWidgets
- Model(Helper)
- BU-related JS(Calendar、Event)
- 公用CW与M两个模块
- 一旦其中某一模块更新,会导致两个文件都需要重新合并
- 用户也需要重新下载整个文件
Tradeoff——折中
- 解耦CommonWidget与Model模块
- 解耦方法,见代码
- common-widgets/main.js
- model/all.js
- 引入CommonWidget或Model模块的方法
- PPY.SC.CommonWidget.XXX
- PPY.SC.ModelHelper.xxxxHelper
- 而不是之前的require('xxxxx.js')
解耦过程中遇到的问题
- 发现之前代码有直接在Helper文件中require controller的情况
- 解决办法:helper中采用Spine.trigger的消息机制向监听者发送消息
- Helper之间存在依赖关系
- eventHelper等依赖labelHelper,因为需要初始化并获取用户已选择的label信息
- 解决方法:暂时没找到更好的处理办法,只能在model/all.js中,优先引入labelHelper.js
如何加载
Seajs.use([CW.js, M.js], function(CW, M){
seajs.use(BU.js, function(BU__){
BU__.init();
})
});
- 呀,多了两次js请求。。。
- 以前是(BU+CW+M).js,一次请求
- 现在是CW.js, M.js, 然后,BU.js
- seajs中对BU与CW的加载采用的是async的方式
script的加载方式
- 最基本的<script src="">,无任何添加剂的,阻塞下载+立即执行
- 带defer的script,<script defer src="">
- 立即下载(不阻塞页面解析),但等到页面parse完后才执行,DOMContentLoaded之前
- 带async的script,<script async src="">
- 立即下载(不阻塞页面解析),但不保证多个async的代码会顺序执行
- defer与async
- 尽量不用defer,ie兼容,但其他浏览器支持不够,且表现不尽相同
- async是html5的特性,至少在高级浏览器上表现一致
我们的折中方案
- seajs中的js的加载,会默认使用async方式
- CW与M的下载是异步同时启动的
- 且两者充分解耦,谁先执行都不要紧
- 同时,保证了BU的下载会是在以上两个下载执行完后,才会启动下载并执行
- 这样:
- 虽然我们增加了两个请求,但是换来了:
- 同时下载两个js文件,减少了加载时间
- 解耦了模块,更新时候只需要下载少量js代码就好
后续开发中需要注意的
- 定义了新的ModelHelper,在Controller一层不要直接require
- 在model/all.js中require并赋值给PPY.SC.ModelHelper.XX
- 使用时候直接从ModelHelper名空间下取
- CommonWidget也是同理处理方式
- 注意引用关系,避免反向引用。比如Helper中require了Controller。解耦方法可以采用Spine.trigger来解决
进一步还可以做的工作
- 对event模块进行区分加载
- 根据用户是否登录
- 区分为包含了themeModule、repeatBox、reminderSetting等模块的event.js
- 以及不包含以上模块的event_nologin.js
- 这么做的原因
- 事件页可能会成为未来的运营点
- 会有很多无登录态的新用户从这里起步访问我们
- 如何最快地将页面展示给用户就很重要了
- 方案
- 像第一点说的,区分加载,尽快完成js加载展示页面
- 页面静态化,对热点事件页可以这样处理
进一步还可以做的工作
- 对event页面分为首屏js与非首屏js
- 首屏与非首屏
- pageMain.js, nfsPageMain.js (none-first-screen)
- seajs.async('nfsPageMain.js'),异步加载
- 对comments模块做区分加载
- 非登录用户,其实只要展示comments列表就好,各种操作代码其实都不需要的
参考文献
Optimize Js load in Kiwi
By shellzhang
Optimize Js load in Kiwi
- 999