JavaScriptパフォーマンス改善(1) document.form1[]は遅い!
JavaScriptパフォーマンス改善(1) document.form1[要素名]は、でら遅い!
【調査対象】
- ブラウザ:
- IE,Firefox
- 遅いJavaScriptコード:
- document.form1[name] または document.form1.elements[name]
- 改善速度:
- IEは数百倍(300〜3000倍以上),Firefoxは10倍程度
- 改善方法:
- 最初にすべての要素をキャッシュしておき、キャッシュから要素を取得する。
【Sample Code】
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Style-Type" content="text/css" /> <meta http-equiv="Content-Script-Type" content="text/javascript" /> <meta http-equiv="Pragma" content="no-cache" /> <meta http-equiv="Cache-Control" content="no-cache" /> <meta http-equiv="Expires" content="0" /> <title>JavaScript performance test</title> <script type="text/javascript"> // timer var TS = { _time: (new Date()).getTime(), _log: [], init: function() { TS._time = (new Date()).getTime(); }, record: function(in_title) { var nowTime = (new Date()).getTime(); var intervalTime = nowTime - TS._time; TS._log.push(in_title + " : " + intervalTime + "ms"); TS._time = (new Date()).getTime(); return intervalTime; }, getRecordList: function() { var result = TS._log; TS._log = []; return result; } } // element cache var FormElementCache = {}; // html initialize window.onload = function() { var formBody = document.getElementById("formBody"); var elementType = [ {tagName: "INPUT", type: "text"}, {tagName: "INPUT", type: "radio"}, {tagName: "INPUT", type: "checkbox"}, {tagName: "INPUT", type: "button"}, {tagName: "INPUT", type: "hidden"}, {tagName: "TEXTAREA", type: ""}, {tagName: "SELECT", type: ""} ]; for (var loop = 0; loop < 2000; loop++) { var type = loop % elementType.length; var e = document.createElement(elementType[type].tagName); if (elementType[type].type) { e.type = elementType[type].type; } e.id = "test" + loop; e.name = "test" + loop; e.value = 1 + loop; formBody.appendChild(e); } } // test program function performanceTest() { TS.init(); var names = []; var felements = document.form1.elements; for (var fi = 0, lenfi = felements.length; fi < lenfi; fi++) { var e = felements[fi]; var ename = e.name; if (ename) { if (FormElementCache[ename]) { if (FormElementCache[ename] instanceof Array) { FormElementCache[ename].push(e); } else { FormElementCache[ename] = [FormElementCache[ename], e]; } } else { FormElementCache[ename] = e; names.push(ename); } } } TS.record("form1.elements cached. count=" + names.length); var form1 = document.form1.elements; for (var loop=0; loop < 1; loop++) { for (var i = 0, len = names.length; i < len; i++) { var e = form1[names[i]]; } } TS.record("document.form1[name] readed (" + loop + " loop)"); for (var loop=0; loop < 100; loop++) { for (var i = 0, len = names.length; i < len; i++) { var e = FormElementCache[names[i]]; } } TS.record("FormElementCache[name] readed (" + loop + " loop)"); alert(TS.getRecordList().join("\n")); } </script> </head> <body> <dl> <dt>JavaScript Performance Test</dt> <dd>document.form1[name] VS FormElementCache[name]</dd> </dl> <input type="button" value="Start!" onclick="performanceTest();" /><br /> <form name="form1"> <div id="formBody"></div> </form> </body> </html>