Thinking About Programming

13 Ways to Avoid Building Web Applications That Suck

Posted: 03/13/2007, Readers: 11424 Perm Link


I get so tired of going to websites that provide interactivity and discovering they suck megatons. This is especially irritating in Fortune 500 companies (like Bell/AT&T/whatever they are called this week with yellowpages.com). None of this is rocket science, yet I am amazed at how companies with deep pockets manage to produce drecky sites. This is your public face, would you go on a date with mud on your face and spinach in your teeth?

At the risk of giving away all of my (not so secret) secrets, here are some useful things to do.

1. Put javascript and css in their place

Javascript and css should be kept in separate files and not embedded in your web pages. I don't care that your IDE can parse and syntax color 8 simultaneous languages in one file, it's hard to read, hard to debug, and brittle when there are multiple people editing the page. I'm ambivalent about adding event handlers upon loading instead of in the html itself but it's not a bad idea. If you want to avoid linking to files then include them in the html using your language or framework include feature.

2. Use compression

All web servers and browsers are capable of dealing with compressed content. Turn it on. It doesn't cost anything, saves bandwidth, makes dialup users happy and dogs wag their tails. You can save more by compressing your javascript files than by removing all the spaces manually. In any case it's easier to code something you can read.

3. If you put a DocType in your page, validate against it

Of all the things you find in the wide world of web, crappy HTML is by far the most common. Why put a DocType in every web page and then serve up invalid content? I always work in strict XHTML even though it isn't served up that way, simply so that I can be assured it's well written. It's a discipline thing. Use the web developers toolkit or Firebug and keep checking all the time. I don't care if IE 6 shows your site correctly. I bet IE7 doesn't. Who would buy a car that only ran on blacktop and not on concrete roads?

4. Don't air your dirty laundry in public

If your web application is properly tested (you do have QA right?) the end user should never see an error message. God forbid your code throws an exception and vomits all over the end user with debugging information. One site I went to threw a monkey wrench and then showed me a page full of every server and application level variable it could find, and then for good measure included them in a comment in the web page. I have also seen so many messages like "could not connect to database" and "timeout occurred reading database" I felt like visiting the competition. And usually did.

If you have to demonstrate poor QA and show an error page at least put it in context of the site and don't scare your customers with it. Architect your logging system to track problems and provide information to the programmers. Don't be like one employer I had who hid the logs from the developers out of some stupid security paranoia.

Whatever you do, don't include your test code and development comments in your web pages or javascript. yellowpages.com happily loads their unittest.js file on every page. Not that I want to test for them.

5. Use modern web design

Table based sites are so 19th century. Yet look around the web and see the fruits of old web design. CSS is your friend. Dreamweaver is your enemy. If your web designers are unable to build sites by hand using modern techniques and style with CSS then don't give them Dreamweaver until they can. There are millions of sites devoted to modern web design so there is no excuse to not learn how. If you can't write HTML by hand then reading the articles won't make an impression. Web design is programming + art. Accessibility, usability and maintainability are all made easy doing things the modern way and treating it as an engineering task.

6. Support all modern browsers

There aren't that many anyway. Other than IE6 and IE7 all the others are pretty similar. Saying you only support IE is stupid these days as there are two fairly different versions, with IE7 being somewhat closer to the others (yet screwed up in its own way). Code to the standards, adjust for IE6 and IE7.

Would you shop in a store that said "Whites Only!"? No, and I don't want to shop in an online store that says "IE only". Even worse are the places where they don't tell you you're not supported until the last minute. It's like going to a store and after filling up your cart, having the cashier tell you "we don't serve your kind here". Not real smart, telling customers to get lost. They will.

7. If your application has special needs, check up front

If you use javascript, flash, cookies, or something special (like a plugin) make sure you check on whatever the first page the customer sees and if you absolutely can't do anything with out it at least let the customer know up front. If you can work without it but have to degrade service either make it transparent or let them know what doesn't work. I don't want to have to explain your site to my mom.

8. Test your application usability with real users

It's amazing how many sites out there are so hard to operate. Sometimes I wonder if anyone other than the engineer actually used the site for its intended purpose. If you offer search, can anyone find useful stuff with it? Is your navigation clear? I went looking for some security hardware for my door and wound up at a Honeywell site, wherein I couldn't find anything useful and gave up after several fruitless moments. Then I went to their competition. Engineers, QA people, managers and the like are not users. If I can't find something I want on your site, then how will my mom?

9. Use a real database

Access is not a real database. Neither is Foxpro. If you can't afford (or don't want to buy) something like Oracle then use MySQL, or even better Postgres (or my personal favorite H2). Access is a toy. Would you drive a lawn mower on the highway? I've always been amazed at companies that have mission-critical information stored on someone's desktop in an Access database. And don't get me started on people who manage data using shared Excel spreadsheets.

10. Don't use platform specific functionality

ActiveX controls are the most evil things you can use. They lock you into a platform, and yet don't work easily in IE7 anyway. Just say no. If you have to Flash is always a better choice since it is available to most people.

11. Realize your customers don't all have T3 lines

An average directory page on amazon.com is around 350K and has 43 separate HTTP requests. Yikes. At least 20% (or more) of people in just the US still have dialup. One friend works by day on internet backbone switches and goes home where he has nothing but dialup available.

Compress, combine and cache were possible. I found that my biggest bandwidth hog was prototype.js. Once I compressed it and delivered it that way it almost vanished from the list. Just because I have a 6MB/sec cable line doesn't mean you aren't paying for it on your end. Most browsers only do 2 connections at a time so why make it hard on your customers and yourself.

12. Deal about accessibility and internationalization early

If your webstore or product site only caters to rock-climbing englishman, maybe you can get away with ignoring the needs of the disabled and those who speak other languages. Think about this before you build.

13. Test early, test often

You do test your web application? Testing should begin long before it's complete. Test the code, test the database, test the usability, test the environment and infrastructure. Test as if people would die if you didn't. Test as if your customers would all leave you if you fail (they will!). Test on all major browsers. On my Macbook Pro I can run IE6, IE7 (I need a bit more disk space), Firefox, Safari and Opera. I am sure a Fortune 500 company can afford more.

If you do all of these things then life will be good, people will love you, you will get rich and everyone will shower you with goodies.

Maybe yes, maybe no; but at least you can know your web application doesn't suck.

Kevin Hoang Le 03/21/2007 13:43
  1. Absolutely NO pop up windows. Pop up windows are evil. Once a window is popped up and somehow gets hidden behind other windows, the link that pops it up will appear not working. If you install Firefox add-ons, they show up again in the pop up windows. Very evil.

  2. Along with the comment about no tables, NO frame-based web application or site should ever be even considered.

  3. If you web application requires sign-in/log-in, ensure that it has a logout command and ensure the logout command does what it's supposed to do regardless if the back button is clicked on. It's possible. Read my articles:

http://www.javaworld.com/javaworld/jw-10-2006/jw-1006-logout.html

or better yet check out my demo:

http://pragmaticobjects.org/properLogoutDemo/

No excuse not to do it right.

codist 03/21/2007 14:04

This site is a perfect example of suckiness: http://www.hrodc.com/. What a monster!

Impatient 03/21/2007 15:53

Here's an irony: that webpagesthatsuck.com site really kind of, well, sucks. Ads all over the place, difficult navigation, etc.

mike 03/21/2007 16:21

so, then, what do you suggest happen if the db is maxed out? to show nothing at all?

jd42 03/21/2007 16:38

I would add to #6 "please re-test the apps you wrote for IE to make sure they work with Firefox..." Amazing how many sites don't work with FF, esp. tech sites where users are prone to use Firefox.

Good article. I've bookmarked so I can share with my team.

jtheory 03/21/2007 19:36

If the DB is maxed out, the point is that showing the details of the error doesn't help the user, any more than stack traces do (or exhaustive debug info...). Your logging should record all of that information for your developers, and probably shoot off an email automatically -- don't expect your customer to copy and paste the error details into an email (because chances are, they'll just go elsewhere).

Instead, tell them what they want to know. Here's the sophisticated approach:

"We apologize; our website is currently experiencing an temporary surge in traffic. The order you submitted could not be processed, and the problem has been automatically reported to the webmaster. Please try back later, or place your order over the phone, at ________. Thank you for your patience!"

Or if you have a simpler error handling system (where you don't have custom messages set up for different errors):

"There was an error processing your request. The details have been reported automatically to the webmaster; most problems are corrected within 24 hours. Please try again later -- we apologize for the inconvenience! If you have an urgent problem, please contact customer support at _____."

You get the idea. The main point is to look at it from your user's standpoint. It's like when your camera's memory card is full -- do you want a screenful of data and a stack trace, or a simple message saying "your memory card is full"?

Tim Weaver 03/21/2007 20:20

DocType should not be optional. Always use DocType and validate against it.

Use a Real Database isn't really great advice. Maybe better advice would be don't use a database if you don't need it. Understand the role of a database, chose wisely [no I'm not advocating Access or Excel], but blanket statements are dangerous. Many times people who don't understand the problem domain are making these decisions and they are just plain wrong.

I would add one:

Hire a real expert in web site development if only to test your ideas out and get an understanding of the platform, design decisions.

mike 03/21/2007 21:11

thanks for the claification jtheory.

codist 03/21/2007 21:23

If your DB is getting maxed out it might an indication of other problems as well. Sometimes all you need is caching; sometimes you might have to look at spreading the load over more servers. Problems aren't always a single point in your architecture.

Of course if you don't need a database don't force yourself to use one, my comment was meant for those apps that need one.

Ian Lloyd 03/22/2007 05:51

Here is something of an irony - I couldn't add a comment on this page at work because you have used a JavaScript library technique to enable the comments facility and the library that you use is stripped by the firewall (because of eval statements contained)

This is another example, I'm afraid, of a sucky technique. A comments facility that simply reveals the fields and requires a library to do this is the proverbial sledghammer to crack a nut. So please add that to the list!

My original reason for commenting was to say that pop-ups can be built accessibly and with standards in mind. I just updated the Perfect Pop-up article that I wrote in 2002 (eek!) to use unobtrusive JavaScript and have also created a pop-up builder to accompany it:

http://accessify.com/features/tutorials/the-perfect-popup/

http://accessify.com/tools-and-wizards/accessibility-tools/pop-up-window-generator/default.php

Mike Owens 03/22/2007 08:48

I'm not a fan of Javascript not gracefully degrading, but once you have a proxy or firewall in place that is filtering Javacript files based on arbitrary language constructs, the problem is pretty much on your end. It's not like eval() can generate any code that the author couldn't have placed in plaintext.

I noticed the.codist{} doesn't even try, but how is any site supposed to gracefully degrade in that situation? Your browser would ignore noscript tags, and JS-based detection would pass, assuming it used a random subset of the language no one can test against.

Deepak Tiwari 03/22/2007 08:49

Excellent material!

I have something to add for point no 2. (Use compression)

There is a side effect of turning on compression. Compressing content before sending to network takes a lot of cpu cycles. So there is a trade off. One should perform few test to find out a threshold value (size of your html/javascript/css file). Assuming the value comes 20kb. Then it does not make sense to compress files less than 20 kb. because the time taken to compress them would be more or less equal or more that what you saved in network time.

Fabrizio 03/22/2007 09:02
  1. DON'T USE Microsoft tools or Microsoft OS!
codist 03/22/2007 09:07

Prototype.js is used by lots of sites. Hard to imagine why anyone turns off 'some' javascript imports; there isn't much I can do to deal with this. But I have worked for paranoid network operations people before so I can see how it happens...

codex 03/22/2007 18:27

I disagree about keeping the javascript and css off the html page -- simply because keeping the number of requests down can greatly improve performance. I put common css and javascript for many pages (that'll just be called once) in an external file -- put anything for one page directly in that page.

turambar 03/25/2007 15:16

classic example of a programmer with one side of thinking. tableless layout doesn't make one site good and css/xhtml is not a miracle pill. content, organisation and ease of usability make one site great or not.

krallendoerfer 03/25/2007 22:03

Good advice but I had to pause at #9. I think what you really want to say with "Use a Real Database" is something more like match the DB to the purpose of the application, the characteristics of the data, and the amount of traffic you expect. I agree that a corporation shouldn't keep its accounts receivable in Access but what about, for example, my facility's loading dock equipment inventory? What possibly could be the harm in them using Access or Foxpro for the DB? This isn't a Fortune 500 app, to be sure, but those data are pretty important to them (mission-critical, in fact) and to the few dozen users each week. The choices for this type of app, given cost and other constraints, is often not between real and toy but instead between toy and jack. If someone (IT management) told them "you gotta use MySQL instead of Access," they'd just go back to emailing Excel sheets like they used to.

codist 03/26/2007 00:09

I guess for me the problem with using lightweight DBs is that often the web applications wind up growing bigger, and ultimately could become a nightmare to support. I've seen this many times so it makes me a bit wary. One app is not a problem, but if you wind up with 10 of them in various departments you have no idea where your data is sitting or if it will be backed up. You can also wind up with security issues when the mission critical data isn't protected. Like everything, there is a balance point.

Matt Schwartz 03/27/2007 10:52

Along with using "a real database" the application should be built for expandability from the start. Many web sites start small and then hit a wall when it's time to expand to multiple database servers. If replication (or something similar) had been planned from the start, expansion would be much easier. For some web apps it can mean a total rewrite.

codist 03/27/2007 15:37

It looks like reddit finally saw the compression light.

Harvey Sugar 03/28/2007 21:51

Great list, I'm book-marking this page.

Especially the comments about tables and valid (X)HTML. I've just finished my third part time contract fixing a Web site that looked fine on IE6 but looked horrible on Firefox. because of ancient formatting techniques and invalid HTML.

snlr 05/02/2007 08:25

Great article! Seriously guys, "not using a real database" is a mistake, "misusing tables for layout" is a mistake ... and mistakes should be pointed out and then avoided. Now IF database A is a real database or IF site B that uses tables is a great site, that is good stuff for another article. Now speaking of other articles ... ping:

http://www.bitweaver.org/wiki/Use bitweaver to build a web site that does not suck