Progressive enhancement, behavior when pages are not fully loaded yet - javascript

I'm developing sites using progressive enhancement implemented completely in jQuery.
For instance, I'm adding onclick event handlers dynamically to anchor tags to play linked MP3 files "inline" using SoundManager and popping up Youtube players for Youtube links, through $(document).ready(function()).
However, if the user clicks on them while the page is loading, they still get the non-enhanced version.
I've thought about hiding the relevant stuff (via display: none, or something like that) and showing it when loaded, or putting a modal "loading" dialog, but both sound like hacks.
Any better ideas? I feel I'm missing something completely obvious here.
Regards,
Alex

I haven't tested this, but you could try live. The thinking is that you could put your click handlers outside of document.ready so they get executed right away. Since live uses event delegation to achieve it's functionality, you don't really need to wait for the DOM to be ready, and any clicks that are made while the page is loading should still be captured by the event handler.
If that doesn't work, you could try putting the Javascript script tags directly underneath whatever they need to bind. It's not pretty, but it will pretty much eliminate the problem.

Assuming you have used good judgement and people are falling for the non-enhanced version just because the delay is too long then I would use CSS to disable the controls. The CSS will load almost right away. Then using Javascript I would toggle the CSS so the controls are re-enabled.
However, my first reaction is that if the user can click it while the page is loading, then your page or connection is too slow. However, if this is seldom the case--less than 1% of the time--then you can shrug it off as long as the user can achieve his goal, that is listen to his music. I say this because once the users realizes that a better experience awaits half a second later, he will usually wait for Javascript to render and then click.

I take the opposite stance from aleemb regarding using CSS. If you use css to disable the controls, then anyone who has javascript disabled or is using accessibility software will be unable to use those controls without disabling your stylesheet entirely.
You could use a very small inline javascript right before the closing body tag to hide the elements via js really quickly. If it's inline and doesn't have to load external resources it will be very fast, generally faster than a user can click.
However, I do agree with aleemb that if your users are able to mentally process the page and make it to the control they want to click before your js is loaded, there's probably a deeper problem with the way your page is loading. Look into ways to decrease load time: compressing image files, gzipping html/css/js files, minify your javascript, combine images into sprites, etc.

I'd suggest following Paolo Bergantino's advise - event delegation is the way to go to avoid the problem altogether.
I had a similar issue where event delegation couldn't do the job - you can read about that here.

Related

Loading image is shown too late for users with slow connection

The issues is with existing ASP.NET MVC 4 project. The View itself is not that big but there are also several service calls and what happens is that people with slow internet connection reports that for some period of time when they request the page it stay unresponsive, so they don't know if the content is loading or something went wrong.
So in general, what I need is a way to show a loading image as the very first thing from this page (or at least fast enough) so even if it takes some time for the browser to download the full content, at least the user will know that something is going on.
However it seems that this is not as trivial as it sounds. I came up with two ideas, one was already proven to not work in all cases and the second is also something that many people doesn't recommend.
What I've tried was to use pure JavaScript in the <head> tag like so:
<html>
<head>
<script>
document.write("<div style='margin-left: 50px; margin-top : 50px;'>LOADING...</div>");
</script>
</head>
Of course the styling is just to get the idea. This seemed like it was working until recently when on a minor build of IE 11 the page broke which after some investigation was proven to be due to the usage of document.write() inside the <head> tag. Even though this seems to work on most browsers and versions the fact that it's a potential danger requires a change in the approach.
The second idea is pretty similar to this, again - writing directly in the <head> tag but this time instead of using document.write() just putting the html markup directly there. From what I've read this is also a recipe for disaster so I don't even want to try it, but those are the two ideas that I could came up with. Everything else just doesn't work for slow internet connections since the mainstream solutions relays on the fact that some part of the DOM is already loaded so you can use it to apply behaviour/style.
I hope I'm not the first one that got this problem so I would appreciate any suggestion on how to solve this issue. Since I am using ASP.NET MVC 4 there was an idea to use a dedicated controller with view which to get called first just for the sake of showing the loading image and then moving to the requested view. Even though this idea seems interesting I didn't have the time to think it over, it also sounds a pretty complicated, but anyways, all help will be appreciated.
When faced with the same issue, we did as you mentioned: Load a super-light-weight page first with a tiny loading icon & "Loading..." text, then called back to the server to pull down the heavy content in chunks using ajax.
If you content is really heavy, it's also worth mentioning that you need make sure you have gzip compression turned on at your web server layer also.
Don't block the rendering of the DOM. Load the page and call your scripts right before the closing body tag and attach to an event like DOMContentLoaded or window.load (if you're using jQuery, that would be $(document).ready). In other words, you should allow the page to load completely, even if it's empty, before running any of your JavaScript.
Then, don't worry about writing the "Loading" div dynamically. Just include it in the rendered HTML and hide it initially. The first thing your JavaScript will do, before issuing any AJAX calls, is to show this "Loading" div.

Does dynamically prefetching a resource using DOM injection work or make sense?

This is largely a theoretical question, for which I do have a practical purpose. I first am looking for some conceptual answers before diving into practice, as perhaps the idea itself does not make sense.
Imagine a slideshow that is entirely javascript-based. Users see a large image on their screen and click to move to the next large image. Upon clicking, the next image is loaded and inserted into the DOM, replacing the previous one.
I recently learned that prefetching directives can help in speeding up the loading of resources that are very likely to be used next. Note that I said resources, not pages. The slideshow is a single page.
In an image slideshow, it is very obvious that it is likely that the next image is needed, thus if image1 is on screen, I could dynamically add this to the DOM:
<link rel="prefetch" href="http://img.mysite.com/img2.jpg">
My questions regarding this idea:
Would it work at all? Do browsers accept this directive when it is dynamically inserted in the DOM at run-time? Would it trigger the prefetch?
Is there a possibility of timing conflicts, where if prefetching would indeed work, it did not finish in time before the use does the "load" without prefetching? Obviously this can happen, but will it have unwanted side effects?
Will specific events such as image onload still work correctly, or are they never triggered in the case of a successful prefetch (assuming it works at all)?
I did a lot of searching but I am unable to find answers on this specific situation of dynamically injected prefetch hints.
onload always gets triggered, even if the image is coming from cache. You do not have to worry about timing effects or race conditions, any such behavior would be a browser bug.
As mentioned in comments, rel=prefetch is not the only way of achieving pre-fetching. It works though even when dynamically inserted into the DOM. After all, you could fetch the image without the prefetch attribute and hide it.

To hide or to remove html loader?

We discussed this topic with colleagues... Is it better to hide/show or add/remove GIF loader in HTML using JavaScript? We came to this:
Hide/show pros:
showing the loader does not require its creation using JavaScript so it should be faster; Is negligible?
is simpler
GIF picture is readily available
Add/remove pros:
removing the loader (thus DOM element) should speed up querying/working with DOM elements
if your site has a lot of loaders, it is possibly slower to download; Can negate using HTML5 Application Cache?
lazy loading - GIF picture needs to be downloaded only if it is necessary
Are there more pros/cons? How do you work with GIF loaders? Which technique do you recommend? Lets assume two scenarios:
There are multiple loaders on the page...
a.) using a single GIF picture
b.) using more GIF pictures
In my experience, hide and show is a better approach because it doesn't mess with the DOM. There probably isn't any performance benefits but if you remove it from the DOM and then re-add it later it is possible to lose JS event bindings unless using jQuery's .on() event handler.
May I also add that while GIFs are a long supported feature of most browsers, CSS animations can create much smoother loading indicators and have smaller file sizes, too.
The answer is, there is no easy answer to your solution. Is it a simple web app? is it a HUGE application that needs to have an animated gif attached to it to load?
If you have a larger application:
simply preload the animated gif (either using modenizr.js or css) and then you can simply make it the background of a div that you can append to anything at any time and remove it gracefully. (extremely fast, saves memory). the downside is that if you are not very experienced chances are you might forget to remove it correctly.
in your css
.loading{height:100px;width:100px;background-image:url(loader.gif);background-position:center center;}
this is now your "loading div" and css will load the background image into memory.
next
what ever ajax div you have (lets assume it is #content)
$("#content").append("<div class='loading'></div");
then whenever you want to get rid of it ( probably on the ajax return call)
$('.loading').remove();
I think this piece of coding resolve the problem:
$(window).load(function() {
$("#loader").remove(); //call the image with id like #loader
});

What is the best approach for a widget-container page - Ajax or iframe?

I need to implement a page of which many parts are dynamic widgets. Which widgets are loaded depend on user choice and are not known before hand. Each of these widgets include some HTML, and some javascript code (to initialize and attach event handlers on the HTML elements). I am wondering what is the best approach to implement such a page and widgets.
AJAX. I could construct response with some HTML followed by a <script> tag. Although returning js code in AJAX is not recommended, I found this works for me (the script get executed, with HTML widget properly initialized and handlers attached). An alternative is to include an 'all-included' script in the container page. In this script I wrap each of widget-specific script in a function, and when the widget is dynamically loaded, I call that function. However, this way I fetch a lot of js code that may not be used.
Iframe. I can also return the widget as a standalone HTML page to be loaded in iframes. This solves the javascript problem, but I need to make cross-domain calls to interacte with other part of the container page.
I think this should be a common problem faced by web developers. I am new to web development, could you share some 'best pratice' tips for my case?
You should be going ahead with jquery+ajax.. There are lots of drawbacks with iframes. Although you could handle each plugin in separate page and avoid any kind of conflict, usablitity becomes a great headache..
In the time of everything going HTML5 based to support mobile platforms, iframes are hard to cuztomise for mobile screens. Moreover iframe takes out the entire apple users as iframes are not supported by apple devices..
jQuery + Ajax(HTML5) along with CSS3 should be the way to proceed..

How can I avoid seeing the rendering of Cufon font replacement tool while loading a page?

I've published a website and every page has an or element with Cufon (cufon-yui.js) and sometimes while the page is loading , the visitor can see the text replacement tool doing it's job. It looks bad, some users are asking about it.
Why would that be happening if I'm using it (cufon) like anybody else and I don't' see this text rendering issue happening in most sites.
Also, there's an issue happening as well, with the Hyperlinks that are using Cufon.
Sometimes the cursor (a hand that appears for hyperlinks) disappear , it's bizarre.
Adding the following to your css should solve the issue:
.cufon-loading {
visibility: hidden;
}
use one of the google web fonts or typeface/
I've just started looking at Cufon, so I'm not sure I'm qualified to give an opinion, but I've read the IE has (or had) rendering issues and that you needed to add <script type="text/javascript">Cufon.now();</script> to the end of your body (right before the </body>. If you are running any other heavy scripts on the page, you might want to put them as low on the page as possible and place the Cufon.now() right above those scripts (place Cufon higher in priority). If that doesn't work, try hiding your Cufon elements with JS as soon as the DOM has loaded (visibility:hidden) and then unhide them when the onload event fires (though I'm not sure that's much better than the text flickering).
Use something better?: http://reisio.com/examples/webfonts/
(if you worry about distribution legality, replace your fonts with any of the numerous free clones available all over the internet)

Categories