xevin
29 Oct 2008, 5:37 AM
Introduction
Have you noticed why other Ext JS or JavaScript intensive application loads faster? there are several ways to defeat slow loading, guess.....
faster PC? 'eeeerk' not all of us has 4GB of RAM, but still no. also if u have no,
Fast DSL/T1? 'eeerrk' again, nope.. still we want faster load time,
or loading all JavaScript on every first load? yeah sure, but "don't keep your clients waiting that much load times..." honestly i did that before, not a good results..horror..
SO what then??
my friend, you need to employ your self on making your scripts in Modular Form, say ill load "A" first, & then "A" has to load "B" when i click this and that.. or "A" requires "B", "C" so on and so fort.. this way it minimizes load times.
How?
...xvnBASE will help you do just that..
but first, u need to specify the Directory where your scripts are located. Do it like this:
new xvnBASE('path/to/scripts').load({ ... });
..or..
modify the preset url in the xvnBASE source code at line 52.
Directory structure will be:
/www/public/lib/mods/Frontend/
+ A.js
+ etc...
/www/public/lib/mods/Vendor/Bluff/
+ jsclass.js
+ etc...
but also you need to understand simple things, in using xvnBASE, the main idea of this is to create your script in modular form by namespace... let me give an example, lets say i have a Frontend and this frontend UI has some bits of needed scripts.
new xvnBASE().load('Frontend.A', [config]);
configs:
{
loadOnce: true, // defaults to true - reloads scripts every call if false
OnPreload: function() {},
OnComplete: function(o){
if (!o.AllLoaded)
{
alert('load failed');
}
else
{
Frontend.A();
}
}
}
...when successfully loaded, namespace Frontend.A will be created and eval the script A.js
Scenario for: if A loads B on [events]..
Frontend.A = function(){
...do ur stuff...
var xyz = Ext.Panel({ ...
listeners: {
beforeshow: function()
{
new xvnBASE().load({
items:[ 'Frontend.B','Frontend.C','Frontend.D' ],
OnComplete: function(o){
if (o.AllLoaded)
{
xyz.show();
}
else
{
alert(o.Store.failedItems);
}
}
});
return false;
}
}
});
};
Scenario for: if A requires B & C..
Frontend.A = function(){
var id = Math.random();
var __win = new Ext.Window({
title : 'Bluff Graph',
width : 400,
height : 330,
plain : true,
resizable : false,
constrain : true,
border : false,
draggable : true,
html : '<canvas id="graph' + id + '"></canvas>'
});
new xvnBASE().load({
items: [ 'Vendor.Bluff.jsclass', 'Vendor.Bluff.excanvas', 'Vendor.Bluff.bluff' ],
OnComplete: function(xo){
if (xo.AllLoaded())
{
__win.show();
// Make a graph object with canvas id and width
var g = new Bluff.Line('graph' + id, 400);
// Set theme and options
g.theme_odeo();
g.title = 'My Graph';
// Add data and labels
g.data('Apples', [1, 2, 3, 4, 4, 3]);
g.data('Oranges', [4, 8, 7, 9, 8, 9]);
g.data('Watermelon', [2, 3, 1, 5, 6, 8]);
g.data('Peaches', [9, 9, 10, 8, 7, 9]);
g.labels = {0: '2003', 2: '2004', 4: '2005'};
// Render the graph
g.draw();
}
else
{
...errr...
}
}
});
};
..Thats it... Imagine your ways to do it...
xvnbase.js
/*
xvnBASE 1.0.5
------------------------------------------------------------------------------------
xvnBASE, Modular Approach using namespace objects
------------------------------------------------------------------------------------
| Author: Kevinralph Tenorio. nivektrio[AT]yahoo.com
| Copyright (c) 2008 Kevinralph Tenorio. All rights reserved.
------------------------------------------------------------------------------------
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
------------------------------------------------------------------------------------
*/
var xvnBASE_Store = {
items: [],
failedItems: [],
find: function(B)
{
var i = 0, A;
while((A = this.items[i++]))
{
if (A == B) return true;
};
return false;
}
};
var xvnBASE = function(url)
{
var _this = this;
this.debug = false;
this.libRoot = (typeof(url) === 'undefined' ) ? '/~dev/base/' : url;
this.Store = xvnBASE_Store;
this._loadedQUEUE = 0;
_this.AllLoaded = function()
{
if (_this.Store.failedItems.length >= 1)
return false;
else
return true;
};
this.Util = {
String: {
toDir: function(string)
{
return string.split('.').join('/');
},
getFilename: function(path)
{
return path.substr(path.lastIndexOf("/") + 1, path.length);
},
toNS: function(ns)
{
if (typeof(ns) == 'undefined') return;
var domains = ns.split('.');
var domain = window;
for (var i=0; i<domains.length; i++)
{
var subdomain = domains[i];
if (!domain[subdomain]) domain[subdomain] = {};
domain = domain[subdomain];
}
return domain;
}
}
};
this.load = function(config, rconfig)
{
if (typeof(config) === 'undefined') return;
if (typeof(config) == 'string')
{
_this._run(config, rconfig);
}
else if (typeof(config) == 'object')
{
if (typeof(config.OnPreload) == 'function') config.OnPreload();
config.loadOnce = (typeof(config.loadOnce) == 'boolean') ? config.loadOnce : true;
_this._loadedQUEUE = 0;
var i = 0, el, tryExec = function()
{
if (_this._loadedQUEUE >= config.items.length && typeof(config.OnComplete) == 'function') config.OnComplete(_this);
};
while((el = config.items[i++]))
{
if (!_this.Store.find(el))
{
var xhr = new _this.Ajax();
//xhr.requestDelay = 1000;
xhr.OnSuccess = function()
{
if (config.loadOnce) {
_this.Util.String.toNS(this.ModuleName);
_this.Store.items.push(this.ModuleName);
}
var src = ";_this._loadedQUEUE++; ";
eval(this.GetResponseText() + src);
tryExec();
};
xhr.OnFailure = function()
{
_this._loadedQUEUE++;
_this.Store.failedItems.push(this.ModuleName);
tryExec();
};
xhr.GetData = function()
{
this.InitializeRequest('GET', _this.libRoot + _this.Util.String.toDir(el) + '.js?t=' + new Date().getTime(), true);
this.Commit(null);
this.ModuleName = el;
};
xhr.GetData();
}
else
{
_this._loadedQUEUE++;
tryExec();
}
}
}
};
this._run = function(mod, config)
{
if (typeof(mod) === 'undefined') return;
if (typeof(config) === 'undefined') config = {};
if (typeof(config.OnPreload) == 'function') config.OnPreload();
var tryExecOnComplete = function(obj)
{
if (typeof(config.OnComplete) == 'function') config.OnComplete(obj);
};
if (_this.Store.find(mod))
{
tryExecOnComplete();
}
else
{
new _this.load({
items : [ mod ],
OnComplete: function(obj)
{
tryExecOnComplete(obj);
}
});
}
};
this.Ajax = function()
{
//---------------------
// Private Declarations
//---------------------
var _request = null;
var _this = null;
//--------------------
// Public Declarations
//--------------------
this.ModuleName = '';
this.GetResponseXML = function()
{
return (_request) ? _request.responseXML : null;
};
this.GetResponseText = function()
{
return (_request) ? _request.responseText : null;
};
this.GetRequestObject = function()
{
return _request;
};
this.InitializeRequest = function(Method, Uri)
{
_InitializeRequest();
_this = this;
switch (arguments.length)
{
case 2:
_request.open(Method, Uri);
break;
case 3:
_request.open(Method, Uri, arguments[2]);
break;
}
if (arguments.length >= 4) _request.open(Method, Uri, arguments[2], arguments[3]);
this.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
};
this.SetRequestHeader = function(Field, Value)
{
if (_request) _request.setRequestHeader(Field, Value);
};
this.Commit = function(Data)
{
if (_request) setTimeout(function(){ _request.send(Data); }, (this.requestDelay ? this.requestDelay : 1));
};
this.Close = function()
{
if (_request) _request.abort();
};
//---------------------------
// Public Event Declarations.
//---------------------------
this.OnUninitialize = function() { };
this.OnLoading = function() { };
this.OnLoaded = function() { };
this.OnInteractive = function() { };
this.OnSuccess = function() { };
this.OnFailure = function() { };
//---------------------------
// Private Event Declarations
//---------------------------
function _OnUninitialize() { _this.OnUninitialize(); };
function _OnLoading() { _this.OnLoading(); };
function _OnLoaded() { _this.OnLoaded(); };
function _OnInteractive() { _this.OnInteractive(); };
function _OnSuccess() { _this.OnSuccess(); };
function _OnFailure() { _this.OnFailure(); };
//------------------
// Private Functions
//------------------
function _InitializeRequest()
{
_request = _GetRequest();
_request.onreadystatechange = _StateHandler;
};
function _StateHandler()
{
switch (_request.readyState)
{
case 0:
window.setTimeout("void(0)", 100);
_OnUninitialize();
break;
case 1:
window.setTimeout("void(0)", 100);
_OnLoading();
break;
case 2:
window.setTimeout("void(0)", 100);
_OnLoaded();
break;
case 3:
window.setTimeout("void(0)", 100);
_OnInteractive();
break;
case 4:
if (_request.status == 200)
_OnSuccess();
else
_OnFailure();
return;
break;
}
};
function _GetRequest()
{
var obj;
try
{
obj = new XMLHttpRequest();
}
catch (error)
{
try
{
obj = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (error)
{
return null;
}
}
return obj;
};
};
};
btw, excuse the english folks, i dont have my critic right now. ^^
Have you noticed why other Ext JS or JavaScript intensive application loads faster? there are several ways to defeat slow loading, guess.....
faster PC? 'eeeerk' not all of us has 4GB of RAM, but still no. also if u have no,
Fast DSL/T1? 'eeerrk' again, nope.. still we want faster load time,
or loading all JavaScript on every first load? yeah sure, but "don't keep your clients waiting that much load times..." honestly i did that before, not a good results..horror..
SO what then??
my friend, you need to employ your self on making your scripts in Modular Form, say ill load "A" first, & then "A" has to load "B" when i click this and that.. or "A" requires "B", "C" so on and so fort.. this way it minimizes load times.
How?
...xvnBASE will help you do just that..
but first, u need to specify the Directory where your scripts are located. Do it like this:
new xvnBASE('path/to/scripts').load({ ... });
..or..
modify the preset url in the xvnBASE source code at line 52.
Directory structure will be:
/www/public/lib/mods/Frontend/
+ A.js
+ etc...
/www/public/lib/mods/Vendor/Bluff/
+ jsclass.js
+ etc...
but also you need to understand simple things, in using xvnBASE, the main idea of this is to create your script in modular form by namespace... let me give an example, lets say i have a Frontend and this frontend UI has some bits of needed scripts.
new xvnBASE().load('Frontend.A', [config]);
configs:
{
loadOnce: true, // defaults to true - reloads scripts every call if false
OnPreload: function() {},
OnComplete: function(o){
if (!o.AllLoaded)
{
alert('load failed');
}
else
{
Frontend.A();
}
}
}
...when successfully loaded, namespace Frontend.A will be created and eval the script A.js
Scenario for: if A loads B on [events]..
Frontend.A = function(){
...do ur stuff...
var xyz = Ext.Panel({ ...
listeners: {
beforeshow: function()
{
new xvnBASE().load({
items:[ 'Frontend.B','Frontend.C','Frontend.D' ],
OnComplete: function(o){
if (o.AllLoaded)
{
xyz.show();
}
else
{
alert(o.Store.failedItems);
}
}
});
return false;
}
}
});
};
Scenario for: if A requires B & C..
Frontend.A = function(){
var id = Math.random();
var __win = new Ext.Window({
title : 'Bluff Graph',
width : 400,
height : 330,
plain : true,
resizable : false,
constrain : true,
border : false,
draggable : true,
html : '<canvas id="graph' + id + '"></canvas>'
});
new xvnBASE().load({
items: [ 'Vendor.Bluff.jsclass', 'Vendor.Bluff.excanvas', 'Vendor.Bluff.bluff' ],
OnComplete: function(xo){
if (xo.AllLoaded())
{
__win.show();
// Make a graph object with canvas id and width
var g = new Bluff.Line('graph' + id, 400);
// Set theme and options
g.theme_odeo();
g.title = 'My Graph';
// Add data and labels
g.data('Apples', [1, 2, 3, 4, 4, 3]);
g.data('Oranges', [4, 8, 7, 9, 8, 9]);
g.data('Watermelon', [2, 3, 1, 5, 6, 8]);
g.data('Peaches', [9, 9, 10, 8, 7, 9]);
g.labels = {0: '2003', 2: '2004', 4: '2005'};
// Render the graph
g.draw();
}
else
{
...errr...
}
}
});
};
..Thats it... Imagine your ways to do it...
xvnbase.js
/*
xvnBASE 1.0.5
------------------------------------------------------------------------------------
xvnBASE, Modular Approach using namespace objects
------------------------------------------------------------------------------------
| Author: Kevinralph Tenorio. nivektrio[AT]yahoo.com
| Copyright (c) 2008 Kevinralph Tenorio. All rights reserved.
------------------------------------------------------------------------------------
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
------------------------------------------------------------------------------------
*/
var xvnBASE_Store = {
items: [],
failedItems: [],
find: function(B)
{
var i = 0, A;
while((A = this.items[i++]))
{
if (A == B) return true;
};
return false;
}
};
var xvnBASE = function(url)
{
var _this = this;
this.debug = false;
this.libRoot = (typeof(url) === 'undefined' ) ? '/~dev/base/' : url;
this.Store = xvnBASE_Store;
this._loadedQUEUE = 0;
_this.AllLoaded = function()
{
if (_this.Store.failedItems.length >= 1)
return false;
else
return true;
};
this.Util = {
String: {
toDir: function(string)
{
return string.split('.').join('/');
},
getFilename: function(path)
{
return path.substr(path.lastIndexOf("/") + 1, path.length);
},
toNS: function(ns)
{
if (typeof(ns) == 'undefined') return;
var domains = ns.split('.');
var domain = window;
for (var i=0; i<domains.length; i++)
{
var subdomain = domains[i];
if (!domain[subdomain]) domain[subdomain] = {};
domain = domain[subdomain];
}
return domain;
}
}
};
this.load = function(config, rconfig)
{
if (typeof(config) === 'undefined') return;
if (typeof(config) == 'string')
{
_this._run(config, rconfig);
}
else if (typeof(config) == 'object')
{
if (typeof(config.OnPreload) == 'function') config.OnPreload();
config.loadOnce = (typeof(config.loadOnce) == 'boolean') ? config.loadOnce : true;
_this._loadedQUEUE = 0;
var i = 0, el, tryExec = function()
{
if (_this._loadedQUEUE >= config.items.length && typeof(config.OnComplete) == 'function') config.OnComplete(_this);
};
while((el = config.items[i++]))
{
if (!_this.Store.find(el))
{
var xhr = new _this.Ajax();
//xhr.requestDelay = 1000;
xhr.OnSuccess = function()
{
if (config.loadOnce) {
_this.Util.String.toNS(this.ModuleName);
_this.Store.items.push(this.ModuleName);
}
var src = ";_this._loadedQUEUE++; ";
eval(this.GetResponseText() + src);
tryExec();
};
xhr.OnFailure = function()
{
_this._loadedQUEUE++;
_this.Store.failedItems.push(this.ModuleName);
tryExec();
};
xhr.GetData = function()
{
this.InitializeRequest('GET', _this.libRoot + _this.Util.String.toDir(el) + '.js?t=' + new Date().getTime(), true);
this.Commit(null);
this.ModuleName = el;
};
xhr.GetData();
}
else
{
_this._loadedQUEUE++;
tryExec();
}
}
}
};
this._run = function(mod, config)
{
if (typeof(mod) === 'undefined') return;
if (typeof(config) === 'undefined') config = {};
if (typeof(config.OnPreload) == 'function') config.OnPreload();
var tryExecOnComplete = function(obj)
{
if (typeof(config.OnComplete) == 'function') config.OnComplete(obj);
};
if (_this.Store.find(mod))
{
tryExecOnComplete();
}
else
{
new _this.load({
items : [ mod ],
OnComplete: function(obj)
{
tryExecOnComplete(obj);
}
});
}
};
this.Ajax = function()
{
//---------------------
// Private Declarations
//---------------------
var _request = null;
var _this = null;
//--------------------
// Public Declarations
//--------------------
this.ModuleName = '';
this.GetResponseXML = function()
{
return (_request) ? _request.responseXML : null;
};
this.GetResponseText = function()
{
return (_request) ? _request.responseText : null;
};
this.GetRequestObject = function()
{
return _request;
};
this.InitializeRequest = function(Method, Uri)
{
_InitializeRequest();
_this = this;
switch (arguments.length)
{
case 2:
_request.open(Method, Uri);
break;
case 3:
_request.open(Method, Uri, arguments[2]);
break;
}
if (arguments.length >= 4) _request.open(Method, Uri, arguments[2], arguments[3]);
this.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
};
this.SetRequestHeader = function(Field, Value)
{
if (_request) _request.setRequestHeader(Field, Value);
};
this.Commit = function(Data)
{
if (_request) setTimeout(function(){ _request.send(Data); }, (this.requestDelay ? this.requestDelay : 1));
};
this.Close = function()
{
if (_request) _request.abort();
};
//---------------------------
// Public Event Declarations.
//---------------------------
this.OnUninitialize = function() { };
this.OnLoading = function() { };
this.OnLoaded = function() { };
this.OnInteractive = function() { };
this.OnSuccess = function() { };
this.OnFailure = function() { };
//---------------------------
// Private Event Declarations
//---------------------------
function _OnUninitialize() { _this.OnUninitialize(); };
function _OnLoading() { _this.OnLoading(); };
function _OnLoaded() { _this.OnLoaded(); };
function _OnInteractive() { _this.OnInteractive(); };
function _OnSuccess() { _this.OnSuccess(); };
function _OnFailure() { _this.OnFailure(); };
//------------------
// Private Functions
//------------------
function _InitializeRequest()
{
_request = _GetRequest();
_request.onreadystatechange = _StateHandler;
};
function _StateHandler()
{
switch (_request.readyState)
{
case 0:
window.setTimeout("void(0)", 100);
_OnUninitialize();
break;
case 1:
window.setTimeout("void(0)", 100);
_OnLoading();
break;
case 2:
window.setTimeout("void(0)", 100);
_OnLoaded();
break;
case 3:
window.setTimeout("void(0)", 100);
_OnInteractive();
break;
case 4:
if (_request.status == 200)
_OnSuccess();
else
_OnFailure();
return;
break;
}
};
function _GetRequest()
{
var obj;
try
{
obj = new XMLHttpRequest();
}
catch (error)
{
try
{
obj = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (error)
{
return null;
}
}
return obj;
};
};
};
btw, excuse the english folks, i dont have my critic right now. ^^