views:

491

answers:

5

I want to show a list with 1000 rows using Json that's support by Struts2 like pug-in. I use flexigrid (jquery) to parse 1000 rows to display. But it's so slow, and sometimes my browser crashes. (Firefox & IE).

So, what is the fastest Javascript framework to parse about 1000 rows?

+1  A: 

1,000 rows of what? jQuery is actually pretty quick, especially since performance upgrades in version 1.4 (released just days ago). If you're experiencing problems showing 1,000 rows, I would first ask you why you're showing that many - no human ought to have to scroll that much. And second, is all of the information crucial, and are you only passing crucial information into the JSON value. And lastly, are you making your DOM unnecessarily-complicated with the way you're adding the data?

Again, if you're querying only what you need to show, and you're showing a reasonable about of data (posting 1,000 rows on the screen isn't reasonable), jQuery will be more than sufficient for your needs.

Jonathan Sampson
plz check my answer comment above, I use Flexigrid to load 1000rows, I think the cause of problem my by Fexigrid :), I will update more about jquery thanks u. :)
Tr.Crab
+1  A: 

I don't think you'll get acceptable performance from just about any grid component showing 1,000 at the same time, especially not on IE (even IE8). But most grids should be able to support having 1,000 in memory (well, depending on how big they are) and displaying a window into them (say, 20 rows, 40 rows, etc.) with paging and filtering options, without a significant performance problem. That would be a better user experience as well, I would think.

Edit

I got curious enough to check, and yeah, JSON parse time is not the problem; it'll be the rendering. Below is an example of very, very simple (not production) paging entirely client-side. On my netbook, IE7 parses the 1,000 rows of simple JSON objects in 36ms, so even complex objects shouldn't be an issue. That's using Prototype's evalJSON, which (even now) just defers to eval and puts the data in parentheses (they'll be changing that).

1000rows.html

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>1,000 Row Test Page</title>
<style type='text/css'>
body {
    font-family: sans-serif;
}
#log p {
    margin:     0;
    padding:    0;
}
</style>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js'&gt;&lt;/script&gt;
<script type='text/javascript' src='1000rows.js'></script>
</head>
<body><div>
<input type='button' id='btnLoadData' value='Load Data'>
<input type='button' id='btnNext' value='Next'>
<input type='button' id='btnPrevious' value='Previous'>
<table>
<thead>
<tr><th>Name</th><th>Description</th><th>Count</th></tr>
</thead>
<tfoot>
<tr><th colspan='3' id='theLabel'></th></tr>
</tfoot>
<tbody id='theData'>
<tr><td colspan='3'></td></tr>
</tbody>
</table>
<hr>
<div id='log'></div>
</div></body>
</html>

1000rows.js (using Prototype; jQuery would be different but similar)

(function() {
    var data, windowTop, WINDOW_SIZE;

    // "Constant" for the size of our window into the data
    WINDOW_SIZE = 20;   // Rows

    // No data yet
    clearData();

    // Hook up our observers when we can
    document.observe('dom:loaded', function() {
        $('btnLoadData').observe('click', loadData);
        $('btnNext').observe('click', function(event) {
            event.stop();
            updateWindow(WINDOW_SIZE);
        });
        $('btnPrevious').observe('click', function(event) {
            event.stop();
            updateWindow(-WINDOW_SIZE);
        });
    });

    // Clear our data to a known state
    function clearData() {
        data = [];
        windowTop = 0;
    }

    // Click handler for the load data button
    function loadData() {
        var success;

        log("Loading data..");
        clearData();
        updateWindow();
        success = false;

        // Note: Using text/plain rather than application/json so
        // Prototype doesn't parse the data for me, so I can measure
        // how long it takes to do it.
        new Ajax.Request("data.txt", {
            onSuccess: function(response) {
                var start, duration;

                success = true;
                log("Got data, parsing");
                start = new Date().getTime();
                data = response.responseText.evalJSON();
                duration = new Date().getTime() - start;
                log("Data parsed in " + duration + "ms");
                updateWindow.defer();
            }
        });
    }

    function updateWindow(offset) {
        var dataElement, labelElement, markup, index, template;

        // Get the target element
        dataElement = $('theData');
        labelElement = $('theLabel');
        if (!dataElement || !labelElement) {
            return;
        }

        // If no data, simply say that
        if (!data || data.length <= 0) {
            dataElement.update("");
            labelElement.update("No information");
            return;
        }

        // Ensure that windowTop is rational
        if (WINDOW_SIZE > data.length) {
            windowTop = 0;
        }
        else {
            if (typeof offset == 'number') {
                windowTop += offset;
            }
            if (windowTop + WINDOW_SIZE > data.length) {
                windowTop = data.length - WINDOW_SIZE;
            }
            if (windowTop < 0) {
                windowTop = 0;
            }
        }

        template = new Template(
            "<tr><td>#{name}</td><td>#{description}</td><td>#{count}</td></tr>"
        );

        markup = "";
        index = windowTop + WINDOW_SIZE - 1;
        if (index >= data.length) {
            index = data.length - 1;
        }
        $('theLabel').update('Showing rows ' + windowTop + ' through ' + index);
        while (index >= windowTop) {
            markup = template.evaluate(data[index]) + markup;
            --index;
        }

        dataElement.update(markup);
    }

    // Log a message
    function log(msg) {
        $('log').appendChild(new Element('p').update(msg));
    }
})();

data.txt (quite boring, of course)

[
    {"name": "Name #0001", "description": "Description #0001", "count": 1},
    {"name": "Name #0002", "description": "Description #0002", "count": 2},
    {"name": "Name #0003", "description": "Description #0003", "count": 3},
    ...
    {"name": "Name #1000", "description": "Description #1000", "count": 1000}
]

...a full copy of data.txt can be found here.

T.J. Crowder
W.0.W, your code's so nice. It's really helpful, thanks u. :)
Tr.Crab
+4  A: 

Show the user what they want to see.

Show 50 rows, add a filter or a search.

If you really think that data should be reachable in a single page, maybe what you want is to fetch data while the user scrolls (and thus pick up smaller portions at a time).

altCognito
I get a list return by Oracle procedure, so that it not changeable, thus, can not use scrollable ResultSet with Oracle.(limitation)
Tr.Crab
Still, cache the data somewhere, be it in the application layer or whatnot, and then page it from there. Of course, I would still be surprised if there was no way to leave the data in some temporary Oracle table (or something along those lines) - but it doesn't change the fact you can cache it somewhere else.
altCognito
plz give me more information about caching with spring jdbc and oracle, thanks u :)
Tr.Crab
+5  A: 

What is the fastest JSON parser for JavaScript?

eval or when available, native JSON parser, at least in Chrome, Safari, Firefox 3.something, Opera 10.50, and even IE8 (only in IE8-mode)

Jani Hartikainen
+1 for actually answering the question the OP asked. ;-)
T.J. Crowder
A: 

If you really want speed, the javascript eval("..."); function is the fastest. Unfortunately it's not safe as it can execute malicious javascript.

There's also the javascript JSON Parser (found here) from JSON.org. They've written the javascript to parse JSON strings to create a JSON object (I've heard that debugging using Firebug, a Firefox add-ons, creates an array of JSON objects but I've never tried it).

The Elite Gentleman