Friday, March 4, 2011

How to Optimise a Website

I've done quite a bit of experimenting and research with website optimisation awhile back, and I thought I'd care to share them with you.

Now, I just want to say that, with these days being mostly high speed internet users, browsers updating their JavaScript engines, and CPU processing being generally fast, this will probably sound like old news (unless you never researched it). Well, you're right! However, as a beginning web developer, I didn't know this issue existed or how to follow up with general optimisation. So I'm glad to display this to the new folk that may not have a clue about it. Archaic methods may be, well, old, but they still work to some extent (especially with a larger number of site visitors).


Why isn't this site optimised then?

Now, I do own some webspace somewhere a friend of mine is lending me for free, but I only have this blog for now, as I really don't have something amazing to show the world just yet. This leads to some possible questions like "why isn't your blog optimised then?". Well, honestly, I am not really trying to attract much attention with it right now, as I previously stated, I don't have a whole lot to show the world just yet. I just rather plug-in play for the time being, expressing my ideas quickly and somewhat "neatly" enough to get by without wasting time on my real projects (game design alone is no easy feat, mind you!). Also, it's not really my website (google's free blogging webspace) where I can customise everything from the bottom up. When the time comes, I will have a website, and it will be optimised, but that isn't today. Anywho...let's get to the actual optimisation stuff.


The misuse or overuse of JavaScript

Here's the biggest issue with most websites...the misuse or overuse of JavaScript. Yes, browsers today have optimised their JavaScript engines to make them run a lot faster than they have in the past, however, this doesn't stop you from doing some basic standard optimisation, as any overuse of JavaScript means you're going to still either overload the CPU's processor or feeding extra information that isn't needed. Now if you want to make HTML5 games (which require JavaScript), that's fine, but it doesn't prevent you from following a couple concepts like "embedding scripts externally". Here's some tricks and tips you can do to keep the code bloat from occurring.

  • Embed scripts externally: <script src='myJavaScript.js'></script>
When we embed scripts externally, we have the opportunity to reuse them, instead of making every page load extra scripts embedded internally in the page like <script> /* do JavaScript code */ </script>. This is bad, don't do this. It not only makes it harder to read your webpage code, but it can never be recycled on your webpages, "bloating" your entire site. Which brings me to the next point.
  • Make your JavaScript external files modular
Now this is a bit harder to explain to those who don't understand programming practices such as Object Oriented Programming (OOP) that teaches these type of practices like modularity. Modularity basically means, make your code behave in a way that it can be reused at another useful given point of time. Let me give a website related example:
Joe Somebody has three script files, 'ImageGallery.js', 'WebGame.js', and 'DropDownMenu.js'. Joe Somebody realised, if he just threw them all in one file called 'MyWebsite.js' at once, he would be forced to use them on every page, even when they're not explicitly shown. He knew if he broke them into realistic branches, he could load each file separately at a different given time on a different given page. This is modularity, breaking things into realistic functionality so when they're called, they can function in multiple places, but without being forced to use them in those same places.
One can actually take this a step further if they desired. However, going too far down the chain can sometimes lead to design confusion, and it's a bit beyond the scope of this writing. Feel free to explore this topic in more detail, as, like I said, it is possible to break these files down and take it a step further, providing less code bloat by only calling what you need out of a script.
What does compress here really mean? It specifically means, remove unnecessary parts to one's code (such as a MyScript.js) such as whitespace and a few other things to "shorten" your code. I don't recommend blindly taking this practice manually, as it is stupid to program so ugly in spaghetti code. Let programs like GZIP handle this for you. GZIP can even handle your HTML, CSS, any type of code in a form of text. Don't GZIP everything, such as images, as I'm about to show, a much better way soon.
  • Quit using JavaScript for everything!
Don't get me wrong, JavaScript is awesome, and I use it a lot, specifically for web games. However, for general website design, it's not always needed. Sure it looks cool, but don't overdo it to the point where embedding JavaScript becomes a routine task to replace HTML or CSS functionality. Appearing fancy vs. bogging down the page is definitely something one needs to take into account, as not all users will care about the fanciness on slower connections. Even faster connections can appear to be slow on peak times or multi-tabbing in browsers. So please take my advice, a dynamic drop down menu can still be just as cool as a static (not dynamically changing) menu at the top. Just understand that most users won't stick around on a webpage if it doesn't bother loading in a very small time period. Users want something NOW, as they expect it even more in the future. They wouldn't have bought a fast internet connection to have to load slow on only your website.

Image optimisation


Now before I jump into this subject, I do want to make the reader aware that image optimisation isn't exactly a bottleneck in page loading. Today in these ages, image caching, or storage for easier access within the browser, prevents a browser from downloading the images again. They are grabbed once and they're done (unless you manually clear your cache of course). However, having 2mb images isn't exactly good on your bandwidth either, unless you really think you can afford letting 2mb per user to drain your available payed bandwidth (which is technically never as unlimited as servers advertise). I'm going to explain when to use filetypes like PNGs, JPG/JPEGs, and GIFs as a rule of thumb. Also, for further brevity on web design, all images intended for use for the internet needs to be 72 PPI (pixels per inch), as this is a web standard.

A PNG is called a portable network graphic file. It's intended use is for Internet is raster (made up of pixels, and is totally different form vector graphics) graphics that are typically small and can provide transparency effects, and can provide LOSSLESS (meaning no loss of image data) under compression. Here's what people don't really explain, "how small?". I personally like to use the rule of thumb to stick anything that's 64x64 (pixels), as a PNG or GIF. Anything between 64x64 and 128x128, I simply check whether a JPEG or a PNG/GIF is the best in terms of low size.
One can compress a PNG even further, by stripping unnecessary data information (like text strings) with a program like PNGCRUSH (which I use all the time for Linux), which can save you, up to or more, ~25% file size. So if I had a PNG file that was say, 4 KB. I just knocked that image size down to ~3KB (I would assume more typically for me). If you want to lower your image size even further, strip the image of transparency (this is unnecessary data that can take up quite a bit of size), lower the image size to a reasonable amount (for whatever your intended purpose), and lower the color count to something reasonable (8-32 colors is a good margin, with the lower being even greater). The lower the color count and size though, the greater the possibility it is most suitable for a GIF, which lowers the file size even further. I personally like to play around with comparing my image file type sizes to get the best result.
On the subject of "how to lower a color count", I personally use GIMP's "posterize" setting under the Color tab. You can then adjust (to lower only) from 1-256 color that you want. You'll have to hit the undo button if you don't like the result, but there's also a preview option while doing this, so there isn't much to worry about. I am not sure about Photoshop or other graphics manipulators, but I believe Photoshop does have some type of color limiter as well (I mean, why not?). Try searching google for the subject if you can't find it.
Here's an example of a experiment I played with using 3D rendered images (lots of a color and detail) on an old browser game project from back in 2007:
  






FileType:             PNG
FileSize:              4108 bytes (~4.0 KB)
Resolution Size:  64x64 (pixels)
Transparency?     Yes
Color Count:       +256
Compressed?       No
Comment:           This is the original file.










FileType:             PNG
FileSize:              2254 bytes (~2.2 KB)
Resolution Size:  64x64 (pixels)
Transparency?     Yes
Color Count:        12
Compressed?       No
Comment: File size lowered ~1.9 KB by simply lowering the color to 12. There's no significant image difference as you can see. Note, always keep the original file so you can go back and convert it to a different color count for "higher quality" if ever desired in the future.









FileType:             PNG
FileSize:              1820 bytes (~1.8 KB)
Resolution Size:  64x64 (pixels)
Transparency?     Yes
Color Count:        12
Compressed?       Yes (PNGCRUSH)
Comment: Lowered the size ~400 bytes by simply compressing.









FileType:             GIF
FileSize:              934 bytes (~1 KB)
Resolution Size:  64x64 (pixels)
Transparency?     Yes
Color Count:        12
Compressed?       GIF's own prepackaged compression method (LZW)
Comment: Yes, the result turned out a bit ugly on the cropped edges. However, this would not have happened if the image were opaque and not transparent (removing transparency would have resulted in a size reduction anyway). Therefore, I recommend it for only opaque backgrounds. We don't want to look like we're from the stone ages on the internet again, do we?


GIF were once known as a copyright problem back in the day, but today it's no longer an issue as it's now officially a web standard and there's no more "hooks" when using them so you don't have to be afraid of being sued.
A GIF's usage is quite similar to PNG, but somewhat different. GIF's support animations, PNGs do not. They both support transparency (though PNG's look more clean on cropped images). They are both intended for lower image size (like the 64x64 rule of thumb I gave earlier). A GIF cannot hold more than 256 colors in a single image, while a PNG is practically limitless. So if you save a image that has over that limit, you will be subjected to losing whatever color(s) that exceed the 256 limit without notice, which makes the file format, LOSSY.
It is also wise NEVER to draw in a GIF format, as it will result in only the predetermined color pallette it contains (or forces you to use). Use PNG or a native file format for your graphics manipulator (.XCF for GIMP and .PSD for photoshop)
GIFs sometimes compress their images much better than PNGs, especially when it comes to a few colors (~24 or less) and small image size (typically significant with ~48x48 or smaller, with smaller being even more significant).
Like PNGCRUSH, there is also a compressor for GIF (even though its already compressed for static images), which allows you to compress animations exclusively. I personally don't use animations (at least haven't yet), but you can always google 'gif compressor' and get something similar to this. Let me know by leaving a comment here if you ever stumble upon a good one (or anything else I may have missed for that matter) that is cross platform (I use Linux) so I can use it too. :)

Always, always, always, use JPG/JPEG file format for photos or images of high color / size quality. I typically use JPEGs for anything 100x100 or higher. Do note that color count doesn't exactly apply in file size reduction there, as I tried and sometimes resulted in a higher file size. It's most likely due to how JPEGs calculate their data to allow them to "stretch" for a more larger image size, providing them to be lower in file size than PNG and GIF.
If you want to lower the size even more though, there is typically options when compressing it with a typical graphics manipulator like Photoshop or GIMP (free alternative that I always use). Usually you should have an option to choose a percentage of image quality traded for compression size. A good rule of thumb is 40% quality for most photo type images from the original image file. There is also a way to strip JPG/JPEGs of unneeded information for the web such as metatags (which can be debated on its usefulness) to further reduce file size. Just use a program like jpegtran or exiftran for the desired effect.

  •  Make use of Sprite Sheets
There are also other practical practices depending on design usage. One I'd like to explicitly mention is the usage of sprite sheets (something very handy for HTML5 games). In the older days when games were designed to be extremely optimised, they typically used something called spritesheets to keep the game from trying to find each graphic internally, making it quicker to grab and use. This applies to web pages too. Once a page starts to load, and if a sprite from a particular sprite sheet is loaded, the whole thing loads at once, giving it a "load now" and not "load later" effect. This can be done through CSS. Here's a more in-depth article about how to apply sprite sheets in your website if you're curious.
Here's a visual example of what a sprite sheet looks like in relation to a video game (I drew these btw):



  •  Use simple patterns for designs similar to gradients
Believe it or not, you can repeat patterns within CSS, making interesting designs. I can literally use and "redraw" an image across the entire page horizontally or vertically without ever using another image (keeping my image size to a measly 200 bytes (0.2 KB) or less. Here's a tutorial on how to apply backgrounds in CSS in general if you're new to CSS. Take for example this image (which I used gif since it's so small and only contained 2 colors), it's only 36 bytes! (the size is 2x2 btw, the image was upscaled to show you it without forcing your eyes to squint):

 


Got a cool web design optimisation you want to share that isn't mentioned here? Comment below!

2 comments:

  1. New tutorial! ;)

    This was actually very beneficial for me at my work however - not like it was a significant change, but compressing our images without any significant issues attached is a pretty great idea for website use in general. ;)

    ReplyDelete