Prev: FAQ Topic - How can I disable the back button in a web browser? (2010-04-17)
Next: FAQ Topic - How do I access a frame's content? (2010-04-18)
From: Sean Kinsey on 17 Apr 2010 11:38 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 17 Apr 2010 14:20 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 17 Apr 2010 16:14 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 17 Apr 2010 16:59 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 17 Apr 2010 16:59
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.) |