os tais 15 discos. o 15 disco

pra começar Afrika Bambaataa...

quando guri, eu sempre ouvia essa música nos sábados a noite, vindo de longe. o que ficou na minha cabeça foi o tecladinho... até que um dia procurando por bandas novas, achei o disco do afrika.

brother, foi foda! na hora que ouvi o tecladinho e lembrei na hora daquela música ao fundo das noites de sábado =D

se vc curte uma música de negão, pode ir ouvir o Planet Rock.

como se não bastasse a clássica Soul Sonic Force, o disco ainda tem Looking For the perfect beat, Frantic Situation e Renegades of Funk.

na real, acho que esse é um dos melhores discos que já ouvi, praticamente todas as músicas são pedradas. só te digo uma coisa brother: ouça!

Improve your jQuery Selectors: 5 Quick Tips

jQuery is a wonderful way to make Javascript usable for everyone. For those not familiar with jQuery, I suggest you load up jquery.com and have a read through. I’ve and few other authors have also written a few jQuery articles on this very site in the past which you might have read. Here are a few that might interest you.
Build Fancy Tabs in JQuery that Fade Text
jQuery – Javascript Made Easy
Tips for jQuery Live Events
jQuery Plugin Tutorial

This post is about going through previously written code and looking at ways we can improve it, both the readability and the efficiency. Mostly these are little snippets of jQuery that perhaps don’t get noticed during a browse through the documents or are rarely useful. So, I’ll shut up and we’ll get started!

1. Don’t Select by Class if Possible.

Native Javascript contains two selectors: getElementById and getElementsbyTagName. You will notice there is no function to select elements by class. jQuery and most libraries do offer this function, and it’s not hard to write your own function to do it. However, due to it not existing natively, any custom function will be slower than using the two native functions above. So if you can avoid it, select elements by ID or by Tag Name over class where ever possible. Sometimes it is unavoidable of course, but if you can avoid it, do.

2. Save Selectors or chain ‘em up

See what’s wrong with this code?

1$("div#elem").hide();
2$("div#elem").css("width","200");
3$("div#elem").show();

Nothing is exactly wrong. However a lot could be improved. Each time $(“div#elem”) appears, jQuery does a search through the DOM for it. In that snippet of code, jQuery has to search three times for the element. Why make it do all the work? Either chain the functions like so:

1$("div#elem").hide().css("width","200").show();

Or save the element (also known as caching):

1var myElement = $("div#elem");
2myElement.hide();
3myElement.css("width","200");
4myElement.show();

Any element that you know you’re going to be referencing loads, save. However if you’re just using it in one block of code, I’d use chaining.

Caching also applies to the “this” keyword. Consider this loop:

1$("div").each(function(i) {
2$(this).addClass("myClass");
3if($(this).hasClass("newClass") {
4$(this).addClass("anotherClass");
5}
6});

While this might look all cosy, look how many times jQuery has to select the current element using $(this). This loop is much better:

1$("div").each(function(i) {
2var $this = $(this);
3$this.addClass("myClass");
4if($this.hasClass("newClass") {
5$this.addClass("anotherClass");
6}
7});

When saving $(this) to a variable, I always name that variable $this, adding the dollar symbol at the beginning. This is because I can’t call a variable “this” as it’s a reserved word.

3. Contextual Information

If you can provide extra information about the location of an element in the DOM, do. For example:

1$(".myElem")

Will work fine, however if you can do this:

1$("div.myElem")

This tells jQuery that the item with the class “myElem” must be within a div. So jQuery can use getElementsByTagName first to narrow down the search.

If you’ve already cached an element (see Tip 2) then you can actually add it as a second parameter when selecting another element:

1$(".myElem", elementYouCachedInAVariable);

This tells jQuery to search for items with a class of “myElem” from within the cached element, again shortening the amount of work jQuery has to do.

4. Avoid Extra Traversing

The most common example of this is as follows:

1$("elem").find("p").hide().parent.find("h2").hide();

What happens here is we find paragraphs within an element, hide it, then select those paragraph’s parent again, then find any h2 elements within that element, then hide it. What’s wrong? We start at the parent level, then find paragraphs within it, but then go back up to parent level to find the h2s within the parent. Why not use the siblings function?

1$("elem").find("p).hide().siblings("h2").hide()

But this can be even further improved, as the find() function can take multiple selectors:

1$("elem").find("p, h2").hide();

Take a look at the original code and what we have now. Much nicer!

5. Make use of andSelf()

Rarely used as much as it should, andSelf() is useful for chaining the previous selection. For example, take code such as this:

1$("div").find("p").addClass("myClass").parent().addClass("myClass");

That would seem the only logical way to do things. But no! Check this out:

1$("div").find("p").andSelf().addClass("myClass");

Which again, saves us repeating the addClass() function and generally is nicer to look at.

If you have any questions, please leave a comment or grab me on Twitter: @Jack_Franklin.

Google Caffeine’s up and running! « Meio Bit

Num post publicado recentemente em seu blog oficial, a Google anunciou que o Caffeine, novo indexador de seu produto mais famoso e utilizado, o buscador homônimo, está pronto e funcionando.

Uma necessidade para a empresa, o Caffeine muda bastante a forma com que o buscador indexa conteúdo produzido na Web. De acordo com a Google, o novo sistema de indexação traz até 50% a mais de resultados novos, recentes, em relação ao antigo. Isso supre necessidades cada vez mais crescentes, tanto de quem produz conteúdo, que deseja vê-lo nos buscadores o quanto antes, quanto de quem consome, que quer estar sempre e cada vez mais atualizado através deles.

O Caffeine foi construído para lidar com os novos tipos de conteúdo surgidos nos últimos anos na Web. Se antes indexar textos era a tarefa primária, hoje a situação é diferente. Atualizações de status, vídeos, imagens, notícias… É muita coisa. A imagem abaixo demonstra a mudança de foco que o Caffeine traz:

Caffeine

Antes, a indexação era feita através de camadas, e os mecanismos do Google varriam a Web inteira para encontrar material novo e/ou atualizado. No Caffeine, a abordagem é diferente. As análises são feitas em pequenas porções, continua e globalmente, sempre atualizando a base de dados do buscador. É esse o segredo para entregar mais conteúdo novo, ainda relevante.

O Caffeine é uma novidade grandiosa, e terá impacto nos próximos anos. Com ele, a escala de páginas indexadas deu um salto enorme — nas palavras da Google. O novo sistema já acrescentou 100 milhões de gigabytes de informações aos bancos de dados do Google, e continua a fazê-lo na base das “centenas de milhares de gigabytes por dia”. Se tudo isso fosse uma pilha de papel, essa cresceria 4,8 km por segundo!

Os benefícios dessa importante mudança “por baixo dos panos” começarão a ser sentidos pelos usuários, segundo a Google, nos próximos meses.

High Performance Web Sites :: Loading Scripts Without Blocking

This post is based on a chapter from Even Faster Web Sites, the follow-up to High Performance Web Sites. Posts in this series include: chapters and contributing authors, Splitting the Initial Payload, Loading Scripts Without Blocking, Coupling Asynchronous Scripts, Positioning Inline Scripts, Sharding Dominant Domains, Flushing the Document Early, Using Iframes Sparingly, and Simplifying CSS Selectors.

As more and more sites evolve into “Web 2.0″ apps, the amount of JavaScript increases. This is a performance concern because scripts have a negative impact on page performance. Mainstream browsers (i.e., IE 6 and 7)  block in two ways:

  • Resources in the page are blocked from downloading if they are below the script.
  • Elements are blocked from rendering if they are below the script.

The Scripts Block Downloads example demonstrates this. It contains two external scripts followed by an image, a stylesheet, and an iframe. The HTTP waterfall chart from loading this example in IE7 shows that the first script blocks all downloads, then the second script blocks all downloads, and finally the image, stylesheet, and iframe all download in parallel. Watching the page render, you’ll notice that the paragraph of text above the script renders immediately. However, the rest of the text in the HTML document is blocked from rendering until all the scripts are done loading.

Scripts block downloads in IE6&7, Firefox 2&3.0, Safari 3, Chrome 1, and Opera

Browsers are single threaded, so it’s understandable that while a script is executing the browser is unable to start other downloads. But there’s no reason that while the script is downloading the browser can’t start downloading other resources. And that’s exactly what newer browsers, including Internet Explorer 8, Safari 4, and Chrome 2, have done. The HTTP waterfall chart for the Scripts Block Downloads example in IE8 shows the scripts do indeed download in parallel, and the stylesheet is included in that parallel download. But the image and iframe are still blocked. Safari 4 and Chrome 2 behave in a similar way. Parallel downloading improves, but is still not as much as it could be.

Scripts still block, even in IE8, Safari 4, and Chrome 2

Fortunately, there are ways to get scripts to download without blocking any other resources in the page, even in older browsers. Unfortunately, it’s up to the web developer to do the heavy lifting.

There are six main techniques for downloading scripts without blocking:

  • XHR Eval – Download the script via XHR and eval() the responseText.
  • XHR Injection – Download the script via XHR and inject it into the page by creating a script element and setting its text property to the responseText.
  • Script in Iframe – Wrap your script in an HTML page and download it as an iframe.
  • Script DOM Element – Create a script element and set its src property to the script’s URL.
  • Script Defer – Add the script tag’s defer attribute. This used to only work in IE, but is now in Firefox 3.1.
  • document.write Script Tag – Write the <script src=""> HTML into the page using document.write. This only loads script without blocking in IE.

You can see an example of each technique using Cuzillion. It turns out that these techniques have several important differences, as shown in the following table. Most of them provide parallel downloads, although Script Defer and document.write Script Tag are mixed. Some of the techniques can’t be used on cross-site scripts, and some require slight modifications to your existing scripts to get them to work. An area of differentiation that’s not widely discussed is whether the technique triggers the browser’s busy indicators (status bar, progress bar, tab icon, and cursor). If you’re loading multiple scripts that depend on each other, you’ll need a technique that preserves execution order.

Technique Parallel Downloads Domains can Differ Existing Scripts Busy Indicators Ensures Order Size (bytes)
XHR Eval IE, FF, Saf, Chr, Op no no Saf, Chr - ~500
XHR Injection IE, FF, Saf, Chr, Op no yes Saf, Chr - ~500
Script in Iframe IE, FF, Saf, Chr, Op no no IE, FF, Saf, Chr - ~50
Script DOM Element IE, FF, Saf, Chr, Op yes yes FF, Saf, Chr FF, Op ~200
Script Defer IE, Saf4, Chr2, FF3.1 yes yes IE, FF, Saf, Chr, Op IE, FF, Saf, Chr, Op ~50
document.write Script Tag IE, Saf4, Chr2, Op yes yes IE, FF, Saf, Chr, Op IE, FF, Saf, Chr, Op ~100

The question is: Which is the best technique? The optimal technique depends on your situation. This decision tree should be used as a guide. It’s not as complex as it looks. Only three variables determine the outcome: is the script on the same domain as the main page, is it necessary to preserve execution order, and should the busy indicators be triggered.

Decision tree for optimal async script loading technique

Ideally, the logic in this decision tree would be encapsulated in popular HTML templating languages (PHP, Python, Perl, etc.) so that the web developer could just call a function and be assured that their script gets loaded using the optimal technique.

In many situations, the Script DOM Element is a good choice. It works in all browsers, doesn’t have any cross-site scripting restrictions, is fairly simple to implement, and is well understood. The one catch is that it doesn’t preserve execution order across all browsers. If you have multiple scripts that depend on each other, you’ll need to concatenate them or use a different technique. If you have an inline script that depends on the external script, you’ll need to synchronize them. I call this “coupling” and present several ways to do this in Coupling Asynchronous Scripts.

High Performance Web Sites :: Frontend SPOF

My evangelism of high performance web sites started off in the context of quality code and development best practices. It’s easy for a style of coding to permeate throughout a company. Developers switch teams. Code is copied and pasted (especially in the world of web development). If everyone is developing in a high performance way, that’s the style that will characterize how the company codes.

This argument of promoting development best practices gained traction in the engineering quarters of the companies I talked to, but performance improvements continued to get backburnered in favor of new features and content that appealed to the business side of the organization. Improving performance wasn’t considered as important as other changes. Everyone assumed users wanted new features and that’s what got the most attention.

It became clear to me that we needed to show a business case for web performance. That’s why the theme for Velocity 2009 was “the impact of performance on the bottom line”. Since then there have been numerous studies released that have shown that improving performance does improve the bottom line. As a result, I’m seeing the business side of many web companies becoming strong advocates for Web Performance Optimization.

But there are still occasions when I have a hard time convincing a team that focusing on web performance, specifically frontend performance, is important. Shaving off hundreds (or even thousands) of milliseconds just doesn’t seem worthwhile to them. That’s when I pull out the big guns and explain that loading scripts and stylesheets in the typical way creates a frontend single point of failure that can bring down the entire site.

Examples of Frontend SPOF

The thought that simply adding a script or stylesheet to your web page could make the entire site unavailable surprises many people. Rather than focusing on CSS mistakes and JavaScript errors, the key is to think about what happens when a resource request times out. With this clue, it’s easy to create a test case:

1 Here's my page!

This HTML page looks pretty normal, but if snippet.com is overloaded the entire page is blank waiting for main.js to return. This is true in all browsers.

Here are some examples of frontend single points of failure and the browsers they impact. You can click on the Frontend SPOF test links to see the actual test page.

Frontend SPOF test Chrome Firefox IE Opera Safari
External Script blank below blank below blank below blank below blank below
Stylesheet blank below flash blank below flash blank below
inlined @font-face delayed flash flash flash delayed
Stylesheet with @font-face delayed flash totally blank flash delayed
Script then @font-face delayed flash totally blank flash delayed

The failure cases are highlighted in red. Here are the four possible outcomes sorted from worst to best:

  • totally blank – Nothing in the page is rendered – the entire page is blank.
  • blank below – All the DOM elements below the resource in question are not rendered.
  • delayed – Text that uses the @font-face style is invisible until the font file arrives.
  • flash – DOM elements are rendered immediately, and then redrawn if necessary after the stylesheet or font has finished downloading.

Web Performance avoids SPOF

It turns out that there are web performance best practices that, in addition to making your pages faster, also avoid most of these frontend single points of failure. Let’s look at them one by one.

External Script

All browsers block rendering of elements below an external script until the script arrives and is parsed and executed. Since many sites put scripts in the HEAD, this means the entire page is typically blank. That why I believe the most important web performance coding pattern for today’s web sites is to load JavaScript asynchronously. Not only does this improve performance, but it avoids making external scripts a possible SPOF.

Stylesheet

Browsers are split on how they handle stylesheets. Firefox and Opera charge ahead and render the page, and then flash the user if elements have to be redrawn because their styling changed. Chrome, Internet Explorer, and Safari delay rendering the page until the stylesheets have arrived. (Generally they only delay rendering elements below the stylesheet, but in some cases IE will delay rendering everything in the page.) If rendering is blocked and the stylesheet takes a long time to download, or times out, the user is left staring at a blank page. There’s not a lot of advice on loading stylesheets without blocking page rendering, primarily because it would introduce the flash of unstyled content.
inlined @font-face

I’ve blogged before about the performance implications of using @font-face. When the @font-face style is declared in a STYLE block in the HTML document, the SPOF issues are dramatically reduced. Firefox, Internet Explorer, and Opera avoid making these custom font files a SPOF by rendering the affected text and then redrawing it after the font file arrives. Chrome and Safari don’t render the customized text at all until the font file arrives. I’ve drawn these cells in yellow since it could cause the page to be unusable for users using these browsers, but most sites only use custom fonts on a subset of the page.
Stylesheet with @font-face

Inlining your @font-face style is the key to avoiding having font files be a single point of failure. If you inline your @font-face styles and the font file takes forever to return or times out, the worst case is the affected text is invisible in Chrome and Safari. But at least the rest of the page is visible, and everything is visible in Firefox, IE, and Opera. Moving the @font-face style to a stylesheet not only slows down your site (by requiring two sequential downloads to render text), but it also creates a special case in Internet Explorer 7 & 8 where the entire page is blocked from rendering. IE 6 is only slightly better – the elements below the stylesheet are blocked from rendering (but if your stylesheet is in the HEAD this is the same outcome).
Script then @font-face

Inlining your @font-face style isn’t enough to avoid the entire page SPOF that occurs in IE. You also have to make sure the inline STYLE block isn’t preceded by a SCRIPT tag. Otherwise, your entire page is blank in IE waiting for the font file to arrive. If that file is slow to return, your users are left staring at a blank page.

SPOF is bad

Five years ago most of the attention on web performance was focused on the backend. Since then we’ve learned that 80% of the time users wait for a web page to load is the responsibility of the frontend. I feel this same bias when it comes to identifying and guarding against single points of failure that can bring down a web site – the focus is on the backend and there’s not enough focus on the frontend. For larger web sites, the days of a single server, single router, single data center, and other backend SPOFs are way behind us. And yet, most major web sites include scripts and stylesheets in the typical way that creates a frontend SPOF. Even more worrisome – many of these scripts are from third parties for social widgets, web analytics, and ads.

Look at the scripts, stylesheets, and font files in your web page from a worst case scenario perspective. Ask yourself:

  • Is your web site’s availability dependent on these resources?
  • Is it possible that if one of these resources timed out, users would be blocked from seeing your site?
  • Are any of these single point of failure resources from a third party?
  • Would you rather embed resources in a way that avoids making them a frontend SPOF?

Make sure you’re aware of your frontend SPOFs, track their availability and latency closely, and embed them in your page in a non-blocking way whenever possible.

Ajaxian » ShowSlow monitors your YSlow and Google Page Speed scores

Tuesday, June 1st, 2010

ShowSlow monitors your YSlow and Google Page Speed scores

Category: Performance

Show Slow has a great new feature. Sergey Chernyshev and team now monitor your YSlow and Page Speed stats:

Show Slow will fire YSlow and Page Speed at your site and collect statistics on a daily basis so you can just sit back and enjoy the graphs!

You can also check out the Alex 100 scores.

Steve Souders said:

Reassuring that the correlation coefficient of Alexa 100 YSlow and Page Speed scores is 0.83!

A very nice utility. Why wouldn’t you monitor your scores?

Posted by Dion Almaer at 6:25 am 3 Comments

-->

High Performance Web Sites :: appendChild vs insertBefore

appendChild vs insertBefore

May 11, 2010 12:15 AM

I’ve looked at a bunch of third party JavaScript snippets as part of my P3PC series. As I analyzed each of these snippets, I looked to see if scripts were being loaded dynamically. After all, this is a key ingredient for making third party content fast. It turns out nobody does dynamic loading the same way. I’d like to walk through some of the variations I found. It’s a story that touches on some of the most elegant and awful code out there, and is a commentary on the complexities of dealing with the DOM.

In early 2008 I started gathering techniques for loading scripts without blocking. I called the most popular technique the Script DOM Element approach. It’s pretty straightforward:

var domscript = document.createElement('script');
domscript.src = 'main.js';
document.getElementsByTagName('head')[0].appendChild(domscript);
Souders, May 2008

I worked with the Google Analytics team on their async snippet. The first version that came out in December 2009 also used appendChild, but instead of trying to find the HEAD element, they used a different technique for finding the parent. It turns out that not all web pages have a HEAD tag, and not all browsers will create one when it’s missing.

var ga = document.createElement('script');
ga.src = ('https:' == document.location.protocol ?
    'https://ssl' : 'http://www') +
    '.google-analytics.com/ga.js';
ga.setAttribute('async', 'true');
document.documentElement.firstChild.appendChild(ga);
Google Analytics, Dec 2009

Google Analytics is used on an incredibly diverse set of web pages, so there was lots of feedback that identified issues with using documentElement.firstChild. In February 2010 they updated the snippet with this pattern:

var ga = document.createElement('script');
ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ?
    'https://ssl' : 'http://www') +
    '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s);
Google Analytics, Feb 2010

I think this is elegant. If we’re dynamically loading scripts, we’re doing that with JavaScript, so there must be at least one SCRIPT element in the page. The Google Analytics async snippet has just come out of beta, so this pattern must be pretty rock solid.

I wanted to see how other folks were loading dynamic scripts, so I took a look at YUI Loader. It has an insertBefore variable that is used for stylesheets, so for scripts it does appendChild to the HEAD element:

if (q.insertBefore) {
  var s = _get(q.insertBefore, id);
  if (s) {
    s.parentNode.insertBefore(n, s);
  }
} else {
  h.appendChild(n);
}
YUI Loader 2.6.0, 2008

jQuery supports dynamic resource loading. Their code is very clean and elegant, and informative, too. In two pithy comments are pointers to bugs #2709 and #4378 which explain the issues with IE6 and appendChild.

head = document.getElementsByTagName ("head")[0] ||
    document.documentElement;
// Use insertBefore instead of appendChild to circumvent an IE6 bug.
// This arises when a base node is used (#2709 and #4378).
head.insertBefore(script, head.firstChild);
jQuery

All of these implementations come from leading development teams, but what’s happening in other parts of the Web? Here’s a code snippet I came across while doing my P3PC Collective Media blog post:

var f=document.getElementsByTagName("script");
var b=f[f.length-1];
if(b==null){ return; }
var i=document.createElement("script");
i.language="javascript";
i.setAttribute("type","text/javascript");
var j="";
j+="document.write('');";
var g=document.createTextNode(j);
b.parentNode.insertBefore(i,b);
appendChild(i,j);

function appendChild(a,b){
  if(null==a.canHaveChildren||a.canHaveChildren){
    a.appendChild(document.createTextNode(b));
  }
  else{ a.text=b;}
}
Collective Media, Apr 2010

Collective Media starts out in a similar way by creating a SCRIPT element. Similar to Google Analytics, it gets a list of SCRIPT elements already in the page, and chooses the last one in the list. Then insertBefore is used to insert the new dynamic SCRIPT element into the document.

Normally, this is when the script would start downloading (asynchronously), but in this case the src hasn’t been set. Instead, the script’s URL has been put inside a string of JavaScript code that does a document.write of a SCRIPT HTML tag. (If you weren’t nervous before, you should be now.) (And there’s more.) Collective Media creates a global function called, of all things, appendChild. The dynamic SCRIPT element and string of document.write code are passed to this custom version of appendChild, which injects the string of code into the SCRIPT element, causing it to be executed. The end result, after all this work, is an external script that gets downloaded in a way that blocks the page. It’s not even asynchronous!

I’d love to see Collective Media clean up their code. They’re so close to making it asynchronous and improving the page load time of anyone who includes their ads. But really, doesn’t this entire blog post seem surreal? To be discussing this level of detail and optimization for something as simple as adding a script element dynamically is a testimony to the complexity and idiosyncrasies of the DOM.

In threads and discussions about adding simpler behavior to the browser, a common response I hear from browser developers is, “But site developers can do that now. We don’t have to add a new way of doing it.” Here we can see what happens without that simpler behavior. Hundreds, maybe even thousands of person hours are spent reinventing the wheel for some common task. And some dev teams end up down a bad path. That’s why I’ve proposed some clarifications to the ASYNC and DEFER attributes for scripts, and a new POSTONLOAD attribute.

I’m hopeful that HTML5 will include some simplifications for working with the DOM, especially when it comes to improving performance. Until then, if you’re loading scripts dynamically, I recommend using the latest Google Analytics pattern or the jQuery pattern. They’re the most bulletproof. And with the kinds of third party content I’ve seen out there, we need all the bulletproofing we can get.

-->

Follow any responses to this entry with the RSS 2.0 feed.

You can post a comment, or trackback from your site.

Ajaxian » Steve’s call to improve browser caching

Tuesday, April 27th, 2010

Steve’s call to improve browser caching

Category: Browsers

Steve Souders was at the Mozilla Web caching summit that we posted on recently. At the event he lead the charge on the default size of the cache, and has written up a call to improve browser caching.

He created a browser survey form to capture information on the size of peoples cache, and this jumps out at you:

The data shows that 55% of people surveyed have a cache that’s over 90% full.

And we wonder why our servers are often serving up content to empty caches? Here Steve tells the story:

In 2007 Tenni Theurer and I ran an experiment to measure browser cache stats from the server side. Tenni’s write up, Browser Cache Usage – Exposed, is the stuff of legend. There she reveals that while 80% of page views were done with a primed cache, 40-60% of unique users hit the site with an empty cache at least once per day. 40-60% seems high, but I’ve heard similar numbers from respected web devs at other major sites.

Why do so many users have an empty cache at least once per day?

I’ve been racking my brain for years trying to answer this question. Here are some answers I’ve come up with:

  • first time users – Yea, but not 40-60%.
  • cleared cache – It’s true: more and more people are likely using anti-virus software that clears the cache between browser sessions. And since we ran that experiment back in 2007 many browsers have added options for clearing the cache frequently (for example, Firefox’s privacy.clearOnShutdown.cache option). But again, this doesn’t account for the 40-60% number.
  • flawed experiment – It turns out there was a flaw in the experiment (browsers ignore caching headers when an image is in memory), but this would only affect the 80% number, not the 40-60% number. And I expect the impact on the 80% number is small, given the fact that other folks have gotten similar numbers. (In a future blog post I’ll share a new experiment design I’ve been working on.)
  • resources got evicted – hmmmmm

OK, let’s talk about eviction for a minute. The two biggest influencers for a resource getting evicted are the size of the cache and the eviction algorithm. It turns out, the amount of disk space used for caching hasn’t kept pace with the size of people’s drives and their use of the Web. Here are the default disk cache sizes for the major browsers:

  • Internet Explorer: 8-50 MB
  • Firefox: 50 MB
  • Safari: everything I found said there isn’t a max size setting (???)
  • Chrome: < 80 MB (varies depending on available disk space)
  • Opera: 20 MB
  • Those defaults are too small. My disk drive is 150 GB of which 120 GB is free. I’d gladly give up 5 GB or more to raise the odds of web pages loading faster.

Even with more disk space, the cache is eventually going to fill up. When that happens, cached resources need to be evicted to make room for the new ones. Here’s where eviction algorithms come into play. Most eviction algorithms are LRU-based – the resource that was least recently used is evicted. However, our knowledge of performance pain points has grown dramatically in the last few years. Translating this knowledge into eviction algorithm improvements makes sense. For example, we’re all aware how much costlier it is to download a script than an image. (Scripts block other downloads and rendering.) Scripts, therefore, should be given a higher priority when it comes to caching.

Time to bump the default size, and get some smarter algorithms in place. Or, you can always run a cache server like polipo ;).

Posted by Dion Almaer at 11:43 am 7 Comments

-->