A lot of effort goes into minimizing the time needed to render a page on the server; however, it is easy to overlook optimization on the client-side. The total time needed to display a page can be divided into two intervals: server processing time and the time between when the first byte is received by a user's browser until the page has finished loading. Even if you're only serving static files, the total time to load a page can still be significant. This entry discusses several techniques developers can use to improve client-side load times.
Another way to reduce loading is to optimize images. Various utilities such as OptiPNG and PNGCrush can significantly reduce image sizes without sacrificing quality. smushit.com does this as well.
If the target audience is spread throughout the world, it may make sense to use a CDN (Content Distribution Network). A CDN is a set of severs placed in different geographical locations to reduce the distance between a user and the data.
Of course, if the browser already has the data requested by a page then there is no need to reload it. Browsers do this automatically through caching but it is possible to use expires headers to direct them to cache certain data longer than they normally would. To do this, you set the expiration date to a time far in the future. But, doing this means you must use a different filename if you want to change data that has been cached. Askapache.com goes over this in more detail and also provides some other suggestions.
Finally, it is important to be able to measure a page's performance before and after it has been optimized. One way to do this is by using the Firefox plugin, Firebug, which shows how long each request takes. YSlow, a plugin for Firebug, provides grades across 13 criteria. In general, the law of diminishing returns applies to the optimization process. Sometimes practicality makes certain enhancements unrealistic.