Joomla system plugin

Same images. A fraction of the weight.

ShrinkRay makes small AVIF and WebP copies of your images, then quietly serves the right one to every visitor.

Upload a 4000px phone photo and ShrinkRay builds 333, 667 and 1600px copies in modern formats. On the front end, it rewrites your pages so browsers pick the smallest file that still looks sharp on their screen. Your originals and your articles are never changed. Switch it off, and everything goes back to exactly how it was.

Joomla 5.4+ and 6.x · PHP GD only, no ImageMagick · Originals never touched

How it works

Three steps, two of them invisible.

Step 1 · On your server

It makes copies

When you upload an image through the Media Manager, or run a batch, ShrinkRay saves resized AVIF and WebP copies in images/_sized/, mirroring your folders. tancho.jpg becomes tancho--333.avif, tancho--1600.webp, and so on.

Step 2 · As each page loads

It rewrites the page

Just before a page is sent, ShrinkRay wraps each <img> in a <picture> element listing those copies. Nothing is saved to your articles; it happens fresh on every page view.

Step 3 · In the browser

The browser picks

The visitor's browser chooses the best format it supports and the smallest size that fits its screen. A phone might load the 667px AVIF; a big monitor, the 1600.

The confusing part, up front

"But the code still says .jpg."

It does, on purpose. ShrinkRay keeps your original file in the <img> tag as the fallback, and adds the copies in <source> tags around it. Browsers read the sources first and only fall back to the original if none of them work.

So if you right-click and copy the image address, or inspect the <img> itself, you'll see .jpg even when a 70 KB AVIF is what's actually on screen. It also isn't a redirect: the image URLs don't change, the page's HTML does. The next section shows how to see what was really delivered.

What you wrote

<img src="/images/equus/tancho/Tancho_06.jpg"
     alt="Tancho" loading="lazy">

What the browser receives

<picture>
  <source type="image/avif" srcset="/…Tancho_06--333.avif 333w,
    /…--667.avif 667w, /…--1600.avif 1600w">
  <source type="image/webp" srcset="/…--333.webp 333w, /…">
  <img src="/images/equus/tancho/Tancho_06.jpg"
       alt="Tancho" loading="lazy">
</picture>

Trust, but verify

How to see it working.

Three checks, from quickest to most convincing. All use your browser's built-in developer tools (F12, or right-click → Inspect).

Check 1 · Is it running?

Search the page source

Press Ctrl+U (Cmd+Option+U on Mac) to view the page source, then search for _sized. If it's there, ShrinkRay is rewriting the page. If it isn't, see "Not seeing it?" below.

Check 2 · What was downloaded?

Watch the Network tab

Open DevTools → Network, filter by Img, and reload. Look at the file names and the Type column: you should see --667.avif or --1600.webp, not the original .jpg, with sizes in kilobytes rather than megabytes.

Check 3 · What's on screen?

Ask the image itself

Right-click an image → Inspect, switch to the Console tab, and type:

$0.currentSrc

That shows the file the browser actually chose for that image, even though the tag still says .jpg.

Backgrounds

Check the computed style

For a section with an inline background, inspect it and open Computed → background-image. It should show a _sized/…avif URL.

Sizes

Watch it change

With the Network tab open, make the window narrow and reload, then wide and reload. Smaller windows should pull smaller copies. A high-resolution screen pulls larger ones than you might expect; that's the browser keeping images sharp.

Not seeing it?

The usual suspects

Is Serve Resized Images switched on (Front End tab)? Is the image in a selected folder, and converted? Is page caching (Joomla's or Cloudflare's) serving an old copy? Clear it and hard-reload with Ctrl+Shift+R.

Image blank? See the server setup note below.

One-time server check

Blank images? Teach your server AVIF.

Some hosts don't recognise the .avif file type and send it as plain text. Browsers reject it, and because a <picture> doesn't fall back once it has picked a source, the image simply shows blank.

Test: open any copy straight in a browser tab, like /images/_sized/<folder>/<name>--667.avif. If you see a picture, you're set. If it downloads, or shows garbage text starting with ftypavif, add these two lines to your site's .htaccess (or add the types under cPanel → MIME Types):

AddType image/avif .avif
AddType image/webp .webp

Then purge your CDN cache completely (Cloudflare: Purge Everything) and hard-reload. Each stamped ?v= URL is cached separately, so purging one plain link isn't enough.

Tancho, standing regally in the pasture

See it on this page

Go on, check Tancho.

This photo is served by ShrinkRay. Try the checks above on it: $0.currentSrc will show an AVIF or WebP copy, while the tag itself still points at the original JPG.

Click it, too. Chaos Loupe opens it in a lightbox, and ShrinkRay has already told Chaos Loupe which resized copy to load.

What's in the box

Set it up once. Forget it's there.

On upload

Converts as you go

Images uploaded through the Media Manager into your chosen folders get their copies immediately. Phone photos are rotated the right way up.

Batch

Catches everything else

One button converts images already on your site, in small chunks so shared hosting doesn't time out. Up-to-date images are skipped, so a stopped run just picks up again.

Formats

AVIF and WebP

AVIF for the smallest files, WebP as the backup, your original as the last resort. Quality and sizes are yours to set; nothing is ever upscaled.

Everywhere

Articles, intro images, modules

It works on the finished page, so article text, intro and full images, and module output are all covered. No template overrides.

Backgrounds

Inline backgrounds too

Sections styled with style="--bg: url(/…)" or an inline background-image get AVIF and WebP as well, with no CSS changes needed.

Speed

Hero preload

Add data-shrinkray-preload to your hero image or section, and it starts downloading the moment the page does, instead of waiting for the stylesheet.

Housekeeping

Cleans up after itself

Removes copies of deleted or renamed originals, and stamps every URL so regenerated copies show up right away instead of stale cached ones.

Activity

Know what happened

A Recent Activity panel in the plugin, plus entries in Joomla's own Latest Actions dashboard module, for every upload conversion.

For the technical crowd

Under the hood.

Works with
Joomla 5.4+ and 6.x, any template.
Server
PHP 8.1+ with GD built with WebP; AVIF needs GD with AVIF support. PHP's exif extension is recommended, for rotating phone photos. No ImageMagick. The web server must send .avif as image/avif (see the server check above).
Inputs
JPG, PNG and WebP, up to 60 megapixels. PNG and WebP transparency is kept.
Output
images/_sized/<same folders>/name--1600.avif by default. Sizes, quality, output folder and source folders are all settings.
Opting out
Add data-shrinkray="false" to any image or element to leave it untouched.
Older browsers
Images always fall back to the original. Inline --bg backgrounds in browsers from before about 2023 show without their photo.
Access
Batch and cleanup tools require a Super User and a valid form token.
License
GNU General Public License v2 or later.

Pairs well with

Built to work together.

Image viewer

Chaos Loupe

A click-to-enlarge lightbox with zoom, galleries and watermarking. With both installed, ShrinkRay hands Chaos Loupe the resized AVIF copies automatically, so the lightbox reuses the image the page already loaded instead of fetching your full-size original. Chaos Loupe then saves downloads as JPEG, so visitors get a file that opens anywhere.

Ready to lose some weight?

Your images, minus the megabytes. Take it, or let's talk.

Download ShrinkRay This email address is being protected from spambots. You need JavaScript enabled to view it.
zip
Version 1.5.1
Filedate 2026-10-07
Size 29.23 KB
Downloads 2

ShrinkRay

Changelog.

1.5.2

Stable

A fix for lazy-loaded images without a width.

  • Lazy-loaded images with no width attribute no longer get sizes="auto". Before loading they're 0px wide, so browsers picked the smallest copy, or showed nothing at all. They now use Default Sizes; images with a width still get auto.

Earlier releases

1.5.1Backgrounds without extra CSS
  • New Background Variables setting. Replace in place (the new default) turns --bg:url(…) directly into an AVIF/WebP image-set(), so stylesheets only need var(--bg). Browsers from before about 2023 show those elements without their photo.
  • Add -set twin keeps the 1.5.0 behavior, for designs that need every browser covered.
1.5.0Backgrounds, preload, cleanup
  • Inline backgrounds: CSS variables and background-image styles pointing into /images get AVIF/WebP versions.
  • data-shrinkray-preload starts hero images downloading immediately, and removes lazy loading from preloaded <img> tags.
  • Clean Up Orphaned Copies removes copies whose original was deleted, renamed or moved.
  • Cache-busting: every copy URL carries a timestamp, so regenerated copies appear right away.
  • Warns when two originals share a name, like photo.jpg and photo.png, since their copies would overwrite each other.
1.4.0Chaos Loupe format
  • Chaos Loupe now gets the AVIF copies by default, so the lightbox reuses the image the page already loaded.
1.3.0Latest Actions
  • Upload conversions appear in Joomla's User Actions Log and the Latest Actions dashboard module.
1.2.0Recent Activity
  • A Recent Activity panel on the Batch tab shows the latest 50 conversions and errors, with a Clear Log button.
1.1.0 & 1.1.1Serving images
  • Serve Resized Images: rewrites front-end pages to use the copies, in Picture (AVIF + WebP) or Srcset-only mode.
  • Fills in Chaos Loupe's enlarge sources automatically.
  • 1.1.1: upload results are written to a log file, since Media Manager uploads can't show messages.
1.0.0 & 1.0.1First release
  • Resized AVIF and WebP copies on upload and by batch, with folder selection, adjustable sizes and quality, and phone-photo rotation.
  • 1.0.1: copies use the double-dash naming convention (name--1600.avif).