In Lesson 1 of this tutorial, we learned how to manipulate images to reduce your download time. Now, it’s time to dig even deeper into the fine art of slimming down those pages.
We’re going to talk about page layout, and that means talking about HTML tables, first and foremost. First, because table-based layouts are the de facto web standard, and foremost because table-heavy designs have a nasty reputation for poor performance.
And CSS layout? It’s faster, better, and smarter. We’ll cover it later. Now, you’re welcome to skip ahead, but The House bets that you’ll keep reading.
CSS is cooler than tables. And smaller. And in the long run, its better. But some CSS-2 layout standards still aren’t showing up the same in every browser. So let’s face it — sometimes right-now compatability trumps future-compatability.
Tables aren’t all bad, anyways. Most designers are taught to design with a grid, so dropping things into a table comes naturally. We’re also fond of their duality; variable-width tables can both define a layout and respond to the unpredictable elements of a page. Being a web designer means coping with unpredictability, and striking a compromise between your design and the user’s flexibility. (Users should be afforded the ability to make fonts larger, for instance). Unfortunately, tables also increase the time it takes to display a web page, and sometimes by a substantial amount.
Tables: Past Performance, Future Returns
Historically, browsers needed to understand a table’s structure before drawing the table’s contents, so that nothing was put on-screen until all of the table’s content was downloaded. How dumb! Even with 99% of a page downloaded, some stubborn browsers wouldn’t even think about laying out a table, until receiving a concluding </table> tag. This foot-dragging was the anathema of dial-up modem users everythwere. Well, back in ’96, it might’ve briefly been celebrated as “cyber” foot-dragging.
Since the advent of IE 5.x, Mozilla 1, and Netscape 6.x, this performance pitfall is automatically avoided. Today’s newer browsers use progressive or “incremental” rendering by default, and will attempt to render tables on a row-by-row basis, rather than pausing and waiting for the </table> tag to begin the process. If a page’s source code relies heavily on tables, and the page downloads in fits and starts, modem users at least have a decent chance of seeing some content on the screen quickly.
Tables perform lamely for another reason, though. As tables get bigger, and nested into one another, the amount of info that needs processing increases exponentially. On mobiles and slower computers, all this processing-intensive work doesn’t come easy, and serious time can pass before a table renders to the screen.
But don’t fool yourself — circa-2003 operating systems require more CPU overhead, and the codebase of today’s web browsers sure ain’t getting smaller. Even Firefox, once a browser, is suddenly a “platform”. And don’t forget the flyweight “thin clients”, web-enabled phones and game consoles, valiantly attempting to take on the wild web. They lack CPU muscle, and don’t show much spirit for parsing table-heavy layouts. Basically, if you’re going to use tables, you still need to do whatever you can to optimize the code. Or, better yet, avoid it altogether.
Accelerating fixed-width tables
If you’ve got a fixed-width table where you’ve explicitly set the TABLE WIDTH attribute to so-and-so many pixels, check this out:
Appling a CSS-1 style of table layout:fixed to a fixed-width table speeds up the display process. With layout:fixed present, browsers use a simpler, faster rendering method to draw a table’s contents, trusting your assertion that everything’s been properly sized-up, already.
Here’s a code example of layout:fixed applied to a table:
<table style="table-layout:fixed" width="600"> <tr height="30"> <td width="150">happy</td> <td width="200">happy</td> <td width="250">happy</td> </tr>
Now, don’t go abusing the browser’s trust! If you apply the table layout:fixed style incorrectly, with widths that don’t quite add up, the browser will catch the error during the rendering process and start things over from scratch. Do that, and your tables will appear slower, not faster.
Bring it to the Table
Here’s another nugget of truth: Browsers prefer easy-chew tables. One old-school trick works, though – remembering that lots of little tables appear to render faster than one big, many-rowed table.
If you’ve got a nine-row table that fills a few screens full of information, go ahead and break it into three smaller tables of three rows each. This strategy is particularly beneficial if your web pages require a lot of vertical scrolling. Your audience can read the contents of your first table as other tables continue to load down in the nether regions of your page.
Don’t Trust WYSIWYG Editors
Tables can be a pain, which is one big reason WYSIWYG HTML editors became popular in the first place. However, while HTML editors make it easier to create tables, they can produce amazingly inefficient code.
The layout windows of WYSIWYG editors often make it tough to spot unnecessarily nested tables, improperly sized table elements, or strange, roundabout HTML code. So if you want your tables to be as slim and efficient as possible, but you still want to use your WYSIWYG editor, then budget some time at the end to validate and clean up your code. Once everything looks the way you want it, jump to “Code View” in the WYSIWYG editor, or drop the dirty HTML into a text-editing app and pick over your code until it is nice and clean.
Nested Tables – the old taboo!
One notorious culprit associated with slow-to-the-screen web pages has always been the nested table. A nested table is created when one table is put inside the cell of another table. Of course, with ever-faster computer hardware, nested tables may not get such a bad rap these days. Well, go ahead and call us old-timers, but nested tables are still sucky in our book.
Why the legendary performance hit with nested tables? For starters, browsers have to work double-time on tables. Unlike most page elements, tables absolutely require two passes of browser “reflow” (layout code-crunching), due to their auto-sizing shrink-wrap behavior. Pass #1 assesses what size each table cell would like to be, and Pass #2 determines how big they actually can be, once other elements on the page have been accounted for.
And there’s the rub. A single-nested table requires two passes, plus one more, because the inner table must be partially re-rendered during outer table’s rendering process. Nest three tables inside one another, and that makes for five passes of reflow. Nest five levels deep, and the browser loops through reflow routines nine times.
Fun Fact: Some tables may even require a third reflow pass when put in tricky situations like specified-percentage-height table cells squatting in an un-sized parent table. Woah! Wait – did we just say “Fact” or “Fun Fact”? Oh. Umm, we meant to say “Fact”.
So avoid using nested tables whenever possible, even if it means making minor alterations or simplifications to page layout. (Remind your design team that Photoshop is an image editor, not a HTML-prototyping application) If you must use nested tables, at least keep them simple — try not to nest more than a few levels deep. Even though table rendering speed issues are less problematic on modern PC hardware, table layouts still hamper screen readers and other accessibility-enhanced browsers. Nested tables doubly so. We’re building web pages here, not those little Russian dolls.
Better Structure, Faster Page
Below is the classic web page layout. You’ll notice the branding across the top, navigation down the left side, and content in the remaining part of the page. It’s pretty common for such pages to be constructed using a large table which defines the entire grid. With the branding, navigation, and content tables nested within the overall framework table, this can be a difficult page for the browser to render.
By making each table independent and concise, any browser can render each element as soon as it finishes reading it. So the first elements of the page appear faster, and the user can take advantage of the features at the top of the page immediately. (Remember, “perceived speed” and “visual accessibility”.)
In the second example, the branding table loads first on the page, followed by the navigation table. And, since we set the alignment of the navigation table to “left”, the content loads next, positioned to the right. The page appears to load faster, and the user has something to see and use almost immediately.
So, as with images, to get the best results with your tables, you need to play around with a variety of solutions until you get a layout that both you and your users can live with. It may seem like a lot of effort just to shave a few seconds off a page’s load time, but competition for user loyalty is fierce, and those seconds can be all that stand between your visitors and the Back button.
CSS:An Overview for Optimizers
Tired of tables yet? (You’re free to shout ‘Hellzyeeeaahh, G!’, without impinging the previous portion of this humble web development narrative.) After all, debugging cross-browser table display issues, or parsing content buried under a mishmash of <td>s, <tr>s and <font> tags gets old, fast.
Hence the hooplah over CSS.
Cascading Style Sheets is a smart standard, promising precise control over the looks and the layout of websites. Idyllic stuff, indeed, for jaded web workers. Well, CSS isn’t quite Utopia, yet – cross-browser snags and snafus still exist. But it’s a solid leap ahead, especially if you’re keen on creating speedy web sites.
We’ll refrain from re-hashing the many treatises on why separating content from markup code is the bee’s knees (i.e. here, here, and here), but we will repeat this much:It is far easier to redesign or repurpose web content that has been built as such using technologies like CSS, XML, and XHTML. This matters for us speed freaks (in the positive, HTML-optimization sense), because serving different versions of a site is a serious consideration. “Optimized” is relative term for broadband users and mobile phone surfers, for example, and one page format is unlikely to satisfy both audiences. Once you’ve separated the content from a page’s architecture, you can publish to multiple formats or designs without doubling or tripling your workload.
Great resources for getting familiarized with CSS (a.k.a stealing code snippets) include Mulders Stylesheets Tutorial right here on Webmonkey, as well as glish.com, bluerobot.com, and Jeffrey Zeldman’s musings on the topic. To see a kick-ass example of a commercial site that pioneered web-standards-compliant code, look no further than Webmonkey’s sister-site Wired, which uses CSS absolute and relative positioning for almost all of its layout concerns.
Like we said, though, this tutorial focuses on optimization – why CSS layout is faster than table layout, and how to make it seem faster still.
Reduced code size probably accounts for 95% of the performance gains you see when jumping from an intricate table-based layout to a smart CSS design. When your source code is shedding kilobytes by the dozen, rendering speed and the like become academic issues.
A CSS layout and text-styling combo is invariably bound to create a smaller page than one laid out with deprecated <table> and <font> tags. That’s because with CSS, you type fewer characters to create the file, so unsurprisingly, the user downloads fewer characters to get the file.
How big of a difference does this make in the end? That depends on a lot of variables, like how complex a particular page is, but it’s probably worth a good 10K on average. Now, I use the rule of thumb that 2K of code represents one second of download/render/latency time, so we’re talking roughly five seconds. Five whole seconds otherwise wasted staring slack-jawed at a computer screen. Remember, for that great majority of people surfing sober, five seconds can be a palpably dull period of time.
CSS helps webmasters determine the order in which page elements are downloaded and when they appear on the screen. This is fantastic for boosting a site’s visual accessibility and perceived speed. For example, a news site can load the story element first, load decorative page elements next, and finally, load the advertisement, regardless of where these items appear on the page.
The user will still take note of a site’s design quality, as well as the advertisement. What they won’t notice, though, are frustrating delays in loading the page. Remember, if a user senses it’s the sponsorships or fancy decorative elements that make a page sluggish, it’s often the sponsors and the site’s image which suffer most.
How do you prioritize what elements get loaded first with CSS? Just put it at the top of the source code, no matter where it’s positioned on the page. Fisher-Price easy.
You don’t need to go the whole Harley with CSS layout to reap the benefits. Simply using CSS styles on your text, in lieu of <font> tags, saves significant space. If you’re reluctant to migrate a tried-and-tested table layout to CSS-positioning, but mellow with the idea of serving unstyled text to the odd out-of-date browser, give this method a test drive.
By the way, this CSS+tables compromise works best for pages with text content spread across many table cells. Since long-winded font tags (<font face="blah, blah, blah" size="blah">) must be repeated in every single table cell, the minimal notation of CSS styles gets leveraged to full effect. A simple “<p>” does the trick via CSS. Of course, try to use a sensible shorthand when naming CSS classes, and don’t explicitly add class attributes to tags if avoidable – why add more characters to your source code than necessary? Imagine those antiquated font declarations repeated thirty times and it’s easy to imagine the space savings.
The Compromise Method
If you’re still straddling the fence between CSS and tables and you have a minimal number of pages to manage, you might consider serving different page formats to different browsers via browser-detection and server-side scripting. Of course, this immediately doubles the amount of coding, testing, and debugging work that’ll need doing, but it may be worthwhile on a small scale, such as on your site’s homepage or a few heavily-trafficked pages.