PDA

View Full Version : IE performance


mglowacki
01-29-2008, 08:39 AM
Hi

Recently I decided to rewrite code from my page to my own ajax code. Previously I've used AJAX4JSF framework, but Tomcat limitation on header size was the reason to change it. AJAX4JSF returns generated HTML as response - that means no html generation by browser, but sent data are larger. As I said because of limit, I have changed to my own code, returning xml from servlet, and now browser generates html.
First solution - DOM, appeared to be totally wrong for IE. My table with about 20 rows + some rows' background graphics was too hard for it - page refreshes every 3 seconds and generation appeared to last also about that time - when scrolling page browser was hanging almost all the time.
Then I decided to concatenate html string and then I improved it by using tables and join() function. Difference is huge, but still every 3 seconds when code is generating, browser hangs for a while. Of course it only affects IE.

What can be done more about this?

Regards,
Michal

liorean
01-29-2008, 10:44 AM
Would really have to see your code in action to determine what is taking time in ie. You got an example page for us to look at?

mglowacki
01-29-2008, 11:19 AM
hi, thanks for reply - hope the code will be enough for now :)


var req_update;
var interval;

function initLive() {
updateTable();
interval = setInterval("updateTable()", 3000);
}

function updateTable() {
var category_id = document.getElementById("Center:form2:categoryIdHidden").value;
var url = "/entryting/LiveentrytingServlet/?action=get_titles&category_id=" + category_id;
if (window.XMLHttpRequest) {
req_update = new XMLHttpRequest();
} else if (window.ActiveXObject) {
req_update = new ActiveXObject("Microsoft.XMLHTTP");
}
req_update.open("GET", url, true);
req_update.onreadystatechange = changeTable;
req_update.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
req_update.send(null);
}

function changeTable() {
if (req_update.readyState == 4) {
if (req_update.status == 200) {
var response = req_update.responseXML.documentElement;
var category_element = response.getElementsByTagName("category")[0];

var titles = response.getElementsByTagName("title");
if(!titles) {
return;
}
var buffer = new Array();
buffer[buffer.length] = "<table cellSpacing=\"0\" cellPadding=\"0\" border=\"0\" id=\"live_table\" >";

for(var i=0; i<titles.length; i++) {
if(i != 0) {
buffer[buffer.length] = "<tr><td><table cellSpacing=\"0\" cellPadding=\"0\" border=\"0\" style=\"margin-top: 5px\">";
} else {
buffer[buffer.length] = "<tr><td><table cellSpacing=\"0\" cellPadding=\"0\" border=\"0\">";
}
var title_name = titles[i].getAttribute("name");
var status = titles[i].getAttribute("status");

buffer[buffer.length] = title_row(title_name, status);
buffer[buffer.length] = "</table></td></tr>";

if(status != 250) {
buffer[buffer.length] = "<tr><td><table cellSpacing=\"0\" cellPadding=\"0\" border=\"1\">";
buffer[buffer.length] = record_row(titles[i].childNodes, title_name);
buffer[buffer.length] = "</table></td></tr>";
}
}
buffer[buffer.length] = "</table>";
var titles_table = document.getElementById("live_table");
titles_table.style.display = "block";
titles_table.innerHTML = "";
titles_table.innerHTML = buffer.join("");
}
}
}

function title_row(title_name, opened) {
var buffer = new Array();
buffer[buffer.length] = "<tr width=\"495px\" style=\"background-image: url(template/images/liveentry/title_header_bg.gif)\">";

if(opened == 250)
buffer[buffer.length] = "<td width=\"458px\" height=\"19px\" style=\"text-align: left\">";
else {
buffer[buffer.length] = "<td height=\"19px\" width=\"495px\" colspan=\"2\" style=\"text-align: left\">";
}

buffer[buffer.length] = "<font face=\"Arial\" class=\"bold\" style=\"margin-left: 5px\">";
buffer[buffer.length] = title_name;
buffer[buffer.length] = "</font></td>";

if(opened == 250) {
buffer[buffer.length] = "<td width=\"37px\" height=\"19px\" style=\"text-align: right\"><img src=\"template/images/liveentry/onhold.gif\" /></td>";
}
buffer[buffer.length] = "</tr>";

return buffer.join("");
}

function record_row(records, title_name) {
var buffer = new Array();
buffer[buffer.length] = "<tr width=\"487px\" style=\"background-color: #FFFFFF\">";
for(var i=0; i<records.length; i++) {
var width;
if(i == 1 && records.length == 3) {
width = Math.ceil(487/records.length) - 2 + "px";
}
else if(i == 1 && records.length == 2) {
width = Math.ceil(487/records.length) + 1 + "px";
}
else {
width = Math.ceil(487/records.length) + "px";
}
var style;
if(i == 0) {
style = "style=\"text-align: left\"";
}
else if(i == 1 && records.length == 3) {
style = "style=\"text-align: center\"";
}
else {
style = "style=\"text-align: right\"";
}

buffer[buffer.length] = "<td width=\"";
buffer[buffer.length] = width;
buffer[buffer.length] = "\" height=\"19px\" ";
buffer[buffer.length] = style;
buffer[buffer.length] = ">";

buffer[buffer.length] = record_table(records[i].getAttribute("id"), records[i].getAttribute("name"), records[i].getAttribute("rate"), title_name);
buffer[buffer.length] = "</td>";
}
buffer[buffer.length] = "</tr>";
return buffer.join("");
}

function record_table(record_id, record_name, record_rate, title_name) {
var buffer = new Array();
var category_id = document.getElementById("Center:form2:categoryIdHidden").value;
var category_name = getText(document.getElementById("Center:form2:outputText2"));

buffer[buffer.length] = "<table cellSpacing=\"0\" cellPadding=\"0\" border=\"0\" style=\"width: 100%\" ";
buffer[buffer.length] = "onclick=\"addLiveentry(this, '";
buffer[buffer.length] = title_name;
buffer[buffer.length] = "', '";
buffer[buffer.length] = category_name;
buffer[buffer.length] = "', '";
buffer[buffer.length] = record_name;
buffer[buffer.length] = "', ";
buffer[buffer.length] = record_rate;
buffer[buffer.length] = ", ";
buffer[buffer.length] = record_id;
buffer[buffer.length] = ", ";
buffer[buffer.length] = category_id;
buffer[buffer.length] = ")\" onmouseover=\"pointerCursor()\" onmouseout=\"normalCursor()\" ";

buffer[buffer.length] = "><tr width=\"100%\"><td style=\"text-align: left; vertical-align: middle\"><font face=\"Arial\" style=\"vertical-align: top; margin-left: 3px\">";
buffer[buffer.length] = record_name;
buffer[buffer.length] = "</font>";

var previous_rate = new Number(getrecordrate(record_id));
record_rate = new Number(record_rate);
if(previous_rate == 0) {
previous_rate = record_rate;
}

if(previous_rate.toFixed(2) != record_rate.toFixed(2)) {
if(previous_rate < record_rate) {
buffer[buffer.length] = "<img src=\"template/images/liveentry/arrow1.gif\"";
}
else if(previous_rate > record_rate) {
buffer[buffer.length] = "<img src=\"template/images/liveentry/arrow-1.gif\"";
}
buffer[buffer.length] = " style=\"padding-left: 2px; padding-top: 1px\" class=\"top_align\"/>";
}

saverecordrate(record_id, record_rate);

buffer[buffer.length] = "</td><td style=\"text-align: right; vertical-align: middle;\" width=\"25px\" class=\"top_align\"><font face=\"Arial\" style=\"margin-right: 3px; vertical-align: top ! important ";

if(document.all) {
buffer[buffer.length] = "top: -1px; ";
buffer[buffer.length] = "position: relative; ";
}
buffer[buffer.length] = "margin-right: 3px; ";
buffer[buffer.length] = "class=\"top_align\">";
buffer[buffer.length] = record_rate.toFixed(2);
buffer[buffer.length] = "</font></td></tr></table>";

return buffer.join("");
}

A1ien51
01-29-2008, 07:54 PM
Wll JavaScript SUCKS at big loops through data.

One trick you can use is to use setTimeout to loop through large datasets. It does not hang the browser.

You also might want to use createElement and appendChild [or insertRow/insertCell]instead of building up the table.

This way you can start building the code and the rows will start to appear instead of having to wait for the entire thing to be built up as a string.

Eric

mglowacki
01-30-2008, 09:44 AM
sorry, I don't get with setTimeout, could you explain please?

createElement/appendChild has appaling performance in IE, tried this at the beginning.

A1ien51
01-30-2008, 10:35 PM
Instead of using a for loop, you build your own using setTimeout. Seems strange, but it helps to not freeze the browser on looping through large datasets.

Basic idea:


var myData = [1,2,3,4,5];
var current = 0;

function displayNext(){
var elem = document.createElement("div");
elem.innerHTML = myData[current];
document.getElementById("foo").appendChild(elem);
current++;
if(current<myData.length)window.setTimeout(displayNext,1);
}


Eric