Yes, I know there are a lot of JS/jQuery programs out there to do this. I'm currently using .js . It's very easy: just a JS file, add a few class attributes to your table, and you're off. In particular, you don't actually need to know JS to use it, and you can add custom sort keys without needing to write your own JS to extend it. I like it a lot for those two reasons. The main problem: my table is ~9300 rows long, and sorting takes 10-20 seconds. So I'm wondering, are any other scripts out there faster than this? These are the ones I've found:
.html (Not even sure what this uses)
/ (Really really nice, but not easy to extend, requires knowing JS/jQuery)
/ (Overkill, I just need a table sorter, not a whole data manipulation program)
/ (Overkill, requires Js/jQuery to extend)
I'm sure there's 5000 other programs that can do what I want, but I don't have the time to figure out and test them all to see if they're fast. Thus I'd like to know if someone out there on StackOverflow can point me to whichever library they know to be fast, so I only have to figure out how to use one program.
(Btw, I've seen Java sort hundreds of thousands of numbers in milliseconds with quicksort; does anyone know what algorithm JS.sort() uses?)
Yes, I know there are a lot of JS/jQuery programs out there to do this. I'm currently using http://www.kryogenix.org/code/browser/sorttable/sorttable.js . It's very easy: just a JS file, add a few class attributes to your table, and you're off. In particular, you don't actually need to know JS to use it, and you can add custom sort keys without needing to write your own JS to extend it. I like it a lot for those two reasons. The main problem: my table is ~9300 rows long, and sorting takes 10-20 seconds. So I'm wondering, are any other scripts out there faster than this? These are the ones I've found:
http://webfx.eae.net/dhtml/sortabletable/sortabletable.html (Not even sure what this uses)
http://tablesorter.com/docs/ (Really really nice, but not easy to extend, requires knowing JS/jQuery)
http://flexigrid.info/ (Overkill, I just need a table sorter, not a whole data manipulation program)
http://datatables.net/ (Overkill, requires Js/jQuery to extend)
I'm sure there's 5000 other programs that can do what I want, but I don't have the time to figure out and test them all to see if they're fast. Thus I'd like to know if someone out there on StackOverflow can point me to whichever library they know to be fast, so I only have to figure out how to use one program.
(Btw, I've seen Java sort hundreds of thousands of numbers in milliseconds with quicksort; does anyone know what algorithm JS.sort() uses?)
Share Improve this question edited Jul 3, 2012 at 4:35 Robert Levy 29.1k6 gold badges64 silver badges95 bronze badges asked Jul 3, 2012 at 4:30 DubslowDubslow 7042 gold badges7 silver badges17 bronze badges 4- 2 you tagged this with jquery but it sounds like you want to avoid taking that dependency... which way is it? – Robert Levy Commented Jul 3, 2012 at 4:37
- 2 Sure, java can sort numbers quickly, but you're sorting the DOM. DOM operations are slow. Your issue starts with 9300 rows in a HTML table. I'd sort it server side. But if you don't want to do that, perhaps storing the data in a JS object, sorting, and re-rendering the table every time would be quicker. – Christian Commented Jul 3, 2012 at 5:04
- @Robert: Yes, I'd like to avoid it, but I'll take anything that's fast and learn JQuery if that's necessary. – Dubslow Commented Jul 3, 2012 at 5:10
- @Christian: I do deliver the HTML sorted by one column, but the data is interesting sorted from many different columns. The JS I currently use reads the HTML, stores the entries in an array, and then uses JS's builtin sort() on the array. – Dubslow Commented Jul 3, 2012 at 5:12
4 Answers
Reset to default 9I have had great success with DataTables (another jQuery plugin) with similar row numbers to what you are talking about. The speed loss you are seeing with javascript over what you have seen in java is it is actually rendering a DOM, which is a lot more work. The beauty of DataTables is you have the ability to source the data from a javascript array (essentially json) - so the sorting is done on the array (similar speed to java), and then only the part of the table the user needs to see is generated in the DOM.
See these urls for examples:
http://datatables.net/examples/data_sources/js_array.html
or
http://datatables.net/examples/data_sources/ajax.html
I suggest using the latter. If its still not fast enough using a static json array, you will want to build a serverside script to take the load off javascript - great example with serverside code here:
http://datatables.net/examples/data_sources/server_side.html
Edit: Infinite Scrolling
As discussed in the comments, the problem isn't the sort, but rather converting the HTML table to JS and back. This may help out by only loading rendering parts of the returned sort as the user views it; the server also provides the JS the same information as the table in JSON form. These two techniques eliminate the HTML-JS conversion and rendering problems, and thus greatly increase speed.
HTML (this is all that has to be rendered initially before the JSON comes along - add as many th tags as you have columns):
<table id="table_id">
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>etc</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
JQUERY:
$(document).ready(function() {
$('#table_id').dataTable( {
"bScrollInfinite": true,
"bScrollCollapse": true,
"sScrollY": "200px",
"bProcessing": true,
"sAjaxSource": 'array.txt'
});
});
array.txt contains:
{ "aaData": [
["This will be in column 1","This in two","this in 3"],
["another row - column 1","another two","another 3"]
]}
Apart from libraries, table sorting is quite easy to do it by yourself.
The time it takes to actually sort the rows is negligible in relation to the time the DOM needs to move items around.
The one thing that WILL give you the best performance, is to detach the rows, arrange them according to your needs and attach them again. You don't need raw JSON data, just detach the $tr's, grab the values you want to compare from td's, make an array of $tr's, sort this array according to the column you want and attach them back to your tbody.
For example, with this technique I am sorting 3000 rows of 15 columns in 1 second time, which is totally viable. With that performance, the only problem is how to fetch 3000 rows to the browser...
I know this post is a bit old, but here's the ES6+ solution that worked pretty great for me.
/**
* Sort table data based on a direction of asc or desc for a specific column
* @param {number} n- column number calling this sort
* @param {string} dir -direction of the sort (asc or desc)
* @param {HTMLSpanElement} targetElem -sort icon
*/
function sortTable(n, dir = "asc", targetElem) {
targetElem.style.cursor = "progress";
let sortArr = [];
let table =targetElem.closest('table');
table.querySelectorAll('tbody > tr > td:nth-Child(' + parseInt(n) + ')').forEach((x, y) => sortArr.push(
{
sortText: x.innerHTML.toLowerCase(),
rowElement: x.closest('tr')
}));
var sorted = sortArr.sort(function (a, b) {
if (dir == "asc") {
if (a.sortText < b.sortText) {
return -1;
}
} else if (dir == "desc") {
if (a.sortText > b.sortText) {
return -1;
}
}
return 0;
});
sorted.forEach((x, y) => {
x.rowElement.parentNode.insertBefore(x.rowElement, x.rowElement.parentNode.children[y]);
});
targetElem.style.cursor = null;
}
In each of my th elements, I have sort icons that I use to call this function. They have their column numbers embedded in a data tag. They look like:
<th data-field-name="lastLogin" role="columnheader" class="lastLogin">Last Login
<span class="fa fa-unsorted sort-icon" title="Sort Descending" data-col-number="6" style="font-size: 1.2em; margin-left: 15px;"></span>
</th>
The click action for the icon:
click(icon){
var parent = icon.closest('tr');
parent.querySelectorAll('.sort-icon').forEach(x => {
if (x == icon) {
return;
}
delete x.dataset.dir;
x.classList.replace('fa-sort-down', 'fa-unsorted');
x.classList.replace('fa-sort-up', 'fa-unsorted');
});
if (icon.classList.contains('fa-unsorted')) {
icon.classList.replace('fa-unsorted', 'fa-sort-up');
icon.title = icon.title.replace('Ascending', 'Descending');
icon.dataset.dir = "asc";
} else if (icon.classList.contains('fa-sort-down')) {
icon.classList.replace('fa-sort-down', 'fa-sort-up');
icon.dataset.dir = "asc";
icon.title = icon.title.replace('Ascending', 'Descending');
} else if (icon.classList.contains('fa-sort-up')) {
icon.classList.replace('fa-sort-up', 'fa-sort-down');
icon.title = icon.title.replace('Descending', 'Ascending');
icon.dataset.dir = "desc";
}
sortTable(icon.dataset.colNumber, icon.dataset.dir, icon);
}
I think this javascript library easy and powerful: http://tabulator.info
Tabulator allows you to create interactive tables in seconds from any HTML Table, JavaScript Array, AJAX data source or JSON formatted data.
Inside the cells you can put text, progress bar, images, other tables!