The WebApp Wizard Web development made magical

7Dec/113

Web performance : further optimization

If you use tools like YSlow, PageSpeed and WebPageTest, you have probably already gone a long way about web performance.

The problem

Working on a website which had already good YSlow / PageSpeed ratings, I just wanted to push a little further: can I go up to 100/100 or get very very close to it? That may seem a bit pointless, I mean : who is going to be able to tell the difference? Will it make any difference for the server, too? Well, I don't know, but I wanted to try this for fun. Yeah, strange kind of fun.

So I looked at the metrics of my favorite tools, and PageSpeed told me something: maybe you should try to inline these scripts. What? Am I not supposed to make my scripts external (rule 8 of my bible)? In fact, not always. Making an extra HTTP request is contrary to rule 1, after all. A small file is often not worth a request. So we'd better make it inline, right into the page, to avoid unnecessary HTTP overhead.

But hey, I don't want to sacrifice my cleanly organized JS folder just for the sake of performance. So I had to come up with something that would inline my scripts/css when necessary, without me having to copy and paste the contents of said resources. More importantly, I want it to be dynamic: maybe my files will grow large enough to be worth an extra HTTP request again. So there is no way I manage this by hand.

The solution

Working with Smarty on this project, I decided to make a little Smarty plugin that would help me doing this. The idea is, based on a file size limit, to include scripts the "normal" way or to inline them.

I came up with two little plugins, one for JS files, the other for CSS files.

The results

Using these plugins resulted in one tiny script (a few hundred bytes) and one CSS, on some pages, to be included inline. To be perfectly honest, I didn't measure if there were any "real" performance improvement, and I don't know if it had such a big impact on performance from the user point of view. But it is obvious that this really tiny javascript file generated more HTTP overhead than its content, which is ridiculous. So inlining it can't be bad for performance either.

I was quite surprised by the results from the metrics point of view, though. My YSlow score jumped from 92 - 93 up to 99! Now, that's what I'm talking about: a pretty solid A-grade score :-) . I didn't expect much gain on the YSlow side, as it doesn't mention anything about inlining your scripts. I was even expecting a slightly lower score as YSlow tells you to make your scripts external. But it seems that it doesn't only rely on some stupid rules of thumb, but rather also on real performance.

99 YSlow A-grade score

The PageSpeed score also jumped from something around 91 to 98, which is less of a surprise, as I just applied its recommendations.

What about the server?

That's nice, but I still have a doubt about overall performance, or, more accurately, server charge. That's not really a problem in my case, as I don't have thousands of simultaneous users, so my server can take a little extra charge, but: looking at my plugins implementation, I wonder if this couldn't be optimized. Each time it is used, it checks the file size to decide whether to inline it or not. I don't know if it's a heavy operation, if there is some kind of cache somewhere in the system that avoids to make disk access each time, etc. And when it decides to inline it, it reads the file contents and writes it in the page. And neither do I know precisely how heavy this is.

Anyway, as I told, that's not much of an issue for me, so the overall performance isn't affected. And that's easy to understand: it's quite easy to shave off 100 from the front end (any HTTP request easily takes that much), but what is 100 ms on the back end? That's a whole lot of time. 100ms of PHP execution (or Ruby, or Python, or Java, or C) is huge: most operations won't take more than a few ms. So I think it's pretty safe to say that avoiding unnecessary HTTP traffic is worth a little extra work on the server. And that's the whole thing! I see people working hard optimizing their server code, just to save 3ms here and there. On the server side, that may be important if you have tons of simultaneous connections, but the user won't even notice. When you start working just a little on front end optimization, you save milliseconds by packs of 500!

More!

So, how could I get up to 100/100 on YSlow (and maybe PageSpeed)? Well, if I look at YSlow output, I see this:

Google Analytics preventing 100 YSlow A-grade score

Google Analytics script is not allowing me to get the holy 100, just because it doesn't set a far-future expiration date, thus making it difficult to cache for the browser. I don't know if there is any way to fix this, and I would be glad to hear there is one. I'm pretty sure that would be a great enhancement for the user, as this script download is not that fast.

15Feb/114

Form submit confirmation, fast and easy

Following some demands, I recently released a new version of Fast Confirm, to make it more easy to implement when dealing, among others, with form submission.

But in the hurry, I forgot to include some features that I developed earlier, thinking "I'll put that online soon". And I didn't. So here there are, the missing features that some of you wanted. With version 2.1.0, you can now tell your confirm boxes that you want them to be unique, just by setting a boolean on invocation.

There is another little thing that I wanted to introduce alongside with the better event handling. Since version 2.0.0, you can simply bind FC to a form submit event, with the "eventToBind" parameter. There is a little problem with that.

Typically, a form will look like :

<form action="action.php" method="post">
   Username: <input type="text" name="username" />
   Email: <input type="text" name="email" />
   <input type="submit" value="Create user" />
</form>

So what happens when the confirm box opens? It opens pointing on the form. That makes no sense. A form is usually not a visual element. You will more likely want the confirm box to be opened on the submit button, or maybe on a fieldset, or even on a input field. But directly on the form tag? No way. Or at least, that would not be very frequent.

So I added the "targetElement" parameter. It simply is a selector that allows you to specify on which element, within the form, you want the confirm box to open. For example, a ":submit" selector will simply make the confirm box open on the submit button of the binded form.

Have a look at the demos!

23Jan/111

Fast Confirm, Universal Paginate, reloaded

Hi everyone.

I finally had some time to re-work on my web projects. Since FastConfirm has been quite appreciated, I decided to take a few minutes to rewrite it a bit. The main concerns were about events management and manipulating it programmatically.

So I decided to take it directly to version 2.0, breaking some backward compatibility. Nothing bad, the usage remains almost the same, except for the "close" method.

So now, you can call:

$('.click_me').fastConfirm('close');

To close the previously opened confirm box.

OK, so this was for the method calling stuff.

You can also now completely delegate event handling to FastConfirm. This feature has been asked for several times, and I must admit I was not really satisfied with the previous plugin usage (well, in fact, you can still use the plugin like you did before). This is mainly useful for form submit confirmation. So now, you can simply do:

$('.confirmable_form').fastConfirm({
   eventToBind: 'submit'
});

And FastConfirm will take care of binding the confirm box on the submit event, allowing it if the user says "yes", canceling it if the user says "no". The same could be true with any event. The new eventToBind parameter defaults to false, which will result on the same behavior than before.

As a reminder, you previously had to write something like this to achieve the same behavior:

$('.button').click(function() {
   $(this).fastConfirm({
      onProceed: function($trigger) {
         $trigger.closest('form').submit();
      }
   });
   return false;
});

That's amazing. But there's one more thing ©. ;-)

The user is now able to close the confirm box by hitting the Escape key. This is the same as clicking "No" and provides a quicker way for the power user. A little detail can sometimes greatly improve the user experience.

I hope you will like this new, rewrote, cleaner and easier version of Fast Confirm. As usual, you can find it here.

Universal Paginate has also been rewrote in order to provide a better control over plugin internals. Methods can now be called the standard way:

$(list).universalPaginate('changeItemTemplate', newItemTemplate); 

for example.

Also, Universal Paginate has a new parameter which overrides ajax requests defaults when querying the server for data on page changes.

As this is the official jQuery plugin authoring recommendations, this rewriting will happen for other plugins, too. It will provide a better consistency and probably less bugs / shitty code.

Oh, and, by the way, these two plugins now pass JSLint. :-)

Last thing, I am very thankful to all of those who contributed to make we want to improve my work, whether with bits of code or simply with comments and requests.

2Nov/100

A new way to paginate

Hi.

Just a little post to tell you I released a new jQuery plugin, Universal Paginate.

It simply allows you to paginate any content, and is not limited to a type of list or table. You want to paginate simple paragraphs? Universal Paginate is here for you. A table? UP is here for you too! Any kind of list (dl, ul, ol)? UP is here, again.

It supports natively some advanced features like remote Ajax JSON datasources, jQuery Templates syntax, on-the-fly changing of the number of elements to display on one page, etc.

Check it out!

4Oct/100

Even lighter and prettier confirmation

Hi all.

I took advantage of working on a little Fast Confirm bug to enhance a bit the user experience. Facing my little confirm boxes, I told myself: these boxes don't stand out as much as they should. Don't disturb the user is nice, but we want him to answer anyway.

So I decided to use a few CSS3 features to make them a bit prettier, a bit more distinct from the rest of the page. So I added a shadow under the box and gave the buttons some color and depth.
I also wanted to get rid of the images I used to make the little arrows on the boxes. So I used some border techniques to achieve that.

The boxes looked like this before:

And now:

I hope you will have a nice time using it.

21Sep/102

How to ask politely the user

When working on a project, you often have to ask the user for information: choice, confirmation, etc. There are a few ways to achieve this: plain old confirm(), prompt(), or fancy dialog boxes (jQueryUI for example), or "inline" stuff.

After having tested Producteev for a while, I found out that I really like the "inline" way. So I decided to do it this way on my current project. I needed an easy, unobtrusive way of asking the user for confirmation. I didn't want to spend hours developing or debugging it, so I came out with this simple plugin: Fast Confirm. It allows you to ask simply and politely the user, without throwing a modal dialog box  in his face. Also, it clearly identifies the source of the confirmation so that there is no doubt what you're talking about.

As usual, there is a tiny demo page to show you how the plugin behaves on a simple use case. Feel free to try it out, download and play with it!

2Sep/100

jQuery plugins I never (OK, rarely) code without

Yes, another "X essential jQuery plugins". But this one focuses on utilities that will make your life easier, and not necessarily the user's one. It's not about shinny UIs here, but just about useful utilities. From time to time, it's also good to think about ourselves. :-)

Well, no more talking, let's go straight to the point.

Livequery

Definitely a must-have. Ever had to re-bind some event handlers when doing dynamic DOM injection? Well, throw away your aspirin and download this plugin. It will save you some time, headaches, and performance. I can already hear: "why not simply using jQuery.live()?". Because Livequery supports a larger number of event types (but it tends to be less and less true) and allows to bind handlers on element creation and removal as well.

ClassLike

Ever wanted to store some data on DOM elements? Well, there is jQuery.data() when you want to attach data to your DOM elements from your JS code. For all other cases, there is ClassLike. ClassLike allows you to easily match and retrieve parts of classnames with regexps. You could have, for example, elements wearing the class "colnumber-X" where X is a number. And you want to get this number out of the classname. Well, ClassLike does it for you with a simple regexp.

jTemplates

jTemplates is not the kind of plugin you will need in every project, but it is still so useful that it deserved his place here. Basically, it's like Smarty, but in JS. Very useful for writing widgets, with live refreshing for example.

Form

How can I not mention the Form plugin? It simply allows you to control your form submissions, do some verifications before submitting, and more.

jQueryUI

Quite a heavy plugin, but really useful, from animations to advanced controls, dialogs, sliders... A must-have too. I won't go any further with this one, everybody knows about it.

Of course, there is no need to blindly add these plugins to your pages, but I think they solve frequent problems, and they deserve, at least, a try. You may just love them. :-)

30Aug/100

Sliding Panel v1.2.0

I just released a new version of Sliding Panel, to allow more positioning possibilities.

Now you can use the offset parameter to position it right where you want it to be, for example, you could place it bottom right either by using:

position: 'right'
offset: {bottom: '0px'}

Which would place it at the bottom right, and make it slide horizontally

Or:

position: 'bottom'
offset: {right: '0px'}

Which would place it at the bottom right, and make it slide vertically.

You can also combine bottom and right offset for example, to fine tune the position, and, maybe, make the tab appear outside your container.

Feel free to try it out!

24Aug/107

Why I don’t localize my jQuery plugins

That's a question (I know, the title is actually the answer to that question) I've asked to myself yesterday. I mean, why do other people deliver jQuery plugins in a full-featured package, including localizations, and I don't? Take jQueryUI and the datepicker date formats for example.

At the beginning, I chose to deliver only the jQuery plugin file, and from now I will prefer to deliver a little package containing a full example (HTML + JS + CSS + PHP - if needed -). But I don't plan to deliver localizations, more than ever.

Why?

First, I don't pretend to know other languages than French well enough. That's already difficult to find the right words in your own language when it comes to describe really shortly, often in only one or two words. I prefer to let you do this job, you will probably be better than me. :-) I release my plugins in English by default (and not French) only to make sure most people will be able to understand.

Second, I have always found that already localized plugins were difficult to blend in an existent architecture. Mostly, localized plugins provide simple javascript files containing variables corresponding to the different strings, in each language. What if you want to get the data from your server? What if you want a more dynamic way to do that? And even when you're in a simple-javascript-file flavor (which I personally like), you've got work to do by yourself. Maybe you want to get all your localized strings in the same place, or maybe you would have organized that another way. OK, all that is not that difficult, but it's always a little pain anyway.

That's why I only set the basics for internationalization. All the user-displayed strings in my plugins are customizable, so you can simply pass the localized strings in parameters. The way you get these localized strings is your business, even if I do recommend a few ones.

2Aug/100

Sliding Panel v1.1.0

In reply to Michael Teague on this post, I decided to make a few improvements to the Sliding Panel jQuery plugin.

The main improvement is about positionning. Now you have the ability to set a sliding panel at the top or bottom of your page, in addition to the left/right options. Everything is managed by the plugin to ensure a good experience: if you choose to set your panel at the top of your page, then it will slide upwards. If you choose to set it at the bottom, then it will slide downwards, etc. In the same way, if you put the panel at the top or bottom, the default tab text will be horizontal instead of vertical (default behavior) for the left and right options.

It has been tested with jQuery 1.3.2/jQueryUI 1.7.2 and jQuery 1.4.2/jQueryUI 1.8.2, so it should work just fine.

Sliding Panel v1.1.0 is out!