博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
优化EXTJS的按模块下载JS的功能
阅读量:6006 次
发布时间:2019-06-20

本文共 4842 字,大约阅读时间需要 16 分钟。

hot3.png

最近有不少用户跟我反馈,访问Joffice页面的某些功能,需要等几秒钟才能出 来。鉴于这种情况,在此分析一下原因,同时也给出一些解决方案,可以帮助Joffice 1.2,Joffice 1.3的开发用户解决这种根本的问题,可以让这种按模块下载js速度提高7-8倍,特别是有一些模块需要加载很多js的时候,其下载速度还高更多。
joffice 1.3以前的版本,按模块下载的原理如下:
在此我们以流程管理模块为例:
在App.import.js中定义该模块所依赖的js,如下:
   
Java代码
  1. FlowManagerView:[    
  2.                 __ctxPath+'/js/flow/ProTypeForm.js',    
  3.                 __ctxPath+'/js/flow/ProDefinitionForm.js',    
  4.                 __ctxPath+'/js/flow/ProDefinitionView.js',    
  5.                 __ctxPath+'/js/flow/FlowManagerView.js',    
  6.                 __ctxPath+'/js/flow/ProDefinitionDetail.js',    
  7.                 __ctxPath+'/js/flow/ProcessRunStart.js',    
  8.                 __ctxPath+'/js/flow/ProDefinitionSetting.js',    
  9.                 __ctxPath+'/js/flow/MyTaskView.js',    
  10.                 __ctxPath+'/js/flow/ProcessNextForm.js',    
  11.                 __ctxPath+'/js/flow/FormDesignWindow.js',    
  12.                 __ctxPath+'/js/flow/FormEditorWindow.js',    
  13.                 __ctxPath+'/js/flowDesign/FlowDesignerWindow.js'    
  14.         ]  
 
在此可以看出,该模块所依赖的js比较多,不过每个js都不大。
当点击左菜单的“流程管理”时,其就通过ScriptMgr来下载其所依赖的js,全部下载完成后,才创建这个流程管理的Panel,并且加到TabCenterPanel中去。
我们的调用下载的js代码如下:
Java代码
  1. function $ImportJs(viewName,callback,params) {    
  2.     var b = jsCache[viewName];    
  3.         
  4.     if (b != null) {    
  5.         var view =newView(viewName,params);    
  6.         callback.call(this, view);    
  7.     } else {    
  8.         var jsArr = eval('App.importJs.' + viewName);    
  9.         if(jsArr==undefined || jsArr.length==0){    
  10.             try{    
  11.                 var view = newView(viewName,params);    
  12.                 callback.call(this, view);    
  13.             }catch(e){    
  14.             }    
  15.             return ;    
  16.         }    
  17.         ScriptMgr.load({    
  18.                     scripts : jsArr,    
  19.                     callback : function() {    
  20.                         jsCache[viewName]=0;    
  21.                         var view = newView(viewName,params);    
  22.                         callback.call(this, view);    
  23.                     }    
  24.         });    
  25.     }    
  26. }  
即我们调用:
Java代码
  1. $ImportJs('FlowManagerView',function(){    
  2.       return new FlowManagerView();    
  3. });  
当传入FlowManagerView时,告诉我们就是需要在App.Import.js中取出该依赖的js数组,然后传给ScriptMgr的load中的scripts参数,告诉他们我们要完成这些js的加载,并且完成后,创建FlowManagerView对象。
现在我们来看一下ScriptMgr的Load方法:
Java代码
  1. ScriptLoaderMgr = function() {    
  2.     this.loader = new ScriptLoader();    
  3.     
  4.     this.load = function(o) {    
  5.         if (!Ext.isArray(o.scripts)) {    
  6.             o.scripts = [o.scripts];    
  7.         }    
  8.     
  9.         o.url = o.scripts.shift();    
  10.     
  11.         if (o.scripts.length == 0) {    
  12.             this.loader.load(o);    
  13.         } else {    
  14.             o.scope = this;    
  15.             this.loader.load(o, function() {    
  16.                         this.load(o);    
  17.                     });  [size=medium][/size]  
  18.         }    
  19.     };    
  20. };  
ScriptLoader的代码如下:
Java代码
  1. /**  
  2.  * 用于动态加载js  
  3.   *  sample is here  
  4.   *   ScriptMgr.load({  
  5.   *   scripts: ['/js/other-prerequisite.js', '/js/other.js'],  
  6.   *   callback: function() {  
  7.   *     var other = new OtherObject();  
  8.   *     alert(other); //just loaded  
  9.   *   }  
  10.   * });   
  11.   */    
  12. ScriptLoader = function() {    
  13.     this.timeout = 10;    
  14.     this.scripts = [];    
  15.     this.disableCaching = true;//false    
  16.     this.loadMask = null;    
  17. };    
  18.     
  19. ScriptLoader.prototype = {    
  20.     showMask : function() {    
  21.         if (!this.loadMask) {    
  22.             this.loadMask = new Ext.LoadMask(Ext.getBody());    
  23.             this.loadMask.show();    
  24.         }    
  25.     },    
  26.     
  27.     hideMask : function() {    
  28.         if (this.loadMask) {    
  29.             this.loadMask.hide();    
  30.             this.loadMask = null;    
  31.         }    
  32.     },    
  33.     
  34.     processSuccess : function(response) {    
  35.         this.scripts[response.argument.url] = true;    
  36.         window.execScript ? window.execScript(response.responseText) : window    
  37.                 .eval(response.responseText);    
  38.         //if (response.argument.options.scripts.length == 0) {    
  39.             this.hideMask();    
  40.         //}    
  41.         if (typeof response.argument.callback == 'function') {    
  42.             response.argument.callback.call(response.argument.scope);    
  43.         }    
  44.     },    
  45.     
  46.     processFailure : function(response) {    
  47.         this.hideMask();    
  48.         Ext.MessageBox.show({    
  49.                     title : '应用程序出错',    
  50.                     msg : 'Js脚本库加载出错,服务器可能停止,请联系管理员。',    
  51.                     closable : false,    
  52.                     icon : Ext.MessageBox.ERROR,    
  53.                     minWidth : 200    
  54.                 });    
  55.         setTimeout(function() {Ext.MessageBox.hide();}, 3000);    
  56.     },    
  57.     
  58.     load : function(url, callback) {    
  59.         var cfg, callerScope;    
  60.         if (typeof url == 'object') { // must be config object    
  61.             cfg = url;    
  62.             url = cfg.url;    
  63.             callback = callback || cfg.callback;    
  64.             callerScope = cfg.scope;    
  65.             if (typeof cfg.timeout != 'undefined') {    
  66.                 this.timeout = cfg.timeout;    
  67.             }    
  68.             if (typeof cfg.disableCaching != 'undefined') {    
  69.                 this.disableCaching = cfg.disableCaching;    
  70.             }    
  71.         }    
  72.     
  73.         if (this.scripts[url]) {    
  74.             if (typeof callback == 'function') {    
  75.                 callback.call(callerScope || window);    
  76.             }    
  77.             return null;    
  78.         }    
  79.     
  80.         this.showMask();    
  81.         //alert('load now?');    
  82.         Ext.Ajax.request({    
  83.                     url : url,    
  84.                     success : this.processSuccess,    
  85.                     failure : this.processFailure,    
  86.                     scope : this,    
  87.                     timeout : (this.timeout * 1000),    
  88.                     disableCaching : this.disableCaching,    
  89.                     argument : {    
  90.                         'url' : url,    
  91.                         'scope' : callerScope || window,    
  92.                         'callback' : callback,    
  93.                         'options' : cfg    
  94.                     }    
  95.                 });    
  96.     }    
  97. };  
从以上我们可以看出,其加载的js数组的时候,是加载完成一个js后,然后 再加载另一个js,直到加载完成后才调用回调函数。若一个模块有20个js,每个js平均下载的时间需要0.5秒,即就需要10秒钟加载。当然我们可以把 这些js合并至一个js,然后下载,这是理论上是可以的,不过不利于代码的划分。
我们知道浏览器是可以同时下载这些js的,只不过我们需要知道什么时候下载完成,下载完成后我们就可以调用回调函数。
鉴于此, 我们通过一个变量来记录其下载js,每完成下载一个就自动加1,若下载完成后,下载的数量就跟我们依赖的js的数量一样,就可以回调,这样我们有多少个js,就产生多少个下载器,每个下载器同时下载这些js,改进后的ScriptMgr的代码如下所示:
Java代码
  1. ScriptLoaderMgr = function() {    
  2.     this.loader = new ScriptLoader();    
  3.     this.load = function(o) {    
  4.         if (!Ext.isArray(o.scripts)) {    
  5.             o.scripts = [o.scripts];    
  6.         }    
  7.         //记数器    
  8.         o.lfiles=0;    
  9.         for(var i=0;i<o.scripts.length;i++){    
  10.             o.url = o.scripts[i];    
  11.             o.scope = this;    
  12.             this.loader.load(o, function() {    
  13.                 o.lfiles++;    
  14.                 if(o.lfiles==o.scripts.length){    
  15.                     if(o.callback!=null){    
  16.                         this.loader.hideMask();    
  17.                         o.callback.call(this);    
  18.                     }    
  19.                 }    
  20.             });    
  21.         }    
  22.     };    
  23. };  
大家可以在访问体验一下:
 
 
  user:csx
  pwd 111

转载于:https://my.oschina.net/u/587349/blog/71621

你可能感兴趣的文章
下午最后的草坪
查看>>
Maven学习总结(七)——eclipse中使用Maven创建Web项目
查看>>
1.部分(苹果)移动端的cookie不支持中文字符,2.从json字符串变为json对象时,只支持对象数组...
查看>>
HDU3257 Hello World!【打印图案+位运算】
查看>>
Node.js 抓取电影天堂新上电影节目单及ftp链接
查看>>
从设计者的角度看 React
查看>>
CSS居中总结大全
查看>>
Elasticsearch 参考指南(安装X-Pack)
查看>>
[LintCode] 604. Design Compressed String Iterator
查看>>
微信小程序黑客马拉松即将开始,来做最酷的 Mini Program Creators!
查看>>
JavaScript基础---函数
查看>>
前端每日实战:120# 视频演示如何用纯 CSS 创作锡纸撕开的文字效果
查看>>
Laravel实用小功能
查看>>
matplotlib绑定到PyQt5(有菜单)
查看>>
利用Powershell和ceye.io实现Windows账户密码回传
查看>>
Windows 8.1 今年 1 月市场份额超 Vista
查看>>
《设计团队协作权威指南》—第1章1.5节总结
查看>>
Chair:支付宝前端团队推出的Node.js Web框架
查看>>
《Total Commander:万能文件管理器》——第3.8节.后续更新
查看>>
BSD vi/vim 命令大全(下)[转]
查看>>