简体   繁体   English

jQuery .prependTo()创建的表导致浏览器“滞后”

[英]jQuery .prependTo() created table causing browser to “lag”

I have a problem I am not able to fix, quite difficult to explain but I will do my best. 我有一个无法解决的问题,很难解释,但我会尽力而为。

Basically I have created a web application (in CodeIgniter ) that takes some data of an array coming from a json encoding and adds rows to a table by using the jQuery .prependTo() method in the success function. 基本上,我创建了一个Web应用程序(在CodeIgniter中 ),该应用程序使用来自json编码的数组的一些数据,并使用成功函数中的jQuery .prependTo()方法向表中添加行。

Every row of the table contains different elements from the database (coming from the json), depending from the value of the i counter. 根据i计数器的值,表的每一行都包含来自数据库的不同元素(来自json)。

The code is as the following (i cut the part about the <tr> and <td> content, it's just styling) 代码如下(我剪切了关于<tr><td>内容的部分,只是样式)

$.ajax({
type: "get",
async: false,
....
....
success: function(data) {


                    var i;
                    var item_cost = new Array();
                    var item_name = new Array();
                    var item_code = new Array();
                    var item_interno = new Array();

                    for(i = 0; i < data.length; i++) {
                       item_cost[i] = data[i].cost;
                       item_name[i] = data[i].name;
                       item_code[i] = data[i].code;
                       item_interno[i] = data[i].codiceinterno;


                       var newTr = // creates the <tr>
                       newTr.html('//creates the <td>')
                       newTr.prependTo("#myTable");
                    }
},

I am sorry if it is a bit unclear, if you need me to update the code because I missed something important let me know and I will do it, but this code alone should explain my problem. 很抱歉,如果您不清楚我是否想更新代码,因为我错过了重要的事情,请告诉我,我会做,但是仅此代码就可以解释我的问题。

The application works beautifully if in the database there are just a little number of rows (for example, i = 300). 如果在数据库中只有少量的行(例如,i = 300),则该应用程序可以很好地运行。 They are showed and rendered correctly and I don't get any browser slowing process. 它们的显示和渲染正确无误,而且我没有任何浏览器速度降低的过程。 But when I work with i = 4000 rows, the browser starts acting slow just like the Javascript code is too heavy to render, and i get "lag" while trying to scroll down the html table, or inputting some values in the input boxes inside the table (to later update it by clicking a button). 但是,当我使用i = 4000行时,浏览器开始运行缓慢,就像Javascript代码太重而无法呈现,并且在尝试向下滚动html表或在内部输入框中输入一些值时出现“滞后”表格(以后通过单击按钮对其进行更新)。 This is my problem: I am quite sure I'm doing something wrong that is loading up too much memory, as I tested this also on very strong computers. 这是我的问题:我很确定自己做错了一些事情,导致我加载了太多的内存,因为我也在非常强大的计算机上进行了测试。 Even totally disabling my CSS won't do the trick. 即使完全禁用我的CSS也无法解决问题。

Thanks for any help you can give me, it would be really appreciated. 感谢您能给我的任何帮助,我们将不胜感激。

The problem 问题

You are using a lot of function call inside a loop. 您在循环中使用了许多函数调用。 That take a lot of juice and the more item you have, the slower it is. 这需要大量的汁液,而且您拥有的物品越多,速度就越慢。

To solve that, we need to reduce the number of function calls. 为了解决这个问题,我们需要减少函数调用的次数。

My suggestion 我的建议

Working with native JavaScript would save on performance here. 使用本机JavaScript可以节省此处的性能。 So I suggestion you use string concatenation instead of DOM manipulation methods of jQuery. 因此,我建议您使用字符串连接而不是jQuery的DOM操作方法。

Let rework you loop. 让您返工。 Since you want your data in a descendant order, we need to reverse the loop : 由于您希望数据按后代顺序排列,因此我们需要反转循环:

for(i = data.length; i >= 0; i--)

Then simple string concatenation to build a tr . 然后通过简单的字符串连接来构建一个tr For that you need a var outside the loop: 为此,您需要在循环外添加一个var:

var myHTML = ''; //That's the one!
var i;
var item_cost = new Array();
var item_name = new Array();
var item_code = new Array();
var item_interno = new Array();

And build the tr with += . 并使用+=构建tr Although, using a single line would make it faster, but less readable : 虽然,使用单行可以使其更快,但可读性较低:

for(i = data.length; i >= 0; i--) {
    item_cost[i] = data[i].cost;
    item_name[i] = data[i].name;
    item_code[i] = data[i].code;
    item_interno[i] = data[i].codiceinterno;


    myHTML += '<tr>';
    myHTML += '<td>'+yourData+'</td>';//add those data here
    myHTML += '<td>'+yourData+'</td>';
    myHTML += '<td>'+yourData+'</td>';
    myHTML += '<td>'+yourData+'</td>';
    myHTML += '<td>'+yourData+'</td>';
    myHTML += '</tr>';
}

Then, prepend it to your table : 然后,将其添加到您的表中:

var myHTML = '';
var i;
var item_cost = new Array();
var item_name = new Array();
var item_code = new Array();
var item_interno = new Array();

for(i = data.length; i >= 0; i--) {
    item_cost[i] = data[i].cost;
    item_name[i] = data[i].name;
    item_code[i] = data[i].code;
    item_interno[i] = data[i].codiceinterno;


    myHTML += '<tr>';
    myHTML += '<td>'+yourData+'</td>';
    myHTML += '<td>'+yourData+'</td>';
    myHTML += '<td>'+yourData+'</td>';
    myHTML += '<td>'+yourData+'</td>';
    myHTML += '<td>'+yourData+'</td>';
    myHTML += '</tr>';
}

$('#myTable').prepend(myHTML);

Limitation 局限性

From my test, the string length can be 2^28 but cannot be 2^29 . 根据我的测试,字符串长度可以为2^28但不能为2^29 That make a maximum length of approx. 这使得最大长度约为。 268,435,456 (approx. might not be the best word here since it's between 268,435,456 and 536,870,912 . 268,435,456 (此处大约不是最好的词,因为它介于268,435,456536,870,912之间。

If you data character count is higher than that (but let be honnest, that would be a lot of data), you might have to split you string into 2 variables. 如果您的数据字符数大于该值(但请记住,这将是大量数据),则可能必须将字符串分成两个变量。

I know this is not a real answer to your question, but... 我知道这不是您问题的真正答案,但是...

jQuery definitely causes the lag - no wonder. jQuery肯定会导致延迟-难怪。 But - whether you choose jQuery to build the table or you just concatenate HTML - let's agree on that: 4000 rows is definitely a lot of data. 但是-无论您选择使用jQuery来构建表还是仅连接HTML,我们都同意:4000行绝对是很多数据。 Too much data? 数据太多? I would say: 200 already is. 我会说:200已经是。 If we go thousands, the question pops up: why? 如果我们成千上万,就会出现一个问题:为什么? Is there any application-related reason you really need to retrieve such a big number of records at once? 您真的有任何与应用程序相关的原因需要一次检索如此大量的记录吗? Some of them will probably never be read. 其中一些可能永远不会被阅读。

Why not try an ajax-based lazy load approach? 为什么不尝试基于Ajax的延迟加载方法? Loading 50-record portions every time would seem more robust IMO, and would definitely be a better UX. 每次加载50个记录的部分将使IMO看起来更强大,并且绝对是更好的UX。

My two cents: Why don't retrieve the rows composed from the server instead of making the client work to compound it? 我的两分钱:为什么不检索由服务器组成的行,而不是让客户端来使其复杂化呢? You could even cache it. 您甚至可以缓存它。 The only thing would be that you'll have more traffic, but in the browser it'll go smoother 唯一的事情是您会有更多的流量,但是在浏览器中它将更加流畅

UPDATE UPDATE

To achieve it, you can make your method to distinguish between ajax input or not, and show only $tbody , or the whole table according to it. 要实现它,您可以使您的方法区分ajax输入与否,并仅显示$tbody或根据它显示整个表。 It would be something like: 就像这样:

$tbody = $this->load->view( 'view_with_oly_tbody', $data, true );
if ( $this->input->is_ajax_request() ) {
    return $tbody;
} else {
    $data['tbody'] = $tbody;
    $this->load->view('your_view_with_table_with_tbody_as_var', $data);
}

Note: Code above will vary according to your views, controller, if you have json in your AJAX or not, write the return in other part, etc. Code above is just for clarify my point with CI. 注意:上面的代码将根据您的视图和控制器而有所不同,如果您的AJAX中是否包含json,请在其他部分中写出return等。上面的代码仅用于阐明我对CI的观点。

Ah! 啊! and you'll have to manage the answer in the client to append/prepend/substitute the body of the table. 并且您将不得不在客户端中管理答案以追加/添加/替换表格主体。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM