tag:blogger.com,1999:blog-11788780.post7160271373547564968..comments2023-12-29T13:22:33.104-08:00Comments on JJinuxLand: JavaScript: DOM vs. innerHTML, Server-driven vs. Client-drivenjjinuxhttp://www.blogger.com/profile/03270879497119114175noreply@blogger.comBlogger16125tag:blogger.com,1999:blog-11788780.post-66808491171590553042009-10-29T22:15:58.976-07:002009-10-29T22:15:58.976-07:00Hey Adam,
Thanks a lot for your response. I real...Hey Adam,<br /><br />Thanks a lot for your response. I really respect your opinion on this subject. I think I get the gist of your opinion, and it reminds me of 280 Slides and Objective-J.<br /><br />Please keep me in mind as your opinions grow and change on this subject.<br /><br />I think the conclusion that I've come to is the least crappy option for my current situation:<br /><br /> * Keep the app mostly server side.<br /> * Use a little Ajax to enhance the page.<br /> * Use jQuery.<br /> * jQuery uses innerHTML instead of the DOM API.<br /> * Send chunks of HTML to the client.<br /> * Mostly render the page on the server.jjinuxhttps://www.blogger.com/profile/03270879497119114175noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-31517518771545385662009-10-29T21:10:12.598-07:002009-10-29T21:10:12.598-07:00JJ, Nice post. I see it as damned-if-you-do, etc. ...JJ, Nice post. I see it as damned-if-you-do, etc. If you mostly keep your app on the server, you usually end up having to stand on your head to factor out common code for the initial page load and the ajax callback. There's also this impediment to introducing additional AJAX fanciness: every bit is more work and more bugs.<br /><br />If you choose to mostly keep your app on the client, the biggest problem you have is that you're writing twice the code; when you add a record, you have to write the code to add it to the local state on the client, and to add it to the server. In such environments, it's also usually very hard to write apps where the client state can be altered by an external action (like a record being updated by another user) since the state is mostly kept on the client. You end up having to make the unfortunate choice between sending relevant state with every server call (like a POP email client) or modeling the client state on the server (which means that you're writing even more of your program twice.) Add to this the additional problems you mention around delivering application functionality into under-equipped browsers, like email clients and search robots (let alone IE,) the slowness of the DOM APIs, and the somewhat sucky initial experience of having to load a bunch of app code and then call back to the server before your app can really start. I'm pretty down on this approach, even though I evangelized it at laszlo for several years.<br /><br />The framework that Eric referenced above is something that we've been developing for the last year. We call it msjs (pronounced like "messages") and it's a <a href="http://en.wikipedia.org/wiki/Dataflow_programming" rel="nofollow">dataflow</a> style system where programs are composed out of nodes that are written in javascript. These nodes send and receive JSON messages and are connected in a well defined way at initialization time. As such, in msjs, the program can be automatically distributed between the client and server by doing some relatively simple graph analysis. Since all of the messaging in the system is JSON, it's easy to call across the client/server boundary without doing any formal RPC.<br /><br />As for how we handle markup, we've done a little of both. For big blocks of declarative markup -- usually for structural layout -- we've enabled inline-XHTML by using <a href="https://developer.mozilla.org/en/E4X" rel="nofollow">E4X</a> on the server. The other thing we did is to implement much of the low-level DOM APIs within our framework, so that we can manipulate DOM elements on the server just as we would on the client. This means that we can deliver properly rendered XHTML pages to the client at startup, but then have a seamless transition to AJAX updates after the page loads; and it's literally the same code running in both places. It's conceivable that we could take this further and automatically work in an environment without javascript, but for now, that's a special consideration for the app developer.<br /><br />At some point, I hope to open-source msjs, but for now it's proprietary, and attached to the product I'm working on. Still, I'd be happy to show you what we've done if you want to check it out sometime.Adam Wolffhttps://www.blogger.com/profile/00807592856743552793noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-90699661764155387222009-10-21T17:41:36.691-07:002009-10-21T17:41:36.691-07:00Thanks, Eric. I'll ping Adam. He's read ...Thanks, Eric. I'll ping Adam. He's read some of my other stuff, but he probably hasn't read this one.jjinuxhttps://www.blogger.com/profile/03270879497119114175noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-77082997254552694512009-10-21T09:14:45.738-07:002009-10-21T09:14:45.738-07:00You should check out what my friend Adam is doing ...You should check out what my friend Adam is doing at some point. I think he's going down an excellent that allows fine-grained choice and code sharing between client and server. <br /><br />As to DOM vs. innerHTML, I think it's mostly a pragmatic choice between performance (DOM bad sadly) and hideous code (innerHTML worse than DOM). I think it's OK to mix and match as you see fit. You can always migrate from one to the other if need be. Another choice is to wrap up common use of innerHTML in better APIs (sort of like ExtJS, which is "all client" but mostly uses innerHTML to construct DOM).Eric Blochhttps://www.blogger.com/profile/02699687256217967826noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-84818401531915105002009-08-24T04:39:55.344-07:002009-08-24T04:39:55.344-07:00> I see two approaches:
> 1. Whole UI is han...> I see two approaches:<br />> 1. Whole UI is handled in javascript using e.g. ExtJS. This is pleasant because server side just serves data and all logic is in one language but then it is invisible to google search<br /><br />The server still has to enforce some business logic.<br /><br />> 2. UI is a HTML generated server-side with mixed javascript. This is ok but html is mixed with language used server-side but it is searchable for google.<br /><br />You can have the server generate HTML, and place all your JavaScript in a static JavaScript file. That's what I'm currently doing. You might have to work a little harder to tell jQuery to bind your event handlers to any new content you fetch via Ajax.jjinuxhttps://www.blogger.com/profile/03270879497119114175noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-66148720318911348382009-08-24T02:37:24.618-07:002009-08-24T02:37:24.618-07:00I see two approaches:
1. Whole UI is handled in j...I see two approaches: <br />1. Whole UI is handled in javascript using e.g. ExtJS. This is pleasant because server side just serves data and all logic is in one language but then it is invisible to google search <br />2. UI is a HTML generated server-side with mixed javascript. This is ok but html is mixed with language used server-side but it is searchable for google.Godfryd's Bloghttps://www.blogger.com/profile/11420153032357814040noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-62366865182690605552009-08-22T18:49:39.784-07:002009-08-22T18:49:39.784-07:00very cool & good tip, thank you very much for ...very cool & good tip, thank you very much for sharing.JavaScriptBank.comhttps://www.blogger.com/profile/06101930747194876360noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-2631940985497542352009-08-21T17:19:55.902-07:002009-08-21T17:19:55.902-07:00I talked to Brandon Goldman who did the JS for box...I talked to Brandon Goldman who did the JS for box.com. He agreed that building HTML fragments on the server and rendering them on the client using jQuery is a good idea. He also agreed that building everything from scratch using DOM methods will cause the browser to keel over painfully. Last of all, we verified that jQuery is using code that at its heart uses innerHTML when you render a snippet of HTML from the server.jjinuxhttps://www.blogger.com/profile/03270879497119114175noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-16843715050411724682009-08-21T16:27:28.649-07:002009-08-21T16:27:28.649-07:00This conversation is also happening on the BayPigg...This conversation is also happening on the BayPiggies mailing list: http://mail.python.org/pipermail/baypiggies/2009-August/005275.htmljjinuxhttps://www.blogger.com/profile/03270879497119114175noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-26109773899779112312009-08-21T12:08:16.069-07:002009-08-21T12:08:16.069-07:00I asked vark.com about this problem, and I got thi...I asked vark.com about this problem, and I got this response:<br /><br />(From Aaron B./M/Philadelphia,PA, Re: **YUI (JavaScript)*<br />I'm not sure how it works specific to YUI, but in jQuery i usually setup an ajax complete event to rebind my event handlers to the new contentjjinuxhttps://www.blogger.com/profile/03270879497119114175noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-50499036514137516052009-08-21T11:55:23.916-07:002009-08-21T11:55:23.916-07:00The Rails JavaScript helpers generate JavaScript c...The Rails JavaScript helpers generate JavaScript code in your HTML that hooks into prototype and Script.aculo.us, which is loaded separately. This is convenient, but it loses the conceptual purity of having your HTML and JavaScript be separate. <br /><br />jRails is a Rails plugin that provides all those Rails helpers, but with jQuery. That's cool, but it still means there's JavaScript in the HTML.<br /><br />There's an intrinsic issue with how jQuery works. When you set up your event handlers, they only apply to the current content. They don't apply to any HTML that has been newly fetched by an Ajax request. There are a few workarounds. See: http://docs.jquery.com/Frequently_Asked_Questions#Why_doesn.27t_an_event_work_on_a_new_element_I.27ve_created.3F. I wonder if YUI has this issue as well.<br /><br />If you use jRails, when you request a snippet of HTML, the JavaScript for that HTML can come with it. This alleviates the jQuery issue. It's "impure", but effective and convenient.<br /><br />Of course, I'm making all this stuff up off the top of my head since I've only read the documentation at this point ;)jjinuxhttps://www.blogger.com/profile/03270879497119114175noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-18342359406809972132009-08-21T11:47:14.697-07:002009-08-21T11:47:14.697-07:00Good comment, Jeff.Good comment, Jeff.jjinuxhttps://www.blogger.com/profile/03270879497119114175noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-79115445717941947962009-08-21T05:19:40.905-07:002009-08-21T05:19:40.905-07:00DOM performance is very implementation-dependent. ...DOM performance is very implementation-dependent. innerHTML is *much* faster than programmatically building a tree.<br /><br />The problem with a JS-heavy interface is that you cannot control the performance of the browser; you *can* directly affect the performance of the server-side stuff.<br /><br />Therefore, I tend to have the server do any heavy lifting, and build the page in as much HTML as possible. When I need dynamic updates, I use injected HTML when possible. That way, JS can be relegated to UI effects and page updates, without putting too much onus on the client.Jeffhttps://www.blogger.com/profile/08755776134312245364noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-29488673418100230932009-08-20T22:52:01.988-07:002009-08-20T22:52:01.988-07:00metapundit.net, I think we're on the same page...metapundit.net, I think we're on the same page.jjinuxhttps://www.blogger.com/profile/03270879497119114175noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-31632330870865390212009-08-20T22:44:40.591-07:002009-08-20T22:44:40.591-07:00I was going to say that the big disadvantage to me...I was going to say that the big disadvantage to me of having the client build the page is that you don't really have "the web" anymore. This is fine for apps (like Gmail say) but not what you want if you hope to be searchable/indexable/scrapeable or hope to degrade gracefully.<br /><br />I tend to use the AHAH approach because I like that you start out with fairly complete html before js is involved. Asynchronous calls can send data as json or whatever but you are getting back a pre-rendered snippet of HTML and this leads to easy code reuse - the server side code that builds one page can probably spit out fragments simply by omitting the outer UI that surrounds the dynamic data...<br /><br />About the only times I break out of this sort of pattern is with large data sets (say datagrids) where json is significantly more compact than the pre-rendered html... I tend to think of this a more of an optimization technique.<br /><br />I wonder if part of the consideration in choosing techniques is people's language preferences. I don't feel nearly as solid in managing extensive codebases in Javascript as I do in PHP or Python so I'd rather do more work server-side and keep the client side code simple. Somebody with serious javascript chops might feel differently.metapundit.nethttps://www.blogger.com/profile/11729350517271714995noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-37841653757306705202009-08-20T22:24:48.228-07:002009-08-20T22:24:48.228-07:00I'm looking at mint.com, since that's one ...I'm looking at mint.com, since that's one of my favorite UIs. I tried turning JavaScript off. The page loads and looks right. That means that the markup is being generated on the server.<br /><br />However, you can't do much. A lot of things are no longer clickable. The search just ignores you. They really aren't putting any serious effort in making the app usable for people with JavaScript turned off. (That's not a complaint, just a useful thing to note.)<br /><br />Some of the tables do look like they are generated on the client. I double checked, and they are HTML, not Flex. It's beautiful, semantic HTML.<br /><br />The front page uses jQuery, but most of the app is built using YUI as mentioned here: http://yuiblog.com/blog/2007/12/05/mint/.<br /><br />I used Firebug to take a peek at the Ajax requests. Here are a few interesting Ajax requests that I saw:<br /><br />GET https://wwws.mint.com/app/getJsonData.xevent?task=categories&token=1030168I45XngvPJcRWiKS3xXU7ihu8b7DtH5wlzhWeQ&r=125083196334<br /><br />I'm guessing that one returns JSON ;)<br /><br />GET https://wwws.mint.com/detailAccount.xevent?accountId=&filterType=null&r=125083117490<br /><br />That one returns a snippet of HTML.<br /><br />POST https://wwws.mint.com/updateTransaction.xevent<br /><br />I wonder what xevent is. Notice that updateTransaction is *not* a noun ;) That means they're not all hung up on RESTful, resource-based routing.jjinuxhttps://www.blogger.com/profile/03270879497119114175noreply@blogger.com