項目開發中,為了提高用戶體驗,查詢時使用dwr向后台發送查詢請求,然后根據查詢結果異步更新頁面中table的內容。
第一次現實方法是用Java代碼將查詢到的數據拼湊HTML(就圖用java寫代碼比js方便,實際上是不知道如何寫出簡潔優美的JS......),將拼湊到的HTML返回到前台,前台JS將獲取到的HTML字符串賦值給div的innerHTML屬性(table被放置在一個div內),代碼如下(這里所有的例子都是簡單的模擬下我的代碼而已):
Java代碼
StringBuilder html = new StringBuilder("<table width='100%'>");
for(int i = 0; i < 1000; i++) {
html.append("<tr>");
for(int j = 0; j < 10; j++) {
html.append("<td>kkkkkkkk</td>");
}
html.append("</tr>");
}
html.append("</table");
Js代碼
document.getElmentById(“_div”).innerHTML = html;
結果當表的字段數為10,記錄數為1000時,IE響應異常緩慢,而且CPU占用率奇高,但等了10-20分鍾后(如果只是純文本還好些,如果其中包含其它HTML元素,如img、div、checkbox等等,響應的時間更多),頁面最終還是生成出來了,但再多發幾次查詢請求,IE所占的內存不斷的升高,一直不釋放,直到重新刷新頁面后內存才會降下來。
上網查了些資料,發現使用innerHTML來更換頁面元素時,IE並沒有釋放替換前的元素所占用的內存,從而存在潛在的IE內存泄露的隱患,尤其是在頁面使用innerHTML進行大量的元素替換操作時。
既然上面的方式存在性能問題,只好換個方式,將后台查詢到的數據使用List來表示記錄行,用Map來表示字段內容,並通過dwr返回到前台轉換成javascript的Array、Object對象,然后用JS的insertRow、insertCell方法來往table中插入tr、td,JS代碼如下(這里所有的例子都是簡單的模擬下我的代碼而已):
Js代碼
<BODY>
<table width="100%" >
<tbody id="_table">
</tbody>
</table>
</BODY>
<SCRIPT LANGUAGE="JavaScript">
<!--
var _row;
var _cell;
for(var i = 0; i < 1000; i++) {
_row = document.getElementById("_table").insertRow(0);
for(var j = 0; j < 10; j++) {
_cell = _row.insertCell(0);
_cell.innerText = "222";
}
}
//-->
</SCRIPT>
使用這種方式,當數據量比較大時其響應速度還是其慢,IE幾乎掛死。
沒有辦法,只好再另辟途徑,這次使用document.createElement()方法來創建tr、td:
Js代碼
<BODY>
<table width="100%" >
<tbody id="_table">
</tbody>
</table>
</BODY>
<SCRIPT LANGUAGE="JavaScript">
<!--
var _row;
var _cell;
for(var i = 0; i < 1000; i++) {
_row = document.createElement("tr");
document.getElementById("_table").appendChild(_row);
for(var j = 0; j < 10; j++) {
_cell = document.createElement("td");
_cell.innerText = "222";
_row.appendChild(_cell);
}
}
//-->
</SCRIPT>
Js代碼
<SCRIPT LANGUAGE="JavaScript">
<!--
var _table = document.getElementById("_table");
var _row;
var _cell;
for(var i = 0; i < 1000; i++) {
_row = document.createElement("tr");
document.getElementById("_table").appendChild(_row);
for(var j = 0; j < 10; j++) {
_cell = document.createElement("td");
_cell.innerText = "222";
_row.appendChild(_cell);
}
}
//-->
</SCRIPT>
這時只需要2、3秒就完成了頁面的刷新^_^,這是因為每次都用document.getElementById()去引用一個對象是比較耗時的,如果使用一個局部變量來引用它,在使用的地方通過局部變量來引用,則可以節省不少性能,但這種差異也只是在大循環中才比較明顯。
另外,如果需要在td中創建其它HTML元素,如img、div、checkbox等等,則響應時間會再慢一些,以上面的例子,大概需要4、5秒。
