1

I have an old-style CGI program which generates a large HTML table. Because the table contents are slow to calculate (even though it's not that big) I would like to print it one row at a time, and have the browser display rows as they are fetched.

If you search online you'll see that style="table-layout: fixed" is supposed to help some browsers do this, but on the other hand Firefox can render incrementally even without it. My test browser is Firefox 4.0b10 on Windows but I cannot get it to display incrementally using the simple example below:

<html>
  <head>
    <title>x</title>
  </head>
  <body>
    <table width="100%" style="table-layout: fixed" rows="4" cols="4">
      <col width="10%" />
      <col width="20%" />
      <col width="30%" />
      <col width="40%" />
      <tr><td width="10%">a</td><td width="20%">b</td><td width="30%">c</td><td width="40%">d</td></tr>
      <!-- flush output, one second pause... -->
      <tr><td width="10%">a</td><td width="20%">b</td><td width="30%">c</td><td width="40%">d</td></tr>
      <!-- flush output, one second pause... -->
      <tr><td width="10%">a</td><td width="20%">b</td><td width="30%">c</td><td width="40%">d</td></tr>
      <!-- flush output, one second pause... -->
      <tr><td width="10%">a</td><td width="20%">b</td><td width="30%">c</td><td width="40%">d</td></tr>
      <!-- flush output, one second pause... -->
    </table>
  </body>
</html>

Instead the page is blank until the end of the download, when the whole table appears. I've tried various ways to tell the browser the table dimensions in advance so it should have no problem displaying it as it arrives, but they don't help. (Removing the hints doesn't help either.)

If I modify my CGI script to close and restart the table between each row, with an extra blank paragraph in between, then the page does render incrementally in the browser. This shows that the data is getting to the browser incrementally - just Firefox is choosing not to render it.

Ironically, much more complex scripts producing larger tables seem to do what I want, showing one row at a time as it downloads, but whenever I try to reduce the output to a minimal test case it doesn't work. This leads me to suspect there is some complexity heuristic used by Firefox's rendering engine.

What's the magic dust I need to tell the browser to always display the table as downloaded so far?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Ed Avis
  • 1,350
  • 17
  • 36

3 Answers3

1

For what it is worth. The Firefox I use Firefox 3.6.16 does not display until the page is downloaded, regardless of what is being downloaded.

You could look for settings in about:config, but I have not seen any solution to this, there are addins to help with displaying placeholders. but they don't always work either.

Just found this

Read it OR try

about:config   - in browse bar
select new
create integer
nglayout.initialpaint.delay
set value to 0

cheers

lmcanavals
  • 2,339
  • 1
  • 24
  • 35
basic info
  • 11
  • 2
  • Thanks, but initial paint delay of 250 milliseconds does not account for it in this case. As I mentioned, Firefox does incremental display really well for some tables and refuses to do it for others - the question is what makes it decide? – Ed Avis May 05 '11 at 10:29
0

First of all, I'd say it's seldom good user interface design to load huge amounts of data at once. In most cases, it's better to offer some sort of search or at least paging functionality. There may be exceptions, but people simply cannot process very large quantities of information, and apps serving far more data than people have any use for aren't just wasting cycles, they are badly designed. Imagine if Google displayed the first 10,000 hits by default, or even 1,000. Most users wouldn't even look beyond the first 5 or so, and the amount of wasted bandwidth...

That said, it may of course not be your fault if the page is badly designed. Or it may be, but you'll need a quick fix before coming back to redesign the solution later. :)

One way to make this happen would be to render the table client-side instead of on the server. If there's nothing else heavy on the page, the user would be served quickly with the other content, and the area where the table will appear could contain an animated GIF or similar to indicate the software is "working". You could use an AJAX-call to fetch the data for the table, and modify the DOM in Javascript. You could then create for instance 100 rows at a time and use window.setTimeout to allow the browser to render the updated DOM before continuing.

A good article explaining the event dispatch model may be of help if you choose to go down this path:

http://dev.opera.com/articles/view/timing-and-synchronization-in-javascript/

The Dag
  • 1,811
  • 16
  • 22
  • 1
    Thanks for your reply. I take the point about serving small amounts of data at a time. In this case, the table typically has about 20 rows, so only a screenful. But it is slow to calculate and the user should not have to wait for the whole thing before seeing the first row. – Ed Avis Mar 01 '11 at 13:20
  • Client-side rendering would be possible - there could be some Javascript which fetches the results from the server and updates the table. But then I would need two versions of the page, because I also wish to generate a pure HTML version to save as a report. (Sometimes HTML pages are sent as email attachments to read on the plane, etc.) Also, it seems a little silly to have the client-side Javascript do an imitation of a web browser, downloading bits of text and adding them to a table, when the browser already has that functionality. – Ed Avis Mar 01 '11 at 13:21
  • The frustrating thing is that this does often work. I have often seen the browser download a large HTML table (containing only plain text) and render it row-by-row as it is downloaded. It just doesn't want to do so in this case, and I can't work out why. – Ed Avis Mar 01 '11 at 13:22
0

OK, so how about dropping client-side rendering but fetching and replacing server-side rendered HTML within a placeholder (and thus the table) multiple times? The server-side would have to use a background thread and supply a handle (e.g. a GUID) in it's initial response that an AJAX call could then use to ask for the table. The server could reply with a few rows plus an indication that it's not done, prompting the client to repeat this until finished.

I suppose it would be a little messy, but at least it would allow you to use the same page for your report. A query string parameter could tell the page whether to render completely or emit script to call back to get the data.

The Dag
  • 1,811
  • 16
  • 22