Closed Bug 373990 Opened 17 years ago Closed 13 years ago

New feature suggestion: window.redraw() or similar from javascript

Categories

(Core :: DOM: Core & HTML, enhancement)

x86
Windows XP
enhancement
Not set
normal

Tracking

()

RESOLVED FIXED

People

(Reporter: duncan.loveday, Unassigned)

Details

Attachments

(3 files, 2 obsolete files)

User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1

This is not a bug, it is a suggestion for a new feature. Sorry if this isn't the place for that.

I'm looking for a way to have Firefox periodically update its display whilst javascript is running....not something it does now, currently it (very sensibly) updates the display when the script completes.

I've a long-running script and want to give the user and indication of progress.

With IE I can open a popup window and update it every so often, for example

function test()
{
var w=window.open("", "dd", "width=600,height=100,left=200,top=300,status=no");
for (var n=0;n<1000001;n++)
{
if (n%100000==0)
{
w.document.open();
w.document.writeln("percent complete=" + n/10000);
w.document.close();
}
}
}

and the results are shown immediately so that you see the value count up to 100%

But with firefox nothing is updated until the end so I get a long pause and then a display showing 100%.

I'm not suggesting turning Firefox into IE, perish the thought, but it would be really nice to be able to say something like "window.redraw()" or "document.flush()" or something to get Firefox to update the display of a given window at a defined point.

Totally non-standard of course...

My only solution so far is to get my javascript to yield whenever it wants to update the display but this is very involved - using generator/iterators via Neil Mix's threads library - and when the code yields all the open windows are updated whereas I only need the progress bar to move. It also means I have to use javascript 1.7 which creates compatability headaches with other browsers.

Reproducible: Always

Steps to Reproduce:
1. N/A - new feature suggestion
2.
3.
Actual Results:  
Firefox doesn't support any means of updating the contents of a window whilst javascript is running other than javascript 1.7 yields which are very involved in my case.

Expected Results:  
It would be "nice" to have a method like "window.redraw()" or "window.refresh()" or "document.flush()" or something to force a chosen window to be updated.
Component: DOM: HTML → DOM: Level 0
Have tried using something more sensible like innerHTML or textContent properties to update the display? That should work.
*Have you

btw, thought I'd let you know. The screen is redrawn any time an element's properties or content is changed, in this case you're not even dealing with DOM elements.
(In reply to comment #1)
> Have tried using something more sensible like innerHTML or textContent
> properties to update the display? That should work.
> 
Try the attached example using innerHTML - the display is only updated at the end.
(In reply to comment #2)
> *Have you
> 
> btw, thought I'd let you know. The screen is redrawn any time an element's
> properties or content is changed, in this case you're not even dealing with DOM
> elements.
> 
I don't believe that is the case but I would love to be wrong. Please post an example where you update the DOM and have the screen updated immediately.

What I'm trying to achieve is a "progress bar" that shows the progress of a long-running javascript function.
Attachment #333910 - Attachment description: Example using innerHTML → Example using innerHTML - doesn't work in IE or Firefox or Opera
Attachment #333911 - Attachment description: Example using document.write - works in IE, Opera → Example using document.write - works in IE, not Opera or Firefox
Attachment #333910 - Attachment description: Example using innerHTML - doesn't work in IE or Firefox or Opera → Example using innerHTML - works in Opera but not IE or Firefox
Hmm. The screen *is* updated everytime an element or attribute is changed (a change that has a visual impact, obviously), that's not in question. What happens in your case is that the changed attributes are only passed to the elements after the loop ends.

I read a bit more about your subject, it seems that it was made this way for performance reasons. All results are evaluated only after the complete loop.

You can use the setTimeout or setInterval functions to achieve this, and that's actually better as it gives you some control over the timing and rate of the function. And you'll need a recursive function instead of a loop.

Here's an introduction to animation with setInterval: http://www.hesido.com/web.php?page=javascriptanimation
Yes, using setInterval (together with a variant of Neil Mix's threading library at http://www.neilmix.com/2007/02/07/threading-in-javascript-17/ using generator/iterators) is how I'm getting around this. But it is hellishly complicated because in order to achieve a progress bar that moves in jumps of say 10% I have to divide up the work my javascript function will perform into 10 equal parts. Each part will do 10% of the work, update the progress bar and schedule the next part using setTimeout. The complexity arises from having to save the javascript state - i.e. the enable part 2 to pick up from where part 1 left off. Bear in mind the javascript has deep call stacks. Using generators helps because it takes care of saving all the state and Neil's library takes care of the scheduling but it means every function in the call stack has to explicitly yield in order to allow the progress bar to move along.

It's not an animation as such or at least it is a special kind of animation, being designed specifically to show the progress of a javascript function.

Some of my javascript functions can take 30 seconds or more to run but believe it or not the user experience is quite satisfactory as long as they have a visual indication of progress. Take that away and even half a second is annoying.

Arguably I shouldn't have long running javascript functions like this but it works well for me. I generate content dynamically from data cached in the browser. More people might start doing this in AJAX type applications.
glad you found a solution. 

Something worthy of note is that Firefox halts any script that takes longer than 5 seconds to complete and asks for user input, so that would be happening at least 6 times through that function of yours.

I think the issue here is you're using JS for something out of it's scope. Javascript is meant for interaction scripting, not for processing or generating large sets of data - interpreted languages are slow. Even having no idea what you're doing I can guarantee you that saving the data and having it processed server-side would be way faster, and you could still fetch it through an AJAX request.

PHP can print an array of 2000 elements in 2 or 3 seconds, Javascript takes at least 40 seconds to create the same + plus the time from the browser halts.
My function doesn't stop actually because of the use of setTimeout to schedule the work in small chunks but point taken - it is a rather unconventional design. I'm not sure I accept that server side processing would be faster - this is an intranet app and it so happens that our desktop PCs are reasonably up to date whilst our servers are old and creaky. My laptop PC, for example, outperforms one of our live servers by a factor of 4 in a straight CPU-bound test.

Admittedly Javascript performance can be rather unpredictable and browser dependent but at it's best can be very good indeed and I certainly don't observe a few thousand elements taking 40 seconds. I generate HTML tables with up to 10K rows in a few seconds.
Assignee: general → nobody
QA Contact: ian → general
I believe this can now be accomplished using worker threads. Attaching an example - has to be in two parts, one .js and one .html
Those separate attachments don't work together so trying a jar file containing both files.
Attachment #500267 - Attachment is obsolete: true
Attachment #500268 - Attachment is obsolete: true
...still no luck, should work using jar:https://bug373990.bugzilla.mozilla.org/attachment.cgi?id=500272!/test.html but doesn't have to save the files locally and run using file:/// url.

Anyway, resolving as FIXED.
Status: UNCONFIRMED → RESOLVED
Closed: 13 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: