pruner.js
is a responsive image Javascript utility using viewport-based rendering. It works by splitting images into tiles and loading only the parts of the image visible within the viewport, like assembling a jigsaw puzzle. This method reduces server-side storage compared to the current best practice of responsive images by eliminating the need for multiple image versions defined for specific breakpoints and reduces data transfer by avoiding the download of ‘waste pixels’—parts of the image outside the visible aperture.
The utility is designed to function not only at defined breakpoints but also dynamically across varying viewport sizes, distinguishing it from traditional responsive image methods. The tile creation process begins with the Tile Calculator which determines the most efficient arrangement of tiles for processing images using the Tile Maker. This tool also generates a snippet of HTML for easy installation, that also uses less HTML than the Picture-Element (<picture>
), and in some cases srcset
, resulting in a simpler and more efficient process to responsive images.
The name was chosen based on the practice of pruning in horticulture: the practice of targetted removal of unhealthy or unwanted parts of a plant to promote healthier growth. Just as pruning in nature encourages a plant to thrive by focusing its energy on the most important branches, pruner.js
optimises web performance by reducing server-side storage and excess data transfer, focusing on what is needed to display the image effectively across viewports. A name related to nature was fitting and thematic, aligning with the principles of sustainable web design.
- Load Only What You See: Servers only the parts of an image that are visible on the screen and reduces unnecessary data transfer by not loading hidden sections of images (waste pixels).
- Save Data: Reduces the number of images needed for responsive images saving storage server-side.
- Better Responsive Images: Provides dynamic viewport-based rendering of images across a range of viewports, rather than just a few predefined breakpoints like
<picture>
. - Easy to Use: The Tile Calculator automates the calculation, while the Tile Maker handles formatting and compression of tiles, as well as the generation of a single line of HTML for easy installation.
- Art Direction: Allows you to set a focal point in the image and specify breakpoints for image scaling on smaller form factors.
- Client-Side Functionality: Operates in the browser with a small piece of Javascript to dynamically create auto-scaling images based on the viewport size.
You can include pruner.js
in your project either by downloading the files or using a CDN. While using a third-party CDN introduces an additional HTTP request, we ensured that it is hosted is using renewable energy.
- Minified: Available via pruner.min.js on unpkg.
- Unminified: Available in the source repository.
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.1.3/dist/pruner.min.js"></script>
You can also install pruner.js
using npm:
npm install pruner --save
In the <img>
tag, instead of using the src
attribute to link an image, we use the data-pruner
attribute. This attribute contains parameters in JSON format for the utility to interpret, specifying how the script should display the image tiles, where to locate them, and including other useful features.
⭐️ Denotes which parameters are optional.
Parameter | Description | Details | Example Installation | |
---|---|---|---|---|
name |
Image Name | The base name of the image files. | banks-of-the-seine (banks-of-the-seine-n.webp) |
|
tile |
Tile Grid | The number of columns and rows the image is split into. | 10 8 (10 columns and 8 rows) |
|
⭐️ | roi |
Region of Interest | This parameter lets you set a specific focal point within the image for art direction. The region of interest adjusts the image's focus based on the chosen tile number, ensuring that off-centre subjects are prominently displayed in the viewport. | 5 (banks-of-the-seine-5.webp) |
⭐️ | scale |
Scale Factor | Defines how much to enlarge the image when the viewport width is at or below the breakpoint in pixels. Formatted as "scale breakpoint" (e.g. 1.2 750). | 1.2 750 (120% 750w) |
path |
Directory for Tiles | The file path to the directory where the image tiles are stored. This parameter is essential for locating and retrieving the image files for display. | tools/tile-maker/processed/banks-of-the-seine/ |
-
Calculating Tiles: The best way to create tiles is by first calcualting the optimal arrangement by using the Tile Calculator. This tool will help you generate the best configuration for your project and will share the parameters needed for the next step.
-
Making Tiles: Once you have your configuration from the Tile Calculator, use the Tile Maker to process your images and create the tiles. Tile Maker will output the tiles and an optional HTML snippet for easy installation.
-
Naming Images: If you used the Tile Maker, you can ignore the next two steps and proceed to installation as the tool handles naming and formatting of images automatically. For manual installation and tile creation, ensure that the parameter
imageName
matches the base name for the tile images (e.g., banks-of-the-seine-1.webp, banks-of-the-seine-2.webp, etc.) and that the images are named sequentially. -
Formatting Images: Images need to be foramtted to WebP. This helps reduce image sizes—WebP lossy versions can be 25% to 34% smaller than JPEGs. This format meets the 'Serve images in modern formats' opportuntiy within the Google Lighthouse test and follows best practices for Sustainable Web Design. WebP is 'widely supported across major browsers', unlike AVIF which is 'newly available across major browsers'. Don’t worry! There is an option for progressive enhancement that enables developers to easily adjust a line of code in the pruner.js script to support additional image formats if they wish.
-
Insert the HTML Snippet: If you used the Tile Maker, locate the exported HTML snippet in the image folder associated with the image name within the processed folder. Copy this snippet into your web project where you want to display the images.
-
Update Parameters: Update the image path
imagePath
parameter within the HTML snippet to point to the location of your tiles. Make sure to also configure any optional parameters (e.g.,ROI
,mobileBreakpoint
,mobileScale
) as necessary to suit your project. Remember to includealt
text as well! -
Include
pruner.js
: To include the utility in your project. Add the either option before the closing</html>
tag in your HTML file-
Option 1: Using locally.
<script async src="/your-path-here/pruner.js"></script>
-
Option 2: Using a CDN.
<script async src="https://unpkg.com/prunerjs@1.1.3/dist/pruner.min.js"></script>
-
After completing the steps with the example image of Banks of the Seine, Vétheuil, by Claude Monet, beginning with the steps in Tile Calculator documentation and then proceeding to the steps in the Tile Maker documentation the HTML snippet will be exported here and tiles here. The HTML snippet looks like this:
<img data-pruner='{"name": "banks-of-the-seine", "tile": "10 8", "path": "your-path-here/"}' alt="" loading="lazy">
The path
and optional parameters (roi
and scale
), along the alt
attribute, were added in manually afterwards:
<img data-pruner='{"name": "banks-of-the-seine", "tile": "10 8", "roi": 5, "scale": "1.2 750", "path": "tools/tile-maker/processed/banks-of-the-seine/"}' alt="Banks of the Seine, Vétheuil, 1880 by Claude Monet" loading="lazy">
⭐️ Denotes which parameters are optional.
Parameter | Description | Value | |
---|---|---|---|
name |
Image Name | banks-of-the-seine |
|
tile |
Tile Grid | 10 8 (10 columns and 8 rows) |
|
⭐️ | roi |
Region of Interest | 5 (banks-of-the-seine-5.webp) |
⭐️ | scale |
Scale Factor | 1.2 750 (120% 750w) |
path |
Directory for Tiles | tools/tile-maker/processed/banks-of-the-seine/ |
Although, on average, only about 0.2% of users disable Javascript, there are instances where scripts may not be accessible e.g. network issues, affecting approximately 0.9% of users. Given that approximately 98.7% of websites utilise JavaScript, it serves as a fundamental part of web infrastructure; if a user is not being served it, the page is likely not functioning correctly. However, some institutions require progressive enhancements for accessibility ensuring their sites work without Javascript. By leaving the src
attribute unpopulated in the <img>
element, we provide an option for a fallback image. While this fallback slightly undermines our goal of minimising image size used in responsve images, it still results in a smaller server-side footprint and less HTML.
Contributions are welcome. Please feel free to submit an issue or a pull request.
pruner.js
is released under the MIT license. Feel free to use and modify it as needed.