優化EXTJS的按模塊下載JS的功能
最近有很多用戶跟我反饋,訪問Joffice頁面的某些功能,須要等幾秒鐘才能出 來。鑑於這種狀況,在此分析一下緣由,同時也給出一些解決方案,能夠幫助Joffice 1.2,Joffice 1.3的開發用戶解決這種根本的問題,可讓這種按模塊下載js速度提升7-8倍,特別是有一些模塊須要加載不少js的時候,其下載速度還高更多。
joffice 1.3之前的版本,按模塊下載的原理以下:
在此咱們以流程管理模塊爲例:
在App.import.js中定義該模塊所依賴的js,以下:
- FlowManagerView:[
- __ctxPath+'/js/flow/ProTypeForm.js',
- __ctxPath+'/js/flow/ProDefinitionForm.js',
- __ctxPath+'/js/flow/ProDefinitionView.js',
- __ctxPath+'/js/flow/FlowManagerView.js',
- __ctxPath+'/js/flow/ProDefinitionDetail.js',
- __ctxPath+'/js/flow/ProcessRunStart.js',
- __ctxPath+'/js/flow/ProDefinitionSetting.js',
- __ctxPath+'/js/flow/MyTaskView.js',
- __ctxPath+'/js/flow/ProcessNextForm.js',
- __ctxPath+'/js/flow/FormDesignWindow.js',
- __ctxPath+'/js/flow/FormEditorWindow.js',
- __ctxPath+'/js/flowDesign/FlowDesignerWindow.js'
- ]
在此能夠看出,該模塊所依賴的js比較多,不過每一個js都不大。
當點擊左菜單的「流程管理」時,其就經過ScriptMgr來下載其所依賴的js,所有下載完成後,才建立這個流程管理的Panel,而且加到TabCenterPanel中去。
咱們的調用下載的js代碼以下:
- function $ImportJs(viewName,callback,params) {
- var b = jsCache[viewName];
-
- if (b != null) {
- var view =newView(viewName,params);
- callback.call(this, view);
- } else {
- var jsArr = eval('App.importJs.' + viewName);
- if(jsArr==undefined || jsArr.length==0){
- try{
- var view = newView(viewName,params);
- callback.call(this, view);
- }catch(e){
- }
- return ;
- }
- ScriptMgr.load({
- scripts : jsArr,
- callback : function() {
- jsCache[viewName]=0;
- var view = newView(viewName,params);
- callback.call(this, view);
- }
- });
- }
- }
即咱們調用:
- $ImportJs('FlowManagerView',function(){
- return new FlowManagerView();
- });
當傳入FlowManagerView時,告訴咱們就是須要在App.Import.js中取出該依賴的js數組,而後傳給ScriptMgr的load中的scripts參數,告訴他們咱們要完成這些js的加載,而且完成後,建立FlowManagerView對象。
如今咱們來看一下ScriptMgr的Load方法:
- ScriptLoaderMgr = function() {
- this.loader = new ScriptLoader();
-
- this.load = function(o) {
- if (!Ext.isArray(o.scripts)) {
- o.scripts = [o.scripts];
- }
-
- o.url = o.scripts.shift();
-
- if (o.scripts.length == 0) {
- this.loader.load(o);
- } else {
- o.scope = this;
- this.loader.load(o, function() {
- this.load(o);
- }); [size=medium][/size]
- }
- };
- };
ScriptLoader的代碼以下:
- /**
- * 用於動態加載js
- * sample is here
- * ScriptMgr.load({
- * scripts: ['/js/other-prerequisite.js', '/js/other.js'],
- * callback: function() {
- * var other = new OtherObject();
- * alert(other); //just loaded
- * }
- * });
- */
- ScriptLoader = function() {
- this.timeout = 10;
- this.scripts = [];
- this.disableCaching = true;//false
- this.loadMask = null;
- };
-
- ScriptLoader.prototype = {
- showMask : function() {
- if (!this.loadMask) {
- this.loadMask = new Ext.LoadMask(Ext.getBody());
- this.loadMask.show();
- }
- },
-
- hideMask : function() {
- if (this.loadMask) {
- this.loadMask.hide();
- this.loadMask = null;
- }
- },
-
- processSuccess : function(response) {
- this.scripts[response.argument.url] = true;
- window.execScript ? window.execScript(response.responseText) : window
- .eval(response.responseText);
- //if (response.argument.options.scripts.length == 0) {
- this.hideMask();
- //}
- if (typeof response.argument.callback == 'function') {
- response.argument.callback.call(response.argument.scope);
- }
- },
-
- processFailure : function(response) {
- this.hideMask();
- Ext.MessageBox.show({
- title : '應用程序出錯',
- msg : 'Js腳本庫加載出錯,服務器可能中止,請聯繫管理員。',
- closable : false,
- icon : Ext.MessageBox.ERROR,
- minWidth : 200
- });
- setTimeout(function() {Ext.MessageBox.hide();}, 3000);
- },
-
- load : function(url, callback) {
- var cfg, callerScope;
- if (typeof url == 'object') { // must be config object
- cfg = url;
- url = cfg.url;
- callback = callback || cfg.callback;
- callerScope = cfg.scope;
- if (typeof cfg.timeout != 'undefined') {
- this.timeout = cfg.timeout;
- }
- if (typeof cfg.disableCaching != 'undefined') {
- this.disableCaching = cfg.disableCaching;
- }
- }
-
- if (this.scripts[url]) {
- if (typeof callback == 'function') {
- callback.call(callerScope || window);
- }
- return null;
- }
-
- this.showMask();
- //alert('load now?');
- Ext.Ajax.request({
- url : url,
- success : this.processSuccess,
- failure : this.processFailure,
- scope : this,
- timeout : (this.timeout * 1000),
- disableCaching : this.disableCaching,
- argument : {
- 'url' : url,
- 'scope' : callerScope || window,
- 'callback' : callback,
- 'options' : cfg
- }
- });
- }
- };
從以上咱們能夠看出,其加載的js數組的時候,是加載完成一個js後,而後 再加載另外一個js,直到加載完成後才調用回調函數。若一個模塊有20個js,每一個js平均下載的時間須要0.5秒,即就須要10秒鐘加載。固然咱們能夠把 這些js合併至一個js,而後下載,這是理論上是能夠的,不過不利於代碼的劃分。
咱們知道瀏覽器是能夠同時下載這些js的,只不過咱們須要知道何時下載完成,下載完成後咱們就能夠調用回調函數。
鑑於此, 咱們經過一個變量來記錄其下載js,每完成下載一個就自動加1,若下載完成後,下載的數量就跟咱們依賴的js的數量同樣,就能夠回調,這樣咱們有多少個js,就產生多少個下載器,每一個下載器同時下載這些js,改進後的ScriptMgr的代碼以下所示:
- ScriptLoaderMgr = function() {
- this.loader = new ScriptLoader();
- this.load = function(o) {
- if (!Ext.isArray(o.scripts)) {
- o.scripts = [o.scripts];
- }
- //記數器
- o.lfiles=0;
- for(var i=0;i<o.scripts.length;i++){
- o.url = o.scripts[i];
- o.scope = this;
- this.loader.load(o, function() {
- o.lfiles++;
- if(o.lfiles==o.scripts.length){
- if(o.callback!=null){
- this.loader.hideMask();
- o.callback.call(this);
- }
- }
- });
- }
- };
- };
你們能夠在訪問體驗一下:
http://oa.jee-soft.cn:8080/index.jsp
http://office.jee-soft.cn:8080/index.jsp user:csx pwd 111
歡迎關注本站公眾號,獲取更多信息