Archive for the ‘Web’ Category

Searchable tab switching in Firefox 3.6

As an emacs user, I’ve found iswitchb (interactive-switch-buffers) to be a huge time saver. Basically, to switch files (buffers) you enter a typically byzantine key combination and then type to search through your open files – as less and less files match your search, the choices narrow down, and you can choose between them. This ends up being way faster than switching with a mouse even in tabbed editors, and I’ve managed to set up a similar thing in Eclipse/Aptana. But until recently I didn’t have the same functionality for switching tabs in Firefox.

The good news is that Firefox 3.6 has this feature built in, though it takes a bit of work to enable. Apparently they’ve been trying to get this feature into Firefox since 3.0, but there’s been a lot of different opinions, so even though they finally shipped it with 3.6, it isn’t on by default. You can turn it on by going to about:config (just type that right into your address bar), then searching for “ctrlTab”. Double-click browser.ctrlTab.previews to turn it to “true”. Now, when you hit Ctrl-Tab, you’ll get a tab switcher that looks a bit like the default Windows Alt-Tab window switcher (though with a much lighter glass effect that honestly looks pretty bad compared to Windows’ Alt-Tab). On other platforms you’ll get a similarly system-integrated look. Unfortunately this popup isn’t exactly what we’re looking for – it doesn’t show all your tabs and you can’t search! However, you can navigate down to “show all X tabs” at the bottom and you get a search box and a list of every tab. That’s a real pain to do every time you want to switch tabs, though. Fortunately, there’s a solution. Instead of hitting Ctrl-Tab, use Ctrl-Shift-Tab, and you’ll start out right at the big tab switcher with search. From here you can type to narrow down your selection and hit Enter to choose your tab. I wish there was a preference to make this full search show up when you hit Ctrl-Tab, but it doesn’t look like there is.

Firefox Ctrl-Shift-Tab tab switcher
Switching between tabs (man, that glass effect is a mess)

Visual issues aside, I wish every program with a tab-oriented UI had a feature like this to make their app faster to use for keyboard users. While we’re at it, Windows and OSX should add search to their built-in window switchers – it could really help when I have a lot of windows open and don’t want to reach for the mouse.

Note: There are a couple extensions for Google Chrome that theoretically give a similar searchable tab switcher, but of the few I tried, none of them could appear with a keyboard shortcut – you had to click an icon on the toolbar, which seems to defeat the point. Apparently the Chrome Extensions API has known problems with keyboard shortcuts, so maybe things will get better soon.

Simple expiring caching for Ruby on Rails

Ruby on Rails has some great caching support built right in, but it’s most useful when you have MemCacheD or DRb around to serve as a cache store. I don’t have access to those everywhere – Dreamhost and other shared hosting providers often prohibit running your own MemCacheD. There’s a default memory store, but it won’t share cached info between Rails server processes. That leaves the file store, which just writes cached objects to a file that gets shared between all your Rails processes on the same box. The main problem with the file store is that it doesn’t support time-based expiration – you have to set up a cron job to sweep out the cache files every once in a while to invalidate your cache.

To get around this, I wrote a tiny, obvious little module that gives a simple syntax for caching objects with the file store. The trick is that it stores the insert time whenever it caches a new object, and compares it with the current time every time it looks it up. If the cached object is too old (or the cache is empty), it throws it away and executes the provided block and caches the new value.

Be sure to use the same expiration whenever you fetch the same object, or things will expire differently depending on where they’re accessed. You can also do a bit of customization for more complex cache invalidations – I have a version of fetch that caches objects within one calendar day and recalculates them only when the date is different. I suppose I could made fetch take an optional Proc to control the caching strategy, but I didn’t really need that much customization. Anyway, this isn’t exactly brilliant new code, but it has made caching objects from my smaller Rails apps a bit easier.

Speeding up jQuery’s each function

In my previous post, “Investigating JavaScript Array Iteration Performance“, I found that among a selection of different array iteration methods, jQuery’s each function was the slowest. It’s worth mentioning again that these investigations are pretty academic – array iteration and looping speed is unlikely to be the source of performance problems compared to actual program logic, DOM manipulation, string manipulation, etc. I just found it interesting to poke into how things work in different browsers. That said, with the recent release of jQuery 1.4 emphasizing performance so much, I wanted to see what if anything could be done to speed up each (which is used inside jQuery all over the place), and whether it would made much of a difference.

Again, the details are after the jump.
(more…)

Investigating JavaScript Array Iteration Performance

The other day I was working on some JavaScript code that needed to iterate over huge arrays. I was using jQuery’s $.each function just because it was simple, but I had heard from a bunch of articles on the web that $.each was much slower than a normal for loop. That certainly made sense, and switching to a normal for loop sped up my code quite a bit in the sections that dealt with large arrays.

I’d also recently seen an article on Ajaxian about a new library, Underscore.js that claimed to include, among other nice Ruby-style functional building blocks, an each function that was powered by the JavaScript 1.5 Array.forEach when it was available (and degrading for IE). I wondered how much faster that was than jQuery’s $.each, and that got me to thinking about all the different ways to iterate over an array in JavaScript, so I decided to test them out and compare them in different browsers.

This gets pretty long so the rest is after the jump.
(more…)

Swoopo Profits Greasemonkey Script – Entertainment Shopping

In the last few weeks I’ve become increasingly obsessed with the evil genius that is Swoopo.com. Swoopo is a penny-auction site – users buy bids for $0.60, and each bid placed on an item increases the price by $0.12. The cost of bids and the amount they increase the price of the item vary depending on the type of auction and the country you’re in. Swoopo does a lot to make it harder to win, though. For example, if the bid is placed within 10 seconds of the end of an auction, the closing time of the auction is extended by 10 seconds or so, so people can have last-second-sniping wars for as long as they want. They also offer a “BidButler” service that will automatically bid for you, and of course if two users in an auction are using it, the BidButlers just fight until they’ve used up all the money they were given. Swoopo’s operation is like cold fusion for money – they make insane amounts of cash off their users, and they only have to drop-ship the item to one user so there’s theoretically very little operating cost (they already have the money from selling bids, and they don’t need to maintain inventory). They’re shameless enough to even have auctions for cash, gold, and even more bids! Because everyone in the auction is paying to participate, even if the winner gets some savings on the item, Swoopo makes far, far more on the sunk bids – sometimes 10x the price of the item in pure profit.

Jeff Atwood (of codinghorror.com) has written about Swoopo multiple times, and some techies have even tried to game the system, but it hasn’t worked. I was introduced to Swoopo through Jeff’s blog but I hadn’t thought about it forever, and for some reason it came up again recently. After looking at it a bit, I was just floored by how they’ve managed to set up such a perfect money-generating system. The company that runs Swoopo is called “Entertainment Shopping”, which I guess is supposed to be a suggestion that it’s like gambling (where it’s “fun” to lose money) though they really, really don’t want to be regulated as gambling. I don’t personally find gambling (or bidding on Swoopo) to be that fun, but I do find it entertaining to watch the astronomical profits tick up as more and more suckers toss money into an auction. So I built a little Greasemonkey script that’ll add the estimated profit to Swoopo above the price of an auction, updating in real time as people place bids.

Example screenshot of Swoopo Profits

It took quite a bit of work to sniff out the prices from the page (I suspect they make it hard to scrape on purpose), but I’ve checked it out and the script works pretty well on current and recent auctions on all of Swoopo’s different sites (US, Canada, UK, Germany, Austria, and Spain). It won’t work on some of their older auctions, where the rules were slightly different (and bid costs were different, too). The basic formula looks like this:

((currentPrice - bidAmount) / bidAmount) * bidCost + currentPrice - worthUpTo

I’m calculating it with all the fairness to Swoopo I can muster. I calculate the number of bids based on the current price and the amount each bid moves the price (bidAmount) times the cost of bids (bidCost). The winner still has to pay the current price, so I add that in, but I subtract what Swoopo says the item is “worth up to” since they probably have to pay around that to drop-ship it to a customer. As the example screenshot shows, this leads to examples like an iMac selling for $364.75 (plus another $392.40 in bids for the winner), but a total pure profit of $9,827.98 for Swoopo. Exciting! I’ll readily admit that my calculation is not always 100% accurate. There are a number of things I don’t take into account – I assume shipping is a wash, so it’s not included. I assume Swoopo’s paying the full retail “worth up to” price when they’re probably not. I count bids as all costing the same even though they might have been won at a “discount” via a bid auction. In cases where I can’t figure out some numbers I default them to hardcoded values, which might be wrong. I also don’t take into account “Swoop it now”, which lets bidders buy the item for its full price minus the money they’ve sunk into bids, effectively getting out of the auction entirely. This would reduce Swoopo’s profits but it isn’t recorded anywhere so I can’t factor it in. So take the number with a grain of salt – it’s entertainment.

Grab the script and start poking around swoopo.com. Hopefully you’ll have as much fun as I have with it.

As a side note about my Greasemonkey scripts, I’ve retired the “Amazon Super Saver Snooper” script. Amazon has changed the way the API used to look up Super Saver eligability works, and I can’t get at that data anymore. More importantly, Amazon now puts “Prime” logos next to Prime-shippable items, so the script isn’t necessary anymore.