From: Sean Kinsey on
On Apr 17, 5:18 pm, Johannes Baagoe <baa...(a)baagoe.com> wrote:
> Evertjan. :
<snip>
> Anyway, here, the stupid problem I had was that when I modified the
> cells, nothing happened on the screen. What I wanted was a simple
> way to say "Hey, browser, I mean *now*!".

Javascript is singlethreaded, and so to make DOM-manipulations more
efficient, the UI isn't synchronized with the DOM-model until after
all the changes has been made. This is for instance to avoid having to
recalculate the layout and redraw the entire document on each mutation
during the dynamic adding of elements to the DOM.
The way most browsers handle this is to wait until the thread goes
into an 'idle' state.

> What I ended up with was
> punching a ribbon in one procedure for another procedure to consume by
> calling a non-standard  deferred execution order sequentially, in order
> implement a sort of "yield()" system call. In 2010, that is not the
> sort of things I expect to have to do in a straightforward application.

Its how it is when you only have a single thread. If you still want a
clean architecture you could model the application as a state machine,
that would make it easy to release the thread whenever you require DOM-
synchronization.

>
> Thanks a lot, anyway - the consensus seems to be that there is no
> better way. Would it qualify as a FAQ?

Perhaps something short to explain the single-threaded nature of
ECMAScript, and how the DOM relates to this.
From: Thomas 'PointedEars' Lahn on
Johannes Baagoe wrote:

> Thomas 'PointedEars' Lahn :
>> Johannes Baagoe :
>>> The page is here:
>>> http://baagoe.com/en/RandomMusings/javascript/time.xhtml
>>
>> I can see no good reason for using XHTML there. I can also see no good
>> reason for serving *only* non-"HTML-compatible" XHTML 1.0 Strict as
>> application/xhtml+xml. Why would you want to exclude e.g. the usually
>> relevant IE/MSHTML from the tests?
>
> No good reason, plenty of bad ones. I am more used to work with XML
> than with SGML these days. I don't like when I can get away with
> forgetting to close an element with a close tag, or quotes around
> attribute values, etc.

Those are actually good reasons for using XHTML (although HTML 4.01 Strict
can alleviate the problem with the _end_ tags), but not for serving it as
application/xhtml+xml to user agents that would support it with text/html
instead.

> I have tools on my editor that presume XML.

IMHO, this is not a good reason. I do not know which editor you are using,
but a good editor for Web development should be able to deal with both HTML
and X(HT)ML. Eclipse WTP/WST can.

> I tend to use the same template to start all my web pages.

That is not a good reason either. (By coincidence, Eclipse WTP/WST can do
that, too, and with ECMAScript-based code.)

> I fairly often embed SVG in XHTML.

That is a good reason for using XHTML (although you can do without the
embedding and use HTML), but not for serving it like that.

> I use XSLT transforms.

That might be a good reason for using XHTML, and serving it as
application/xhtml+xml. I am not sure, but client-side XSL stylesheets might
not work with XHTML served as text/html. It should not matter at all for
server-side stylesheets.

> I could pass all the XHTML pages trough a simple XSLT transform that
> turns them into HTML 4.01 Strict. I could put the operation in a
> Makefile, too... or in an Apache module. I know there is one.

Or you could serve it as text/html to clients that do not support
application/xhtml+xml, based on the Accept-Type request header they sent.

> More trouble than I have cared to take till now. Is it worth it?

If you want the majority of Web clients to work with it ...
(Currently true regardless whether one of us likes that.)

>> <http://www.w3.org/TR/xhtml-media-types/>
>
> I shall have a closer look, but I fairly often put elements from
> the SVG namespace into XHTML, and I may put in others...

That is not a good reason for serving XHTML *like that*, see above.

>> Anyhow, SHORTTAG syntax is not recommended for elements which content
>> model is not EMPTY, like `script', `th', and `td'. So use <th></th>
>> instead of <th/>.
>>
>> <http://www.w3.org/TR/REC-xml/#NT-EmptyElemTag>
>
> Yeah, I know. But AFAICS, nobody is hurt. If I were a Kantian,
> that would be no excuse, admittedly. I'm a Utilitarian, however,
> so I need evidence that the integral of happiness over all sentient
> beings increases if I write <th></th> instead of <th/>.

I do not know of an application/xhtml+xml-supporting client that exhibits
any problems with that syntax, primarily because I do not use XHTML often
(there rarely is a need), and when I have had to use it in production
environment it was served as text/html (and I could not find anything to
change that). But is it a wise course of action to ignore normative
recommendations for the language that the language you are using is based
on?

Regardless, once you serve XHTML as text/html to clients that do not support
application/xhtml+xml you will have plenty of evidence, starting with the
`script' element causing script runtime errors if you write it like that.
This newsgroup has seen it before.

>> var generators = {
>> ...
>> };
>
>> The identifier `RandomMathRandom' should be `randomMathRandom' as it
>> does not refer to a function that is called as a constructor.
>
> Well, it returns an Object of a particular kind.

It returns a reference to an object that already exists. It is neither a
constructor nor a factory.

> The upper case is there to encourage users to think of it as returning
> that. No harm that I can see in pretending it is a constructor and calling
> it with new, if that is what one is used to do with Functions which return
> an Object of a particular kind.

You would want to deceive users and support their misconceptions about
proper use of the `new' operator?

>> resetAll() and timeAll() can be a lot more efficient if you store the
>> values of `cells.length', `rows.length', and other repeatedly used,
>> unchanging properties in a local variable and use the variable value
>> instead, and count backwards where possible.
>
> Sure, but they don't get called enough to make me hunt for optimisation.

AIUI, the purpose of your question was to increase the responsiveness of
your application. In a single-threaded environment that boils down to
increasing the runtime efficiency of the underlying code.

>> I would also not use strict comparison with host objects' properties;
>> there is no obvious speed advantage here (cf. ES5, 11.9), but you would
>> lose the advantage of implicit type conversion should an implementation
>> not yield a value of the expected type (here: Number).
>
> Isn't it *supposed* to yield a Number?

It is, in fully conforming DOM implementations that implement the specified
ECMAScript binding. However, there have been examples where some properties
were not implemented exactly as specified. Is it a wise course of action to
risk that your application does not work in such implementations in the
future when it could continue to work?

> Anyway, ACK.

ACK

>> HTH
>
> It does indeed. Many thanks.

You're welcome.


PointedEars
--
Anyone who slaps a 'this page is best viewed with Browser X' label on
a Web page appears to be yearning for the bad old days, before the Web,
when you had very little chance of reading a document written on another
computer, another word processor, or another network. -- Tim Berners-Lee
From: Johannes Baagoe on
Sean Kinsey :
> Johannes Baagoe :

>> Anyway, here, the stupid problem I had was that when I modified the
>> cells, nothing happened on the screen. What I wanted was a simple
>> way to say "Hey, browser, I mean *now*!".

> Javascript is singlethreaded,

Of course, but it seems to me that my problem is unrelated to that fact.

> and so to make DOM-manipulations more efficient, the UI isn't
> synchronized with the DOM-model until after all the changes has been
> made. This is for instance to avoid having to recalculate the layout
> and redraw the entire document on each mutation during the dynamic
> adding of elements to the DOM. The way most browsers handle this is
> to wait until the thread goes into an 'idle' state.

If I want the whole result of a lengthy computation to be displayed
once and for all at the end of that computation, I build the entire
new tree as a DocumentFragment, and only append - insert - replace
it when I am done. Or if I am lazy, I build the entire String to
be inserted - /horresco referens/ - as innerHTML before actually
inserting it. Contrariwise, when I update successive sub-nodes of
`document.documentElement` *in situ*, it means that I want my changes
to be displayed *piecemeal*, at the moment I insert them where they
are supposed to reflect what the user sees.

But here, I get the impression that "most browsers" (I'm happy to
see that Opera is an exception) simply assume that I am a fool who
doesn't know the difference, and that they don't even provide a way
for me to overrule that assumption. Something like `document.render()`
when I mean "Now!", or perhaps `lazyRendering(false)` once and for
all, would be welcome. In their absence, the net result appears to
be that I must resort to an ugly hack to force what IMHO should be
the default behaviour.

(Ah well, that's just the way things are. The polite assumption
that people know what they are doing seems to yield steadily to the
perhaps more realistic assumption that they don't.)

>> What I ended up with was punching a ribbon in one procedure for
>> another procedure to consume by calling a non-standard  deferred
>> execution order sequentially, in order implement a sort of "yield()"
>> system call. In 2010, that is not the sort of things I expect to
>> have to do in a straightforward application.

> Its how it is when you only have a single thread.

I don't even think that is related. Opera gets it right, and its
implementation is no less single-threaded than the others'. Actually,
it doesn't strike me as a javascript issue at all; modifying the
document tree with Java or whatever other language happens to
manipulate the DOM would, it seems to me, raise exactly the same
issues. Or am I missing something?

> If you still want a clean architecture you could model the application
> as a state machine, that would make it easy to release the thread
> whenever you require DOM- synchronization.

That is essentially what I came up with. It seems an extravagant
solution to a problem that shouldn't exist it the first place.

>> Thanks a lot, anyway - the consensus seems to be that there is no
>> better way. Would it qualify as a FAQ?

> Perhaps something short to explain the single-threaded nature of
> ECMAScript, and how the DOM relates to this.

Again, I don't believe that is the point.

--
Johannes
From: Jeremy J Starcher on
On Sat, 17 Apr 2010 15:14:10 -0500, Johannes Baagoe wrote:

> Sean Kinsey :
>> Johannes Baagoe :
>
>>> Anyway, here, the stupid problem I had was that when I modified the
>>> cells, nothing happened on the screen. What I wanted was a simple way
>>> to say "Hey, browser, I mean *now*!".
>
>> Javascript is singlethreaded,
>
> Of course, but it seems to me that my problem is unrelated to that fact.

Opera excluded for the moment ...

Stop to think of this.

The browser window is single threaded. Your code modify the DOM. The
browser window doesn't update the visual display because it is SINGLE
THREADED and your code has that thread. The repaint won't get its time
in until your code has finished.

Opera, AFAIK, uses two threads per window. One to run the user interface
code and update the DOM and the other run scripting. (I'm only guessing
at details.)

So yes.. Opera does something that no other browser I know of does.
Everywhere else you have to let your script quit running and let the
browser breath (and repaint the screen) then continue your script based
on some event.

If you don't believe that the fact that the browser window is single
threaded is the point, then change what you believe.
From: Thomas 'PointedEars' Lahn on
Johannes Baagoe wrote:

> Sean Kinsey :
>> Johannes Baagoe :
>>> Anyway, here, the stupid problem I had was that when I modified the
>>> cells, nothing happened on the screen. What I wanted was a simple
>>> way to say "Hey, browser, I mean *now*!".
>>
>> Javascript is singlethreaded,

I would not go that far (and I would not use the term "Javascript" to begin
with).

> Of course, but it seems to me that my problem is unrelated to that fact.

I don't think that is correct either.

>> and so to make DOM-manipulations more efficient, the UI isn't
>> synchronized with the DOM-model until after all the changes has been
>> made. This is for instance to avoid having to recalculate the layout
>> and redraw the entire document on each mutation during the dynamic
>> adding of elements to the DOM. The way most browsers handle this is
>> to wait until the thread goes into an 'idle' state.
>
> If I want the whole result of a lengthy computation to be displayed
> once and for all at the end of that computation, I build the entire
> new tree as a DocumentFragment, and only append - insert - replace
> it when I am done. Or if I am lazy, I build the entire String to
> be inserted - /horresco referens/ - as innerHTML before actually
> inserting it. Contrariwise, when I update successive sub-nodes of
> `document.documentElement` *in situ*, it means that I want my changes
> to be displayed *piecemeal*, at the moment I insert them where they
> are supposed to reflect what the user sees.
>
> But here, I get the impression that "most browsers" (I'm happy to
> see that Opera is an exception) simply assume that I am a fool who
> doesn't know the difference, and that they don't even provide a way
> for me to overrule that assumption. Something like `document.render()`
> when I mean "Now!", or perhaps `lazyRendering(false)` once and for
> all, would be welcome. In their absence, the net result appears to
> be that I must resort to an ugly hack to force what IMHO should be
> the default behaviour.

It is impossible for the DOM implementation to know what you are up to, so
many implementors take the conservative approach and queue all your DOM
"requests" until there is sufficient time allocated to the process to do so.
That is a Good Thing! After all, reflows are usually of less importance
than the script that is currently running. Think about it: Usually you do
not want to trigger a reflow every time you modify properties of a DOM
object; that would make the DOM-accessing script very slow.

However, by using window.setTimeout() you are providing information to the
implementation that you want the changes to happen at a specific moment in
time, by which they should and can take precedence over other subprocesses
(including further script execution). The DOM changes might even take place
in another thread then, but ISTM it is impossible to know that for sure (I
am not so sure about it anymore since the window.setTimeout() implementation
I saw as proof for Geckos might as well be only triggered with Web workers).

>>> What I ended up with was punching a ribbon in one procedure for
>>> another procedure to consume by calling a non-standard deferred
>>> execution order sequentially, in order implement a sort of "yield()"
>>> system call. In 2010, that is not the sort of things I expect to
>>> have to do in a straightforward application.
>>
>> Its how it is when you only have a single thread.
>
> I don't even think that is related. Opera gets it right, and its
> implementation is no less single-threaded than the others'.

This is not a question of right or wrong.

> Actually, it doesn't strike me as a javascript issue at all; modifying the
> document tree with Java or whatever other language happens to
> manipulate the DOM would, it seems to me, raise exactly the same
> issues. Or am I missing something?

Yes. To begin with, Java is a programming language that has built-in thread
support.


PointedEars
--
Use any version of Microsoft Frontpage to create your site.
(This won't prevent people from viewing your source, but no one
will want to steal it.)
-- from <http://www.vortex-webdesign.com/help/hidesource.htm> (404-comp.)