Feature-Policy HTTP Header and Web Browser Control

There is one completely incomparable technique that allows you to keep the performance of a web project under control. It consists in introducing mechanisms into the development process, the results of which are clearly visible. These mechanisms are designed to always remind the programmer of the importance of performance. There is something in this context that I really like. This is the Feature-Policy HTTP header . This title is a relatively new feature that allows a developer to make certain browser features turn on and off while browsing his site. For example, you can tell the browser that it should not allow the use of the Geolocation API by passing it the following header:







Feature-Policy: geolocation 'none'

There Feature-Policyare many advantages to using a header in terms of security and performance. But I now especially like how Feature-Policyyou can use it to make website performance issues that are usually easy to overlook more noticeable. This can be compared to something like "performance linting." In particular, we are talking about identifying problems with images used in web projects.

Oversized-images policy


If the image is transmitted to the browser in a format that it supports, such an image will be displayed. This is standard browser behavior. The browser, trying to help those who are viewing the page, also automatically scales such images. Therefore, they look good even if they are represented by huge graphic files. As a result, if you use images that are larger than the sizes needed by the page, then this is, at first glance, invisible.

Policy ( directive )oversized-imagestells the browser that it should not allow the use of images whose size exceeds, by a specified number of times, the size of their containers. The image, in accordance with the standard restriction, cannot be more than 2 times the container. But this value, if necessary, can be redefined.

So, if the browser receives the next header, it will not allow you to display images taken from any sources (this is set thanks none), the dimensions of which are more than 2 times the size of their containers (in width or height).

Feature-Policy: oversized-images 'none';

If you need more flexibility, you can tell the browser that it should not display images that are more than 3 times larger than the containers:

Feature-Policy: oversized-images *(3) 'none';

In any case, if the image does not fit the specified boundaries, a stub will be displayed instead of the image, and an error message will be sent to the console.


If the site uses the oversized-images policy, large images will be uploaded, but a stub will be displayed instead, and an error message will be displayed in the console

Unoptimized Images


Another common problem with graphics is the use of non-optimized images. Quite often you can come across images that were not adequately compressed. Their size, however, can be selected correctly. So, to files with photos, when shooting and creating them, a lot of unnecessary metadata can be added, which often remain in files and when used in browsers. One particularly annoying example of this is images, the metadata of which contains their own thumbnails for preview. Many times I saw how the thumbnail embedded in the image (the presence of which designers and developers did not even know), “weighed” more than the image itself!

Among other things, here you can recall the usual image compression, supported by many formats, which allows you to achieve the perfect balance between picture quality and file size.

The unoptimized-lossy-images and unoptimized-lossless-images policies let the browser know that it matches file size and image size in pixels.

Feature-Policy: unoptimized-lossy-images 'none';
Feature-Policy: unoptimized-lossless-images 'none';

If the number of bytes per pixel (Byte-per-pixel, BPP) is too high, then the browser will display a stub instead of the image and display an error message in the console.


Applying unoptimized- * policies causes a stub to be displayed instead of inappropriate images - just like using the oversized-images policy, the

recommended BPP level for lossy compressed images is 0.5, and 1 for lossless compressed images. In addition, when analyzing images, a slight deviation of their total size from these levels is allowed. Now this deviation for images compressed with loss is 1 Kb, for images compressed without loss - 10 Kb.

For example, suppose we have a JPEG image of 200x200 pixels. JPEG is a lossy image compression format, resulting in a recommended BPP level of 0.5. At the same time, the total image size may exceed the recommended size by only 1 Kb. To find out what size a similar image should suit a browser, you need to multiply the dimensions of the sides of the image in pixels by each other and by BPP, and then add the allowed deviation to what happens.

(200 x 200 x .5) + 1024 = 21,024byte, or 20.5Kb

If the image is compressed without loss, then a deviation from the “ideal” size of 10 Kb is allowed, while the BPP of such an image will be 1. Otherwise, the calculations look exactly the same:

(200 x 200 x 1) + 10,240 = 50,240byte, or 49.1Kb

The size of the permitted deviation is likely to change in the future. In fact, although Blink, by default, uses this indicator for images compressed without loss, equal to 10 Kb, experiments are already underway with a policy unoptimized-lossless-images-strictthat changes this indicator, lowering it to the level of 1 Kb.

Media not specified


The new is the well-forgotten old.

For a long time the use of image attributes height, and widthwas more or less common. Without these attributes, the browser did not know how much space the image should occupy until the moment the image was loaded. This led to shifts in page layouts. The page was displayed, and then, after the image arrived, its content shifted. The browser once again had to recount the layout in order to allocate space for the image.

When the time came for layouts in which image sizes had to be flexibly resized using CSS, the presence or absence of these attributes no longer played a special role. As a result, many simply stopped using these attributes.

But thanks to recent workinitiated by Jen Simmons, Firefox and Chrome can calculate the aspect ratio of images based on their attributes heightand width. When this approach is combined with the styles applied to images, it turns out that browsers can reserve space for images during the initial passage of the layout.

The unsized-media policy tells the browser that all media elements must have attributes that specify the sizes of these elements. If there are no such attributes, the browser should use the default values. Everything, in fact, is a little more complicated, but the bottom line is that if the image does not have the appropriate attributes, the browser uses the standard 300x150pixel value .

Feature-Policy: unsized-media 'none';

When this policy is applied, images will be displayed, but if their size is not specified in HTML, the developer will quickly notice that the images are displayed in the default size. And, as usual, an error message will be sent to the console.


Applying the unsized-media policy leads to the fact that images and videos without the height and width attributes are displayed, but the browser sets their sizes to 300x150 pixels.

Probably, it’s worth mentioning one feature that at first seemed unusual to me. She shows herself when sharing policiesunsized-mediaandoversized-images. In this situation, one should not be surprised at the appearance of more than before, the number of messages about too large images. The fact is that due to the application of the policy, theunsized-mediabrowser resizes images that do not have attributesheightandwidthup to300x150pixels. After which it is this size that the browser uses as a reference point to determine whether the image matches its container.

Attracting attention to less visible issues


In image-related policies, I like the fact that they, in the process of developing projects, make it possible to make visible what is usually hidden. As a result, the developer learns that he did not take care of optimizing the images, or that he forgot to set their attributes heightand width. All these errors are immediately reflected in the appearance of the pages. In fact, the main advantage of using the above policies is that they allow the developer to quickly find out about problems with the images. While politicsunsized-mediacan lead to a decrease in the number of situations in which “shifts” of page layouts occur; the use of other policies does not prevent the loading of inappropriate images. As a result, the only strong point of applying these policies is that they draw the attention of developers to problems.

There are several more policies that may be useful in terms of analyzing pages for the impact of something on their performance. This is where policies like sync-script come to mind (this policy blocks the execution of synchronous scripts), sync-xhr(blocks synchronous AJAX requests) and document-write(blocks calls document.write).

These policies are great tools for controlling certain aspects of page performance, but they themselves do not provide developers with the same noticeable feedback that many of the above policies provide in the form of missing images. Of course, if the page has a synchronous script, without which it is not displayed, then this is not easy to miss (and such pages are not so difficult to find). But these policies usually indicate errors in the form of messages displayed on the console. And to be honest, I suspect that most developers do not pay much attention to the console (I think we should all be more careful about the console).

But, nevertheless, we can make the errors detected by the "invisible" policies much more noticeable using the APIReportingObserver for monitoring violations and for displaying relevant notifications on the page. Such notifications can be made very noticeable.

let reportingAlerts = document.createElement('ul');
  reportingAlerts.setAttribute('id','reportingAlerts');
  document.body.appendChild(reportingAlerts);

const alertBox = document.getElementById('reportingAlerts');

new ReportingObserver((reports, observer) => {
  let fragment = document.createDocumentFragment();
  
  Object.keys(reports).forEach(function(item) {
    let li = document.createElement('li');
    li.textContent = reports[item].body.message + ': ' + reports[item].body.featureId;
    fragment.appendChild(li);
  });
  
  alertBox.appendChild(fragment)
}, {types: ['feature-policy-violation'], buffered: true}).observe();

I sketched an example in CodePen of how this might look.


An example of how you can display notifications of policy violations specified by the Feature-Policy header. Such notifications are designed for output in the development environment, or where the project is prepared for output to production.

Less use of the Feature-Policy header


The big minus of using the header Feature-Policyis its support by browsers. Apparently, now it is supported only by Blink-based browsers (Opera, Edge, Chrome, Samsung). Firefox and Safari browsers support the attribute allowfor items iframe. But even where it is Feature-Policysupported, to ensure the health of many of the policies, you need to enable the flag Experimental Web Platform features(you can find it at the address about:flags).

How I Use Feature-Policy Header


That minus of the title Feature-Policy, which is mentioned above, for me personally is not a particular problem. I prefer to use the policies defined by this header as a browser-based page checker. Therefore, I do not need to strive to apply Feature-Policyin production, or to ensure that policies work for all my users. They are needed only by me, as well as by those who are developing the site. I, in any case, use Chrome as the main browser in the development process. Therefore, ensuring performance Feature-Policein my work environment is to enable the appropriate flag. After this, the politicians work without any additional intervention on my part.

I found that the easiest way to use the header is Feature-Policywith a browser extensionModHeader . This extension allows you to set your own headings that are passed to pages when they are viewed.


The ModHeader extension allows you to configure Feature-Policy header options. They can be turned on and off, if desired

. I have three sets of header valuesFeature-Policythat I periodically use:

  • oversized-images 'none'; unoptimized-lossy-images 'none'; unoptimized-lossless-images 'none';
  • unsized-media 'none'; oversized-images 'none'; unoptimized-lossy-images 'none'; unoptimized-lossless-images 'none';
  • script-sync 'none'; unsized-media 'none'; oversized-images 'none'; unoptimized-lossy-images 'none'; unoptimized-lossless-images 'none';

I often keep the first one turned on. It’s very exciting to travel through web pages to which the policies used in it apply. It is scary to look at how large some images are. There are many things on the modern web that could be improved.

So, politics is very often triggered on the pages unsized-media(and I also sin by this), so its use during normal work on the Internet is inconvenient. That is why I have it highlighted in a separate policy, which I can turn on and off. The same applies to policies sync-scripts, the application of which "breaks" many sites.

Some of the teams I worked with started using the policies I described during development. This allows them to quickly pay attention to previously invisible problems. Of course, I recommend including all policies Feature-Policyin the development environment, which allows you to quickly identify and correct errors.

Summary


I hope that support Feature-Policywill appear, as a result, not only in Chrome. Although this is my main browser, I have to use other browsers as well. It would be helpful if they supported Feature-Policy. But here, however, we see that rare situation when even experimental support of a certain opportunity is enough for it to be of real benefit.

Subtle performance issues are also problems. And the ability to make such problems more visible is one of the best methods that a developer can use in order to identify and fix them.

Dear readers! Do you plan to use the Feature-Policy heading to identify inconspicuous issues in web projects?


All Articles