HIDARI日記(右)

そのときどき興味ある技術を中心にだらだら書いてます。内容は個人の見解であり、所属する企業を代表するものではありません。

はじめてVirtual DOMを触ったよ

Room metro #29 に参加して VirtualDOM をほんの少し教わったので忘れないうちに書いておきます(とかいいつつすでに怪しいけども)。

ほとんど当日のメモそのままなので内容的にアレなところあるかも(言い訳

VirtualDOMってなにか

HTMLのDOMと全く同じものをJSで作ったもの。

本来ブラウザのものであるDOMを、JSのオブジェクトとして仮想的に構築したデータ構造。

今まではブラウザが持つDOMを直接触ってた。 するとDOM変更のタイミングで毎回ブラウザのレンダリングが走る。これはとても重い処理。 この重さを軽減するために、VirtualDOMを使ってJSで変更を行ったあと、まとめてDOMに反映する。

VirtualDOMからのDOMの更新では、更新前のVirtualDOMとの差分だけが実際のDOMに反映される。これによって無駄な更新が入らず速度面で有利になる。VirtualDOMがイケてるところ。と言われている。 ここを抑えておかないとそこらの記事はナンノコッチャになる。

話題の?Reactとは

Virtual DOMを使ったプロダクト。まだよくわからん。

今回の続きとして勉強会を計画中とか風のうわさで本人から聞いたので楽しみにしてます。

ハンズオン

Matt-Esch/virtual-dom

を使って簡単なTODOアプリを作成。 上記のライブラリは本当に生のVirtualDOMを扱うもので、通常はこれをラップしていい感じにVirtualDOMを操作してくれるライブラリを使うとのこと。

ざっくりと手順の紹介

まずは virtual-dom/dist at master · Matt-Esch/virtual-dom から virtual-dom.js をローカルに保存。

次にVisualStudioから新しくASP.NET Applicationプロジェクトを作成。

f:id:hidari-yori:20150202225007j:plain

この時、空のテンプレートを選択して余計なフォルダーや参照は追加しないようにする。

f:id:hidari-yori:20150202225031j:plain

ASP.NET Applicationプロジェクトが作成できたら、そこにHTMLファイル追加。

f:id:hidari-yori:20150202225057j:plain

さらに、先ほどダウンロードした virtual-dom.js を追加。

f:id:hidari-yori:20150202225123j:plain

ここまでが準備。この状態まで持ってこれたら、あとはひたすらコードを書いていくだけ。

そしてできたものがこちら。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="virtual-dom.js"></script>
<title>Hoge</title>
</head>
<body>
<div>
<input type="text" name="todo"/>
<button type="button" name="add">add</button>
</div>
<div class="list"></div>
<script>
   var todos = [],
   textbox = document.querySelector("[name=todo]");

   document.querySelector("[name=add]").addEventListener("click", function () {
       var todoText = textbox.value;
       todos.push(todoText);

       var newTodoVDom = createVDom(todos);
       var patch = virtualDom.diff(todoVDom, newTodoVDom);

       todoNode = virtualDom.patch(todoNode, patch);
       todoVDom = newTodoVDom;

   }, false);

   function applyTodosVDom(todos)
   {
       var newTodoVDom = createVDom(todos),
       patches = virtualDom.diff(todoVDom, newTodoVDom);

       todoNode = virtualDom.patch(todoNode, patches);
       todoVDom = newTodoVDom;
   }

   function createVDom(todolist) {
       var textVDoms = todolist.map(function(todo) {
           return virtualDom.h("div", {}, [
           virtualDom.h("button", {
               onclick: function() {
                   todos.splice(indexedDB, 1);
                   applyTodosVDom(todos);
               }
           }, "complete!"),
           virtualDom.h("span", {}, todo)
           ]);
       });

       return virtualDom.h("div", {}, textVDoms);
   }

   var todoVDom = createVDom(todos);
   var todoNode = virtualDom.create(todoVDom);
   document.querySelector(".list").appendChild(todoNode);
</script>
</body>
</html>

おわりに

以上がはじめてのVirtualDOM体験でした。

めとべやのみなさんありがとうございました。