📜 ⬆️ ⬇️

Adaptive images without shamanism

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.
  1. Be elements of site design (backgrounds, buttons, etc.).
  2. To be loaded through special modules (for example, images in a photo album).
  3. 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:
  1. 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.
  2. With the help of the directive in .htaccess rewriting of all site images to the php-script adaptive-images.php .
  3. 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).
  4. The script gives the picture to the client.

Adaptive Images Pros



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.

What happens


Js-script modification: adaptive.js

Here 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: .htaccess

Rewrite 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.php

Removed 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




The solution was not perfect, but despite the drawbacks, we achieved the desired result, freeing front-end developers from unnecessary work.

Source: https://habr.com/ru/post/214071/


All Articles