One of the cool things we released along with the Kendo UI Winter Release last week is the brand new Kendo UI Music Store demo . It’s a complete, end-to-end demo designed to show many of the pieces from Kendo UI Web, DataViz, (and soon Mobile) working together in the context of a “real app,” along with the necessary server code to expose JSON web services and load and persist data in a database. It is based on a Microsoft demo originally created for ASP.NET MVC, but the concepts are universal. Our plan is to eventually provide alternate implementations of the server code in Java and PHP so you can view the demo in the language you prefer most.
The complete source for the demo is available on GitHub .
This demo also happens to be one the top requested features (more than 480 votes!) on the official Kendo UI UserVoice feedback portal ( feedback.kendoui.com ). We’re stoked that this demo delivers on one the major things you guys (our customers and community) have been demanding for a while.
So, we’re happy with the demo, but in the initial release it had a problem. It had FOUJUI .
More than a year ago, I coined "FOUJUI" to described a problem common to applications that rely heavily JavaScript UI. In short, FOUJUI occurs when you rely on JavaScript to build part of your UI (render HTML/apply CSS) after your page loads. Since JavaScript takes time to download and run, users potentially see a version of your page "pre-JavaScript UI" and then suddenly (after your scripts run) they see the "correct" layout.
The problem is easy to ignore since it doesn't impact the function of an app or site, but it's ugly, distracting, and not the kind of first impression you want to give your users.
The first release of the Kendo UI Music Store demo did exactly this. Because Kendo UI Web widgets were used with a mix of server-side HTML rendering, there was a brief flash of the uninitialized HTML (as rendered on the server) before the JavaScript ran and the final layout kicked-in. You can see the effect in the GIF below:
This is a perfect chance to fix FOUJUI and show one technique for solving the problem in your own apps.
I’m a big fan of fixing FOUJUI with opacity animations. The technique is simple and the effect looks very nice. In general, the idea behind this solution is:
Why opacity? Why not use something like “display:none” or “visibility:hidden”? Two reasons:
The first step to fixing the problem in our Music Store demo, then, is hiding all portions of the UI that need to be initialized by JavaScript. You can, of course, hide ALL of your page UI (similar to a loading screen), but that’s a bit heavy handed for the web. I’d prefer to just hide the areas that need initialization. Done well, odds are many users won’t even notice the loading effect, which is a good thing!
Referring to the GIF above, we can see one of the worst FOUJUI offenders is the Menu. In the Music Store (as in many apps), the menu HTML is rendered dynamically server-side making the sub-menu items appear as visible un-styled links until Kendo UI is initialized.
We should do two things for this type of situation to provide the best loading experience:
The code required for these two techniques is quite simple:
<!--BEFORE--> <ul id="menu" data-role="menu"> <!--AFTER--> <ul id="menu" data-role="menu" class="k-widget k-reset k-header k-menu k-menu-horizontal" style="opacity:0;">
It’s a little more work, but it is worth it when you’re optimizing for FOUJUI. If you’re not sure how to build the HTML by hand, just inspect elements using browser dev tools to see what JavaScript normally does to build the final widget HTML and CSS.
For the rest of the elements on the Music Store homepage, I apply more of a catch-all FOUJUI opacity setting:
<div id="body" style="opacity:0;"> <!--Server-side view engine code--> @RenderBody() </div>
Next, I need to setup my CSS transition so that the eventual opacity change will be animated by the browser. Adjusting the length of this animation will determine how subtle or “obvious” the loading animation appears.
/* Global CSS Transitions ------------------------------------- */ * { -webkit-transition:opacity 1s; -moz-transition:opacity 1s; transition:opacity 1s; }
I’ve used the universal selector to apply the transition to all opacity changes in my app. It has no perf implications (
as I discussed previously
), and it’s more convenient than explicitly targeting all CSS selectors where I want this transition to happen.
Only one word of caution:
if you are using opacity to do other things in your app, the universal selector approach could cause some unintended transitions.
Finally, I just need to run some JavaScript to change the opacity of these now hidden elements from 0 to 1 once I know the necessary JavaScript UI initialization is complete. The animation will happen “for free” thanks to CSS transitions. To keep things simple, I can just put this line at the bottom of my page, after all other JavaScript has run, implicitly ensuring the opacity change happens after my JavaScript UI is ready:
<script> //Place this at the bottom of the page (after all other scripts) $("#body").css("opacity", 1); </script>
Ideally, you want to run this code as soon after JavaScript widgets are initialized to minimize the time it takes for users to see your UI. In the case of the Music Store, I use the “bottom of the page” technique for most elements, except UI widgets in the page header (like the Menu). For the menu and search box, I run very similar code in the JavaScript module that initializes those Kendo UI widgets.
(If you want to see all of my changes, exactly as I applied them to the Music Store demo, here is the git commit showing exactly what I did .)
After these simple change are applied, our FOUJUI is gone! Now, thanks to some extra hand-coded HTML and precise opacity settings, users see most of the UI when the page loads, and the pieces that need initialization are pleasantly displayed when they’re ready. The final effect can be viewed live on the demo site , or you can see the result in the GIF below:
I said it once in this post, but I’ll say it again. Don’t ignore FOUJUI!
It’s easy to do. If nothing else, the Music Store demo proves even teams with awareness of the problem and solution can overlook this obvious detail. The problem is easily solvable if you take the time to polish your final result.
As more UI moves to the client (instead of being rendered on the server), apply techniques like this so the web remains a beautiful place and not a frustrating mess of “now you see it, now you don’t” HTML. Got it? Good.
Todd Anglin is Vice President of Product at Progress. Todd is responsible for leading the teams at Progress focused on NativeScript, a modern cross-platform solution for building native mobile apps with JavaScript. Todd is an author and frequent speaker on web and mobile app development. Follow Todd @toddanglin for his latest writings and industry insights.