Anyone who has encountered the task of making adaptive graphics knows that there are already many decisions, but no unanimous decision exists. Often, the choice and application of solutions for adaptive images become a headache for front-end developers. They have to replace
src
images, upload single-pixel images and sculpt other crutches. It did not suit us and we decided to make our scooter.
On typical sites, images can appear in three ways.
- Be elements of site design (backgrounds, buttons, etc.).
- To be loaded through special modules (for example, images in a photo album).
- Pasted through the WYSIWYG CMS editor (for example, in the text of the article).

We wanted to get such a solution, which would be some kind of "superstructure" above the site. So that you can not get into the CMS code, through which images are uploaded to the site, and also not to prepare adaptive images manually.
First comes to the aid of the implementation of
Adaptive Images ...
Adaptive Images method
The idea is to provide these very adaptive images with a minimum of changes in the site code. The algorithm is as follows:
- A small javascript writes the maximum value of the device width / height into cookies. It is assumed that a picture larger than this size does not make sense to show.
- With the help of the directive in
.htaccess
rewriting of all site images to the php-script adaptive-images.php
. - In the php-script there is a configuration of permissions (associated with media queries of styles). The value from the cookie is adjusted to the closest value from this config. If an image along the requested path exists and its width is larger than the required one, the image is clamped and placed in a special cache folder (if it was not squeezed beforehand).
- The script gives the picture to the client.
Adaptive Images Pros
- There is no need to change the site code, except for inserting a single line js.
- No need to pinch the pictures manually, they will perehmut if necessary.
- No extra client requests.
- The lifetime of cached images is supported - when updating the original, sooner or later the cached ones will be updated.
- Easy to implement, just as easy to roll back, if you need to change the size of the pictures, everything is solved by editing one array.
Cons Adaptive Images
And now a little about sad things. This solution implies that all (generally all) pictures on the site will be given not by nginx, not apache, but by a php-script. Each picture is the start of the php interpreter (even if the picture is already pinched). This is both
slow and
ideologically incorrect .
')
We wanted to keep the advantages of this method and get rid of such a terrible flaw.
Our option
The main idea: do not run a php script if the image already exists. For this apache, at the time of the redirect, you must know the name of the image compressed under this resolution. This means that the definition of the resolution must be transferred from php to js. So js should not just calculate the maximum value from the width / height of the device, but also determine the required resolution, and write it in the cookie.
Also, in order for apache to check for the presence of a picture, it must know the rule by which the pinched images are saved (in particular, the name of the cache folder), which is generally defined in the php script.
Here we obviously lose some flexibility and get some kind of duplication of information.
- The permissions array should be duplicated in the js-script.
- The cache folder and the rule for saving images should be duplicated in
.htaccess
.
What happens
Js-script modification: adaptive.jsHere js, as before, takes the maximum value from the height and width of the device. Determines whether a pixel density modifier (retina / non retina), and on the basis of this data writes to the cookie
resolution
.
Rewriting instructions: .htaccessRewrite has become a little more complicated, but now it checks for the presence of a compressed image before contacting the backend.
RewriteCond %{REQUEST_URI} ^/upload/iblock/.+\.(?:jpe?g|gif|png)$
The rule only works on images from the
/upload/iblock/
directory.
RewriteCond %{REQUEST_FILENAME} -f
Moreover, only on real-life pictures, in contrast to the original.
RewriteCond %{HTTP:Cookie} (^|;\ *)resolution=([1-9][0-9]+)
The rule will work only if there is a digital cookie
resolution
. If not, the web server will give the original image.
RewriteRule .* /images_adaptive/%2%{REQUEST_URI} [L]
We move to the folder with cached images, assuming that this folder is called
images_adaptive
. This is followed by the resolution and the requested path of the original. That is, if the request for
/images/photo.jpg
came, and the user's resolution was calculated as 1024, then the adaptive picture will be located along the path
/images_adaptive/1024/images/photo.jpg
.
RewriteCond %{REQUEST_URI} ^/images_adaptive/.+\.(?:jpe?g|gif|png)$
A request for an adaptive picture came - rewriting from the previous rule, or a direct request, which, by the way, should not be. That is, nowhere links directly to this folder, of course, can not be put.
RewriteCond %{REQUEST_FILENAME} !-f
If there is still no such file, that is, the image has not yet been compressed to the required size (and here we kill unnecessary requests in php when the image is repeated).
RewriteRule .* ai.php [L]
We send a request to our php-script, which will find, pinch if necessary, and give the desired picture.
Script Handler: ai.phpRemoved permission definition. It must be remembered that in this script the array of permissions must match the same in
adaptive.js
, and the path to the cache folder must match the one used in the
.htaccess
rule.
Cons of our fork
- Redundancy of stored data. If we have one picture and 5 desired sizes, in which it needs to be pressed, the server will store in the worst case all 6 images (original and 5 copies). At the same time, even if you do not need to pinch the picture (say, it is 300 × 100, and the minimum resolution is 480), the picture will still be “squeezed”, that is, copied 5 times. Under each resolution, to avoid the return of statics through php.
- Updating responsive images. When the original image is updated, the script processor will not know anything about it. Here we need to think about whether it is suitable for each specific case, and how to deal with it. Periodically clear the cache at all, or something else.
- Duplication of information in php, js and .htaccess
The solution was not perfect, but despite the drawbacks, we achieved the desired result, freeing front-end developers from unnecessary work.