Showing posts with label Dianoga. Show all posts
Showing posts with label Dianoga. Show all posts

Friday, March 26, 2021

Is There Still a Place for Dianoga on Your Sitecore Website in 2021?

This is a copy of my article, originally placed here to keep all things in one place.

Some time ago, I worked with Akamai CDN, which was configured on the top of the Sitecore project. I was impressed by the different features provided on the edge. One of these features was image optimization. Image optimization is a feature that allows you to decrease image size without losing quality. I was able to turn on/off it with one click in the admin console.

Dianoga is an open-source module that is responsible for image optimization in the Sitecore world. But the more and more Sitecore websites use CDN. Let's find out what should be used and when: Dianoga or CDN Image Optimization

Before writing this article, I was under impression that all modern CDNs have image optimization features. But it is not the main and must-have feature. Let's compare the most-popular CDNs to find out, do they provide this feature?

Name Support Image Optimization Links
Cloudflare CDN Yes 1. 2. 3.
Google Cloud CDN No 1.
Amazon CloudFront No 1. 2.
F5 Yes 1.
Fastly Yes 1. 2.
Akamai Yes 1. 2. 3.
Microsoft Azure CDN Yes 1. 2.
Incapsula CND Yes 1. 2.

The comparison showed that almost all CDNs could be configured to provide image compression. But not all of them. Also, almost all of them provide this feature included in pricing plans. You don't need to pay additional money to get it. However, there are other limitations. Not all CDNs support all image formats. And you don't have the flexibility to configure as you want, but for 95% of cases, you would not need it.

Let's back to our initial question:

When do we need to use Dianoga and when CDN image optimization?

Each individual project is different. Before making choice you will need to get more information about image optimization on your CDN: pricing, formats, features, limits, etc. If you are happy with that list then it would be better to configure image optimization on CDN level and forget about it.

But there are still many cases when Dianoga will be a better choice:

  1. Your CDN doesn't have image optimization feature
  2. Your CDN image optimization feature is not free for charge
  3. Your CDN image optimization feature doesn't work with formats that are widely used on your website
  4. You need flexibility in configuration, how images should be optimized
  5. You need not only optimization, but compression as well

Wednesday, April 11, 2018

Using WebP Format in Sitecore

It is a copy of this blog post to have all my articles in one place.
WebP is promising format that allows good optimization comparing to JPEG and PNG. According to tests it provides lossless images that are 26% smaller compared to PNGs and lossy images that are 25-34% smaller than comparable JPEG images at equivalent SSIM quality index.
This format becomes more and more popular over the web nowadays. Google promotes WebP format, it released WebP as open source to allow anyone works with it and suggest improvements. But, is it supported by major browsers? Going to CanIUse gives answer that not:


(support details are on 2018/01/21, it could be changed over time)

It is supported by Chrome, Opera, Chrome for Android. Safari and Firefox are experimenting(not supported yet) with supporting WebP images. IE and Edge doesn’t support it.
But how it can be used now, when not all browsers support it? Each browser(web client) provides Accept header when getting resources from server. If this header contains image/webp, web server know that it can returns WebP format. As example Akamai CDN use this behavior. It can return optimized WebP images for web clients who support it and JPEG and PNG for those who doesn’t support.
Let’s consider how it could be used in Sitecore. It has no sense to add support of WebP format to media library for now, we can’t return this file format to all web clients. But it makes sense to return WebP format to web clients that can use it. Saving about 25% of time on loading images can make big difference for user experience, especially on mobile. I decided don’t write new image optimizer from the scratch and add support of WebP to well known tool for images optimization for the Sitecore: Dianoga.
To make it works, we should get understanding how Sitecore Media Library and Sitecore Media Library cache work. Sitecore media library creates files on disk after each request, or uses previously created files. By default these files are located under \Website\App_Data\MediaCache\website\{some folders}. There are few files in each folder. First type of files is cache for image. It is image itself, Sitecore don’t need to preprocess width, height and other parameters for each media request. It does processing only once. Second type of files is .ini file, it is metadata for cached object. Metadata contains next values:
Key. e.g. ?as=False&bc=0&h=0&iar=False&mh=0&mw=0&sc=0&thn=False&w=0. Key contains all media query parameters.
Extension - extension of file.
Headers - cached headers that should be returned to web client
DataFile - file name of object that should be returned to web client.

We need to extend forming of key, to add one more parameter that will indicate support of WebP format. It will require extending of MediaRequestHandler:

public class MediaRequestHandler : Sitecore.Resources.Media.MediaRequestHandler
{
 protected override bool DoProcessRequest(HttpContext context, MediaRequest request, Media media)
 {
  if (context?.Request.AcceptTypes != null && (context.Request.AcceptTypes).Contains("image/webp"))
  {
   request.Options.CustomOptions["extension"] = "webp";
  }

  return base.DoProcessRequest(context, request, media);
 }

 private static bool AcceptWebP(HttpContext context)
 {
  return context?.Request.AcceptTypes != null && (context.Request.AcceptTypes).Contains("image/webp");
 }
}

Our key will contain one more additional parameter: extension. E.g.: ?as=False&bc=0&h=0&iar=False&mh=0&mw=0&sc=0&thn=False&w=0&extension=webp
Let’s add handler that will process WebP compatible requests based on
CommandLineToolOptimizer:

public class WebPOptimizer : CommandLineToolOptimizer
{
 public override void Process(OptimizerArgs args)
 {
  //If WebP optimization was executed then abort running other optimizers
  //because they don't accept webp input file format
  if (args.AcceptWebP)
  {
   base.Process(args);
   args.AbortPipeline();
  }
 }

 protected override string CreateToolArguments(string tempFilePath, string tempOutputPath)
 {
  return $"\"{tempFilePath}\" -o \"{tempOutputPath}\" ";
 }
}

It is very easy, it runs cwebp.exe tool that converts JPEG or PNG to WebP. It doesn’t utilize all available command line options, and could be tuned depending on requirements. All others code changes are more about Dianoga configuration and unit tests, I will not stop on them in this article. If you want more details, you can review all changes in GitHub repository.

How to enable Dianoga WebP support for your project:
  1. Clone GitHub repository and build project
  2. Enable Dianoga.WebP.config.disabled config
  3. Open web.config and change line <add verb="*" path="sitecore_media.ashx" type="Sitecore.Resources.Media.MediaRequestHandler, Sitecore.Kernel" name="Sitecore.MediaRequestHandler" /> to <add verb="*" path="sitecore_media.ashx" type="Dianoga.MediaRequestHandler, Dianoga" name="Sitecore.MediaRequestHandler" />
  4. If you have custom MediaRequestHandler (e.g. Habitat is used) then skip step 3 and override DoProcessRequest method with detection of support of WebP format. See MediaRequestHandler code listening above.

P.S. It is experimental feature, use it on your own risk. :-)