2012-04-11 9 views
3

私は、約300のDIVにHTMLデータを設定しているので、18秒かかるスクリプトがあります。以下のコード:JSONコールバックのHTMLデータを300以上のDIVに効率的に取り込む方法は?

HTML:

<div id="window"> 
     <div id="wall"> 
      <div class="module"> 
       <div> 
        <div class="face front"></div> 
        <div class="face back"></div> 
       </div> 
      </div> 
     </div> 
    </div> 

Javascriptを:私は2つの.html()呼び出しをコメントアウトした場合

for (i = 0; i < numModules-1; ++ i) 
{ 
    var $mod = $('.module:eq(0)').clone(); 

    modLeft += modSize; 
    if (modLeft + modSize > $('#wall').width()) 
    { 
     modLeft = 0; 
     modTop += modSize; 
    } 
    $mod.css({ 
     left: modLeft, 
     top: modTop 
    }).appendTo('#wall'); 
} 

$.getJSON('html_server.php?callback=?', function(data) { 
    var htmlCount = data.length; 

    for (i = 0; i < numModules /* 300 or more */; ++ i) 
    { 
     var pick = Math.floor(Math.random() * Math.floor(htmlCount/2)) * 2; 
     var contentFront = data[pick]; 
     var contentBack = data[pick+1]; 
     var modStyle = ''; 
     var $mod = $('.module:eq(' + i + ')'); 
     var $modFront = $mod.find('.front'); 
     var $modBack = $mod.find('.back'); 

     // Set HTML content on front & back of module 
     $modFront.html(contentFront); 
     $modBack.html(contentBack); 
    } 
}); 

、実行時間は約110msに低下するので、これらは明らかに犯人です。そして、HTMLコンテンツは最大で300バイトのデータではありません。

アドバイスはありますか?

EDIT:DIVを作成するコードを追加しました。おそらく、私はgetJSONコールバック内でそれを動かすことができ、HTMLが作成されたときにドロップすることができますか?助けてくれますか?

+6

あなたのHTMLは見られますか?これを最適化する方法はたくさんありますが、すべてのdivを保持しているものを取り出し、デタッチし、javascriptオブジェクトとして編集してから、1つの.htmlをすべて実行した後に行うのが最適な方法です。あなたのhtml構造が分からないと書くことは難しいでしょう:) – Patricia

+0

@CaptSaltyJack - > '.module'の中で' .front'と '.back'はどうですか?そうすれば、for..loopの中に.module string/arrayを構築し、それらをループ外の#wallにプッシュすることができます。 –

+0

私は皆さんが提案していることは、最初にHTMLを構築してから、ワンショットで追加することだと思います。問題は、上のコードで分かるように、それぞれのCSSの位置を明示的に設定する必要があるため、 '$ mod.css()'を使うと便利です。 '

'のような生の文字列を作る以外に、これを行うには他にもいくつかの方法がありますか? – CaptSaltyJack

答えて

2

moduleをテンプレートとして作成し、その内容をレスポンスに置き換えました。また、HTMLロジックをJSONの下に移動して、一度行うことができます。下記をご覧ください。

var modTmpl = '<div class="module"><div><div class="face front">{CONTENT_FRONT}</div><div class="face back">{CONTENT_BACK}</div></div></div>'; 

$.getJSON('html_server.php?callback=?', function(data) { 
    var htmlCount = data.length; 

    var pick, tmp, $mods = []; 
    for (i = 0; i < numModules /* 300 or more */; ++ i) 
    { 
     pick = Math.floor(Math.random() * Math.floor(htmlCount/2)) * 2; 
     tmp = modTmpl 
       .replace(/{CONTENT_FRONT}/, data[pick]) 
       .replace(/{CONTENT_BACK}/, data[pick+1]); 
     $mods.push(tmp); 
    } 
}); 

/* 
    I am leaving the below code untouched as it seems like you are 
    positioning each module. If not then you can just 
    $('#wall').append($mods.join('')); and remove below for loop 
*/ 
for (i = 0; i < numModules-1; ++ i) 
{ 
    var $mod = $mods[i]; //use the pushed modules and append now 

    modLeft += modSize; 
    if (modLeft + modSize > $('#wall').width()) 
    { 
     modLeft = 0; 
     modTop += modSize; 
    } 
    $mod.css({ 
     left: modLeft, 
     top: modTop 
    }).appendTo('#wall'); 
} 
+0

@CaptSaltyJackこれはあなたがそのHTMLを投稿したばかりの人にはたまたま答えられていた可能性があります:P –

+0

良い答え+1、sidenoteとしてjQueryにはかつて[tmlp()](http://api.jquery.com/jquery)がありました。 tmpl /)関数は、決してどこにもいないようだが、これには便利だっただろうか?正規表現の使用について狂っているのではなく、それがまだ別々のモジュールを追加していて、オリジナルとほとんど同じくらい遅くなっているということでしょうか? – adeneo

+0

@adeneoありがとう..ちょっと..単純な文字列を置き換えるよりもはるかに多くの機能を持っていて、looongの時間のベータ版です。テンプレートの他にも優れたプラグインがあります。http://dev.af83.com /2010/09/15/jquery-mustache-more-than-just-a-jquery-plugin.html –

0

小さな遅延値を持つsetTimeoutデバイスで、これらのグループをまとめて作成するといいでしょう。それは処理です。したがって、知覚される始動速度はより速い。 AJAXスピナーなどを読み込んでいるときにスイッチをオンにして、レンダリング中にユーザーがすぐにやり取りできるようにすることができます。

+0

より速くする必要があります。ロックアップは問題ではありません。 – CaptSaltyJack

2

それは実際のマークアップを見ることなく伝えるのは難しいですが、おそらくのようなものになるはずです:

JSのすべてを構築
$.getJSON('html_server.php?callback=?', function(data) { 
    var mod=''; 
    for (i = 0; i < numModules /* 300 or more */; ++ i) { 
     var pick = Math.floor(Math.random() * Math.floor(data.length/2)) * 2; 
      mod += '<div class="module'>; 
      mod += '<div class="front">'+data[pick]+'</div>'); 
      mod += '<div class="back">'+data[pick+1]+'</div>'); 
      mod += '</div>'; 
    } 
    $('#someParent').html(mod); 
}); 

を、一度だけDOMに挿入すると、ここに行くための方法ですが、それ実際のマークアップに基づいて構築する必要があります。上の例は、それを行う方法の一般的な例です。

+0

もう一度コードを読んでから外に出してください。$ modFrontと$ modBackはローカル変数で、特定のセクションかもしれません。あなたがコードを外側に定義した後でも、それをすべてコードに追加します最後のセクション。 –

+0

私が投稿したときにそれを変更したが、もう一度変更することに気づいただけで、JSでオブジェクトを作成する方法を追加する必要があります。 – adeneo

+0

これはおそらく行く方法です。私は自分のコードを少し調整して、これをテストしています。基本的に '.clone()'に最初のループを使うのではなく、@adeneoのような未加工のHTMLからすべてのDIVを作成します。 – CaptSaltyJack

関連する問題