D6 imagefield uses the $getsize parameter of theme_image() to populate the dimension attributes (width and height) of the HTML image tag. However, this involves calling getimagesize(). This means performing I/O for every image in every page request.
There are a number of problems with this:
- It's slow. Even checking a file exists on a local file system every time you serve it has performance issues. I have personal experience of dramatically speeding up a site by removing this sort of code. Syscalls are expensive and to be avoided as much as possible. This is why we switched from time() to $_SERVER['REQUEST_TIME'].
- If the image is in a directory that is mounted as a remote filesystem (very common) then performance is really appalling.
- If the image URI is a streamwrapper to S3 or rackspace then it isn't possible to read in the image at all.
- If the image hasn't been generated yet then it isn't possible to determine the dimensions.
When imagefield made it into core, it did not use the $getsize facility. $getsize was later removed from core completely: #908282: Remove unnecessary I/O from theme_image()
The patch in this thread takes a different approach that doesn't have the scalability problems of D6 imagefield:
- Dimension columns are added to the schema for image fields. These are populated when the image is added to the field. The D7 patch creates and populates these columns in an update function.
- Image effects provide an addition callback that just transforms the dimensions of the image. When theming a styled image tag, these transformations are applied cumulatively to the dimensions of the source image in the same manner as the actual image transformation. Unlike D6 imagefield, this works for styled images that are yet to be generated and also for images that are not being stored locally.
So you get the best of both worlds - no I/O is performed. It works with remote streamwrappers. The first time an image style is rendered it has the correct dimensions in the tag. This prevents the page from jumping around during AJAX image upload and after node save.
User interface changes
Image effects may now (optionally) supply a dimensions transformation callback. The patch updates the API documentation. The patch also has a test to ensure that effects with no transformation callback still work correctly.
Original report by jensimmons
If I inspect source on a Drupal 6 website (that's using filefield, image field, image cache, etc) I see HTML that looks like this:
<img src="/sites/example.com/files/something/kitten.png" width="500" height="350" alt="a picture of a cute kitten">
But, when I go to a Drupal 7 website, the height and width are not specified. :(
This is a performance bug. The page has to be rendered twice when no height and width are specified — the first time in drops images into a small space, calculates their height and width, and then renders the page once it knows their actual size. It's terrible.
Is this a regression bug? The data for height and width is right there. It's known. It's just not printed. We want to fix this as soon as possible.