Published at July 30, 2012
| Tagged with:
Django
,
web development
,
jQuery
,
optimisation
,
javascript
,
Development
,
Web
Preface: Have you noticed how on some websites when you click on a link that opens a lightbox or any overlay for first time it takes some time to display the border/background/button images. Not quite fancy, right?
This is because the load of this images starts at the moment the overlay is rendered on the screen. If this is your first load and these images are not in your browser cache it will take some time for the browser to retrieve them from the server.
Solution: The solution for this is to preload the images i.e. to force the browser to request them from the server before they are actually used. With a simple javascript function and a list of the images URLs this is a piece of cake:
$.preLoadImages = function() {
var args_len = arguments.length;
for (var i=0; i < args_len; i++) {
var cacheImage = document.createElement('img');
cacheImage.src = arguments[i];
}
}
$.preLoadImages('/img/img1.png', '/img/img2.png')
Please have in mind that the code above uses the jQuery library.
Specialty: Pretty easy, but you have to hardcode the URLs of all images. Also if you are using Django compressor then probably you are aware that it adds extra hash to the URLs of the images in the compressed CSS files. The hash depends from the COMPRESS_CSS_HASHING_METHOD settings and can not be avoided. It is pretty useful cause it forces the client browser to reload the images every time when something has been changed. unfortunately our hardcoded list of URLs does not have this hash. So wouldn't it be much simpler if instead of hardcoding URLs we just read them from the CSS files?
Solution 2:
$.preLoadImages = function() {
$.get($('link[rel="stylesheet"]')[0].href, function(data){
r = /url\(['|"]?(\S+\.(gif|jpg|jpeg|png)[^'(]*)['|"]?\)/ig;
while (match = r.exec(data)){
var cacheImage = document.createElement('img');
cacheImage.src = match[1];
}
});
}
$.preLoadImages()
Now with the help of regular expressions we can read the image URLs directly from the CSS file together with the hash part. Please note the zero index in the css file selector, if your main CSS is not the first declared style-sheet then you will have to change the index according to its position.
I hope you will find this solutions simple and useful. As always feel free to comment, share and propose code improvements.
Published at July 12, 2011
| Tagged with:
speed
,
web
,
cache
,
memcached
,
optimisation
,
heavy load
,
Development
,
Web
... five major question to ask yourself before using cache
After we learned about Why, Where, What and How of caching web sites now it is time to see when to use it.
The application cache is mainly used for speeding up and/or decreasing the load of frequently executed and(but not necessary) heavy resource using methods. So the first question is:
1) If you have method the consumes lots of CPU time and/or memory can it be optimised?
If you can optimize your code and make the method run faster and consume less resource than do this first and then reconsider whether you still need to cache it..
2) Will caching save you load/wait?
Have in mind that accessing cache has its own load. So caching the result of relatively light operations is pointless. Try to find where your biggest load/wait came from and use cache there.
3) For how long the cache should be valid?
This depend from how often the data is changed. We can split it in 3 major cases.
Case 1: The data changes on equal amounts of time, for example it is updated by cron. In this case you can set the expire time equal to the time interval in which the cron is runned. Example - you are reading a feed with the news from the last hour.
Case 2: The data is changed on random intervals of time - but not real time(i.e. from minutes to hours). In this case you should choose an average amount of time for which you think the data is persistent or even if it is changed you can serve the outdated one to the client. In this case the best way is to be able to invalidate cache when data changes. This is usable if the data is from the same type, for example - news list. Just add a line that invalidates cache on every news affecting operation(add/edit/delete). If you have composite data, for example mix of news, weather cast and currency rates for the day you'll just have to wait the cache to expire by it self.
Case 3: The data is updated real-time(every second, sometimes more than once in a second). If you are watching/playing on the market you really need real-time info for the current rates. But if don`t need the real-time date, for example you are displaying just informative graph with the daily changes you can cache and update it rarely(for example on every few minutes) then it changes.
So you have determined how long your cache should stay valid and the next question is:
4) Will the data be accessed more than once for the cache period?
If not then don't cache it or reconsider to increase cache validity time(question 2).
5) How big is the data to be cached?
Memcached has 1MB limit per cached item. For web(no matter is it site or application) this limit is fair enough for most/all of the cases. If you plan to store something bigger thing again and be sure you are not doing something wrong. If you really need to cache bigger amount of data consider to use another cache storage - database or file system.
If you are an advanced developer you will subconsciously know whether to use cache or not. But this questions may be really helpful if you are a novice.
I am open to hear what you ask yourself before using cache.
Update:
One more case when it is mandatory to use caching(if you can) is when you have frequent calls to an outer API. For example Retrieving Google Analytics Data.