Event wanted after page is refreshed

D

David Mark

Jorge said:
A reflow is not a redraw. There's (usually) many (more) reflows per
redraw. Reflows happen during normal JS execution,

For seemingly the millionth time, re-flows happen on exiting execution
contexts (in virtually every known graphical browser).

but redraws
(exception: Opera) don't.

You are out of your tiny little mind. :)
 
J

Jorge

(...)
For seemingly the millionth time, re-flows happen on exiting execution
contexts (in virtually every known graphical browser).

No. Reflows happen as needed. E.g. simply reading an .offsetWidth can
trigger a reflow.
 
J

Jorge

No. Reflows happen as needed. E.g. simply reading an .offsetWidth can
trigger a reflow.

And 5 lines later, in the very same piece of code, reading it again
might trigger yet another reflow.
 
D

David Mark

Jorge said:
No. Reflows happen as needed. E.g. simply reading an .offsetWidth can
trigger a reflow.

I don't any of these are standard terms. I've always used reflow (or
re-render) to refer to all of the expensive behind-the-scenes crap that
goes into updating the rendering (and can lead to unwanted peek-a-boo
behavior and/or performance drags).

So no, just getting the offsetWidth will not update the rendering.
Obviously it will _recalculate_ the offset width of that element, which
may entail considering queued rendering changes.

Exiting an execution context after mutating the DOM will update the
rendering (in some cases, it depends on numerous factors). But the
rendering is never updated during an execution context (even in Opera).
That's all you really need to know. I see people are no writing tools
to try to observe and analyze all of this stuff. I imagine they'll be
just as insightful as the leak detectors were.
 
D

David Mark

Jorge said:
And 5 lines later, in the very same piece of code, reading it again
might trigger yet another reflow.

Another _recalculation_ of the offsetWidth, but only if something
changed in between. So what?
 
J

Jorge

Another _recalculation_ of the offsetWidth, but only if something
changed in between.  So what?

You ought to watch this, from beginning to end:
"Faster HTML and CSS: Layout Engine Internals for Web Developers"
 
D

David Mark

Jorge said:
You ought to watch this, from beginning to end:
"Faster HTML and CSS: Layout Engine Internals for Web Developers"

Don't be an idiot. Somebody generalizing about how to write efficient
"Web 2.0" apps (or whatever?) Why would that interest me roughly
fourteen years later? This stuff is not new, Jorge. People can make up
new names for it, but it's still the same old shit and most of it is
common sense.
 
S

Stefan Mueller

Stefan,

All you need to do is to wrap the whole thing in a setTimeout
(sortingCode ,0); That will warrant a redraw *before* it executes.
Like this:

elem.onclick= function onclick () {
  elem.onclick= null; //trash useless double-clicks
  setTimeout(function () {

    //Put your sorting code here.

    elem.onclick= onclick;
  }, 0);};

Jorge,

I tried to implement setTimeout but I'm not sure if I did it correct
(the way you advised me to do):
var_this_global = this;
var_todo_global = "function_sort(var_this_global);";
setTimeout(var_todo_global, 1200);

It only works if I set the value in setTimeout to at least 1200. It
works if you click a second time on a column header while the sorting
is running. But it doesn't work if you click a third time.
Because I have to set the value to at least 1200 it always takes 1.2
seconds until the sorting starts.

Stefan
 
D

David Mark

Stefan said:
Jorge,

I tried to implement setTimeout but I'm not sure if I did it correct
(the way you advised me to do):

That's assuming Jorge advised you correctly (usually a stretch). As I
mentioned, you don't really have a problem. If your process takes too
long (and it definitely does), you need to break it up. Then the clicks
(or whatever user actions) will not be "cached" while the engine is
waiting for your sort to finish. Solve the real problem and the
imagined one will go away. ;)
var_this_global = this;
var_todo_global = "function_sort(var_this_global);";
setTimeout(var_todo_global, 1200);

It only works if I set the value in setTimeout to at least 1200. It
works if you click a second time on a column header while the sorting
is running. But it doesn't work if you click a third time.
Because I have to set the value to at least 1200 it always takes 1.2
seconds until the sorting starts.

You are wasting your time. Do what I told you to do. You can't go
wrong that way.
 
J

Jorge

Jorge,

I tried to implement setTimeout but I'm not sure if I did it correct
(the way you advised me to do):
  var_this_global = this;
  var_todo_global = "function_sort(var_this_global);";
  setTimeout(var_todo_global, 1200);

It only works if I set the value in setTimeout to at least 1200. It
works if you click a second time on a column header while the sorting
is running. But it doesn't work if you click a third time.
Because I have to set the value to at least 1200 it always takes 1.2
seconds until the sorting starts.

Ok. check this one:
http://jorgechamorro.com/cljs/092/

Does it work for you ?
 
J

Jorge

I have some doubt here. The author writes under "Minimizing
repaints and reflows", referring to DOM modifications through
JavaScript:

"• Don't change individual styles, one by one. …"

But that looks like nonsense, as the browser will surely not
reflow the document while the JavaScript code is still running,
at least not while the same JavaScript function is still
running.

In fact, wouldn't it be wise for the browser to wait until all
JavaScript processing has finished and the processor has nothing
better to do?

reflow !== redraw (!)

Say you've got:

element.style.color= "red";
var height= element.offsetHeight; //won't reflow (except in IE :))

But:
element.style.fontSize= (a different value);
var height= element.offsetHeight; //requires a reflow
 
J

Jorge

For repaint, sure, but not for reflow.

Opera does -under certain circumstances- *redraw* in a separate
thread, in parallel with JS execution. That's wiser imo, but a
window.redraw() DOM method would be even wiser yet :)
 
G

Garrett Smith

kangax said:
Browsers differ, but there's usually a _reflow_ and there's a _repaint_.
Reflow is when render tree is recalculated; repaint — when screen is
updated.


Querying `offsetWidth` does trigger _reflow_. Obviously, all queued
changes need to be applied before returning value.


Tools are actually quite useful. Do you know that IE reflows when
changing, say, color (!) style of an element (whereas Chrome, for
example, doesn't). Do you know that IE reflows even when changing style
of "display:none" element?

You might also be interested in:

<http://www.phpied.com/rendering-repaint-reflowrelayout-restyle/>

The author of that article makes several claims, but does not state the
basis for any of them.

What the author considers to be triggering reflow applies to recent
popular browsers. Some of it is incorrect for Safari 2, slightly older
versions of Gecko (1.8), and Blackberry9000.

The author says reflow happens "when you request style information such
as" and the list that follows includes `currentStyle`.

I do not know how the author arrived at that conclusion. I cannot see
why it is necessary for IE to recalc when currentStyle is accessed.

MSDN on cascaded style state:-
| Represents the cascaded format and style of the object as specified by
| global style sheets, inline styles, and HTML attributes.

But then he doesn't bother explaining that before moving onto a
solution: createDocumentFragment. The author states that appending to
content within a documentFragment won't cause a reflow. Sounds pretty
obvious, but the focus on documentFragment is misleading; there's
nothing magic about documentFragment.

The key fact that the author misses is that the documentFragment is not
in the DOM. The key *principle* to avoid (and this is nothing new,
folks), is to perform all the node creation/appending before adding to
the DOM.

| Will the browser reflow when you update stylesheet collections
| programatically? Here's the test case using addRule and removeRule
| (which in Firefox are insertRule/deleteRule):

That's misleading. addRule is a method of an IE stylesheet; part of IE
DOM. insertRule is the standard method, not the Firefox method.

That blog entry seems to have some missing semicolons.


The dynaTrace blog that he links to states:-
In "Rendering triggered by Property Read Access", the author does not
define clearly what he means by "read access". Instead he uses jQuery
height() method.
http://blog.dynatrace.com/2009/12/12/understanding-internet-explorer-rendering-behaviour/

The graphic depicted on that blog seems to indicate that dynaTrace found
a repaint after `isXMLDoc`, which is called by attr.

Is there something valuable or informative anywhere there?
Good link.
 
J

Jorge

Sure, but the question is, when is the reflow required and when
does it actually happen?

Reflows happen as needed: either because your code is asking for data
that requires (and triggers) it, or because it's time for a reDRAW.
The sensible thing to do for the browser is nothing, while the
running JavaScript code may be adding more DOM changes, then do
one reflow in the end.

....unless your code asks for some data that triggers it.

Even if reflows are known to be expensive operations, simply asking
for an .offsetXXX seems to be very expensive too, even when it should
*not* trigger a reflow. At least that's what it looks like in this
test:

http://jorgechamorro.com/cljs/094/

The relative speeds I see (in a Mac) are:

Reflow needed read .offsetXXX speed S O C FF
Don't care NO 100% 100% 100% 100%
NO YES 10% 25% 32% 42%
YES YES 1.4% 2.8% 3.9% 9.5%
 
S

Stefan Mueller

By the way, how do you sort? Do you use JavaScript's array sort
function? If not, you probably should, for higher speed.

Hans-Georg

I'm not using the JavaScript's array sort function because I want to
add additional features (empty rows should always be at the end /
already sorted columns should not get mixed up while another column
gets sorted / ...).
Anyway, thanks for the hint.

Stefan
 
G

Garrett Smith

kangax said:
What is it exactly that doesn't trigger reflow in Safari 2, older Gecko
and Blackberry? And how do you know that it doesn't?

Reading width property failed me before.

There was an element in the page directly followed by a script that was
trying to read offsetWidth and it was getting the wrong value.
I see his arrival to such conclusion right after list itself:

"All of these above are essentially requesting style information about a
node, and any time you do it, the browser has to give you the most
up-to-date value. In order to do so, it needs to apply all scheduled
changes, flush the queue, bite the bullet and do the reflow."

currentStyle is a cascaded style. What queue needs to be flushed?

MSDN on *currentStyle*:-
You're nitpicking :) He didn't say that `insertRule` is Firefox's
method. He said that in Firefox there's `insertRule`. I could also say
that there's `insertRule` in Safari, and that wouldn't be wrong. It
would be just incomplete and somewhat unprofessional.

There isn't any good reason for preferring the non-standard addRule
method over the standard one. The quirks that come with IE dhtml methods
are not always copied the same in other browsers.

With standard method, there is a specification that is clearer then MSDN
and doesn't have all the associated quirks copied over.
I also noticed that some tests are in quirks mode
(<http://www.phpied.com/files/reflow/restyle.html>), which is not a good
idea.
Right, not a good idea.
I was annoyed by that too. Was it `offsetHeight`?
The tool vendor seems to be referring to jQuery `height` method.

#upper:
`isXMLDoc` is called, then "Rendering (Scheduling layout task #47)".

#lower:
`css` is called, then "Rendering (Scheduling layout task #47)"

| Why does this happen, especially as the property change on the upper
| div element has no effect on the lower div element? When the height
| property of the lower div element is accessed Internet Explorer
| realizes that there is a scheduled layouting task.

Accessing the `height` property of the `jQuery.prototype.init` object
should not require layout update.

The paragraph continues:-

| As this task might – and most likely will – change layout properties
| of other elements it is performed before layouting-related information
| is returned by the DOM call.

Calling the `height` property of the `jQuery.prototype.init` object
should not require layout update.

I should clarify that. The constructor for a jQuery object is the init
function, which is in the prototype property of the jQuery function. The
jQuery constructor is in the prototype, as jQuery.prototype.init.

Any object created by jQuery is an instance of jQuery.prototype.init.
For example, using jQuery:

$() instanceof jQuery.prototype.init;

true

Kind of an odd design, but that is beside the point.

The calling a jQuery.init's `height` property is a not DOM update. There
is no reason that it should require layout update.

When the tool vendor called `height`, the tool displayed rendering
scheduling notification in two cases:

#upper:
`isXMLDoc` is called, then "Rendering (Scheduling layout task #47)".

#lower:
`css` is called, then "Rendering (Scheduling layout task #47)"

Did I miss learning something?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top