Global Filter function hangs in IE
Global Filter function hangs in IE
bryceray1121
Posts: 65Questions: 0Answers: 0
I've developed a global filter for my tables. This filter will take input from a user then search all the tables on the page filtering them to the user input. This function is mostly working properly in all browsers. Two main problems exist.
1) In firefox when I search via this method the search term is automatically entered into each individual tables filter box. However, in IE the term is only entered into the first tables filter input. All tables filter but only one will list the filter text so it may become confusing to the user.
2)The search function is acceptably quick in firefox. In IE, the search hangs (often prompting a slow script dialogue from the browser). The script eventually completes. The problem is the process gives the illusion of a frozen browser.
My test group:
I'm using a decent sized test group of 12 tables with any where from 1-30 rows. About 1/4 of the tables are completely empty.
The code I have right now:
[code]
function globalSearch(value){
if(value == null) value = document.getElementById("searchInput").value;
for(var i=0;i<(oTable.length);i++){
$.fn.dataTableExt.iApiIndex = i;
if((oTable.fnGetNodes( ).length) > 0){
oTable.fnFilter(value);
}
}
$.fn.dataTableExt.iApiIndex = 0;
}
[/code]
This code is pretty straight forward. The only performance adjustment I could think to add was skipping empty tables. This does provide a significant performance improvement if your environment is likely to have a few empty tables.
Can anyone provide any suggestions on:
1). Improvements I can make to this function to improve the overall performance?
2). Improvements I can make to specifically improve performance in IE?
1) In firefox when I search via this method the search term is automatically entered into each individual tables filter box. However, in IE the term is only entered into the first tables filter input. All tables filter but only one will list the filter text so it may become confusing to the user.
2)The search function is acceptably quick in firefox. In IE, the search hangs (often prompting a slow script dialogue from the browser). The script eventually completes. The problem is the process gives the illusion of a frozen browser.
My test group:
I'm using a decent sized test group of 12 tables with any where from 1-30 rows. About 1/4 of the tables are completely empty.
The code I have right now:
[code]
function globalSearch(value){
if(value == null) value = document.getElementById("searchInput").value;
for(var i=0;i<(oTable.length);i++){
$.fn.dataTableExt.iApiIndex = i;
if((oTable.fnGetNodes( ).length) > 0){
oTable.fnFilter(value);
}
}
$.fn.dataTableExt.iApiIndex = 0;
}
[/code]
This code is pretty straight forward. The only performance adjustment I could think to add was skipping empty tables. This does provide a significant performance improvement if your environment is likely to have a few empty tables.
Can anyone provide any suggestions on:
1). Improvements I can make to this function to improve the overall performance?
2). Improvements I can make to specifically improve performance in IE?
This discussion has been closed.
Replies
[code]
FireFox
table 0: 75, table 1: 49, table 3: 54, table 4: 52, table 6: 62, table 9: 101, table 10: 64, table 11: 50, table 12: 53, table 13: 57
table 0: 51, table 1: 47, table 3: 51, table 4: 51, table 6: 47, table 9: 51, table 10: 60, table 11: 49, table 12: 58, table 13: 49
table 0: 48, table 1: 53, table 3: 51, table 4: 51, table 6: 48, table 9: 51, table 10: 68, table 11: 49, table 12: 51, table 13: 49
IE8
table 0: 62, table 1: 35, table 3: 43, table 4: 44, table 6: 39, table 9: 46, table 10: 57, table 11: 33, table 12: 24, table 13: 34
table 0: 55, table 1: 58, table 3: 45, table 4: 45, table 6: 35, table 9: 65, table 10: 76, table 11: 26, table 12: 27, table 13: 40
table 0: 53, table 1: 35, table 3: 55, table 4: 54, table 6: 39, table 9: 41, table 10: 52, table 11: 22, table 12: 24, table 13: 31
IE7
table 0: 488, table 1: 969, table 3: 965, table 4: 952, table 6: 917, table 9: 924, table 10: 1211, table 11: 15317, table 12: 39599, table 13: 3845
table 0: 550, table 1: 965, table 3: 972, table 4: 957, table 6: 924, table 9: 944, table 10: 1225, table 11: 15393, table 12: 38994, table 13: 3925
table 0: 529, table 1: 981, table 3: 965, table 4: 978, table 6: 959, table 9: 963, table 10: 1218, table 11: 15570, table 12: 39611, table 13: 3798
[/code]
This is the function I used with the benchmarking elements in it:
[code]
function globalSearch(value) {
var loTable = oTable;
if ((value === undefined) || (value === null)) {
value = document.getElementById("searchInput").value;
}
var executionTime = "";
for (var i=0;i < (loTable.length);i++) {
$.fn.dataTableExt.iApiIndex = i;
if ((loTable.fnGetNodes( ).length) > 0) {
var start = new Date().getTime();
loTable.fnFilter(value);
var stop = new Date().getTime();
executionTime += ", table "+i+": "+ (stop - start);
}
}
alert(executionTime);
$.fn.dataTableExt.iApiIndex = 0;
}
[/code]
Each test was run using the same search term on the same data on the same number of tables. You will notice some table elements are skipped, this is because they are empty tables.
This is a pretty sizable difference in fnFilters execution. Any ideas on what might be causing this?
Yeah - the IE7 JS engine :-). I'm afraid it looks like you are simply hitting a performance issue with the IE7 engine which is well known to be horribly slow. It's a nice idea to skip over empty tables and your code is very similar to the fnFilterAll API plug-in: http://datatables.net/plug-ins/api#fnFilterAll
You could try disabling a few features and see if that helps in IE7. Specifically bSortClasses will likely make a difference ( http://datatables.net/faqs#speed ) and I would think that sorting will as well.
Beyond that, I think it's time to start looking at a profiler to see where speedups could be made specifically for IE7.
Allan
I loaded all of my html tables in to a test html document. Added a search input and button and ran this function. The function is not perfect or tested that much but it performs a basic filter on all the tables.
[code]
function search(){
var value = document.getElementById('inputText').value;
var table = getElementsByClassName("dataTable")
for(var x=0;x
[code]
function globalSearch(value) {
var loTable = oTable;
if ((value === undefined) || (value === null)) {
value = jQuery("#searchInput").val();
}
for (var i=0;i < (loTable.length);i++) {
if ((loTable[i].fnGetNodes( ).length) > 0) {
loTable[i].fnFilter(value);
}
}
}
[/code]
I tested this in IE7 (firefox, IE8, etc) and I am now seeing more appropriate search execution times. I'm not sure what the root cause of this problem was but it is fixed now.
Nice one - excellent to hear that this is sorted! I would have thought that if anything would go funny with iApiIndex it would simply cause a JS error, rather than taking a long time. However, as long as it works now... :-)
Regards,
Allan
I've noticed that the error only occurs when I pass an empty value to fnFilter "". For example consider this data set of timings:
[quote]9-15
12-13
9-25
9-26
8-29
12-568
89-1651
50-132
15-23
10-24
8-19
17-27
12-21
14-21
29-37[/quote]
Each row of these timings represents a individual table on the page. The first number represents the time required for the table to filter the word "high". As you can see the timings are in a respectable range. The second number, after the dash, is the time required to reset the filter to its original state. I do this by passing an empty value to fnFilter(""). As you can see some tables have significantly higher values when I am "resetting" the filter. It is also important to note that the time scale to the number of rows in the table. So the table 89--1651 has more rows than the table 12-13.
I also get higher timings if I first filter "high" then filter just "hi". I think the main problem has to do with the timing to add a row back to the table.
I created the timing by inserting this code to the data tables library in this.fnFilter:
[code]
if ( iColumn === undefined || iColumn === null )
{
var start = new Date().getTime();
/* Global filter */
_fnFilterComplete( oSettings, {
"sSearch":sInput+"",
"bRegex": bRegex,
"bSmart": bSmart,
"bCaseInsensitive": bCaseInsensitive
}, 1 );
if ( bShowGlobal && oSettings.aanFeatures.f )
{
var n = oSettings.aanFeatures.f;
for ( var i=0, iLen=n.length ; i
DataTables' filtering does to optimisation such that smaller filtering sets will run faster and a filter gets more selective - which I suspect will explain the timing differences. But it will be interesting to see if the filtering as a whole can be speed up for you (although I'm not sure how, or I would have done it by now :-) ).
Allan