XF 2.3 Image optimization, enhanced image resizing, and more!

Image optimization with WebP support​

Arguably, we could have talked about this in our bumper Boosting performance entry but it wasn't quite ready to be shown at that point. (I started working on it this week and I haven't yet mastered the art of time travel).

Initially the scope of our WebP support in XenForo 2.3 was to merely allow users to upload WebP files and have them correctly displayed inline. This would have been a positive change on its own as the format becomes more prevalent across the web, but it doesn't really do much on its own to solve the issue of disk usage which, of course, then also has a positive effect on performance.

But, this wasn't enough.

hys_4_option.png


If you wish to optimize, automatically, all future image uploads you simply need to enable this option.

On upload, all currently supported image types (except GIFs) will be saved to WebP format.
Side note: As is the case now, thumbnails, profile banners and avatars (and anything else that has a programmatically set file name) will be served with a .jpg extension, regardless of the underlying file format.

If you have custom content types which already use the attachment system, such as we do with Media Gallery and Resource Manager, images uploaded to those will be automatically optimized too.

In fact, if your add-on handles uploads via the default approach, namely the XF\Http\Upload class, all new image uploads will be optimized automatically. This extends out into pretty much every system we have, including the admin asset upload system.

As a developer, if you wish to opt-out of this behaviour for any reason, you can do so with the following one-liner:

PHP:
$upload->setImageOptimize(false);

That deals with future uploads, but, many of you will be wondering how to optimize existing files. So you'll be pleased to hear that you are able to rebuild all of your existing attachments, avatars and profile banners automatically.

hys_4_rebuilds.png


These are somewhat typical rebuilds that you can kick off from within your admin control panel on the "Rebuild caches" page.

With this being a rather intensive and lengthy process, if you'd prefer to run this without the risk of browser timeouts and supervision, you can also use one of the built in commands:

Code:
xf-rebuild:attachment-optimization
xf-rebuild:avatar-optimization
xf-rebuild:profile-banner-optimization

As a developer, adding support for your own content types is trivial by extending the AbstractImageOptimizationJob class.

We have run this already on a development copy of the XenForo Community forum. In doing so, the file size reported via the xf_attachment_data table before the conversion was around 40GB. The file size reported after the conversion is around 19GB.

These are significant savings and will also have a positive impact on performance.

The "not so good" news​

WebP is now supported by every single major browser. Anyone using an up to date browser will not experience any issues with viewing images. However, certain Apple devices and browsers prior to September 2020 do not support WebP.

Specifically, if you are using iOS 14 or above, there is no issue at all. Safari 14 and above is great, too but you must be running at least macOS 11 Big Sur for WebP images to display.

In earlier browsers, these users will simply not see WebP images at all. They will appear as broken images.

As time progresses, this is naturally an ever decreasing issue as people update their software and hardware. But it is something you should be aware of and think about before blanket converting all images to WebP.
 

Enhanced image resizing​

In the age of cameras that fit in our pockets producing photos with an ever increasing number of megapixels, I'm sure you may have run into a situation where XenForo complains that a photo is too big. Either due to file size limits or a restriction we impose on the size of images that we allow your server to resize.

In that latter case, the limit is defaulted to images containing no more than 20 million pixels. And, while that can be increased by setting a custom value in src/config.php, that limit was set over a decade ago and even the cheapest shared hosting isn't going to explode like @Kier's house being hit by lightning, just to handle the resizing of a large image.

However, we've increased that limit in XF 2.3 by default as follows:

PHP:
$config['maxImageResizePixelCount'] = 48000000;

If you need a smaller (or larger) limit, that can be done by adding the above to your src/config.php file and adjusting the value accordingly.

With that very minor point out of the way, let me explain to you now why it matters a lot less.

Starting with XenForo 2.3, the "attachment manager" which powers the file upload system for things like resources, media gallery and other attachments, is now able to resize images before they reach your server.

If you have max width/height dimensions set, already XF will resize those for your on the server side, but with 2.3 we will first attempt to resize those on the client side.

I have a sample photograph which is 14,026 x 14,026 pixels wide (that's nearly 200 megapixels!). In XF 2.2 if I were to upload this, I would likely receive an error stating that file is too large to upload. I could adjust the aforementioned config value, but obviously your users can't do that. In XF 2.3, the file is resized entirely on the client side using JavaScript APIs before being uploaded to the server.

Because resizing an image effectively destroys any embedded metadata such as EXIF data, we have also introduced a new third party library that can optionally capture the EXIF data before resizing. This is crucial for XenForo Media Gallery to ensure we can still display EXIF data in the gallery even for an image that has been resized.

No more annoying errors for your users and thanks to the power of most modern devices, it's pretty quick too, and on the whole takes less time to upload than it would do because the file being transferred to the server is smaller.
 

Use any emoji for smilies and reactions​

This new feature is a little more miscellaneous than some, though it sort of involves images, kinda, I guess...?

I think most of you missed the clue in @Kier's first 2.3 HYS post:


You can be forgiven, if you missed it, for maybe thinking that Kier had simply uploaded Apple-style emojis for his reaction images, but this isn't actually the case.

Starting with XF 2.3, you can now add custom smilies and reactions by simply defining which emoji you would like to use.

You can search for the emoji you want to use by starting to type an emoji short code, or even just using the emoji keyboard on your device to input the desired emoji directly:

hys_4_reaction_emoji.webp


You will note the options are there still for uploading a custom image or even using a sprite, but the default reactions (including the previously custom-made thumbs up reaction) are now pulling from emoji instead.

This means reactions and smilies using emoji will now also adhere to the emojiStyle option which usually affects post content. The big clue in @Kier's HYS post is he has native device emoji enabled, so they are rendered in the Apple style. By default, we still use JoyPixels, but it's good to know that there is a choice of styles available.
hys_4_joypixels.webp


hys_4_twemoji.webp

Side note: Do people even still use Twemoji? What do we even call it now? Xemoji? Xmoji? Muskmoji? 💩moji?

hys_4_native.webp


Smilies work in exactly the same way. Of course, for some, that is less useful as we provide the emoji picker and support emojis anyway when composing content.

But if you prefer to disable the emoji picker in the editor picker, and want to only display smilies, you can at least now map certain emojis that you do want to offer to smilies, thus displaying a smaller subset of the available emoji for use.
 

Size variants for the admin asset uploader​

Now, this feature is somewhat more of a development tool, but it is image related so it fits here. This feature was primarily written to be made use of in the new style, before it was decided we should delay that until version 3.0.

You may be familiar with the asset uploader system which we added in XenForo 2.2 which allows you to upload certain images directly in the admin control panel without firing up your (S)FTP program.

You can use this already in XenForo to upload reaction images, smilie images, and style properties for things like logos.

Starting with XenForo 2.3, this feature can be utilised by developers to automatically create various size variants for an uploaded asset.

The first step is to use the AssetVariantTrait in your Entity which has one required method to implement:

PHP:
public function getAssetVariantSizeMap(): array  
{  
   return [  
      'image_url' => [  
         's' => 128,  
         'm' => [512, 456]  
      ]  
  ];
}

This should return an array keyed by the name of the field which holds the URL to the uploaded asset. The inner array is then keyed by size code to represent the size of the variant. If the value of the size code is an integer, that variant will be resized to a square. If an array is provided, the first element of the array is the width and the second element of the array is the height.

In the above example the following files will be created:
  • data/assets/your_asset_name/your_file.png - the original uploaded file at full size
  • data/assets/your_asset_name/your_file - s.png - the asset resized to a 128 pixel square
  • data/assets/your_asset_name/your_file - m.png - the asset resized and cropped to 512 x 456 pixels
We have also introduced a new Templater function named asset_display which can be used like this:

HTML:
<img src="{{ base_url(asset_display($entity, 'image_url', 's')) }}" />
 

Tracking sizes for embedded images​

In something that could have been mentioned in our Boosting performance HYS had somebody (me) not forgotten about it, we also bring news this week of improvements which should reduce Cumulative Layout Shift (CLS) for hot-linked images within content.

Currently if you embed an image from a URL, we have no prior knowledge of the dimensions or aspect ratio of that image. As far as the browser knows, the image is 0 x 0 pixels, and when it starts to load, no space is reserved for it on the screen, therefore causing the layout of the page to shift as it loads.

This has a negative knock on effect not only on performance metrics, but also the overall user experience as things start jumping around the screen.

We will now track these sizes within the embed_metadata field of the content and to a certain extent, can rebuild that information when the "Post embed metadata" rebuild is run against existing content (if the dimensions have been stored by the image proxy).
 
this is nice to see....but i still wonder about how post view shrinks them down anyway, its serving alot of useless data but if it created a third image size, close to what is used in posts, then we could still have full sized images for blowing up after clicking into lightbox etc...
its a step in the right direction seems like, but is there a chance that will ever happen or some reason why not? i know that means a bigger file system, but sounds like thats easier to do with webp and thats always sort of bugged me.
 
I don't understand what it is you're asking.

You can insert into posts at full size, although they will be constrained by the post div which is largely determined by screen size but also by the max forum width.

Or you can insert as a thumbnail.

Are you asking for some sort of third option?
 
The suggestion is to effectively have small (thumbnail) large (full size) and a third version of the image for displaying in the post - almost like a larger thumbnail, with the large not being loaded until opened in the lightbox.

It does make sense but the file size issue is still key here. Even WebP savings are only 30% and while a medium sized image is going to be smaller anyway, for some forums that does add some heft to what they’re storing.

Not ruling it out but I have seen the additional storage requirements for stuff like this being seen as a net negative by some.
 
I don't understand what it is you're asking.

You can insert into posts at full size, although they will be constrained by the post div which is largely determined by screen size but also by the max forum width.

Or you can insert as a thumbnail.

Are you asking for some sort of third option?
I think he is asking for the image to be adjusted to the post max-width, possibly scaling down the dimensions even further?
 
The post max width is dependent on the viewport width, so I don't really see how it can be optimised, other than for the absolute largest width.
Which wouldn't help at all with small devices.

As above, any micro-optimisations are going to have a negative effect on server storage, so not sure there would be a net benefit overall.

Most (all) devices these days are more than capable of loading multi MB images without issue so it seems like fixing a problem which doesn't really exist.
 
its good practice to serve the best slimmed down version anyway, even if devices "can" do it..not everyone has an unlimited data plan and some forums can have over a hundred images or such on a page. its a little niche, and a little as described it just helps to understand that thank you.
 
Because resizing an image effectively destroys any embedded metadata such as EXIF data, we have also introduced a new third party library that can optionally capture the EXIF data before resizing. This is crucial for XenForo Media Gallery to ensure we can still display EXIF data in the gallery even for an image that has been resized.
Is this done on client side or on the server side? I'm asking this because I see "exif-reader.js".
 
Is this done on client side or on the server side? I'm asking this because I see "exif-reader.js".
The image is resized on the client-side, so the EXIF data would also need to be extracted on the client-side (if you resize on the client-side, I would assume the EXIF data would be lost by the time the resized image was sent to the server).

I don't have any firsthand knowledge one way or the other, just how I would logic it out.
 
Yeah, client-size image resizing will remove the EXIF data, so it's extracted on the client first and sent with the upload.
 
Back
Top Bottom