We have seen the
<img> tag before: it's used to insert an image on a page.
src attribute gives the URL (absolute or relative) for the image file and the
alt attribute gives text that can be used to replace the image if it can't be loaded.
You can also specify a width and height for the image (in pixels):
<img src="vacation.jpg" alt="Us on vacation" width="400" height="300" />
Specifying the size lets the browser draw the page before it loads the image (since it knows how much space to leave on the screen). Loading the page will feel faster to the user.
<img src="vacation.jpg" alt="Us on vacation" width="400" height="300" />
But do not use this to resize a big image. The width and height should match the image size (or maybe half size, for high-resolution screens).
If you use a large image file, the user still has to download it, which will be slow. Resize in an image editor to the size you need, so the file is small.
Be careful of your file sizes!
Remember that the user has to download all of your HTML + CSS + JS + images to see the page. Images are the ones likely to be very large. The larger they are, the slower it will be.
A suggested target: <1 MB for all files combined on your page. The developer tools
Network tab will show you the combined sizes of the files.
Definitely a bad idea: using images straight from your phone (or other camera).
Those will be several MBs each. If you want to use a picture you took, use an image editor to crop/​resize to what you actually need.
Try loading your page from a slow wi-fi or mobile network to get a better idea what your users may deal with.
The developer tools
Network tab has an option to
throttle to a slower speed, so you can experience a mobile user's page load.
There are two basic ways to represent images for the web: bitmap or vector graphics.
In bitmap graphics (or raster graphics), images are a grid of pixels. Each pixel has a colour. If the pixels are small enough, our eye is fooled into seeing an image.
With vector graphics, images are a collection of shapes: lines, curves, circles, etc.
Vector images are nice.
They can be scaled more smoothly: you can can grow/​shrink a circle (or line or curve) as much as you want. That's nice for printing, or high resolution displays, or for zooming on a mobile device.
It's often easier to edit a vector image: you can manipulate shapes separately since they are represented separately in the file.
Vector images often have smaller file sizes, if the image is made of the kind of shapes they naturally store.
Bitmap (raster) images are nice.
Vector images are limited the shapes they can represent: bitmap can represent anything.
Cameras (and scanners, etc) naturally produce bitmap images because that's how their sensors work.
Bitmap images likely have smaller file sizes where you don't have vector-friendly shapes (and use your format properly: more later).
The lesson is probably: use vector when it fits; bitmap otherwise.
Vector images make sense for a company logo or shape-based design. Bitmaps for photographs or other non-simple-shape images.
There's really only one vector image format to worry about for the web: SVG, Scalable Vector Graphics.
Other vector formats you might have seen: PDF, Adobe Illustrator, EPS.
There are more choices of file format for bitmap images, and more options when you create/save the files.
Knowing the differences can make your images look better with smaller files.
We need to choose an image format appropriate for the web. Like with HTML and CSS, we are limited to what users' browsers can handle.
That means PNG, JPEG, and GIF (and SVG for vector images).
[There are a few newer formats that could be used, WebP, JPEG XR, but they have imperfect browser support. My experience is that using PNG or JPEG well is good enough to not worry about the newer formats. Further evidence: Facebook, Instragram, etc all use JPEG or PNG, even if your browser supports WebP.]
Our goal throughout this section is to have the smallest possible file size with an acceptable quality image.
For bitmap images, the first step is going to be to resize the file to the size you need. Resizing with
height in the
<img> tag doesn't change the file size.
For each pixel, we need to store a colour. How much information do we need to store for each pixel?
The answer depends on how many choices of colour we have for each pixel.
The default is usually 24-bit colour: the file stores 24 bits for each pixel and get 224 = 16.8 million possible colours. Also called full colour.
(Not coincidentally: there are also 224 six-character CSS colour codes that allow the same colour choices.)
This is enough to represent photographs, or other images with many colours, but lots of data to store, leading to large files.
If our image doesn't have a lot of unique colours, we can limit the number of choices for each pixel and thus store less information for each.
This usually this means choosing a palette of colours for the image, then choosing each pixel from those. Often 28 = 256 colours, requiring 8 bits for each pixel.
Or some smaller power of two.
Storing 8 instead of 24 bits per pixel should make the file ≈1/3 the size, but at the cost of having fewer possible colours in the image.
So, this is a great idea for images that have few unique colours, like including logos, drawings, comics, or screenshots. For images with lots of colours, we'll make the image look much worse: photographs, full-colour illustrations.
number of colours might be higher than is obvious. This looks like three: white, black, and red:
But on a closer look, there are many greys, pinks, and dark reds:
JPEG images only stores 24-bit colour.
PNG can store 24-bit full colour, or 8-bit or less paletted images.
GIF can store 8-bit colour or less.
Especially when working with PNG, check your image editing program for
colour depth or
Choose the smallest palette possible, but no smaller.
We also need compression: raw pixel data is too large, even for small images.
Windows BMP files are usually not compressed, and huge. (A 500×500 pixel full colour image will be 732 kB.) They don't make sense on the web.
Every other bitmap format uses some kind of data compression to make smaller files.
Compression can be lossless or lossy.
With lossless compression, you can compress and uncompress and you'll get exactly the same thing back.
With lossy compression, there may be some changes, but hopefully not noticeable.
PNG and GIF use lossless compression algorithms. PNG's compression is generally better, and produces smaller files.
SVG images are often compressed with a lossless algorithm (but not always: they tend to be big when not).
JPEG uses a lossy compression method designed for photographs.
Given a photograph, JPEG should be much smaller than PNG and visually identical.
For non-photograph images, JPEG usually does a bad job. Same simple image, saved as JPEG (scaled 2×):
Detail (scaled another 10×):
JPEG compression has a quality scale: 1 to 100 (or similar, depending on the program). Lower quality will
lose more, but have a smaller file size.
Generally, quality 50 or higher looks the same to me. You can choose the smallest file size where you're happy with the quality.
When you have an image to put on a web page, what do you actually do?
First choice: vector or bitmap?
If SVG makes sense for your image, you probably should use it.
The previous SVG example (left) and converted to PNG (right) look the same:
The SVG version is 15 kB (after compression); the PNG is 44 kB (after my usual tricks to make a small file).
And the SVG is still a vector image, so it scales smoothly. A detail of the SVG and PNG at 10×:
All-around, a better choice.
If you have a picture that doesn't make sense as a vector image, forcing it to be one isn't going to go well:
Original JPEG: 29 kB. Compressed SVG: 87 kB (and worse quality).
For a bitmap image, you need to ask if it is a photograph or not: photos should be JPEG. Non-photos should be PNG (since the compression is better than GIF, and you have more colour choices.).
Something like this scanned text is probably not going to work well in a vector format.
This original image (scaled 50% here) is 24-bit colour and 88 kB.
It doesn't seem like there are a lot of distinct colours: changing to 4-bit palleted colour (
indexed with 16 colours in GIMP) looks the same to me (right):
… but is 16 kB.
Maybe this could be a vector image? In Inkscape, you can
Trace bitmap to convert to vector curves (right):
It's 39 kB compressed, and probably slightly worse looking.
When an image is a photograph, we probably want JPEG. This image (cropped from a phone photo) was a JPEG originally and 214 kB (scaled 50% here):
But the JPEG quality option was 96 (probably because that was the phone's default). JPEG with quality 50 (right) looks the same to me, and is 68 kB:
JPEG with quality 5 (right) is only 24 kB, but probably lower quality than I would like:
Saving the original as a PNG looks identical (because it has 24-bit colour and lossless compression, left) but is 603 kB. Reducing to 8-bit colour looks okay (right), but is still 229 kB.
You can sometimes get a little more savings with automated tools that will try compression options not usually available in image editing programs, and give you the best results.
Lesson: choice of file format, colour depth, and compression have a huge impact on file size. If you make good choices, you can get a small file with no noticable loss in quality.
On the web, file size matters. Files double the size take twice as long to download, and your site will be slower.
My experience: on most web sites (that have some images), I can bring the total download size to about 50% by knowing these things and applying them.
Some examples from students' assignments in CMPT 165:
.jpgfile, but actually contained PNG data 258 kB. Renamed file
.png. Saved as JPEG at quality 75: 36 kB