I have a jsp which uses a lot of javascript and it’s just not fast enough. I would like to optimize it so first, here’s a part of the code:
In the jsp I have the initialization:
window.onload = function () {
formCollection.pageSize.value = "<%= pagingSize%>";
elemCollection = iDom3.Table.all["spis"].XML.DOM;
<% if (resultList != null) { %>
elementsNumber = <%= resultList.size() %>;
<%} else { %>
elementsNumber = 0;
<% } %>
contextPath = "<%= request.getContextPath() %>";
}
In my js file I have two types of js functions:
// gets the first element and sets it's value to all the other;
//the selectSingleNode function is used because I use XSLT transformation
//to generate the table
_setTehJed = function(){
var resultId = formCollection.elements["idTehJedinice_spis_1"].value;
var resultText = formCollection.elements["tehnicka_spis_1"].value;
if (resultId != ""){
var counter = 1;
while (counter<elementsNumber){
counter++;
if(formCollection.elements["idTehJedinice_spis_"+counter] != null){
formCollection.elements["idTehJedinice_spis_"+counter].value=resultId;
formCollection.elements["tehnicka_spis_"+counter].value=resultText;
}
var node=elemCollection.selectSingleNode("/suite/table/rows/row[@id = 'spis_"+counter+"']/data[@col = 'tehnicka']/title");
node.text=resultText;
var node2=elemCollection.selectSingleNode("/suite/table/rows/row[@id = 'spis_"+counter+"']/data[@col = 'idTehJedinice']/title");
node2.text=resultId;
}
}
}
// sets the elements checkbox to checked or unchecked
_SelectCheckRokCuvanja = {
all : [],
Item : function (oItem, sId) {
this.all["spis_"+sId] = oItem.value;
if (oItem.checked) {
elemCollection.selectSingleNode("/suite/table/rows/row[@id = 'spis_"+sId+"']/data[@col = 'rokCheck']").setAttribute("default", "true");
}else{
elemCollection.selectSingleNode("/suite/table/rows/row[@id = 'spis_"+sId+"']/data[@col = 'rokCheck']").setAttribute("default", "false");
}
}
}
I’ve used these tips:
- https://web.archive.org/web/20151029015752/http://blogs.msdn.com:80/b/ie/archive/2006/08/28/728654.aspx
- http://code.google.com/speed/articles/optimizing-javascript.html
but I still think something could be done like defining the functions like this:
In the jsp:
window.onload = function () {
iDom3.DigitalnaArhivaPrihvat.formCollection=document.forms["controller"];
iDom3.DigitalnaArhivaPrihvat.formCollection.pageSize.value = "<%= pagingSize%>";
iDom3.DigitalnaArhivaPrihvat.elemCollection = iDom3.Table.all["spis"].XML.DOM;
<% if (resultList != null) { %>
iDom3.DigitalnaArhivaPrihvat.elementsNumber = <%= resultList.size() %>
<%} else { %>
iDom3.DigitalnaArhivaPrihvat.elementsNumber = 0;
<% } %>
}
in the js:
iDom3.DigitalnaArhivaPrihvat = {
formCollection:null,
elemCollection:null,
elementsNumber:null,
_setTehJed : function(){
var resultId = this.formCollection.elements.idTehJedinice_spis_1.value;
var resultText = this.formCollection.elements.tehnicka_spis_1.value;
if (resultId != ""){
var counter = 1;
while (counter<this.elementsNumber){
counter++;
if(this.formCollection.elements["idTehJedinice_spis_"+counter] !== null){
this.formCollection.elements["idTehJedinice_spis_"+counter].value=resultId;
this.formCollection.elements["tehnicka_spis_"+counter].value=resultText;
}
var node=this.elemCollection.selectSingleNode("/suite/table/rows/row[@id = 'spis_"+counter+"']/data[@col = 'tehnicka']/title");
node.text=resultText;
var node2=this.elemCollection.selectSingleNode("/suite/table/rows/row[@id = 'spis_"+counter+"']/data[@col = 'idTehJedinice']/title");
node2.text=resultId;
}
}
},
_SelectCheckRokCuvanja = {
all : [],
Item : function (oItem, sId) {
this.all["spis_"+sId] = oItem.value;
if (oItem.checked) {
this.elemCollection.selectSingleNode("/suite/table/rows/row[@id = 'spis_"+sId+"']/data[@col = 'rokCheck']").setAttribute("default", "true");
}else{
this.elemCollection.selectSingleNode("/suite/table/rows/row[@id = 'spis_"+sId+"']/data[@col = 'rokCheck']").setAttribute("default", "false");
}
}
}
but the problem is scoping (if I do it like this, the second function does not execute properly). Any suggestions?
Edit: Data structure of the table:
<row id="spis_3">
<data col="rokCheck" type="check" default="false" onchange="_ChangeTypeRokCuvanje(this,'3')" >
<title>false</title>
<description>Tehnička jedinica</description>
</data>
selectSingleNode()is a pretty expensive operation. You should try to avoid it. There are two solutions:Iterate over the data structure yourself (so you don’t have to search the DOM for the table but you can directly modify row by row).
Since you assign every row an ID, you should be able to use
document.getElementById()without the expensive XPath lookup.Use a framework like jquery to get all relevant nodes at once (-> only 1 expensive lookup) and then iterate over the list.
[EDIT] See Traversing an HTML table with JavaScript and DOM Interfaces for an example how to implement #1.