icon 2013/09/26 DOM操作の最適化によるJavaScriptチューニングにチャレンジ!
HTML5エキスパートで有名な吉川さん(同性w)からCodeIQの問題があったので挑戦!

DOM操作の最適化によるJavaScriptチューニングにチャレンジ!

オリジナル


    var button = document.querySelector('button'),
        ul = document.querySelector('#output'),
        itemCount = 0;

    function addItems() {
      for ( var i = 0; i < 10; i++ ) {
        itemCount++;
        ul.innerHTML += '<li><article class="item">'
                      + '<h1 class="title">アイテム' + itemCount + '</h1>'
                      + '<p class="detail">詳細' + itemCount + '</p>'
                      + '</article></li>';
      }
    }

30分くらいでざっとコーディングして提出

提出コード


    var button = document.querySelector('button'),
        ul = document.getElementById('output'),
        itemId = 0;

    var itemTemplate = '';
    var addCount = 10;
    var output = document.getElementById("output");

    function createItem() {
        itemId++;
        var item = new Object();
        item.title = 'アイテム' + itemId;
        item.detail = '詳細' + itemId;
        return item;
    }

    function loadItemTemplate(item) {
        var li = document.createElement('li'); 
        var article = document.createElement('article');
        var h1 = document.createElement('h1');
        var p = document.createElement('p');

        article.setAttribute('class', 'item');
        h1.setAttribute('class', 'title');
        p.setAttribute('class', 'detail');

        h1.textContent = item.title;
        p.textContent = item.detail;

        article.appendChild(h1);
        article.appendChild(p);
        li.appendChild(article);
        return li;
    }

    function addItems() {
      for ( var i = 0; i < addCount; i++ ) {
        itemTemplate = loadItemTemplate(createItem());
        document.getElementById('output').appendChild(itemTemplate);
      }
    }
テンプレートのHTML生成がループしてるので無駄だなと思いつつ、この程度だと計測時間が変わらなかったのでとりあえず。

丁寧にアドバイスを頂きました。

- Document Fragmentを経由
- getElementById()は高コストなのでキャッシュする

提出コード



    var button = document.querySelector('button'),
        ul = document.getElementById('output'),
        itemId = 0;

    var template;
    var addCount = 10;
    var li;
    var article;
    var h1;
    var p;

    loadItemTemplate();

    function createItem() {
        itemId++;
        var item = new Object();
        item.title = 'アイテム' + itemId;
        item.detail = '詳細' + itemId;
        return item;
    }

    function loadItemTemplate() {
        template = document.createElement('li'); 
        article = document.createElement('article');
        h1 = document.createElement('h1');
        p = document.createElement('p');

        article.setAttribute('class', 'item');
        h1.setAttribute('class', 'title');
        p.setAttribute('class', 'detail');

        article.appendChild(h1);
        article.appendChild(p);
        template.appendChild(article);
    }

    function bindItem(item) {
        h1.textContent = item.title;
        p.textContent = item.detail;
        var itemRow = template.cloneNode(true);
        ul.appendChild(itemRow);
    }

    function addItems() {
      for ( var i = 0; i < addCount; i++ ) {
          bindItem(createItem());
      }
    }

cloneNode()を利用してみたけど、なんかViewの分離がちょっと汚くなっちゃたかな?
insertNode()とかを使って、ツリーを操作した方がスムーズなのかも。

このサイトについて

HTML5 & CSS3化しつつあるので、現在IEには対応してません。
できれば、Google Chromeやら Apple SafariのWebKit系をお勧めします。

DBからプログラムまで一応全て自作なので、バグってたらすいません。
実験でFlash版(Flex版)を先に作りましたが、ちょっと停止してます。

プロフィール

新宿近辺でSE & プログラマーしてます。
Webアプリの開発・設計とか、最近はiPhoneとか奮闘してます。
デザインはさっぱりです。

音楽は、昔からCubase打ち込み人間で、そっちの方が経歴は長いですが、最近はやる暇がないです。。。

今は、Gon's Privates ってバンドのキーボードやってます。
単発的に、なんちゃってジャズ系のライブもやってます。

名古屋生まれなのでドラゴンズ好きです。

Info && SNS

Gmail

 yohei.yoshikawa@gmail.com

Twitter

 http://twitter.com/yoo_yoo_yoo

あんまつぶやきませんが、一応技術系メインで使ってます。情報交換はこちらへ

FaceBook

 http://www.facebook.com/#!/profile.php?id=1439130626

海外の知り合いがいないので閑散としてます。

mixi

 http://mixi.jp/show_profile.pl?id=230072

音楽仲間とかはこっちメインでやってます。興味があればこちらへ