Use generic tools like firebug to get a good feel for what really happens in your browser. How many files are requested? How long does everything take?
Some common problems and solutions:
Number of requests. Something that helps a lot: combining your javascript and css files into one file each. There are tools to help you with that. For images, you can do the same for icons by making one big sprite image.
Total download size. Javascript-driven map websites are quite big download-wise. You can minify your javascript by automatically removing non-significant whitespace. Use a tool for it and integrate it into your build sequence. And set up your webserver to gzip your files on the fly. Openlayers is normally 2650kb, minified it is 950kb and minified+gzipped 210kb!
Also dead unused code can take up a lot of unnecessary space. Google closure can help you detect it. Especially with big webgis projects it is easy to have unused code. Openlayers, for instance, almost surely has functionality that you don’t need. A minimal openlayers client with WMS only has to be 40kb minified and gzipped!
Lot of repeated request. Browsers requesting items over and over and over again. Set cache headers (for instance with apache’s mod_expires module). Allow the client to cache items.
Look at yslow to get extra tips on improving your page speed.
Tile your map. It helps improve the user-percieved speed. And especially for static maps that can be cached, it helps the speed enormeously. And something like mapproxy/tilecache/geowebcache can help you further. You can take a hybrid approach with static data via tiles and dynamic data with a generic WMS request.
My name is Reinout van Rees and I program in Python, I live in the Netherlands, I cycle recumbent bikes and I have a model railway.
Most of my website content is in my weblog. You can keep up to date by subscribing to the automatic feeds (for instance with Google reader):