Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I don't think you'll get acceptable performance from just about any grid component showing 1,000 <em>at the same time</em>, 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.</p> <h3>Edit</h3> <p>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 <a href="http://prototypejs.org" rel="nofollow noreferrer">Prototype's</a> <code>evalJSON</code>, which (even now) just defers to <code>eval</code> and puts the data in parentheses (they'll be changing that).</p> <p><strong>1000rows.html</strong></p> <pre><code>&lt;!DOCTYPE HTML&gt; &lt;html&gt; &lt;head&gt; &lt;meta http-equiv="Content-type" content="text/html;charset=UTF-8"&gt; &lt;title&gt;1,000 Row Test Page&lt;/title&gt; &lt;style type='text/css'&gt; body { font-family: sans-serif; } #log p { margin: 0; padding: 0; } &lt;/style&gt; &lt;script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js'&gt;&lt;/script&gt; &lt;script type='text/javascript' src='1000rows.js'&gt;&lt;/script&gt; &lt;/head&gt; &lt;body&gt;&lt;div&gt; &lt;input type='button' id='btnLoadData' value='Load Data'&gt; &lt;input type='button' id='btnNext' value='Next'&gt; &lt;input type='button' id='btnPrevious' value='Previous'&gt; &lt;table&gt; &lt;thead&gt; &lt;tr&gt;&lt;th&gt;Name&lt;/th&gt;&lt;th&gt;Description&lt;/th&gt;&lt;th&gt;Count&lt;/th&gt;&lt;/tr&gt; &lt;/thead&gt; &lt;tfoot&gt; &lt;tr&gt;&lt;th colspan='3' id='theLabel'&gt;&lt;/th&gt;&lt;/tr&gt; &lt;/tfoot&gt; &lt;tbody id='theData'&gt; &lt;tr&gt;&lt;td colspan='3'&gt;&lt;/td&gt;&lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;hr&gt; &lt;div id='log'&gt;&lt;/div&gt; &lt;/div&gt;&lt;/body&gt; &lt;/html&gt; </code></pre> <p><strong>1000rows.js</strong> (using Prototype; jQuery would be different but similar)</p> <pre><code>(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 &lt;= 0) { dataElement.update(""); labelElement.update("No information"); return; } // Ensure that windowTop is rational if (WINDOW_SIZE &gt; data.length) { windowTop = 0; } else { if (typeof offset == 'number') { windowTop += offset; } if (windowTop + WINDOW_SIZE &gt; data.length) { windowTop = data.length - WINDOW_SIZE; } if (windowTop &lt; 0) { windowTop = 0; } } template = new Template( "&lt;tr&gt;&lt;td&gt;#{name}&lt;/td&gt;&lt;td&gt;#{description}&lt;/td&gt;&lt;td&gt;#{count}&lt;/td&gt;&lt;/tr&gt;" ); markup = ""; index = windowTop + WINDOW_SIZE - 1; if (index &gt;= data.length) { index = data.length - 1; } $('theLabel').update('Showing rows ' + windowTop + ' through ' + index); while (index &gt;= windowTop) { markup = template.evaluate(data[index]) + markup; --index; } dataElement.update(markup); } // Log a message function log(msg) { $('log').appendChild(new Element('p').update(msg)); } })(); </code></pre> <p><strong>data.txt</strong> (quite boring, of course)</p> <pre><code>[ {"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} ] </code></pre> <p>...a full copy of data.txt can be found <a href="http://pastie.org/784738" rel="nofollow noreferrer">here</a>.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload