`
man1900
  • 浏览: 429226 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

优化EXTJS的按模块下载JS的性能

    博客分类:
  • EXT3
阅读更多

最近有不少用户跟我反馈,访问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);
					});
		}
	};
};

 

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

 

 

分享到:
评论
5 楼 man1900 2012-08-08  
ZQX123456 写道
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  
                    }  
                });
 
上面代码中为什么是argument、我看ext的api应是params、难道是版本问题?

argument是js函数本身的写法,用于传递参数
4 楼 ZQX123456 2012-08-07  
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  
                    }  
                });
 
上面代码中为什么是argument、我看ext的api应是params、难道是版本问题?
3 楼 ZQX123456 2012-08-07  
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  
                    }  
                });
 
上面代码中为什么是argument、我看ext的js应是params、难道是版本问题?
2 楼 man1900 2010-06-11  
要看你单位的带宽是否够大
1 楼 mygol 2010-06-10  
服务器放在局域网中 通过花生壳访问外网 不知道ext能否胜任

相关推荐

    Extjs 性能优化 High Performance ExtJs

    本文适合有一定javascript基础(明确js的面向对象,继承,作用域等)并能熟练使用extjs框架(明确各组件间的继承关系)的人阅读,目的在于对extjs的前台架构进行性能上的优化,核心思想为:“按需索取,晚使用,晚加载...

    extjs与系统切分模块设计

    extjs与系统切分模块设计 extjs与系统切分模块设计 extjs与系统切分模块设计

    ExtJS 6.2 实战 下载

    ExtJS 6.2 实战

    Extjs API 文档 下载

    ExtJs API 文档 下载,初学者必备

    EXTJS批量上传下载

    EXTjs批量上传下载功能

    extjs-3.4.0下载

    extjs-3.4.0下载,含API文档

    extjs extjs-basex.js

    extjs-basex.js extjs-basex.js extjs-basex.js

    Extjs 2.2 Extjs 3.21 js

    里面包含Extjs 2.2和Extjs 3.2.1版本两个文件

    ExtJS 7.6 SDK trial

    ExtJS 7.6 SDK trial

    extjs4完整下载

    ExtJS4正式版(官方完整下载包):含所有的源代码,html,api文档,示例。官方网站下载现在需要注册,这个仅供爱好者个人学习使用,如果项目中使用请至官方网站购买。

    extjs-basex.js

    extjs-basex.js extjs-basex.js extjs-basex.js

    extjs4.x学习笔记

    从开发大型的web后台或者企业管理系统来看,ExtJs3的缺陷还是比较明显的,从ExtJs4 开始引入了MVC架构,从而能够从容的组织系统的JS文件了。 从ExtJs5开始则引入了MVVC架构。 从网上资料来看,多数都是停留在ExtJs3...

    ExtJs源码

    extjs 源码,有兴趣的可以学习下

    ExtJS实现文件下载

    ExtJS实现文件下载的方法 前台代码: Ext.get('outputuser').on('click', function(e){ Ext.MessageBox.confirm('提示','确定要导出用户吗?',function(btn){

    ExtJS如何自定义图片按钮组件

    1.ExtJS自定义组件,图片按钮为例. 2.此图片按钮背景完全为图片,没有边框,需要使用者提供2张图片,一张初始化用,一张点击后用,可在'imgPaths:'属性里填写,格式为'01.jpg~02.jpg' 3.解压后请将所有附件放置您extjs...

    ExtJS Ext ExtJavascript Javascript

    ExtJS Ext ExtJavascript Javascript

    extjs6.2 SDK下载

    本包为extjs6.2包,可以直接使用sencha CMD运行。 sencha CMD使用方法可以查看教程

    extjs4.0引用的JS和CSS

    extjs4.0引用的JS和CSS文件,方便实用

    ExtJS书籍资料打包下载

    1.Ext中文手册(100页) 2.ExtJS教程(83页) 3.ExtJS面板的布局(只是书籍中的一章) 4.深入浅出ExtJS(部分...个人能力有限,在网上只找到这些资料,希望能对大家有一点用处,如果下载了的朋友觉得不满意,请轻拍。

    eclipse-ExtJs插件

    应该是目前写js和ExtJs最好的工具。 先到http://www.easyjf.com/上下载ExtJS2.0。 说明: 1,将下载的压缩包解压到eclipse的安装目录,完成后重启(自动会加载插件,也可CMD ECLIPSE目录 使用命令 eclipse -clean ...

Global site tag (gtag.js) - Google Analytics