adding context to the selector is much faster than refining your selector

This is true in the general case. With respect to your specific examples however it is not necessarily true for jQuery <= 1.2.6.

Up to and including jQuery 1.2.6 the selector engine worked in a "top down" (or "left to right") manner. Meaning that both your examples would operate like this (roughly):

var root = document.getElementById('bar'); return root.getElementsByTagName('li');

jQuery 1.3.x (ie, Sizzle, which jQuery embeds) introduced a "bottom up" (or "right to left") approach to querying the DOM. So $('#bar li') now becomes (roughly):

var results = []; var elements = document.getElementsByTagName('li'); for(var i=0; i < elements.length; i++) { var element = elements[i]; var parent = element.parentNode; while(parent) { if(parent.id == 'bar') { results.push(element) break; } parent = parent.parentNode; } } return results

There are benefits and downsides to both approaches. You found one of the downsides.