4

I'm trying to adapt a jquery-ui codebase to use RequireJs, and I'm deploying it on a much slower (but scalable) virtualized cloud service than the dedicated host I was using before.

My pages are by default an ugly catastrophe of vanilla HTML. The only thing that brings this mess to life are calls to JavaScript functions, which give it the appropriate tab controls and layout. In fact, the page is laid out long and vertical...one section after another...before I call the .tabs() function which folds them up into a single unit with a horizontal control.

(Fairly confident I'm "doing it right" in the jQuery UI mindset. By not building the whole UI through code to start with, it can be at least looked at with JavaScript disabled. Though I doubt anyone is still using Lynx, there are issues of accessibility...or making sure your content is analyzable by search engines. I'll spare you my old man speech about how this is an absurdist way of achieving content/UI separation. :-/)

When I was using <script> tags to load my 3rd party library dependencies and the $(document).ready to run the jQuery UI voodoo, the user never saw the vanilla ugly HTML. Now that I'm using RequireJs, the page.js file lags and loads asynchronously after the HTML...waiting for libraries that aren't really needed for the DOMready handling. The slower server makes this look really awful.

I could of course use CSS styling to hide the ugliness at the outset, and overlay with a "Loading..." graphic until the UI was ready. That's what came to mind first, and a similar approach is suggested here:

Jquery UI interface looks ugly before document.ready

(Note: It seems like such a common problem that I'd almost think there'd be a RequireJs plugin that went ahead and did this. Is there?)

In any case, I didn't seem to have to worry about this before...and I'm wondering if I'm missing some simpler solution. How do you keep users from seeing "ugly" HTML if you're using RequireJs?

Community
  • 1
  • 1

3 Answers3

3

I'm with you that you should do some CSS wizardry and then in RequireJs's "kick it off" script, hide it. You should also consider SEO impact and JavaScript disabled scenarios.

Remember, at the end of the day, it's just HTML, CSS, and JavaScript. What ever templating / code generation system you use to get you there, at the end of the day, it's just HTML content, styled with CSS, and animated with JavaScript.

robrich
  • 13,017
  • 7
  • 36
  • 63
  • Thanks for the vote of confidence, although there is this trend where I feel like I'll only ask a StackOverflow question when I sort of already know the answer. Maybe I should use it in more of a "lazyweb" spirit and ask questions *before* I think about them. :) That said, think this could/should be done as a requireJs plugin? – HostileFork says dont trust SE May 15 '12 at 21:18
  • :D One of the benefits of StackOverflow is that you start thinking through the problem in much clearer terms -- http://en.wikipedia.org/wiki/Rubber_duck_debugging. I say don't abandon this great critical thinking. – robrich May 15 '12 at 22:07
1

I'd argue that it makes more sense to use something like node-browserify to do all of your Javascript module requires and then stream down the single JS file to the end-user.

Why go through all of the TCP handshakes and HTTP headers to get the same thing at a much lower performance when the client is obviously not intended to be run in an offline mode?

Hey Doc, it hurts when I do this.

Well, then don't do that!

Community
  • 1
  • 1
  • My usage of requirejs is based on a desire to get a uniform handling between node.js and browser, and here you are challenging that decision. I'm already addled enough. :) But thanks, I will look at it. My understanding is that RequireJs can (if you and your library dependents follow the right process) fold all your javascripts into one file, and I was hoping to get there down the road. But it's one painful step at a time. See: http://stackoverflow.com/questions/10302724/calling-methods-in-requirejs-modules-from-html-elements-such-as-onclick-handlers – HostileFork says dont trust SE May 15 '12 at 21:21
  • Well, I'll have to admit a bit of bias since I've written a couple of Node.js libraries, but I think the CommonJS ``require`` syntax (adopted by Node.js) is much more sane than RequireJS's system. Why? Module loading is generally an initialization step, before any action occurs. RequireJS turns it into an asynchronous process since all script loading on the browser *is* async, but if you can't do anything until it's all loaded, **one** HTTP roundtrip makes more sense than 5-10. You're probably not going to use RequireJS's *one* advantage: dynamically load a module while your page is running. –  May 15 '12 at 21:27
  • Second point: the browser is going to pause rendering while it's loading a `` –  May 15 '12 at 21:31
  • I know this is chatty, and StackOverflow doesn't like comment-chatter. But I was in a debate once with people about Git vs. Mercurial and I said "git will win, regardless of merit" (although I happened to believe in Git's merits for intended purpose). I feel like I turned out to be right and the people I was advising who chose mercurial shot themselves in the foot, in a sense. So I'll ask: regardless of the merits or failings of requirejs, will it "win" anyway? Or is the guy who made it just very well spoken and a good web designer, and it will fall by the wayside in 1-2 years? – HostileFork says dont trust SE May 15 '12 at 21:35
  • Neither will win. [ECMAScript's module syntax will win in ES6](http://wiki.ecmascript.org/doku.php?id=harmony:modules). I will note, though, that while the syntax looks like Python's it's basically just a syntactic variant of the CommonJS ``require`` function. RequireJS will die shortly. –  May 15 '12 at 21:39
1

I'm having the same issue with Jquery Mobile and RequireJS.

I first tried following this tip and hid the "ugly HTML" by adding CSS:

.requireJS-init { visibility: hidden;}
.requireJS-init.done { visibility: visible;}

and assiging .requireJS-init when the page fires up and removing it once everything has been loaded by adding another class done (you could remove the initial class, too I guess).

However this causes two problems:
1. Users might have a blank page for a while depending on your content being loaded
2. IE8 fails, because (in my case) Jquery Mobile tries to focus on elements while they are still hidden.

I tried moving around the class form HTML to BODY to elements holding the page content, but nothing really worked.

A much easier CSS-only solution is this:

.ui-mobile-rendering:before { 
    width: 100%; 
    position: absolute; 
    top: 0; 
    bottom: 0;         
    left: 0; 
    right: 0; 
    display: block; 
    height: 100%; 
    z-index: 0; 
    background:#fff url(../images/ajax-loader.gif) no-repeat center center; 
    content: "" 
    }

The ui-mobile-rendering class is on the body while JQM does it's widget enhnacements. Once the page is done, the class is removed. By adding a fullscreen :before - in this case with the JQM loader as background image - you hide everything on the page until it's rendered. No need for visibility:hidden, IE8 doesn't complain (thank good, IE8 and FF3.6 know :before).

frequent
  • 27,643
  • 59
  • 181
  • 333
  • I missed this answer back when I had this problem, and as it so happens it's been 2 years until I've actually gotten back around to addressing it (see [blackhighlighter.org](http://blackhighlighter.org)). I put the style on but it doesn't seem to do anything, am I doing it wrong? – HostileFork says dont trust SE Mar 20 '14 at 11:38
  • let me check again if this still works. Has been a while since I looked at it. Will repost here. – frequent Mar 20 '14 at 14:17