2009-07-28 48 views
1

我为照片实验室构建了一个Web工具,以启动由打印机处理的打印指令。是我的jQuery脚本执行不良?

在旧版Mac上,我的脚本表现不佳。 我在想我的脚本中是否有一些低性能部件。

你们看到如此低效的零件吗?

THX,最大

$(function() { 

/* when start button is clicked */ 
$('.start_btn').click(function() { 

    /* remove all previous input fields */ 
    $("#dialog_fieldset").children().remove(); 

    /* save id */ 
    id = $(this).attr('name'); 

    /* get data from db */ 
    $.post("inc/get_start_order_infos.inc.php", { id: id }, 

     /* Callback */ 
     function(data){ 

      /* make data globally available */ 
      daten = data; 

      /* build the var 'infos_html' */ 
      var infos_html = '<label for="kunden_nr">Kunden-Nr.</label><input type="text" name="kunden_nr" id="kunden_nr" '; 
      infos_html += 'value="' + data.kunden_nr + '" class="text ui-widget-content ui-corner-all" />'; 
      infos_html += '<label for="sort">Sort</label><input type="text" name="sort" id="sort" value="'; 
      infos_html += data.sort_nr + '" class="text ui-widget-content ui-corner-all" />'; 

      /* append infos_html to the fieldset */ 
      $('#dialog_fieldset').append(infos_html); 

      /* Code Index */ 
      anzahlCodes = 1; 

      /* For each element within the sub array codes */ 
      for(e in data.codes){ 

       /* build the var 'code_html' */ 
       var code_html = '<label for="code' + anzahlCodes + '">Code ' + anzahlCodes; 
       code_html += '</label><input type="text" name="code' + anzahlCodes + '" id="code' + anzahlCodes; 
       code_html += '" value="' + data.codes[e] + '" class="text ui-widget-content ui-corner-all" />'; 

       /* append code_html to the fieldset */ 
       $('#dialog_fieldset').append(code_html); 
       anzahlCodes++; 
      } 

      $('#dialog').dialog('open'); 
      $('#kunden_nr').select(); 

    }, "json"); 

    return false; 
}); 

$("#dialog").dialog({ 
    bgiframe: false, 
    autoOpen: false, 
    height: 350, 
    modal: true, 
    buttons: { 
     'Auftrag starten': function() { 

      /* close dialog */ 
      $(this).dialog('close'); 

      /* create the info array to be submitted */ 
      var arr_infos = new Array(); 
      arr_infos[0] = id; 
      arr_infos[1] = $('#kunden_nr').attr('value'); 
      arr_infos[2] = $('#sort').attr('value'); 

      /* write inputs into the str_codes */ 
      var str_codes = ""; 
      for (var i=1; i < anzahlCodes; i++){ 
       var cde = '#code' + i; 
       if(i == 1){ 
        str_codes += $(cde).attr('value'); 
       } 
       else{ 
        str_codes += "<--->" + $(cde).attr('value'); 
       } 
      } 


      /* execute start */ 
      $.post("inc/start_orders.inc.php", { 'corrected_infos[]':arr_infos, 'corrected_codes': str_codes }, 

       /* Callback */ 
       function(data){ 
        $('#notice').remove(); 

        /* if start was successful */ 
        if (data.mstype == 'success'){ 

         /* the pressed button */ 
         btn = ".start_btn[name=" + id + "]"; 
         /* the tr where the button is inside */ 
         tr = $(btn).parent().parent(); 
         /* remove red */ 
         $(tr).removeClass('rot'); 

         /* set text of Kunden-Nr. td */ 
         $(tr).children().eq(3).text(arr_infos[1]); 

         /* set text of Sort td */ 
         $(tr).children().eq(4).text(arr_infos[2]); 

         /* set text of Code td */ 
         $(tr).children().eq(5).text(str_codes); 

         /* set text of start td */ 
         $(tr).children().eq(8).text('ja'); 

         /* prepend notice */ 
         $("#outline").prepend("<div id='notice'>" + data.ms + "</div>"); 
        } 

        /* if not successful */ 
        else { 
         $("#outline").prepend("<div id='notice' class='notice_err'>" + data.ms + "</div>"); 
        } 
       }, "json"); 
     }, 
     'Abbrechen': function() { 
      $(this).dialog('close'); 
     } 
    } 
}); 

回答

6

我的建议在代码中作为注释由//++指示。通常,当您尽可能少地搜索或修改DOM时,JavaScript会更快。

关注的要点是在你的循环和$(tr).

你重复使用我还没有测试此代码。

$(function() { 
    //++ jQuery doesn't cache this call, so it has to search the DOM each time. 
    //++ I've moved any node that is requested more than once here 
    var dialog_fieldset_node = $("#dialog_fieldset"), 
     dialog_node   = $("#dialog"), 
     kunden_nr_node  = $("#kunden_nr"), 
     outline_node   = $("#outline"); 
    //++ variables that you're using as globals I've moved here so that they can be shared 
    //++ between the event handlers, but aren't poluting the global scope. They are accessible 
    //++ to each event handler via the closure property of this annonymous function. 
    var id = null; 
    //++ Since you're creating the code <INPUT> nodes, store a refernce to them at that time 
    //++ instead of having to find them in the DOM again later. Now, anzahlCodes doesn't need 
    //++ to be available to both handlers. 
    var code_input_nodes = []; 

    /* when start button is clicked */ 
    $('.start_btn').click(function() { 
     /* remove all previous input fields */ 
     dialog_fieldset_node.children().remove(); 

     /* save id */ 
     id = $(this).attr('name'); 

     /* get data from db */ 
     $.post("inc/get_start_order_infos.inc.php", { id: id }, 
      /* Callback */ 
      function(data){ 
       /* make data globally available */ 
       daten = data; 

       /* append infos_html to the fieldset */ 
       //++ No need to build a string in a variable that you're only going to use once. You might want 
       //++ to build this out using DOM methods as I did below. Since its only done once, there might 
       //++ not be a difference performancy wise 
       dialog_fieldset_node.append(
        '<label for="kunden_nr">Kunden-Nr.</label><input type="text" name="kunden_nr" id="kunden_nr" ' + 
        'value="' + data.kunden_nr + '" class="text ui-widget-content ui-corner-all" />' + 
        '<label for="sort">Sort</label><input type="text" name="sort" id="sort" value="' + 
        data.sort_nr + '" class="text ui-widget-content ui-corner-all" />' 
       ); 


       //++ 1) `var e` to keep `e` from begin global. If you want this side effect, you should be explicit about it. 
       //++ 2) Create nodes via DOM methods to avoid running the HTML parser. node variables are defined outside of the 
       //++ loop to avoid overhead of instantiation and scope-chain modification (minimal, but effective for large sets 
       //++ of iterations. 
       //++ 3) Append created nodes to a document fragment and then append the fragment to the `dialog_fieldset_node` to 
       //++ avoid multiple, unnecessary DOM tree reflows (which are slow). 
       var fragment  = document.createDocumentFragment(), 
        label_node = null, 
        input_node = null; 
        anzahlCodes = 0; 
       //++ Seems this needs to be reset everytime 
       code_input_nodes = []; 

       /* For each element within the sub array codes */ 
       for(var e in data.codes){ 
        label_node = document.createElement("LABEL"); 
        label_node.setAttribute("for", anzahlCodes); 
        label_node.innerHTML = "Code " + anzahlCodes; 

        input_node = document.createElement("INPUT"); 
        input_node.setAttribute("type", "text"); 
        input_node.setAttribute("name", "code" + anzahlCodes); 
        input_node.setAttribute("id", "code" + anzahlCodes); 
        input_node.setAttribute("class", "text ui-widget-content ui-corner-all"); 
        input_node.setAttribute("value", data.codes[e]); 

        //++ store a reference for later use 
        code_input_nodes.push(input_node); 

        /* append code_html to the fieldset */ 
        fragment.appendChild(label_node); 
        fragment.appendChild(input_node); 
        anzahlCodes++; 
       } 
       dialog_fieldset_node.append(fragment); 

       dialog_node.dialog('open'); 
       kunden_nr_node = $("#kunden_nr"); 
       kunden_nr_node.select(); 

      }, 
      "json" 
     ); 

     return false; 
    }); 

    dialog_node.dialog({ 
     bgiframe: false, 
     autoOpen: false, 
     height: 350, 
     modal: true, 
     buttons: { 
      'Auftrag starten': function() { 
       /* close dialog */ 
       $(this).dialog('close'); 

       /* create the info array to be submitted */ 
       var arr_infos = [id, kunden_nr_node.attr('value'), $('#sort').attr('value')]; 

       /* write inputs into the str_codes */ 
       var str_codes = ""; 
       for (var i in code_input_nodes) { 
        str_codes += (i ? "" : "<--->") + code_input_nodes[i].attr('value'); 
       } 


       /* execute start */ 
       $.post("inc/start_orders.inc.php", { 'corrected_infos[]':arr_infos, 'corrected_codes': str_codes }, 
        /* Callback */ 
        function(data){ 
         $('#notice').remove(); 

         /* if start was successful */ 
         if (data.mstype == 'success'){ 
          /* the tr where the button is inside */ 
          //++ 1) Was this intentionally global? Global variables are the slowest to access because they 
          //++ are at the end of the scope-chain (which *sometimes* makes a difference, depending on depth). 
          //++ 2) Instead of wrapping `tr` in `$()` every time you use it, just do it once. 
          var tr = $(
            $(".start_btn[name=" + id + "]").parent().parent() 
           ); 
          //++ Avoid calling `.children()` multiple times, just do it once. 
          var tr_children = tr.children(); 

          /* remove red */ 
          tr.removeClass('rot'); 

          /* set text of Kunden-Nr. td */ 
          tr_children.eq(3).text(arr_infos[1]); 

          /* set text of Sort td */ 
          tr_children.eq(4).text(arr_infos[2]); 

          /* set text of Code td */ 
          tr_children.eq(5).text(str_codes); 

          /* set text of start td */ 
          tr_children.eq(8).text('ja'); 

          /* prepend notice */ 
          outline_node.prepend("<div id='notice'>" + data.ms + "</div>"); 
         } 

         /* if not successful */ 
         else { 
          outline_node.prepend("<div id='notice' class='notice_err'>" + data.ms + "</div>"); 
         } 
        }, 
        "json" 
       ); 
      }, 

      'Abbrechen': function() { 
       $(this).dialog('close'); 
      } 
     } 
    }); 
}); 

希望有所帮助。

2

嘿最大。如果你还没有,我建议你为Firefox安装Firebug。然后,您可以使用Javascript分析功能找出代码中放缓的地方。

这是一个很好的tutorial与Firebug分析。

祝你好运。

+0

虽然这将有助于检测哪些功能较慢,但它不会帮助解释原因。 – 2009-07-28 09:34:35

+0

这就是大脑的用途。 – hobodave 2009-07-28 09:35:23

+0

贾斯汀,你需要知道它在哪里,然后才能解决它,有时只是看代码,它不是明显的位置... – 2009-07-28 20:38:09

1

好吧,您只需要浏览一下您的代码,您所看到的最大错误就是在您的第二个回调函数(最下面的那个)中,您可以继续重新选择行的子元素。你应该真的把这个常见的查询结果分配给一个变量并使用它。我想你会看到性能的提高。这就是我会改变它:

/* beginning of callback code */ 

if (data.mstype == 'success') { 

    /* the pressed button */ 
    btn = $(".start_btn[name=" + id + "]"); 
    /* the tr where the button is inside */ 
    tr = $(btn).parent().parent(); 
    /* remove red */ 
    tr.removeClass('rot'); 

    /***** This is the change *****/ 
    var children = $(tr).children(); 

    /* set text of Kunden-Nr. td */ 
    children.eq(3).text(arr_infos[1]); 

    /* set text of Sort td */ 
    children.eq(4).text(arr_infos[2]); 

    /* set text of Code td */ 
    children.eq(5).text(str_codes); 

    /* set text of start td */ 
    children.eq(8).text('ja'); 
    /* prepend notice */ 
    $("#outline").prepend("<div id='notice'>" + data.ms + "</div>"); 
} 

/* end of callback code */ 

除此之外,你需要更具体,究竟它是坏的表现是来自为此,你可以使用Firebug像其他人那样指出。

0

请注意,这个dialog_fieldset_node.children().remove();将更适合通过empty(); dialog_fieldset_node.empty();