DOMアクセス
DOMアクセス
・DOMアクセスは最小化する。
・ループ内でのDOMアクセスは避ける。
// アンチパターン
for (var i = 0; i < 100; i += 1) {
document.getElementById("result").innerHTML += i + ", ";
}
// 変数を利用した改善
var i, content = "";
for (var i = 0; i < 100; i += 1) {
content += i + ", ";
}
document.getElementById("result").innerHTML += content;
・DOM参照を変数に割り当てて使用する。
// アンチパターン
var padding = document.getElementById("result").style.padding,
margin = document.getElementById("result").style.margin;
// 改善案
var style = document.getElementById("result").style.
padding = style.padding;
margin = style.margin;
document.querySelector("ul .selected");
// クエリーセレクターは他のDOMメソッド選択方式より速い。
・頻繁にアクセスするエレメントにid属性を追加するのも性能向上に役立つ。 なぜなら、document.getElementById("id")
がノードを探す最も早い方法。
DOM操作
DOM操作
・DOMアップデートは最小化した方が良い。
・アップデート時に画面をrepaintしてエレメントをreflowするのに費用がたくさんかかるため。
・サブツリーを追加する時は、サブツリーの構成要素をすべて生成した後、最後に一度だけ追加してくれる。
// アンチパターン
var p, t;
p = document.createElement("p");
t = document.createTextNode("first paragraph");
p.appendChild(t);
document.body.appendChild(p);
p = document.createElement("p");
t = document.createTextNode("second paragraph");
p.appendChild(t);
document.body.appendChild(p);
// 改善案
var p, t, frag;
frag = document.createDocumentFragment();
p = document.createElement("p");
t = document.createTextNode("first paragraph");
p.appendChild(t);
frag.appendChild(p);
p = document.createElement("p");
t = document.createTextNode("second paragraph");
p.appendChild(t);
frag.appendChild(p);
document.body.appendChild(frag);
・存在するツリーを変更する場合には、サブツリーのルートを複製して変更した後、元のノードと変える。
var oldnode = document.getElementById("result"),
clone = oldnode.cloneNode(true);
oldnode.parentNode.replaceChild(clone, oldnode);
イベント
イベントリスナーは以下のように実装できる。
var b = document.getElementById("clickme");
if (document.addEventListener) {
b.addEventListener("click", myHandler, false);
} else if (document.attachEvent) {
b.attachEvent("onclick". myHandler);
} else {
b.onclick = myHandler;
}
function myHandler(e) {
var src, parts;
e = e || window.event;
src = e.target || e.srcElement;
if (src.nodeName.toLowerCase() !== "button") {
return ;
}
parts = src.innerHTML.split(": ");
parts[1] = parseInt(parts[1], 10) + 1;
src.innerHTML = parts[0] + ": " + parts[1];
if (typeof e.stopPropagation === "function") {
e.stopPropagation();
}
if (typeof e.cancelBubble !== "undefined") {
e.cancelBubble = true;
}
if (typeof e.preventDefault() === "funtion") {
e.preventDefault();
}
if (typeof e.preventDefault() !== "undefined") {
e.returnValue = false;
}
}
・setTimeOut()
やWebWorker
を利用してスレッドのような機能を実現することができる。
XMLHttpRequest
XMLHttpRequest
・JavaScript から HTTP リクエストを生成する特別なオブジェクト
・生成過程は以下の通りである。
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = handleResponse;
xhr.open("GET", "page.html", true);
xhr.send();
JSONP
JSONP
・JSON with padding
・ブラウザの同一ドメインポリシーの制約を受けない。
・JSONPリクエストURL形態
http://example.org/getdata.php?callback=myHandler
・上でgetdata.phpがウェブページかスクリプトになることができる。
・getdata.php ファイルが受信されると、myHandler({"hello":"world"}) のようなコールバック関数が実行される。
ウェブページロード戦略
ウェブページロード戦略
・scriptタグに入るエレメントを見てみよう。
・type="textjavascript":HTML5では必須属性ではなく、マークアップ有効性検査のための場合でなければ使用しない。
・async (defer):非同期スクリプトのロードで、スクリプトを受け取る間、他のダウンロードを妨げない。