Sencha Touch--Support 2 browsers in just 228K!

G

Garrett Smith

What he talks about is also partially present in these documents (by
same author):

<https://developer.mozilla.org/en/Notes_on_HTML_Reflow>

That document discusses reflow (in Gecko).

That document discusses painting (in Gecko) and states the event that
triggers it as being content received. It does not state which mechanism
is responsible for triggering repainting.

Nicole Sullivan's blog? I'll normall pass on that one. It seems you've
got a disagreement with the fact that there's no way to force the
browser to repaint, but you won't actually say that and just post up links.

So lets see what the OO-CSS expert has to say.

| A repaint occurs when changes are made to an elements skin that
} changes visibility, but do not affect its layout

The repaint may occur after a request for a style change has been made,
but that won't happen every time.

Try writing a loop-based animation and if you can get it to update, then
you've gotten a repaint to occur.

var i;
for(i = 0; i < 1000; i++) {
moveDiv();
}

function moveDiv(){
document.getElementById("a").style.left = i + "px";
repaint();
}

function repaint() {
// your code here.
}

Also do realize that when you flesh out the repaint, even if you can get
it to work (it won't happen, but try if you like), then the fact that it
works could not be used as argument that a repaint can be forced; it
would only show that you did something and then a repaint occurred.
<quote>

[...]

element.style.width = ‘50px’;
var v = element.offsetWidth;
element.style.width = ‘55px’;
v = element.offsetWidth;

You just caused two reflows to happen, since asking for offsetWidth
forced the element to reflow in order to answer you question (because it
had a pending change to style).

Does not state that reading `offsetWidth` will trigger a repaint?

No, it doesn't. That's a good thing for Mr Hyatt because that would be a
false statement.

What it says is -- well it says exactly what it says, which is short and
simple, so I won't try and paraphrase.

And so reading offsetWidth to trigger a repaint would be a demonstration
of a misconception that the consequences of doing that would cause a
repaint (it won't).
This is the real performance bottleneck to be wary of. Browsers are
smart about avoiding reflows when they can, but if you create code that
forces a reflow in order to answer a question, then you can create
severe performance bottlenecks.
Informative, but not any evidence that a repaint can be triggered.
 
G

Garrett Smith

On 2010-07-18 02:42 PM, David Mark wrote:
ext-touch-debug.js..............458k

[...]

Where does this "native-first dual approach" term come from? I know
what you mean, but I've never heard it called that.

I have named the query antipattern Native First Dual Approach, or "NFD
approach".

The NFD approach is to try to use `document.querySelectorAll`, where
supported and where it is either unsupported or where it throws an
error, a fallback selector matching engine is used.

Libraries that use NFD include jQuery, YUI, and Ext-js, among others.

Native-first Dual Approach Diagram

(query input)
|
<Native QSA Support?>
Y N
| |
| |
[Try Use QSA] +-- [Use Fallback]
| / |
<error thrown?> / <Fallback Supports Input?>
Y N-+ Y N
| /| | [Throw error]
| / | | |
[Use Fallback*] | [perform match |
| and return result] |
| | |
[return result] | |
| | |
END END END

Diagram of native-first dual approach. Notice the three different
possible endings.

Most queries with attribute or pseudoclass selectors will have a
different path depending on the browser, version, and rendering mode.

Libraries that use NFD include jQuery, YUI, and Ext-js, among others.
Dojo does the opposite. Dojo uses the fallback first and then, if that
works, tries to use querySelectorAll. This might seem odd, but when the
problems with NFD query engine is understood, it is much safer. Another
approach is to filter all input by defining an `isValidQuery` type of
function to make sure that it is valid.


CSS Selectors are recursively defined:

| selector
| : simple_selector [ combinator selector | S+ [ combinator? selector
| ]? ]?

As such, it is not possible to parse one with a javascript RegExp
because javascript RegExps are not recursive. The input must be parsed.

Normative Reference:
CSS2.1 said:
Each bug in Ext-JS's selector engine necessarily propagates to a higher
level. When the selector engine's behavior is changed, that change is
propagated to all of the higher level dependencies. Such behavioral
changes cause instability. The alternative to causing such changes is to
not fix the bugs.

I haven't bothered tracking down all of their problems as nobody has
offered me any money to do so. :)

[...]
If it had simply handed queries off to `querySelectorAll`, it would not
have created as many problems.

Yes, I forgot about their inexplicable preprocessing.

It's like car with shoes for wheels. I could never forget that.
Clearly tacked on my author(s) who had no idea what they were doing (a
common theme with these things). Who knows what they were thinking as
there are no explanatory comments.

There are from me. I explain exactly what the code does. I did not have
to test it before making the analysis to know exactly how the code would
perform and where it would fail.

I was able to find the defects very quickly.
For such a Frankenstein-like effort it probably is. Much of it sounds
like it is describing ExtJS.

Actually the current Ext-JS version does not support XPath. The code
comment appears to be a hold-over from past jQuery copying efforts which
had, in older versions of Ext, supported XPath.

Regardless, to code comment is wrong. The code does not do what it says
it does.

It is a singleton in the sense that there is only one of them.

The various "privete" code comments are false claims.

[...]
There's very little CSS3 in Sencha, despite the disingenuous ad
campaign. Not much HTML5 either. Who knew marketers lied? :)

The source code explains what it does. Those who are unable or unwilling
to analyze the source code won't know. Fortunately that does not include
me.

The thread isn't as negative as some might see it. I showed that I can
provide good code reviews that anyone at any level of experience -- the
authors included -- should be able to appreciate. The review on the
query engine provided a good model for making code review. I would like
to encourage such reviews more.

In addition to writing code, I provide assessments of code (in-house
reviews) and mentor other developers. If the code is not awful -- and
unfortunately most front end code is -- I can show how the code can be
made to run twice as fast, on more devices, at less than half the size.

The documentation does not reflect reality.
If at all. The first question on the mind of Web developers seems to
be about popularity. They seem to think that popularity implies
continuous improvement and easy support, despite overwhelming evidence
to the contrary (see jQuery).

Appeal to popularity.
Yes. What is surprising is that anyone would listen to "experts" who
advocate scripts based on pretty graphics and snazzy demos.

What else can they listen to? You think they want to come on usenet and
read code reviews? And if they do, do you think they can understand your
code reviews? Try and read the code review you wrote from the point of
view of someone who is ignorant.

My code review outline:
<http://groups.google.com/group/comp.lang.javascript/msg/316e025b15e466a3?dmode=source>

and follow-up:
<http://groups.google.com/group/comp.lang.javascript/msg/c8f81b8b3486e3e8?dmode=source>

Should those be linked from the the Code Guidelines doc and Code Review
Guidelines docs?
The Ext people think they are qualified, though that misconception has
likely been shaken at this point (unless they are locked up in sound-
proof booths with blinders on).

What the Ext people think of themselves does not matter.

"Is the salesman trying to make the product look good? Is there anything
that he might not have told me, out of ignorance or otherwise?"
This would not have been much investment and could have helped avoid
such an amazing waste of money[1].

Yes. It's a shame to see people throwing good money after bad.

They seem misguided.
Hell, I did it for free. Well, not really. I just touched on the
highlights here. I charged for the full analysis. Some people

So they paid you? You wrote above that nobody offered you any money to
do so.
realize that spending a little money to avoid wasting a lot makes good
business sense. It didn't take me a week and I didn't charge anywhere
near $5,000. But I could definitely write a similar (and much better)
framework in that neighborhood (and did so for one client about a year
back).

The investors may not have known that such an analysis was even
possible. Can the source code be analyzed by an independent third party?
Who knows?

Returning to the car-purchasing example, a buyer might want to take the
car he so likes (nice radio, comfy seats, looks cool, etc), down to his
own mechanic for an analysis.

Someone in the predicament of making assessments of the framework, but
not having the skill to do so does not need a "mobile applications
development framework shop"! What he needs is one or a few individuals
who are qualified of making an assessment.

Basically, what the investors needed was an expert analysis prior.

The uninformed cannot know the least amount of time it will take to make
such assessment. A very complicated framework that had good code and a
sophisticated build process might take considerable time to and effort
investigate and drawing metrics for it is going to be very involved and
complicated.

It turned out that such rigorous investigations would not have been
necessary in this case because the code is so bad that it can be
dismissed. Continued analysis beyond that point is pointless.

What is the point in finding out how they've packaged and organized
they're bugs? By accident, the `hasRightMarginBug` identifier was found
to be absent and with the many false comments about properties being
"private" (they aren't).
Oh, I bet somebody from Sencha is taking notes. The question is
whether they have anyone on the payroll who can interpret them in a
timely fashion.

I don't much care for giving free help to the Ext-JS guys. About 8
months ago, a colleage of mine informed me that they were in need of a
JS developer. I re-familiarized myself with their code and found room
for major improvement.

And so I gave my colleage the "OK" to pass on my contact info. So,
rather helping them, I get to do remote project postmortem, pro bono.

[...]
Happens all the time.


And the choice to use Sencha Touch is exponentially worse, which could
only be described as insane.

No, it could be described as misguided or not fully informed, or
informed, but not understanding the ramifications.

Do not consider "misguided" to be an insult; it is a position that most
of us are in, in more ways than we realize.
 
D

David Mark

On 2010-07-18 02:42 PM, David Mark wrote:
[...]
ext-touch-debug.js..............458k
[...]

Where does this "native-first dual approach" term come from?  I know
what you mean, but I've never heard it called that.

I have named the query antipattern Native First Dual Approach, or "NFD
approach".

But who knows that? Using this abbreviation without explaining
exactly what it means will likely lead to confusion.
The NFD approach is to try to use `document.querySelectorAll`, where
supported and where it is either unsupported or where it throws an
error, a fallback selector matching engine is used.
Yes.


Libraries that use NFD include jQuery, YUI, and Ext-js, among others.

Native-first Dual Approach Diagram

    (query input)
         |
<Native QSA Support?>
  Y              N
  |              |
  |              |
[Try Use QSA]   +-- [Use Fallback]
   |                /     |
  <error thrown?>  / <Fallback Supports Input?>
   Y           N-+        Y          N
   |            /|        |     [Throw error]
   |           / |        |             |
[Use Fallback*] |   [perform match      |
                 |    and return result] |
                 |          |           |
            [return result] |            |
                   |        |           |
                  END       END         END

Diagram of native-first dual approach. Notice the three different
possible endings.

Most queries with attribute or pseudoclass selectors will have a
different path depending on the browser, version, and rendering mode.

Yes. It's a completely insane design for a browser script. And the
sad thing is that most jQuery scripts (including jQuery itself) rely
on queries for everything.
Libraries that use NFD include jQuery, YUI, and Ext-js, among others.
Yes.

Dojo does the opposite. Dojo uses the fallback first and then, if that
works, tries to use querySelectorAll.
Whatever.

This might seem odd, but when the
problems with NFD query engine is understood, it is much safer.

I don't see how. Their fallback is complete BS. So what will it do
when QSA contradicts it?
Another
approach is to filter all input by defining an `isValidQuery` type of
function to make sure that it is valid.

Yes, that is the only 100% solution. Of course, most of the offending
libraries needn't bother as they support very few browsers that lack
QSA and will likely stop "supporting" the ones that don't (e.g. IE <
8) very soon. In the query department, they'll be reduced to wrappers
for QSA and will then have more time to find other things to screw up.
CSS Selectors are recursively defined:

| selector
|  : simple_selector [ combinator selector | S+ [ combinator? selector
| ]? ]?

As such, it is not possible to parse one with a javascript RegExp
because javascript RegExps are not recursive. The input must be parsed.

No question. That's what I did.
Normative Reference:
CSS2.1 <http://www.w3.org/TR/CSS2/grammar.html#grammar>


I haven't bothered tracking down all of their problems as nobody has
offered me any money to do so.  :)
[...]


Regardless, I'm sure that ExtJS fails to account for this (among many
other things).  Just like jQuery!  :)
But that is about Ext-JS (big version), not Sencha. In Sencha, all of
this stuff throws errors.
Of course as it has no query engine; it simply hands off all queries
to QSA.
If it had simply handed queries off to `querySelectorAll`, it would not
have created as many problems.
Yes, I forgot about their inexplicable preprocessing.

It's like car with shoes for wheels. I could never forget that.

I try not to retain every little screw-up I see in JS libraries.
Thankfully I don't need to (unlike those who insist on relying on such
things).
There are from me. I explain exactly what the code does.

I know what the code does. I don't know what sort of thinking went
into the authors' decision-making. There's no convenient explanation
for such lunacy.
I did not have
to test it before making the analysis to know exactly how the code would
perform and where it would fail.

Yes, seeing that code the first time was a spit-take moment for me as
well.
I was able to find the defects very quickly.

Yes. It's amazing that virtually every line of code in the thing is
defective. Like shooting fish in a barrel. Of course, the
uninitiated can't fathom this, so I often hear the knee-jerk "wow you
must have spent a lot of time on that" reaction. The reality is the
authors' didn't spend near enough time. The fact that all of the
"majors" are similarly defective leads to "aw, you just don't like
frameworks" retorts. If you don't know any better, reviews are easy
to misinterpret.
Actually the current Ext-JS version does not support XPath.

I thought I saw it in there. Whatever.
The code
comment appears to be a hold-over from past jQuery copying efforts which
had, in older versions of Ext, supported XPath.

Regardless, to code comment is wrong. The code does not do what it says
it does.
Clearly.


It is a singleton in the sense that there is only one of them.

But that carries no weight in JS as there are only one of any object.
There are no classes of objects, so there is no such differentiation
to be made.
The various "privete" code comments are false claims.

Yes. And they confuse the hell out of people.
[...]


There's very little CSS3 in Sencha, despite the disingenuous ad
campaign.  Not much HTML5 either.  Who knew marketers lied?  :)

The source code explains what it does. Those who are unable or unwilling
to analyze the source code won't know. Fortunately that does not include
me.

Unfortunately, those who would use something like this are unlikely to
bother. Anyone who knows anything about this stuff would throw it
away after reading the first line.
The thread isn't as negative as some might see it.

It's really hard to be positive about something so negative. That's
another thing that the masses seem to misunderstand. These things
really are incompetently done. There's no dancing around that fact.
It's like they'd prefer to be lied to than to hear that truth.
I showed that I can
provide good code reviews that anyone at any level of experience -- the
authors included -- should be able to appreciate.

I thought this was my review. Granted you chipped in a few bits. If
they have any sense at all, the authors are taking notes. Of course,
you can't really learn browser scripting from reading a review. There
wasn't time to turn every point into a tutorial.
The review on the
query engine provided a good model for making code review. I would like
to encourage such reviews more.

Then encourage them more. :)
In addition to writing code, I provide assessments of code (in-house
reviews) and mentor other developers.

Yes, I do as well. For those who want to learn (and actually save
time rather than perpetually flushing it down the toilet). Most
don't, apparently seeing Web development as some sort of puzzle that
they need to solve on their own.
If the code is not awful -- and
unfortunately most front end code is -- I can show how the code can be
made to run twice as fast, on more devices, at less than half the size.

I often find there's room for more dramatic improvement than that. I
can remember a Dojo grid that took *minutes* to sort and I got that
down to less than ten seconds. How? By eliminating unnecessary
reflows/repaints. How did I do that? By eliminating function calls
in between updating the cells. Of course, there was no guarantee that
those reflows/repaints would occur on each call, but they clearly did
often enough to decrease performance by roughly a factor of 10. I've
made similar improvements in similar fashion to hundreds of
functions. The rules don't seem to change, nor do the percentage of
people who understand them (which is very small).
The documentation does not reflect reality.

Neither does the code. If only they did not reflect reality in the
same way. :)
Appeal to popularity.

Yes. I find such appeals revolting. Programming is a science after
all. And these scripts are 100% transparent. It's not like being
stuck with a buggy OS (as some pseudo-intellectual observers like to
compare them to).
What else can they listen to? You think they want to come on usenet and
read code reviews?

Some do, if only for the entertainment value. A few may actually
learn something. The rest don't understand the words, so focus on the
pervasive negativity, which makes them feel compassion for the bums
that are trying to fleece them into using bogus scripts, buying
worthless books, etc.
And if they do, do you think they can understand your
code reviews?

There's nothing particularly subterranean about my reviews
(particularly not this one).

Try and read the code review you wrote from the point of
view of someone who is ignorant.

Well, if they don't know JS at all (which is a good bet as the authors
of these scripts sure don't).
My code review outline:
<http://groups.google.com/group/comp.lang.javascript/msg/316e025b15e46...>

and follow-up:
<http://groups.google.com/group/comp.lang.javascript/msg/c8f81b8b3486e...>

Should those be linked from the the Code Guidelines doc and Code Review
Guidelines docs?

I don't understand the question.
What the Ext people think of themselves does not matter.

The point is that they don't seek out qualified opinions as they think
their own qualify as such (see Google, Yahoo, etc.)
"Is the salesman trying to make the product look good? Is there anything
that he might not have told me, out of ignorance or otherwise?"

Who are you quoting?
This would not have been much investment and could have helped avoid
such an amazing waste of money[1].
Yes.  It's a shame to see people throwing good money after bad.

They seem misguided.

And lighter in the wallet. :)
So they paid you? You wrote above that nobody offered you any money to
do so.

Not Ext. I reviewed the whole thing from stem to stern for a client.
And certainly Ext (er Sencha) has never been a client of mine.
The investors may not have known that such an analysis was even
possible. Can the source code be analyzed by an independent third party?
Who knows?

I'm sure the investors didn't know anything about the source code.
They were likely dazzled by the pretty graphics (which make up the
bulk of the archive).
Returning to the car-purchasing example, a buyer might want to take the
car he so likes (nice radio, comfy seats, looks cool, etc), down to his
own mechanic for an analysis.

Someone in the predicament of making assessments of the framework, but
not having the skill to do so does not need a "mobile applications
development framework shop"! What he needs is one or a few individuals
who are qualified of making an assessment.

Basically, what the investors needed was an expert analysis prior.

Of course. And they clearly didn't get one.
The uninformed cannot know the least amount of time it will take to make
such assessment. A very complicated framework that had good code and a
sophisticated build process might take considerable time to and effort
investigate and drawing metrics for it is going to be very involved and
complicated.

It turned out that such rigorous investigations would not have been
necessary in this case because the code is so bad that it can be
dismissed. Continued analysis beyond that point is pointless.

Like I said, I was pretty sure it was DOA on line 1. At least, that
was a pretty strong indicator. By the time I got three or four dozen
lines in, I was definitely sure. But I went ahead and read the rest.
It was good for a laugh anyway.
What is the point in finding out how they've packaged and organized
they're bugs? By accident, the `hasRightMarginBug` identifier was found
to be absent and with the many false comments about properties being
"private" (they aren't).

You should read Dojo some day. Now there's a comedy classic. :)
I don't much care for giving free help to the Ext-JS guys.

I don't either. That's why I don't solve *every* problem for them in
the reviews (much to the chagrin of some anonymous posters).
About 8
months ago, a colleage of mine informed me that they were in need of a
JS developer.

They need more than one.
I re-familiarized myself with their code and found room
for major improvement.

Yes, they've got plenty of vacancies. :)
And so I gave my colleage the "OK" to pass on my contact info. So,
rather helping them, I get to do remote project postmortem, pro bono.

There seems to be a scene missing. (?)
[...]


Happens all the time.
And the choice to use Sencha Touch is exponentially worse, which could
only be described as insane.

No, it could be described as misguided or not fully informed, or
informed, but not understanding the ramifications.

I meant in light of this thread. Obviously, if they haven't read it
then they don't know.
Do not consider "misguided" to be an insult

I don't consider it an insult any more than misinformed or even
ignorant. Of course some people are ignorant of the fact that
ignorance is not the same as stupidity.
it is a position that most
of us are in, in more ways than we realize.

Not me. I know exactly where I'm going. :)
 
G

Garrett Smith

Yes. You mentioned browser documentation. That's the one I'm aware of,
and it's related to the topic discussed here.


But the previous one does, afaict (although vaguely).

"A style change reflow is performed when the presentation shell's global
stylistic information is changed; e.g., addition or removal of a style
sheet, a change to the shell's default font."


What's with ad hominem? :) I'm failing to see how it matters on which
blog WebKit developer explains when/how reflow occurs in WebKit?

What ad hominem? Are you reading more into what I wrote?

What you seem to fail to grasp is that recalc != repaint. That is,
recalc is not causing pixels to be visully updated to the user.

A repaint is when the browser paints the pixels so they are visually
rendered.
Wait, didn't I start original reply with "There certainly are observable
ways to trigger ..."? Is that "not actually saying it"?

So you think you can force a repaint, huh?

It didn't actually happen in the loop test, though, did it?
I linked to Hyat's comment though, not post itself. He even says that
most of what she says doesn't apply to WebKit in an earlier comment:

<quote>
Just FYI, very little of what you’ve written here applies to WebKit.
There’s nothing overly scary about either a typical reflow or repaint in
WebKit as long as what you do doesn’t affect the geometry of the entire
page.
HEre is a complete example.

Notice that when the div gets to "500" that the title will update in
chrome. You may want to bump the j loop up to 50000 iterations -- 10x
what it is now (5000) to notice that.

The div starts at the left and ends 1000px left from that. It is not
ever visibile at 500. Setting innerHTML didn't change that; nothing
will. You can't make the browser repaint.

The best you can do is give it a condition under which it thinks a
repaint should occur and then wait for it to do that. It won't do it on
exiting each function but it should probably want to do that after
completing the stack of execution contexts.

<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>How do I make the browser repaint?</title>
</head>
<body>
<div id="a" style="position: absolute; background: red; width: 20px;
height: 20px; top: 4em; left: 0;">a</div>
<script>

function start(){
var i;
for(i = 0; i < 1000; i++) {
moveDiv();
}

function moveDiv(){
document.getElementById("a").style.left = i + "px";
repaint();
}


function repaint() {
if(i === 500) {
for(var j = 0; j < 5000; j++) {
document.getElementById("a").innerHTML = "b";
document.title = new Date(j).toString();
}
}
// your code here.
}
}
</script>
<button onclick="start()">start()</button>
</body>
Given lack of standard or definitive documentation, observations is the
only thing we can work with. In Chrome your code does in fact trigger
repaints every time style is queried (screenshot —
<http://twitpic.com/26xr2n/full>).

No, it does not.
Look at multiple "layout" events, followed by "Style recalculation".

That is style recalc. Remember recalc != repaint.
That's what I meant by "observable ways to trigger reflow/repaint".

You're conflating repaint and reflow now with punctuation.
<quote>

[...]

element.style.width = ‘50px’;
var v = element.offsetWidth;
element.style.width = ‘55px’;
v = element.offsetWidth;

You just caused two reflows to happen, since asking for offsetWidth
forced the element to reflow in order to answer you question (because it
had a pending change to style).

Does not state that reading `offsetWidth` will trigger a repaint?

No, it doesn't. That's a good thing for Mr Hyatt because that would be a
false statement.

What it says is -- well it says exactly what it says, which is short and
simple, so I won't try and paraphrase.

And so reading offsetWidth to trigger a repaint would be a demonstration
of a misconception that the consequences of doing that would cause a
repaint (it won't).
This is the real performance bottleneck to be wary of. Browsers are
smart about avoiding reflows when they can, but if you create code that
forces a reflow in order to answer a question, then you can create
severe performance bottlenecks.
Informative, but not any evidence that a repaint can be triggered.

He said "...but if you create code that forces a reflow". As I read it,
that means you _can_ create code that forces reflow. Why would he talk
about something nonexistent?

Once again, does the quote from Hyatt state that reading `offsetWidth`
will trigger a repaint?
 
D

David Mark

That document discusses reflow (in Gecko).


That document discusses painting (in Gecko) and states the event that
triggers it as being content received. It does not state which mechanism
is responsible for triggering repainting.


Nicole Sullivan's blog? I'll normall pass on that one. It seems you've
got a disagreement with the fact that there's no way to force the
browser to repaint, but you won't actually say that and just post up links.

So lets see what the OO-CSS expert has to say.

| A repaint occurs when changes are made to an elements skin that

} changes visibility, but do not affect its layout

The repaint may occur after a request for a style change has been made,
but that won't happen every time.

Try writing a loop-based animation and if you can get it to update, then
you've gotten a repaint to occur.

var i;
for(i = 0; i < 1000; i++) {
   moveDiv();

}

function moveDiv(){
   document.getElementById("a").style.left = i + "px";
   repaint();

}

function repaint() {
   // your code here.

}

Also do realize that when you flesh out the repaint, even if you can get
it to work (it won't happen, but try if you like), then the fact that it
works could not be used as argument that a repaint can be forced; it
would only show that you did something and then a repaint occurred.

Browsers don't *always* reflow/repaint on exiting execution contexts.
But the fact is that they do sometimes (I know this from experience).
Nobody but the browser developers know exactly what factors determine
whether they do it or not. The above example likely illustrates that
they abstain while in the middle of a loop.

The important thing to know is that they do *not* repaint until they
exit the context that queued the style changes. You can't force
repaints on demand, but can certainly avoid them when needed.
 
D

David Mark

What ad hominem? Are you reading more into what I wrote?

What you seem to fail to grasp is that recalc != repaint.  That is,
recalc is not causing pixels to be visully updated to the user.

A repaint is when the browser paints the pixels so they are visually
rendered.



So you think you can force a repaint, huh?

It didn't actually happen in the loop test, though, did it?

That doesn't mean that it won't do it in all cases. The browser knows
it is in a loop after all.
HEre is a complete example.

Another loop. You can can't force a repaint, but you can't predict
when they will happen either (your theory about waiting until the
execution stack is exhausted is definitely wrong).
Notice that when the div gets to "500" that the title will update in
chrome. You may want to bump the j loop up to 50000 iterations -- 10x
what it is now (5000) to notice that.

The div starts at the left and ends 1000px left from that. It is not
ever visibile at 500. Setting innerHTML didn't change that; nothing
will. You can't make the browser repaint.

The best you can do is give it a condition under which it thinks a
repaint should occur and then wait for it to do that. It won't do it on
exiting each function but it should probably want to do that after
completing the stack of execution contexts.

Your general "it won't do it on exiting each function" statement is
just as false as saying it will do it on demand. The fact is that
browsers do sometimes reflow/repaint on exiting execution contexts
(and before the stack is exhausted). It would certainly be nice if
they didn't, but I know from experience that is not the case. For
one, I can't count how many times I've improved the performance of
widgets by avoiding function calls in the middle of updating styles.
And I mean exponentially, so it wasn't just the overhead of calling
the functions. For two, I've dealt with flickers and twitches due to
"unexpected" repaints. They happen in some contexts and the solution
is always the same.
 
G

Garrett Smith

[snip massive overquote]
Another loop. You can can't force a repaint, but you can't predict
when they will happen either (your theory about waiting until the
execution stack is exhausted is definitely wrong)

What's wrong and why?

Exhausting execution contexts -- sounds like they need to get some sleep.
Your general "it won't do it on exiting each function" statement is
just as false as saying it will do it on demand. The fact is that

No, that statement is correct and the xample shows that to be true.
tt render the div -- no repainting. Function `moveDiv` calls
`document.getElementById` and `repaint` each 1000x. Function repaint
calls the `Date` constructor and `Date.prototype.toString` 5000x each.
That makes 11000 function calls, if I counted right.

All that is needed to determine that the browser will not repaint on
exiting each function call is to find one case where exiting a function
call does not cause a repaint.

The example fulfills that requirement. No repainting took place after
any of some 11000 function calls.
 
D

David Mark

[snip massive overquote]
Another loop.  You can can't force a repaint, but you can't predict
when they will happen either (your theory about waiting until the
execution stack is exhausted is definitely wrong)

What's wrong and why?

I explained that. In short, it's false.
Exhausting execution contexts -- sounds like they need to get some sleep.

That word has other meanings.
No, that statement is correct and the xample shows that to be true.

No it doesn't. Your sample demonstrates that at least one browser on
one PC failed to do it in a loop. I find it quite reasonable that
browsers would abstain from repaints in such a loop. Don't you?
tt render the div -- no repainting. Function `moveDiv` calls
`document.getElementById` and `repaint` each 1000x. Function repaint
calls the `Date` constructor and `Date.prototype.toString` 5000x each.
That makes 11000 function calls, if I counted right.

All that is needed to determine that the browser will not repaint on
exiting each function call is to find one case where exiting a function
call does not cause a repaint.

As I've said (about 1000 times now, dating back for years). They
don't *always* do it. The key word is *always*. So your loop does
not disprove my position.
The example fulfills that requirement. No repainting took place after
any of some 11000 function calls.

And likely won't after 11 million function calls. All you have
demonstrated is one case where a browser does not repaint.
 
G

Garrett Smith

On 2010-07-19 11:57 PM, kangax wrote:
On 7/20/10 1:04 AM, Garrett Smith wrote:
On 2010-07-19 06:52 PM, kangax wrote:
On 7/19/10 3:32 PM, Garrett Smith wrote:
On 2010-07-19 12:29 AM, Ry Nohryb wrote:
On 2010-07-18 10:51 PM, Ry Nohryb wrote:
(...)

[snip massive overquote]
HEre is a complete example.
Another loop. You can can't force a repaint, but you can't predict
when they will happen either (your theory about waiting until the
execution stack is exhausted is definitely wrong)

What's wrong and why?

I explained that. In short, it's false.

Here you go again with "I've already explained" stories, claiming to
have done things that never took place. My my what an imagination.
That word has other meanings.

Get some rest.
No it doesn't.

The example shows a function call completing and a repaint no occurring
and so "it won't do it on exiting each function" is a true statement.

Your sample demonstrates that at least one browser on


Just one? Or most? Or was it every browser you tested in?

Which browser updated the position of the div at 500 and what else did
you do to get it to do that?
one PC failed to do it in a loop. I find it quite reasonable that
browsers would abstain from repaints in such a loop. Don't you?

What "reasonable browser behavior"?
As I've said (about 1000 times now, dating back for years). They
don't *always* do it. The key word is *always*. So your loop does
not disprove my position.

The example proves "it won't do it on exiting each function", which you
claimed to be false and *that* claim was a false claim.

Have you been sleeping?
And likely won't after 11 million function calls. All you have
demonstrated is one case where a browser does not repaint.

That was all that was needed to suppor the claim "it won't do it on
exiting each function".
 
R

Ry Nohryb

(...) The above example likely illustrates that
they abstain while in the middle of a loop.

The important thing to know is that they do *not* repaint until they
exit the context that queued the style changes.  You can't force
repaints on demand, but can certainly avoid them when needed.
(...)

Except Opera. Oper repaints in a separate thread, in parallel with the
JS thread:

http://jorgechamorro.com/cljs/101/

Only in Opera: you'll see a growing green dot dropping.

Tested in : navigator.userAgent: Opera/9.80 (Macintosh; Intel Mac OS
X; U; en) Presto/2.6.30 Version/10.60.
 
R

Ry Nohryb

Except Opera. Oper repaints in a separate thread, in parallel with the
JS thread:

http://jorgechamorro.com/cljs/101/

Only in Opera: you'll see a growing green dot dropping.

Tested in : navigator.userAgent: Opera/9.80 (Macintosh; Intel Mac OS
X; U; en) Presto/2.6.30 Version/10.60.

Oops, forgot to paste in the code:

window.onload= function (here, stop, s) {
here= document.getElementById('here');
s= 9;
while (s < 4e2) {
here.style.fontSize= ++s+ "px";
stop= +new Date()+ 50;
while (+new Date() < stop) { ; }
}
here.style.fontSize= "";
setTimeout(onload, 1e3);
};
 
D

David Mark

On 2010-07-20 11:33 AM, David Mark wrote:
On 2010-07-19 11:57 PM, kangax wrote:
On 7/20/10 1:04 AM, Garrett Smith wrote:
On 2010-07-19 06:52 PM, kangax wrote:
On 7/19/10 3:32 PM, Garrett Smith wrote:
On 2010-07-19 12:29 AM, Ry Nohryb wrote:
On 2010-07-18 10:51 PM, Ry Nohryb wrote:
(...)
[snip massive overquote]
HEre is a complete example.
Another loop.  You can can't force a repaint, but you can't predict
when they will happen either (your theory about waiting until the
execution stack is exhausted is definitely wrong)
What's wrong and why?
I explained that.  In short, it's false.

Here you go again with "I've already explained" stories, claiming to
have done things that never took place. My my what an imagination.

My, my what a jackass.

Not only have I provided anecdotal evidence, which most assuredly
happened (do you really think I would make up stories for you?), but
I've provided at least one example that remains on the Web to this
day. That was months ago, which is indicative of how ridiculous this
"debate" has become. I was right. You were/are wrong. No amount of
semantics will change that.
Get some rest.

Get some sense.
The example shows a function call completing and a repaint no occurring
and so "it won't do it on exiting each function" is a true statement.

Your statement is (intentionally) vague. If you are saying that it
won't do it on *every* function exit, then you have been agreeing with
me all along. (?)
Your sample demonstrates that at least one browser on

Just one? Or most? Or was it every browser you tested in?

I didn't test your code at all. But from experience I know that it
likely won't repaint during the loop (which proves absolutely
nothing).
Which browser updated the position of the div at 500 and what else did
you do to get it to do that?

You really think I bothered with your code?
What "reasonable browser behavior"?

Who are you quoting?
The example proves "it won't do it on exiting each function", which you
claimed to be false and *that* claim was a false claim.

Have you been sleeping?

Again, your position has been that it *never* does it except when the
execution stack is finished. That's false. The statement "it won't
do it on exiting each function" can be interpreted two ways (that it
will never do it on such exits and that it may well do it some of the
time). Recall that the latter has been my assertion all along (and
the former yours).
That was all that was needed to suppor the claim "it won't do it on
exiting each function".

See above.
 
G

Garrett Smith

On 7/20/10 1:04 AM, Garrett Smith wrote:
On 2010-07-19 06:52 PM, kangax wrote:
On 7/19/10 3:32 PM, Garrett Smith wrote: [...]
Nicole Sullivan's blog? I'll normall pass on that one.

What's with ad hominem? :) I'm failing to see how it matters on which
blog WebKit developer explains when/how reflow occurs in WebKit?

What ad hominem? Are you reading more into what I wrote?

I still don't see that be taken as a personal attack on Nicole Sullivan.

You quoted Dave Hyatt, the context in which the comment was made matters
and so although normally I'd pass on reading that blog, it seemed only
proper that the blog entry should be read so as to understand the
context of Hyatt's context.

So I'm not sure where I went wrong. Or if.

[...]
The best you can do is give it a condition under which it thinks a
repaint should occur and then wait for it to do that. It won't do it on
exiting each function but it should probably want to do that after
completing the stack of execution contexts.
Right.

[...]


Second — and more important — I have a different understanding of
"force/trigger"; I know that browsers don't _repaint_ on every change of
style (and/or querying of computed style after such change) but making
browser perform repaint in the near future falls under the definition of
"trigger repaint" for me. Browser doesn't repaint _immediately_ but it
still does eventually, which means that repaint was forced/triggered.

If there is new layout information that needs painting, the browser will
hopefully paint it.

The code in question may address an issue in webkit with repainting. Or
it may address a problem that the authors have created.

Method `Ext.Element.prototype.repaint` triggers an error condition by
setting `dom.style.background = null`.

That mistake is one of many mistakes.

Think about reviewing some of this code. For example, you could look at
`El.get` from ext-touch-debug-w-comments.js.

I suggest (to anyone) to read it carefully, see what it does, what it
gets wrong, and then test that. Then post up the findings. Just a
reminder: Quick quips about the code are not helpful to anyone.

I picked this function because there are things in it that I suspect you
won't like.

El.get = function(el){
var extEl,
dom,
id;

if(!el){
return null;
}

if (typeof el == "string") {
if (!(dom = document.getElementById(el))) {
return null;
}
if (Ext.cache[el] && Ext.cache[el].el) {
extEl = Ext.cache[el].el;
extEl.dom = dom;
} else {
extEl = El.addToCache(new El(dom));
}
return extEl;
} else if (el.tagName) {
if(!(id = el.id)){
id = Ext.id(el);
}
if (Ext.cache[id] && Ext.cache[id].el) {
extEl = Ext.cache[id].el;
extEl.dom = el;
} else {
extEl = El.addToCache(new El(el));
}
return extEl;
} else if (el instanceof El) {
if(el != El.docEl){


el.dom = document.getElementById(el.id) || el.dom;
}
return el;
} else if(el.isComposite) {
return el;
} else if(Ext.isArray(el)) {
return El.select(el);
} else if(el == document) {

if(!El.docEl){
var F = function(){};
F.prototype = El.prototype;
El.docEl = new F();
El.docEl.dom = document;
}
return El.docEl;
}
return null;
};
 
G

Garrett Smith

On 2010-07-20 11:33 AM, David Mark wrote:
On 2010-07-19 11:57 PM, kangax wrote:
On 7/20/10 1:04 AM, Garrett Smith wrote:
On 2010-07-19 06:52 PM, kangax wrote:
On 7/19/10 3:32 PM, Garrett Smith wrote:
On 2010-07-19 12:29 AM, Ry Nohryb wrote:
On 2010-07-18 10:51 PM, Ry Nohryb wrote:
(...)
[snip massive overquote]
HEre is a complete example.
Another loop. You can can't force a repaint, but you can't predict
when they will happen either (your theory about waiting until the
execution stack is exhausted is definitely wrong)
What's wrong and why?
I explained that. In short, it's false.

Here you go again with "I've already explained" stories, claiming to
have done things that never took place. My my what an imagination.

My, my what a jackass.

That's David Mark I know. And *that* is a example of ad hominem.

More graceful ways to recognize a mistake than that exist.
Not only have I provided anecdotal evidence, which most assuredly
happened (do you really think I would make up stories for you?), but
I've provided at least one example that remains on the Web to this
day. That was months ago, which is indicative of how ridiculous this
"debate" has become. I was right. You were/are wrong. No amount of
semantics will change that.

I've stated nothing wrong. I've stated now four or five times that the
browser won't repaint on exiting each function. You chose to argue about
that. Why you would choose to argue about that can only be explained by
you and so far you've not explained anything that supports why you
believe the statement I made was incorrect.

And while I cannot say your absense of an explanation is wrong, your
claim that I was wrong is false and your claim that you have made an
explanation was also not true. It's not the first time you've made such
claims. Recall when I was copying everything you did, how I copied all
of your best jQuery code reviews? How I was "aping" your code?

The claim that my statement was false was incorrect. I can't see why
you're having such trouble realizing it. Anyone who read it carefully
and tested the example I posted should see that the statement I made is,
in fact, correct and proven by my example.

Is your ego getting in the way of recognizing the mistake? Pretty much
anyone can recognize that what was posted was correct and continuing to
say that it wasn't is unlikely to change that.

Pity. Given what you've posted, I am afraid that the reader's judgment
call may be to dismiss your review as that of a man who is not reasonable.
Get some rest.

Get some sense.

[...]
Which browser updated the position of the div at 500 and what else did
you do to get it to do that?

You really think I bothered with your code?

I know that you tend to not read specs and don't test things very well.
You tend to post carelessly and the formatting of the code reviews marks
an example of that.
Who are you quoting?

You brought up the subject of reasonable browser behavior but didn't say
what that was.
Again, your position has been that it *never* does it except when the
execution stack is finished.

OK. That's where you went wrong. I did not make that claim.
 
D

David Mark

On 2010-07-20 12:24 PM, David Mark wrote:
On 2010-07-20 11:33 AM, David Mark wrote:
On 2010-07-19 11:57 PM, kangax wrote:
On 7/20/10 1:04 AM, Garrett Smith wrote:
On 2010-07-19 06:52 PM, kangax wrote:
On 7/19/10 3:32 PM, Garrett Smith wrote:
On 2010-07-19 12:29 AM, Ry Nohryb wrote:
On 2010-07-18 10:51 PM, Ry Nohryb wrote:
(...)
[snip massive overquote]
HEre is a complete example.
Another loop.  You can can't force a repaint, but you can't predict
when they will happen either (your theory about waiting until the
execution stack is exhausted is definitely wrong)
What's wrong and why?
I explained that.  In short, it's false.
Here you go again with "I've already explained" stories, claiming to
have done things that never took place. My my what an imagination.
My, my what a jackass.

That's David Mark I know. And *that* is a example of ad hominem.

You don't know me and you always pull this sort of stupid shit where
you bait relentlessly and then cry when scolded. What the hell is
wrong with you? Next time, refrain from calling me a liar.
More graceful ways to recognize a mistake than that exist.

I've made no mistake.

[...]
OK. That's where you went wrong. I did not make that claim.

You stuck to that claim for months. Pardon me if I missed your
recent, vaguely worded flip-flop. So you finally get it that browsers
don't wait until the end of the execution stack to reflow/repaint?
That should help you learn how to optimize browser scripts,
particularly widgets. Glad I could help. :)
 
G

Garrett Smith

On 2010-07-20 12:24 PM, David Mark wrote:
On 2010-07-20 11:33 AM, David Mark wrote:
On 2010-07-19 11:57 PM, kangax wrote:
On 7/20/10 1:04 AM, Garrett Smith wrote:
On 2010-07-19 06:52 PM, kangax wrote:
On 7/19/10 3:32 PM, Garrett Smith wrote:
On 2010-07-19 12:29 AM, Ry Nohryb wrote:
On 2010-07-18 10:51 PM, Ry Nohryb wrote:
(...)
[snip massive overquote]
HEre is a complete example.
Another loop. You can can't force a repaint, but you can't predict
when they will happen either (your theory about waiting until the
execution stack is exhausted is definitely wrong)
What's wrong and why?
I explained that. In short, it's false.
Here you go again with "I've already explained" stories, claiming to
have done things that never took place. My my what an imagination.
My, my what a jackass.

That's David Mark I know. And *that* is a example of ad hominem.

You don't know me and you always pull this sort of stupid shit where
you bait relentlessly and then cry when scolded. What the hell is
wrong with you? Next time, refrain from calling me a liar.
More graceful ways to recognize a mistake than that exist.

I've made no mistake.

[...]
OK. That's where you went wrong. I did not make that claim.

You stuck to that claim for months. Pardon me if I missed your
recent, vaguely worded flip-flop. So you finally get it that browsers

What I wrote wasn't vague at all!

You surrounded what I wrote in quotes, then said it was false and stuck
with it for three or four posts.
don't wait until the end of the execution stack to reflow/repaint?
That should help you learn how to optimize browser scripts,
particularly widgets. Glad I could help. :)

Your design advice is reflected in the style of code seen in "my library".

The claim that the browser uses completing a function call with in a
call stack as a trigger to repaint is a different matter.

I can't recall ever seeing a test case as evidence to that. I don't
anticipate seeing one either.
 
R

RobG

Another loop.  You can can't force a repaint, but you can't predict
when they will happen either (your theory about waiting until the
execution stack is exhausted is definitely wrong).

It may be a trivial example, but a repaint will generally occur when
an alert dialog is presented:

<script type="text/javascript">

window.onload = function(){
window.setTimeout(foo, 1000);
};

function foo() {
var i,
el = document.getElementById('d0'),
n = 10000,
s = 6;

while (s < 1000) {

// Show alert dialog at half way
if (s == 500) {
alert('redraw...');
}

el.style.fontSize = ++s + "pt";
i = n;

// Simulate doing stuff
while (i--) ;
}
};

</script>

<div id="d0"
style="color: green; vertical-align:top;">°</div>
 
D

David Mark

On 2010-07-20 03:44 PM, David Mark wrote:
On 2010-07-20 12:24 PM, David Mark wrote:
On 2010-07-20 11:33 AM, David Mark wrote:
On 2010-07-19 11:57 PM, kangax wrote:
On 7/20/10 1:04 AM, Garrett Smith wrote:
On 2010-07-19 06:52 PM, kangax wrote:
On 7/19/10 3:32 PM, Garrett Smith wrote:
On 2010-07-19 12:29 AM, Ry Nohryb wrote:
On 2010-07-18 10:51 PM, Ry Nohryb wrote:
(...)
[snip massive overquote]
HEre is a complete example.
Another loop.  You can can't force a repaint, but you can't predict
when they will happen either (your theory about waiting until the
execution stack is exhausted is definitely wrong)
What's wrong and why?
I explained that.  In short, it's false.
Here you go again with "I've already explained" stories, claiming to
have done things that never took place. My my what an imagination.
My, my what a jackass.
That's David Mark I know. And *that* is a example of ad hominem.
You don't know me and you always pull this sort of stupid shit where
you bait relentlessly and then cry when scolded.  What the hell is
wrong with you?  Next time, refrain from calling me a liar.
I've made no mistake.
Again, your position has been that it *never* does it except when the
execution stack is finished.
OK. That's where you went wrong. I did not make that claim.
You stuck to that claim for months.  Pardon me if I missed your
recent, vaguely worded flip-flop.  So you finally get it that browsers

What I wrote wasn't vague at all!

Of course it was. Read it aloud until you comprehend the dual
meaning. Or don't. I'm tired of this discussion (and the dozens that
lead up to it).

The fact is that you have recently changed your position to match
mine. Previously you argued vehemently that browsers *never* did
reflows or repaints until the end of the execution stack. You didn't
say that sometimes they did and sometimes they didn't as that was what
I was saying. It's not like those months worth of arguments were some
sort of misunderstanding. Your point was clear, as was mine.
You surrounded what I wrote in quotes, then said it was false and stuck
with it for three or four posts.
Whatever.


Your design advice is reflected in the style of code seen in "my library"..

Indeed there are parts of My Library that avoid unwanted reflows/
repaints to avoid unwanted flashes of content, performance loss, etc.
Does that surprise you?
The claim that the browser uses completing a function call with in a
call stack as a trigger to repaint is a different matter.

I never claimed anything of the sort. You always leave out the
"sometimes" part.
I can't recall ever seeing a test case as evidence to that.

Your amnesia is a well-known problem and I imagine the style of code
in "your library" reflects that.
I don't
anticipate seeing one either.

I suggest you try very hard to retrieve that part of your memory.

And how the hell do you not know this stuff anyway? It's really
basic. Dojo's stupid grid was setting innerHTML on hundreds of cells,
calling functions to do each one. Took minutes. I eliminated the
function calls and reduced it to seconds. If you don't have lots of
similar anecdotes, then you either have no experience with such things
or you don't know what the hell you are doing. Clear?
 
D

David Mark

It may be a trivial example, but a repaint will generally occur when
an alert dialog is presented:

<script type="text/javascript">

window.onload = function(){
  window.setTimeout(foo, 1000);

};

function foo() {
  var i,
      el = document.getElementById('d0'),
      n = 10000,
      s = 6;

  while (s < 1000) {

    // Show alert dialog at half way
    if (s == 500) {
      alert('redraw...');
    }

    el.style.fontSize = ++s + "pt";
    i = n;

    // Simulate doing stuff
    while (i--) ;
  }

};

</script>

<div id="d0"
  style="color: green; vertical-align:top;">°</div>

Yes. Calling a host methods (as opposed to native functions) doesn't
usually allow for that, but it makes sense that those that display
modal dialogs are an exception.
 

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

Forum statistics

Threads
473,754
Messages
2,569,528
Members
45,001
Latest member
Kendra00E1

Latest Threads

Top