Tax rates

I’d been wondering who those 46% who don’t pay federal income taxes are. Here’s a break-down. In short, 23% are at or below the poverty line, 7% get deductions related to cost-of-living (e.g. earned income tax credit, child credit) that push their taxable income below the line, 10% are retired. That leaves 6% in the “other” category.

I find it mind boggling that, here in the USA, 30% of people are struggling to make ends meet.

When AJAX is too slow

Back in the day, web pages were just web pages. What you see is (more or less) what you got. These days, we have web applications where there’s a lot of back-and-forth communication between the web browser and the web server. In essence, where you used to load a new page to get more data, your web browser just updates a portion of the page you’re already on. The new model is called AJAX.

That works great when you’re going to be interacting with a web application for a long time. But if you want to load the page quickly and then jump to a different page, AJAX can be a bad idea. I’ve got one of those situations at work right now. It’s a to-do list, where people choose a task to work on. Someone will eventually need to do all the tasks, but when the list is big they’ll either just click on the first one (to hurry) or look more carefully and do triage.

My first attempt was a single web page with all the tasks in an HTML table. When the table is moderately large (over 30 tasks), it took over a second to load. After a day of optimization, I got that down to 0.6 to 0.7 seconds. Not the 0.1 seconds that Google recommends, but reasonable. If it takes more than a second the user’s mind will wander while waiting for it.

Then I AJAXified it. Converted the simple HTML table to a YUI Datatable. My 0.6 seconds shot up to 1.7 seconds. Why? Instead of loading one web page and rendering it, it now (1) loads the web page, (2) loads the JavaScript program that displays the datatable, (3) waits for the web page to finish rendering before running that program, (4) the program calls the web server to get the column descriptions, and then (4) the program calls the web server to get the data. The column data (which takes 0.2 seconds to generate) is being generated in triplicate. The to-do tasks themselves take half a second (0.13 seconds each), but–and this is the real killer– we don’t even start on that until everything else is done.

So how do we make this quicker? We need to move as much as possible back into the original page: un-AJAXify it. In my case, that’s not easy. Behind the scenes, the web page is constructed with XHTML and then converted into HTML before being sent to the web browser. I’ve got a lot of helper code that assumes we’re doing XHTML, so that’s not negotiable. XHTML is a lot like HTML, except that we can’t just dump a block of JavaScript into it. Nor can we send it as XHTML and pretend it’s HTML. The web browser, upon seeing that, assumes we don’t know what we’re doing and tries to “fix” it in ways that break things. So to totally un-AJAXify it, I’ll need to go back to writing a simple (X)HTML table, and then write some JavaScript to convert that into the YUI DataTable.

Another option is to take the to-do list payload and treat it as a JavaScript script, so it gets loaded simultaneously with the other scripts and images on the page. This is what I call Poor-Man’s AJAX, because I used that trick back in the days when only Internet Explorer supported AJAX. It’s not quite as fast in my case as having the data in the page, but it should still be fairly fast, and it’s easier to program.

The moral of the story? Sometimes the new, fast way of doing things can slow you down, so it’s good to have some old-fashioned tricks up your sleeves. Though, this being computers, old-fashioned means circa 2004 or so. (When you’re really in trouble, that’s when you reach back to your circa-1980 performance tricks. But that’s a story for another day.)

Posted in UU

A harbinger of things to come?

I just did a Google search for “Project Gutenberg.” Rather than finding the Project Gutenberg website, Google filled the results with entries from its own e-book catalog. A Bing search took me right to Project Gutenberg.

I filled out a complaint form (Google has a link at the bottom of the page.) A few minutes later, it was giving correct results. Questions: was this a broken server, or a normal result? Was my later search influenced by my complaint? If so, did it only affect my search results? No matter how well-intentioned the folks at Google are, there is too much incentive for bias, and it is too hard to detect* for bias not to creep in over time.

*See Appendix A of this academic paper for a discussion of the dangers of search engine bias.

How to avoid Harry Potter (hint: Tiffany Aching)

For the past year or two, I’ve been reading Harry Potter to my seven year old daughter for a bedtime story. It started out at about her level, but by the fifth book it’s definitely at a teen level because of dark themes, including sadism and torture. (Professor Umbridge, I’m looking at you.) We’re up to the last book, and I’m avoiding it. Not just for the adult themes, but also for fear of what to read when we’re done. After all, when she’s misbehaving, the only threat that always works is to threaten that we won’t read Harry Potter that night.

Happily, my friend and coworker suggested The Wee Free Men by Terry Pratchett. It’s the first of a four-book series about a no-nonsense girl named Tiffany Aching who wants to be a witch, and how she teams up with a band of fairies whose three skills are fighting, drinking, and stealing.

That was the first book I’ve ever found that can compete with Harry Potter. And boy have I tried. We’re already on the second book (A Hat Full of Sky), and I’m not sure which series she’ll want to finish first.

If you have a child under the age of 10 who has not yet read all the Harry Potter books, I strongly recommend The Wee Free men as a speed bump after the first two books.