pruner.js is a JavaScript utility that enhances image handling by stitching multiple images into a single canvas. It works by dividing large images into smaller tiles and only loading the necessary tiles based on the viewport size. This approach not only reduces the total amount of data transferred but also improves performance by ensuring that only visible parts of the image are processed. By minimising data transfer and leveraging efficient image management, pruner.js accelerates loading times and supports sustainable web design practices.
You can include pruner.js
in your project either by downloading the files or using a CDN.
Link directly to the minified version using Unpkg (we recommend downloading the file to reduce HTTP requests):
<script async src="https://unpkg.com/prunerjs@1.0.4/dist/pruner.min.js"></script>
You can also install pruner.js
using npm:
npm install pruner --save
Attribute (data-pruner
)
imageName
: The base name of the images used in conjunction with the image (string).cols
: Number of columns (integer).rows
: Number of rows (integer).tileWidth
: Width of each tile in pixels (integer).tileHeight
: Height of each tile in pixels (integer).mobileBreakpoint
: The screen width in pixels below which the mobile image is loaded (integer).mobileScale
: Scale factor for mobile view (optional, numeric).imagePath
: Path to the directory where images are stored (string).Images
imageName
matches the base name used for the pruner tile images. For instance, if imageName
is landscape
, the images should be named landscape 1.webp
, landscape 2.webp
, and so on.You can initialize pruner.js
using vanilla JavaScript or by setting attributes in your HTML.
window.onload = () => {
new Pruner('data-pruner');
};
You can use the data-pruner
attribute to configure how the image is processed.
<img data-pruner='{"imageName": "landscape", "cols": 5, "rows": 5, "tileWidth": 300, "tileHeight": 200, "mobileBreakpoint": 768, "mobileScale":1.4, "imagePath": "assets/"}' alt="Landscape photography of mountains in New Zealand by Tobias Keller" loading="lazy">
data-pruner
imageName
: landscape
cols
: 5
(5 columns)rows
: 5
(5 rows)tileWidth
: 300
pixelstileHeight
: 200
pixelsmobileBreakpoint
: 768
pixelsmobileScale
: 1.4
140%imagePath
: /assets/
(path to images)Include pruner.js
in your HTML file:
<script src="https://github.com/overbrowsing/pruner/raw/main/path/to/pruner.js"></script>
Set Up Images:
imageName
matches the base name used for the pruner tile images. For instance, if imageName
is landscape
, the images should be named landscape 1.webp
, landscape 2.webp
, and so on.data-pruner
attributes to the image, specifying the name of the image, the number of columns, rows, tile width, tile height, mobile breakpoint, mobile scale factor, and image path.On mobile devices (below the mobileBreakpoint
), only the central tiles of the grid are loaded for improved performance. This is determined by the mobileScale
parameter, which adjusts the scaling of the tiles based on the device’s screen size. For larger screens, the entire tiled image grid is constructed and displayed on a canvas.
To evaluate the performance improvements from using pruner.js
compared to loading two full images for desktop and mobile, tests were conducted using the Example HTML Setup. The test image (1500 x 1000px) was split into a 5x5 grid, with each tile measuring 300 x 200px. All image assets are available in the /assets
folder. The original image was sourced from T. Keller on Unsplash.
This experiment compared two approaches to image loading:
pruner.js
: Loading 25 tiles (300 x 200px) plus the 2 KB minified script.To ensure consistent and accurate results, the following factors were considered:
To Note:
pruner.js
across different viewport sizes (mobile, medium desktop, large desktop).pruner.js
across each viewport size.pruner.js
, including the size of the minified script itself.📱 Small 650px | 💻 Medium 1100px | 🖥️ Large 1680px | 📁 All Assets | |
---|---|---|---|---|
Before | ||||
📁 Size (KB) | 50 KB | 194 KB | 194 KB | 244 KB (2 Images) |
🌱 CO₂e (g) | 0.013 g | 0.053 g | 0.053 g | 0.067 g |
After | ||||
🧩 Tiles | 6 | 16 | 20 | 25 |
📁 Size (KB) | 26 KB | 83 KB | 105 KB | 156 KB |
🌱 CO₂e (g) | 0.007 g | 0.022 g | 0.029 g | 0.043 g |
Savings | ||||
📁 ∆ Size (KB) | -24 KB | -111 KB | -89 KB | -88 KB |
🌱 ∆ CO₂e (g) | -0.006 g | -0.031 g | -0.024 g | -0.024 g |
✂️ Reduction (%) | 46 % | 57.1 % | 45.4 % | 36.1 % |
Ongoing testing is being conducted to expand the sample size and further verify the results.
There is also a Python visualisation tool designed to determine the optimal combination of tile count, row height, and tile size, and mobile scaling. This tool ensures efficient asset usage and performance across various common viewport dimensions.
For more information on installation and usage instructions, please refer to this document.
The application can also be found in this directory.
pruner.js
is released under the MIT license. Feel free to use and modify it as needed.