DNS Google

Un Official dns google Blog

HTTP Caching

Author: Steve Lamm, Engineer on Web Performance

Recommended experience: Basic understanding of HTTP, Configuring web server.
When you set the correct HTTP caching headers, you get a double win because revisits to your web pages load faster and there is less load on your web server.


The cache, which is local copies of resources, works because many resources change infrequently. When a browser can reuse a local copy, it saves the time to set up a connection as well as the time to download. The key to making the cache work effectively is HTTP caching headers, which are sent by the web server to specify how long a resource is valid and when it last changed.
The HTTP protocol gives two ways to define how long a resource is valid: the Expires header and the Cache-Control: max-age header. The Expires header specifies a date after which a resource is invalid. At that point, the browser will ask for the resource again. max-age works much the same way but it specifies how long a resource is after it is downloaded instead of giving a specific date. That is nice because you can configure your web server with a constant value.
We recommend that you set the Expires header or max-age to be at least one month in the future and preferably a year in the future. You only need to set one of the two headers. If you set both, the max-age header overrides the Expires header. If your resources change more often than that, you can change the names of the resources. A common way to do that is to embed a version number into the URLs. The main HTML page can then refer to the new versions as needed.
Once a resource is invalid, a browser has two options. It can download the resource again, or do a conditional GET request which only downloads the file if it has changed. In order to make a conditional GET request, the browser needs a way to specify what version it has in the cache. Once again it is up to the web server to provide that, and once again the HTTP protocol gives possibilities: the Last-Modified header and the ETag header.
The Last-Modified header is the date the file last changed. The ETag header is a unique identifier for a particular version of the file. We recommend that you use the Last-Modified header because if the date is sufficiently far back, the browser may choose to skip requesting the file altogether.
To see these headers in action, try loading each of these pages twice:
To load the pages a second time, either click on the link again, or click on the address bar of the page and press Enter. If you click the Reload button, that forces the browser to do conditional GET requests if the resources are in the cache.
To take a closer look at these examples, you can download HttpWatch and use it to look at the HTTP headers.
To explore this topic in more detail, see Optimize Caching in the Page Speed tool documentation.

Additional resources

For information on writing the headers, try a search for "expires header" and your web server or programming language. Here are a couple direct links:

Improving website performance with Page Speed

It is often possible to make the contents of a web page take fewer bytes without changing the appearance or function of the page. Reducing the number of bytes a client has to download makes the page load faster. In this tutorial we look at three ways to reduce the size of web content. We also explain how to use Page Speed to help make resources smaller.
Page Speed is a Firefox extension that evaluates web pages and gives suggestions on how to improve them. Instructions for installing Page Speed are available at http://code.google.com/speed/page-speed/download.html. I chose Page Speed because I am familiar with it. YSlow is a similar tool which also gives excellent advice to make your web pages faster.


Compress images

Image files are often created with extra information embedded in the file. For example, JPEG files written by many image programs include the name of the program that wrote them. PNG images can often be made smaller by changing the way the image is encoded. These transformations are lossless. That is, the compressed image looks identical to the uncompressed image, but uses fewer bytes.
The Page Speed rule "Optimize images" tries to losslessly compress all images in a page. When it succeeds, it shows the compressed versions. To use the minimized version of an image, in the Page Speed panel, click the link to the compressed version, save it, and use it instead of the original image

Minify JavaScript

Removing comments and white space from large JavaScript files can make them substantially smaller, without changing their functionality.
The Page Speed rule "Minify JavaScript" runs all JavaScript on a page through a JavaScript minimizer. If this generates a smaller file, Page Speed displays a link to that file. To use the minified JavaScript, click the link, save the minified file, and change your HTML to refer to the minified file.
You will want to keep the original JavaScript file around in case you want to change it in the future. Minified JavaScript is much harder to read and modify. If you modify your JavaScript frequently, a command line JavaScript minimizer that runs as part of your build process might be more convenient than Page Speed. JSMIN, available at http://www.crockford.com/javascript/jsmin.html, is such a program.

Remove unused CSS

CSS files contain rules that apply style attributes to elements in a web page. If a rule does not apply to any element in a page, removing it will result in fewer bytes being sent to the client, with no change in the appearance of the web page. However, because external style sheets may be included by more than one page, you must be careful to only remove rules that no page uses. The Page Speed rule "Remove unused CSS" can tell you which rules are not used in a given page. By running Page Speed on all pages that use an external stylesheet file, you can determine which rules are not used and remove them.

More ways to make your pages faster

The three suggestions above are a small sample of the issues Page Speed can detect and recommend fixes for. Page Speed and YSlow both rank their suggestions, so that you know which changes to your page are most likely to have a large impact. Running these tools on your page periodically and fixing issues they find will give your users faster pages.
Make the mobile web faster

Make the mobile web faster

Author: Jeremy Weinstein, Google Webmaster
Mobile internet usage is skyrocketing worldwide. Throughout 2009, 50% of all new internet connections worldwide are coming from phones (eMarketer, 2008 and 2009). Google internal data shows that as mobile browsers improve, users' browsing habits increase.
Mobile browsers render web pages differently from desktop browsers, so some steps are needed to make them work well on phones. This article contains some basic technical and non-technical tips for making your web content faster and more suitable for consumption on mobile devices.

Make your pages and applications accessible to mobile

Provide an obvious link to the mobile version from the desktop version.
Do you really want users browsing your media-rich 800-pixel-plus wide site on mobile screens without even realizing there's a version you toiled over just for mobile? Make sure your users are even aware a mobile counterpart exists.
Use a conventional mobile URL, and advertise it.
No accepted standard exists for providing an address to a mobile version of a desktop service, but there are some recognized conventions: m.yoursite.com, mobile.yoursite.com or yoursite.com/mobile. Choose a simple mobile URL and publish it on your desktop site.
Make the user interface work for mobile devices.
Avoid requiring users to do a lot of typing. Provide large, actionable, clickable UI features. Provide URLs that are short and easy to type. Use easily actionable UI widgets and features that compose well together in a small format. Think about the scenario your mobile user is in when they're looking at your site: probably not sitting comfortable at a desk, so information must be able to be found fast. Make sure your content is clearly labeled and succinct.
Gmail for mobile
Gmail provides a mobile version which is more accessible for mobile devices.
Format your website for a range of mobile browsers.
Full-featured (Mobile Safari, Android, etc.), half-featured (BlackBerry), and small-featured (older-style flip phones) browsers all exist in the mobile space. Consider how your mobile web page will look on screen sizes all the way from 150x128 to 640x480. Mobile browser standards can also differ by country. If you have an international audience, make sure your design is flexible enough to meet the devices available in those countries.

Reduce the number of requests and the amount of data transferred

To avoid a dramatic increase in latency, it is a good idea to reduce the number of times your website or application must make a round-trip request to your server. Single large objects load faster than many small ones due to TCP and socket behavior. Keep in mind that while these are general best practices, they especially apply to mobile.
Sprite your images using CSS or transfer your images using a data URI scheme. See the logo image on a Google Search result page for an example of a CSS sprite. Some of Google's services, such as Wave, consolidate static requests by using the data URI scheme, which is a way of including static data items in-line on a web page. The data URI technique will not work on older browsers and should be used for pages and applications specifically designed for iPhone, Android, or other modern mobile web browsers.
An image created with the data URI scheme.
Including an image by its base64 string may cause a loss in some compression provided by image formats (data transferred this way must rely solely on gzip for compression). But, you do avoid opening a new connection/HTTP request, which is often a more important savings factor for mobile.
Instead of having a CSS file that imports several others, or a JavaScript file that loads other bits of code, consolidate all of your page's dependencies into a single file. Reducing your page down to a single file (and thus  a single request) will yield an increase in speed.
Minify your code.
The less code, the smaller the amount of data transferred, the faster your page will load. While the size of data transferred is often not as important as minimizing round trips, every bit helps on high-latency mobile connections. See an article on HTML optional tags and CSS optimization.
Eliminate redirects.
Sometimes web pages and web services will redirect a single request several times. If your service requires redirects, perform the redirection server-side rather than client side, in order to reduce client-side round trip requests.
Load contents lazily.
Transfer data when needed and preload where appropriate. Don't load images that will never be seen by the end user. Time-to-text on mobile is important. If you have a mobile application that displays a gallery of images, consider downloading the previous and next image to increase UI speed, but don't load images that are far "out of reach."

Take advantage of new features in HTML

Use an application cache for local content storage.
HTML5 browsers (Mobile Safari, Android) can use an application cache to both reduce page startup time and to enable offline features.
Use CSS3 instead of images where possible.
HTML5 browsers that support CSS3 (again, Mobile Safari, Android) can use attributes for rounded corners, gradients, shadows, text transformations, canvas, and more. Using CSS to design your page instead of images can reduce data transfer.
New APIs provided by HTML5 are already being used to make Google's mobile applications. Some examples include: Mobile Gmail uses Application Cache. Mobile Google Search uses the HTML5 Geolocation API to show location-aware results. Google Maps for Mobile and Mobile Gmail both use the canvas tag to avoid transferring images.
Plan for the lowest common denominator.
If you want your page or application to reach as many users as possible, you'll have to ensure its compatibility with varying degrees of support by mobile devices. Not only is minimalist code faster, but in general, the less complex the code, the more compatible it will be.
Some warnings:
  • Flash is currently not supported even by iPhone or Android browsers. Don't use it for mobile websites.
  • Many BlackBerrys do not have CSS and JavaScript enabled by default. Most users will not dig through menus to enable them.
  • JavaScript on devices with slow processors can be expensive to execute. Besides implementing network-based optimizations, it's important to make sure your client-side code is lean, mean, and uses minimal memory too.

Test, test test

If you're a web developer, you're already familiar with the pains of cross-browser compatibility on desktop web browsers. Cross-browser testing is just as important for mobile devices.
In order to better format content for mobile device screens, mobile browsers may resize text and images and interpret CSS differently from desktop web browsers. Verify usability after the mobile browser has "had its way" with your page.
Reading a mobile web page or using a mobile application can feel very different once you try it in your hand. Don't assume interaction on your PC is equivalent to interaction on a mobile device.
Testing resources:

Additional resources

Minimizing browser reflow

Author: Lindsey Simon, UX Developer
Recommended knowledge: Basic HTML, basic Javascript, working knowledge of CSS
Reflow is the name of the web browser process for re-calculating the positions and geometries of elements in the document, for the purpose of re-rendering part or all of the document. Because reflow is a user-blocking operation in the browser, it is useful for developers to understand how to improve reflow time and also to understand the effects of various document properties (DOM depth, CSS rule efficiency, different types of style changes) on reflow time. Sometimes reflowing a single element in the document may require reflowing its parent elements and also any elements which follow it.
There are a great variety of user actions and possible DHTML changes that can trigger a reflow. Resizing the browser window, using JavaScript methods involving computed styles, adding or removing elements from the DOM, and changing an element's classes are a few of the things that can trigger reflow. It's also worth noting that some operations may cause more reflow time than you might have imagined - consider the following diagram from Steve Souders' talk "Even Faster Web Sites":
From the table above it's clear that not all changes to the style in JavaScript cause a reflow in all browsers, and that the time it takes to reflow varies. It is also somewhat clear that modern browsers are getting better at reflow times.
At Google, we test the speed of our web pages and applications in a variety of ways - and reflow is a key factor we consider when adding features to our UIs. We strive to deliver lively, interactive and delightful user experiences.

Guidelines

Here are some easy guidelines to help you minimize reflow in your web pages:
  1. Reduce unnecessary DOM depth. Changes at one level in the DOM tree can cause changes at every level of the tree - all the way up to the root, and all the the way down into the children of the modified node. This leads to more time being spent performing reflow.
  2. Minimize CSS rules, and remove unused CSS rules.
  3. If you make complex rendering changes such as animations, do so out of the flow. Use position-absolute or position-fixed to accomplish this.
  4. Avoid unnecessary complex CSS selectors - descendant selectors in particular - which require more CPU power to do selector matching.
In this video, Lindsey explains some simple ways to minimize reflow on your pages:




Minimizing browser reflow

Author: Lindsey Simon, UX Developer
Recommended knowledge: Basic HTML, basic Javascript, working knowledge of CSS
Reflow is the name of the web browser process for re-calculating the positions and geometries of elements in the document, for the purpose of re-rendering part or all of the document. Because reflow is a user-blocking operation in the browser, it is useful for developers to understand how to improve reflow time and also to understand the effects of various document properties (DOM depth, CSS rule efficiency, different types of style changes) on reflow time. Sometimes reflowing a single element in the document may require reflowing its parent elements and also any elements which follow it.
There are a great variety of user actions and possible DHTML changes that can trigger a reflow. Resizing the browser window, using JavaScript methods involving computed styles, adding or removing elements from the DOM, and changing an element's classes are a few of the things that can trigger reflow. It's also worth noting that some operations may cause more reflow time than you might have imagined - consider the following diagram from Steve Souders' talk "Even Faster Web Sites":
From the table above it's clear that not all changes to the style in JavaScript cause a reflow in all browsers, and that the time it takes to reflow varies. It is also somewhat clear that modern browsers are getting better at reflow times.
At Google, we test the speed of our web pages and applications in a variety of ways - and reflow is a key factor we consider when adding features to our UIs. We strive to deliver lively, interactive and delightful user experiences.

Guidelines

Here are some easy guidelines to help you minimize reflow in your web pages:
  1. Reduce unnecessary DOM depth. Changes at one level in the DOM tree can cause changes at every level of the tree - all the way up to the root, and all the the way down into the children of the modified node. This leads to more time being spent performing reflow.
  2. Minimize CSS rules, and remove unused CSS rules.
  3. If you make complex rendering changes such as animations, do so out of the flow. Use position-absolute or position-fixed to accomplish this.
  4. Avoid unnecessary complex CSS selectors - descendant selectors in particular - which require more CPU power to do selector matching.
In this video, Lindsey explains some simple ways to minimize reflow on your pages:

Additional resources

Optimizing JavaScript code

Optimizing JavaScript code

Authors: Gregory Baker, Software Engineer on GMail & Erik Arvidsson, Software Engineer on Google Chrome
Recommended experience: Working knowledge of JavaScript
Client-side scripting can make your application dynamic and active, but the browser's interpretation of this code can itself introduce inefficiencies, and the performance of different constructs varies from client to client. Here we discuss a few tips and best practices to optimize your JavaScript code.

Working with strings

String concatenation causes major problems with Internet Explorer 6 and 7 garbage collection performance. Although these issues have been addressed in Internet Explorer 8 -- concatenating is actually slightly more efficient on IE8 and other non-IE browsers such as Chrome -- if a significant portion of your user population uses Internet Explorer 6 or 7, you should pay serious attention to the way you build your strings.
Consider this example:
var veryLongMessage =
'This is a long string that due to our strict line length limit of' +
maxCharsPerLine +
' characters per line must be wrapped. ' +
percentWhoDislike +
'% of engineers dislike this rule. The line length limit is for ' +
' style purposes, but we don't want it to have a performance impact.' +
' So the question is how should we do the wrapping?';
Instead of concatenation, try using a join:
var veryLongMessage =
['This is a long string that due to our strict line length limit of',
maxCharsPerLine,
' characters per line must be wrapped. ',
percentWhoDislike,
'% of engineers dislike this rule. The line length limit is for ',
' style purposes, but we don't want it to have a performance impact.',
' So the question is how should we do the wrapping?'
].join();
Similarly, building up a string across conditional statements and/or loops by using concatenation can be very inefficient. The wrong way:
var fibonacciStr = 'First 20 Fibonacci Numbers
';
for (var i = 0; i < 20; i++) {
fibonacciStr += i + ' = ' + fibonacci(i) + '
';
}
The right way:
var strBuilder = ['First 20 fibonacci numbers:'];
for (var i = 0; i < 20; i++) {
  strBuilder.push(i, ' = ', fibonacci(i));
}
var fibonacciStr = strBuilder.join('');

Building strings with portions coming from helper functions

Build up long strings by passing string builders (either an array or a helper class) into functions, to avoid temporary result strings.
For example, assuming buildMenuItemHtml_ needs to build up a string from literals and variables and would use a string builder internally, instead of using:
var strBuilder = [];
for (var i = 0, length = menuItems.length; i < length; i++) {
  strBuilder.push(this.buildMenuItemHtml_(menuItems[i]));
}
var menuHtml = strBuilder.join();
Use:
var strBuilder = [];
for (var i = 0, length = menuItems.length; i < length; i++) {
  this.buildMenuItem_(menuItems[i], strBuilder);
}
var menuHtml = strBuilder.join();

Defining class methods

The following is inefficient, as each time a instance of baz.Bar is constructed, a new function and closure is created for foo:
baz.Bar = function() {
  // constructor body
  this.foo = function() {
  // method body
  };
}
The preferred approach is:
baz.Bar = function() {
  // constructor body
};

baz.Bar.prototype.foo = function() {
  // method body
};
With this approach, no matter how many instances of baz.Bar are constructed, only a single function is ever created for foo, and no closures are created.

Initializing instance variables

Place instance variable declaration/initialization on the prototype for instance variables with value type (rather than reference type) initialization values (i.e. values of type number, Boolean, null, undefined, or string). This avoids unnecessarily running the initialization code each time the constructor is called. (This can't be done for instance variables whose initial value is dependent on arguments to the constructor, or some other state at time of construction.)
For example, instead of:
foo.Bar = function() {
  this.prop1_ = 4;
  this.prop2_ = true;
  this.prop3_ = [];
  this.prop4_ = 'blah';
};
Use:
foo.Bar = function() {
  this.prop3_ = [];
};

foo.Bar.prototype.prop1_ = 4;

foo.Bar.prototype.prop2_ = true;

foo.Bar.prototype.prop4_ = 'blah';

Avoiding pitfalls with closures

Closures are a powerful and useful feature of JavaScript; however, they have several drawbacks, including:
  • They are the most common source of memory leaks.
  • Creating a closure is significantly slower then creating an inner function without a closure, and much slower than reusing a static function. For example:
    function setupAlertTimeout() {
      var msg = 'Message to alert';
      window.setTimeout(function() { alert(msg); }, 100);
    }
    is slower than:
    function setupAlertTimeout() {
      window.setTimeout(function() {
        var msg = 'Message to alert';
        alert(msg);
      }, 100);
    }
    which is slower than:
    function alertMsg() {
      var msg = 'Message to alert';
      alert(msg);
    }

    function setupAlertTimeout() {
      window.setTimeout(alertMsg, 100);
    }
  • They add a level to the scope chain. When the browser resolves properties, each level of the scope chain must be checked. In the following example:
    var a = 'a';

    function createFunctionWithClosure() {
      var b = 'b';
      return function () {
        var c = 'c';
        a;
        b;
        c;
      };
    }

    var f = createFunctionWithClosure();
    f();
    when f is invoked, referencing a is slower than referencing b, which is slower than referencing c.
See IE+JScript Performance Recommendations Part 3: JavaScript Code inefficiencies for information on when to use closures with IE.

Avoiding with

Avoid using with in your code. It has a negative impact on performance, as it modifies the scope chain, making it more expensive to look up variables in other scopes.

Avoiding browser memory leaks

Memory leaks are an all too common problem with web applications, and can result in huge performance hits. As the memory usage of the browser grows, your web application, along with the rest of the user's system, slows down. The most common memory leaks for web applications involve circular references between the JavaScript script engine and the browsers' C++ objects' implementing the DOM (e.g. between the JavaScript script engine and Internet Explorer's COM infrastructure, or between the JavaScript engine and Firefox XPCOM infrastructure).
Here are some rules of thumb for avoiding memory leaks:

Use an event system for attaching event handlers

The most common circular reference pattern [ DOM element --> event handler --> closure scope --> DOM ] element is discussed in this MSDN blog post. To avoid this problem, use one of the well-tested event systems for attaching event handlers, such as those in Google doctype, Dojo, or JQuery.
In addition, using inline event handlers can lead to another kind of leak in IE. This is not the common circular reference type leak, but rather a leak of an internal temporary anonymous script object. For details, see the section on "DOM Insertion Order Leak Model" in Understanding and Solving Internet Explorer Leak Patterns and and an example in this JavaScript Kit tutorial.

Avoid expando properties

Expando properties are arbitrary JavaScript properties on DOM elements and are a common source of circular references. You can use expando properties without introducing memory leaks, but it is pretty easy to introduce one by accident. The leak pattern here is [ DOM element --> via expando--> intermediary object --> DOM element ]. The best thing to do is to just avoid using them. If you do use them, only use values with primitive types. If you do use non-primitive values, nullify the expando property when it is no longer needed. See the section on "Circular References" in Understanding and Solving Internet Explorer Leak Patterns.
Optimizing OpenSocial Gadgets

Optimizing OpenSocial Gadgets

Author: Tyler Odean, iGoogle Product Manager
Recommended experience:
In this article we'd like to highlight a few basic steps that gadget developers can take to improve the performance of their gadgets in iGoogle and on other OpenSocial enabled containers throughout the web. Gadgets that load quickly and are responsive to user input are more popular and more likely to remain installed on a user page, and a compact properly-cached gadget reduces hosting and bandwidth costs. With a few simple steps you can accelerate your gadget's performance.

Use tools to profile your gadget and pinpoint bottlenecks

The best practices for designing a gadget are the same as the best practices for maintaining any web property. You can use plugins and tools such as Page Speed and Firebug to profile the requests that your gadget is making to identify bottlenecks. For a list of tools that can help you improve the performance of your gadget, please check the downloads page. We recommend loading containers as a baseline and then compare the latency of the empty container with the latency of the container with the gadget installed in a variety of browsers and cache states. For more information on how to use profilers to diagnose your gadget, check out the latency measurement tutorial.

Use caching for your dynamic content

Most containers offer support for the Cache-Control HTTP header. You have server-side control over how your resources are cached, so be sure to set your headers appropriately for maximum benefit.
The Cache-Control header is best described in the HTTP/1.1 specification but there are some simpler descriptions available as well. If you're not sure about the cache headers your server is currently sending, you can try some publicly available tools to examine the cache headers on your files and see if they need to be tweaked.
Be aware that the Cache-Control header will be examined for all content coming from your server, including XML application specs, responses from makeRequest (both prefetched and not), and proxied images. Be sure to set caching headers for all of this content! You can also take advantage of the container to ensure that your content is appropriately cached by directing requests through gadgets.io.getProxyURL( OrigURL ). Proper caching will not only reduce end-user latency, it will also help minimize bandwidth costs associated with hosting your gadget. For more information on using gadgets.io.getProxyURL you can check out the OpenSocial Latency Combat Field Manual.

Reduce the number of fetches

Clients that use persistent connections SHOULD limit the number of simultaneous connections that they maintain to a given server. A single-user client SHOULD NOT maintain more than 2 connections with any server or proxy.
Because of this, some internet browsers (such as IE7, for example) will only maintain up to two parallel connections to a server and will serialize any other image/CSS/javascript download connections your gadget is making. Inlining and consolidating scripts, spriting your images together and other forms of request batching will significantly increase the responsiveness of your gadget. Aim for a single CSS and a single JS file in production. And of course, if you aren't making use of a particular section of CSS or JS, you should remove it from the gadget code. Ideally any resources which absolutely need to be loaded separately should be distributed over multiple servers so that browsers don't bottleneck the requests because of the concurrency restriction. Batching requests, lazy loading and preloading can all be employed to help reduce the number of open connections and roundtrips that your gadget requires - check out the OpenSocial Latency Combat Field Manual for more advice and suggestions.

Other best practices

  • Turn on gzip for any content you deliver. Good things come in small packages.
  • Run the Gadget Checker. The Gadget Checker gadget checks your gadget code for many common errors, some of which can definitely affect latency.
  • Minimize Javascript and CSS. Any resources which your gadget does not use should not be delivered. Also don't forget to minify the javascript.
  • Split CSS and image files over 2-4 servers. Browsers limit the number of concurrent connections to any one server. If requests cannot be batched, they should be distributed over several servers to avoid this bottleneck.
  • Place Javascript as late in the page as possible. Gadgets and webpages are loaded and rendered from the top down. Let user visible content like HTML, images and CSS be higher priority in download order.

Optimizing web graphics

Author: Susie Sahim, Web Designer and Google Doodler
Recommended skills: Basic image manipulation
When you optimize every line of code for your website, don't forget about your static content - including images. Simple improvements can drastically decrease your download size, without diminishing the site's quality.


Here are a few tips to help you make your web graphics load faster

Crop out excess white space

Sometimes you have extra space or padding around graphics so that they don't touch accompanying text or web page elements. Instead, crop out that space and use CSS to create the padding around the graphic.

Use the best file format

For images containing flat illustrations or artwork, use the 8-bit PNG or GIF format and reduce the number of colors in the palette. Some image programs such as PhotoShop allow you to save the image for the web and fine-tune the image settings. By reducing the color palette from 256 to something like 32, you greatly reduce the size of the file. The less colors that the image has, the smaller the file size is going to be.
For very detailed and colorful artwork or for photographics, JPG and 24-bit PNG are typically used because they have a much larger color palette. While a 24-bit PNG results in superior image quality, this comes at the price of a larger file size. When you can, use JPG instead and adjust the quality setting so you can compress the image as much as possible within your desired tolerance for image quality.
To compare and contrast, here are the file sizes of the above graphic in various formats:
  • JPG, 60 quality - 32K
  • PNG-8, 256 colors - 37K
  • GIF, 256 colors - 42K
  • PNG-24 - 146K
Also note that JPG has an option called "Progressive" mode. This option adds multiple copies of the image at lower resolution to make the image appear quickly on the screen, while progressively improving in quality. But it also increases the overall size of the image.
PNG also has a similar feature called "Interlaced". You may want to turn this feature off so that the full image downloads quicker.
Because the 8-bit PNG and GIF formats have the potential to result in much smaller image files, try to keep this in mind when creating graphics and illustrations for your site. Try to keep the amount of colors to a minimum and use flat graphics instead of photographs. This way you can create images with palettes of 16 colors, keeping the file size extremely small and fast to download.

Additional resources