Skip to content

Commit

Permalink
Fix #61 CDN support by adding a MediaProvider and CacheKey pipeline a…
Browse files Browse the repository at this point in the history
…nd made it easy to enable this with a separate WebP CDN config
  • Loading branch information
markgibbons25 committed Mar 12, 2020
1 parent 0d6d3c0 commit 5ce6bf5
Show file tree
Hide file tree
Showing 12 changed files with 167 additions and 145 deletions.
46 changes: 12 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

An automatic image optimizer for the Sitecore media library. Reduce the size of your images served from Sitecore by 8-70%, completely automatically.

When media images are requested, Dianoga automatically runs [mozjpeg](https://github.com/mozilla/mozjpeg), [PNGOptimizer](http://psydk.org/pngoptimizer), [nQuant](https://nquant.codeplex.com/), [SVGO](https://github.com/svg/svgo) or [WebP](https://developers.google.com/speed/webp/) on the image data immediately after it is placed in the Sitecore media cache.
When media images are requested, Dianoga automatically runs [mozjpeg](https://github.com/mozilla/mozjpeg), [PNGOptimizer](http://psydk.org/pngoptimizer), [SVGO](https://github.com/svg/svgo) or [WebP](https://developers.google.com/speed/webp/) on the image data immediately after it is placed in the Sitecore media cache.

Dianoga ensures that your site is always serving fully optimised media library images even if you are using Sitecore's dynamic resizing features (for example with [Adaptive Images](https://marketplace.sitecore.net/en/Modules/Sitecore_Adaptive_Images.aspx)). Even if you have already optimized every image uploaded into the media library, after Sitecore performs image processing the result is _not_ optimized (an unfortunate limitation of most other image optimization libraries for Sitecore is that they only apply to the original image).

Expand All @@ -11,10 +11,10 @@ Dianoga is also great for situations where content editors may not be image edit
## Format Support

Dianoga supports:
* JPEGs (via mozjpeg - lossless optimization)
* PNGs (via PNGOptimizer - lossless, and/or nQuant or pngquant - lossy)
* JPEGs (via mozjpeg - lossless or lossy)
* PNGs (via PNGOptimizer - lossless / pngquant - lossy)
* SVGs (via SVGO - lossless, and automatic gzipping of SVG media responses)
* WebP (via cwebp - lossy by default but easy to change to lossless)
* WebP (via cwebp - lossless or lossy)
* Auto convert JPEG/PNG/GIF to WebP based on browser support

Additional format support is possible to add via new processors in the `dianogaOptimize` pipeline.
Expand Down Expand Up @@ -76,42 +76,20 @@ Browser sends request to server to get image. If browser supports WebP image for
### How to enable WebP support:
1. Enable `Dianoga.WebP.config.disabled` config and adjust any parameters if you require lossless or higher quality than the default
2. 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" />`
3. If you have custom `MediaRequestHandler` (e.g. Habitat or SXA is used) then override `DoProcessRequest` method with detection of support of WebP format:

```C#
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);
}
```
`<add verb="*" path="sitecore_media.ashx" type="Sitecore.Resources.Media.MediaRequestHandler, Sitecore.Kernel" name="Sitecore.MediaRequestHandler" />`

### If you run Sitecore under CDN,
to

`<add verb="*" path="sitecore_media.ashx" type="Dianoga.MediaRequestHandler, Dianoga" name="Sitecore.MediaRequestHandler" />`

1. Check [CDN support wiki](https://github.com/kamsar/Dianoga/wiki/CDN-Support-for-WebP)
2. Uncomment `settings` section in `Dianoga.WebP.config`:
OR if you use SXA

```XML
<settings>
<setting name="MediaResponse.VaryHeader">
<patch:attribute name="value">Accept,Accept-Encoding</patch:attribute>
</setting>
</settings>
```
`<add verb="*" path="sitecore_media.ashx" type="Dianoga.MediaRequestHandlerXA, Dianoga" name="Sitecore.MediaRequestHandler" />`

3. Enable the special patch of the GetMediaStreamSync in `Dianoga.WebP.config` strategy which patches it to run first in the `getMediaStream` pipeline:
OR if you have a custom `MediaRequestHandler` then you need to make some changes - see `MediaRequestHandler.cs`

```XML
<processor type="Dianoga.Invokers.GetMediaStreamSync.OptimizeImage, Dianoga" patch:before="processor[1]" />

```
3. If you run Sitecore under CDN: review and enable `Dianoga.WebP.CDN.config.disabled`


## Upgrade
Expand All @@ -138,6 +116,6 @@ You can optimize any type of image that the media library supports with Dianoga.

Adding a new `Processor` to the config will enable you to call a micro-pipeline you define to process that type.

In your `Optimizer` micro-pipeline you can add or remove optimizers (e.g. nQuant) that are applied in order to the specified file type.
In your `Optimizer` micro-pipeline you can add or remove optimizers that are applied in order to the specified file type.

Comments are available in the config files and source for your perusal.
4 changes: 0 additions & 4 deletions packages/repositories.config

This file was deleted.

27 changes: 27 additions & 0 deletions src/Dianoga/Default Config Files/Dianoga.WebP.CDN.config.disabled
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!--
Configures Dianoga to support WebP on a CDN
-->
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/">
<sitecore>
<pipelines>
<!-- Run the Sync processor first so that no other Sitecore processors are run for webp -->
<getMediaStream>
<processor type="Dianoga.Invokers.GetMediaStreamSync.OptimizeImage, Dianoga" patch:before="processor[1]" />
</getMediaStream>
<!-- Generate a unique HTML cache key for renderings since the links will have query string extension=webp -->
<mvc.renderRendering>
<processor
type="Dianoga.WebP.Pipelines.GenerateCacheKey, Dianoga"
patch:after="processor[@type='Sitecore.Mvc.Pipelines.Response.RenderRendering.GenerateCacheKey, Sitecore.Mvc']" />
</mvc.renderRendering>
</pipelines>

<mediaLibrary>
<!-- Add query string "extension=webp" to media links if the browser supports it for a unique CDN cache key. -->
<mediaProvider
type="Dianoga.WebP.MediaProvider, Dianoga"
patch:instead="mediaProvider[@type='Sitecore.Resources.Media.MediaProvider, Sitecore.Kernel']"/>
</mediaLibrary>

</sitecore>
</configuration>
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,7 @@
<AdditionalToolArguments>-q 80 -lossy</AdditionalToolArguments>
</processor>
</dianogaOptimizeGif>

<getMediaStream>
<!-- Enable this if you are using Sync mode -->
<!--
<processor type="Dianoga.Invokers.GetMediaStreamSync.OptimizeImage, Dianoga" patch:before="processor[1]" />
-->
</getMediaStream>

</pipelines>

<mediaLibrary>
Expand Down Expand Up @@ -85,14 +79,6 @@
<parameter description="extension" name="extension"/>
</protectedMediaQueryParameters>
</requestProtection>

<!-- Enable this section if you are running Dianoga under CDN. It adds "&web=true" to media links if the browser supports it for a unique CDN cache key. -->
<!--
<mediaProvider type="Dianoga.MediaProvider, Dianoga"
patch:instead="mediaProvider[@type='Sitecore.Resources.Media.MediaProvider, Sitecore.Kernel']"/>
-->

</mediaLibrary>

</sitecore>
</configuration>
121 changes: 68 additions & 53 deletions src/Dianoga/Dianoga.csproj
Original file line number Diff line number Diff line change
@@ -1,56 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net452;net462;net471</TargetFrameworks>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Description>Automatic media library image file optimization for Sitecore</Description>
<Version>5.0.0-rc.4</Version>
<Authors>Kam Figy, Mark Gibbons</Authors>
<PackageProjectUrl>https://github.com/kamsar/Dianoga</PackageProjectUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<RepositoryUrl>https://github.com/kamsar/Dianoga</RepositoryUrl>
<PackageIconUrl>https://kamsar.net/nuget/dianoga/logo.png</PackageIconUrl>
<PackageTags>sitecore optimization</PackageTags>
<Copyright>Copyright 2020</Copyright>
<Company />
<Product />
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net452'">
<PackageReference Include="Sitecore.Kernel">
<Version>8.2.180406</Version>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net462'">
<PackageReference Include="Sitecore.Kernel">
<Version>9.0.180604</Version>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Sitecore.XA.Foundation.MediaRequestHandler">
<Version>3.8.1</Version>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net471'">
<PackageReference Include="Sitecore.Kernel">
<Version>9.3.0</Version>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Sitecore.XA.Foundation.MediaRequestHandler">
<Version>9.3.0</Version>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Web" />
<Reference Include="System.XML" />
</ItemGroup>
<ItemGroup>
<Content Include="Default Config Files\*" PackagePath="content\App_Config\Include\Dianoga" />
<Content Include="Dianoga Tools\**\*" Exclude="Dianoga Tools\SVGO\**\*" PackagePath="content\App_Data\Dianoga Tools" />
</ItemGroup>
<PropertyGroup>
<TargetFrameworks>net452;net462;net471</TargetFrameworks>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Description>Automatic media library image file optimization for Sitecore</Description>
<Version>5.0.0-rc.4</Version>
<Authors>Kam Figy, Mark Gibbons</Authors>
<PackageProjectUrl>https://github.com/kamsar/Dianoga</PackageProjectUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<RepositoryUrl>https://github.com/kamsar/Dianoga</RepositoryUrl>
<PackageIconUrl>https://kamsar.net/nuget/dianoga/logo.png</PackageIconUrl>
<PackageTags>sitecore optimization</PackageTags>
<Copyright>Copyright 2020</Copyright>
<Company />
<Product />
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net452'">
<PackageReference Include="Sitecore.Kernel">
<Version>8.2.180406</Version>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Sitecore.Mvc">
<Version>8.2.180406</Version>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net462'">
<PackageReference Include="Sitecore.Kernel">
<Version>9.0.180604</Version>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Sitecore.Mvc">
<Version>9.0.180604</Version>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Sitecore.XA.Foundation.MediaRequestHandler">
<Version>3.8.1</Version>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net471'">
<PackageReference Include="Sitecore.Kernel">
<Version>9.3.0</Version>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Sitecore.Mvc">
<Version>9.3.0</Version>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Sitecore.XA.Foundation.MediaRequestHandler">
<Version>9.3.0</Version>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Web" />
<Reference Include="System.XML" />
</ItemGroup>
<ItemGroup>
<Content Include="Default Config Files\*" PackagePath="content\App_Config\Include\Dianoga" />
<Content Include="Dianoga Tools\**\*" Exclude="Dianoga Tools\SVGO\**\*" PackagePath="content\App_Data\Dianoga Tools" />
</ItemGroup>
<ItemGroup>
<None Remove="Default Config Files\Dianoga.WebP.CDN.config.disabled" />
</ItemGroup>
</Project>
22 changes: 0 additions & 22 deletions src/Dianoga/Helpers/MediaOptionsHelpers.cs

This file was deleted.

6 changes: 3 additions & 3 deletions src/Dianoga/MediaRequestHandler.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System.Linq;
using System.Web;
using System.Web;
using Dianoga.WebP;
using Sitecore.Resources.Media;

namespace Dianoga
Expand All @@ -8,7 +8,7 @@ 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"))
if (context?.Request.QueryString?["extension"] == "webp" || context.BrowserSupportsWebP())
{
request.Options.CustomOptions["extension"] = "webp";
}
Expand Down
4 changes: 2 additions & 2 deletions src/Dianoga/MediaRequestHandlerXA.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#if !NET452
using System.Linq;
using System.Web;
using Dianoga.WebP;
using Sitecore.Pipelines;
using Sitecore.XA.Foundation.MediaRequestHandler.Pipelines.MediaRequestHandler;

Expand All @@ -16,7 +16,7 @@ protected override bool DoProcessRequest(HttpContext context)
{
return mediaRequestHandlerArgs.Result;
}
if (context?.Request.AcceptTypes != null && context.Request.AcceptTypes.Contains("image/webp"))
if (context?.Request.QueryString?["extension"] == "webp" || context.BrowserSupportsWebP())
{
mediaRequestHandlerArgs.Request.Options.CustomOptions["extension"] = "webp";
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Dianoga.Helpers;
using Dianoga.WebP;

namespace Dianoga.Optimizers.Pipelines.DianogaWebP
{
Expand Down
26 changes: 26 additions & 0 deletions src/Dianoga/WebP/Helpers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System;
using System.Linq;
using System.Web;
using Sitecore.Resources.Media;

namespace Dianoga.WebP
{
public static class Helpers
{

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

public static bool BrowserSupportsWebP(this MediaOptions mediaOptions)
{
return mediaOptions.GetCustomExtension() == "webp";
}

public static string GetCustomExtension(this MediaOptions mediaOptions)
{
return mediaOptions.CustomOptions["extension"];
}
}
}

0 comments on commit 5ce6bf5

Please sign in to comment.