Here are a few ideas. Not sure how much this will help, but worth a shot...

1. put selectors that are used more than once into variables
2. rather than a bare class, use a tag name when possible in your selectors 3. instead of using string concatenation to build a DOM structure, use an array and join it
4. optimize your for loops by storing the length in a variable

Here is what it might look like:

$(document).ready(function(){

  var comment_data = eval(' [{"pk": 1, "model": "book.comment",
  "fields": {"name": "C. Lesh", "comment": "This paragraph is great!",
  "chapter": 2, "paragraph": 0}}, {"pk": 2, "model": "book.comment",
  "fields": {"name": "Steve Smith", "comment": "So far, so good.",
  "chapter": 2, "paragraph": 0}},{"pk": 3, "model": "book.comment",
  "fields": {"name": "Frank Rizzo", "comment": "You writing is awful.
  Really awful", "chapter": 2, "paragraph": 1}},{"pk": 4, "model":
  "book.comment", "fields": {"name": "Fabrizzio", "comment": "I like
  Django.", "chapter": 2, "paragraph": 0}},{"pk": 5, "model":
  "book.comment", "fields": {"name": "Barbra", "comment": "You have
stuff you should be doing.!", "chapter": 2, "paragraph": 2}},{"pk": 6,
  "model": "book.comment", "fields": {"name": "George B.", "comment":
  "What the heck is a Django?", "chapter": 2, "paragraph": 2}}] ');

  var comments = [];

  for (var t=0, p=$('p').length;t<p;t++){
        temparray = [];
        for (var i=0, cd=comment_data.length; i<cd; i++){
      if (comment_data[i].fields.paragraph == t) {
        temparray.push(comment_data[i]);
      }
    }
        comments[t] = temparray;
  }

  var $flag = $('<div class="flag"></div>').insertBefore('p');
var $commentContainer = $('<div class="comment-container"></ div>').insertAfter('p');

  $flag.each(function (i) {
        if (comments[i].length > 0) {
                var temphtml = "";
                var $this = $(this);
$this.html('<span class="has-comments">' + comments[i].length + '</span>');
                for (var z=0, c=comments[i].length;z<c;z++) {
                        temphtml = [
                        temphtml,
                        '<div class="sig">',
                          comments[i],
            [z].fields.name,
          '</div>',
          '<div class="comment">',
            comments[i],
            [z].fields.comment,
          '</div>'
        ].join('');
                }
          $commentContainer.eq(i).html(temphtml);
        } else {
                $this.html('<span></span>');
                $commentContainer.eq(i).html("Add a new comment.");
        }
    $this.click(function(){
      $commentContainer.eq(i).slideDown('fast');
    });
  });
});


You might also want to try triggering all of this on $(window).load() rather than $(document).ready()

by the way, I couldn't help myself, so I swapped all double quotes with single quotes and vice versa. It's really just a preference, but it makes more sense to me, especially when using HTML strings that include attribute values.

Hope this helps. I didn't run this code, so I'm not 100% sure I don't have a typo in there somewhere.

--Karl
_________________
Karl Swedberg
www.englishrules.com
www.learningjquery.com



On Jan 19, 2008, at 12:59 PM, cjl wrote:


I'm taking my first steps with jQuery, and have run into a performance
problem. I am trying to construct a customized "inline" comment system
for a project I am working on, similar to the one used on:

http://www.djangobook.com/en/1.0/chapter02/

Before I figure out the server side, I wanted to build a working
client side implementation. I have posted a rough draft here:

http://www.instantdjango.com/beta/chapter1.html

If you view the page source you will see the following javascript:

$(document).ready(function(){

var comment_data = eval(' [{"pk": 1, "model": "book.comment",
"fields": {"name": "C. Lesh", "comment": "This paragraph is great!",
"chapter": 2, "paragraph": 0}}, {"pk": 2, "model": "book.comment",
"fields": {"name": "Steve Smith", "comment": "So far, so good.",
"chapter": 2, "paragraph": 0}},{"pk": 3, "model": "book.comment",
"fields": {"name": "Frank Rizzo", "comment": "You writing is awful.
Really awful", "chapter": 2, "paragraph": 1}},{"pk": 4, "model":
"book.comment", "fields": {"name": "Fabrizzio", "comment": "I like
Django.", "chapter": 2, "paragraph": 0}},{"pk": 5, "model":
"book.comment", "fields": {"name": "Barbra", "comment": "You have
stuff you should be doing.!", "chapter": 2, "paragraph": 2}},{"pk": 6,
"model": "book.comment", "fields": {"name": "George B.", "comment":
"What the heck is a Django?", "chapter": 2, "paragraph": 2}}] ');

var comments = [];

for (t=0;t<$("p").length;t++){
        temparray = []
        for (i=0;i<comment_data.length;i++){
       if (comment_data[i].fields.paragraph == t)
{temparray.push(comment_data[i])};
   };
        comments[t] = temparray;
};

$("p").before("<div class='flag'><span class='has-comments'></span></
div>");
$("p").after("<div class='comment-container'></div>");

$(".flag").each(function (i) {
        if (comments[i].length > 0) {
                temphtml = "";
$(this).html("<span class='has-comments'>" + comments[i].length + "</
span>");
                for (z=0;z<comments[i].length;z++){
                        temphtml = temphtml + "<div class='sig'>" + comments[i]
[z].fields.name + "</div><div class='comment'>" + comments[i]
[z].fields.comment + "</div>";
                }
        $(".comment-container").eq(i).html(temphtml);
        }
        else {
                $(this).html("<span></span>");
                $(".comment-container").eq(i).html('Add a new comment.');
        };
   $(this).click(function(){
       $(".comment-container").eq(i).slideDown("fast");
});
});
});


Here is my goal, in pseudocode:
1. Load the page, with data serialized as JSON coming from the server
(faked here by providing the JSON).
2. eval the JSON data into a variable.
3. crunch the JSON data into an array, so that I can figure out which
comments apply to which paragraphs
4. for every paragraph in the document add a div before and after
5. fill in the number of comments into the appropriate "flag" div, and
the comments into the "comment" div

The script works, but it is slow for 109 paragraphs.

Any suggestions to speed things up?
The main problem I see (Firefox, Windows XP) is that the page does not
display at all until the javascript finishes processing. Is there a
way to display the page first, then run the javascript? Maybe I could
center a div that says "loading comments" and hide it after the
comments load, but as things stand the browser freezes for 5 or so
seconds.

Help?

Thanks in advance,
CJL

Reply via email to