Created
January 31, 2025 13:54
-
-
Save KoenRijpstra/71f02b95497f4c59132c6c5d284410f5 to your computer and use it in GitHub Desktop.
Benchmark comparing Sharp's WebP encoding with/without smartSubsample - runs 100 iterations to measure processing time and file size differences
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sharp from 'sharp' | |
import { promises as fs } from 'fs' | |
async function convertToWebp(inputPath, outputPath, options) { | |
const startTime = performance.now() | |
try { | |
const input = await fs.readFile(inputPath) | |
await sharp(input) | |
.webp(options) | |
.toFile(outputPath) | |
const endTime = performance.now() | |
const stats = await fs.stat(outputPath) | |
return { | |
time: endTime - startTime, | |
size: stats.size, | |
path: outputPath | |
} | |
} catch (error) { | |
console.error(`Error converting image: ${error.message}`) | |
return null | |
} | |
} | |
async function runTest() { | |
const [noSmartResult, smartResult] = await Promise.all([ | |
convertToWebp( | |
'./test.png', | |
'./test-no-smartSubsample.webp', | |
{ quality: 100, smartSubsample: false } | |
), | |
convertToWebp( | |
'./test.png', | |
'./test-smartSubsample.webp', | |
{ quality: 100, smartSubsample: true } | |
) | |
]) | |
return { noSmartResult, smartResult } | |
} | |
async function compareWebpOptions() { | |
const inputFile = './test.png' | |
const iterations = 100 | |
try { | |
await fs.access(inputFile) | |
const results = { | |
noSmart: { times: [], sizes: [] }, | |
smart: { times: [], sizes: [] } | |
} | |
console.log(`Running ${iterations} tests...`) | |
for (let i = 0; i < iterations; i++) { | |
const { noSmartResult, smartResult } = await runTest() | |
results.noSmart.times.push(noSmartResult.time) | |
results.noSmart.sizes.push(noSmartResult.size) | |
results.smart.times.push(smartResult.time) | |
results.smart.sizes.push(smartResult.size) | |
process.stdout.write(`Progress: ${i + 1}/${iterations}\r`) | |
} | |
// Calculate averages | |
const avgNoSmartTime = average(results.noSmart.times) | |
const avgSmartTime = average(results.smart.times) | |
const avgNoSmartSize = average(results.noSmart.sizes) | |
const avgSmartSize = average(results.smart.sizes) | |
console.log('\n\nAverage Results after', iterations, 'iterations:') | |
console.log('\nWithout smartSubsample:') | |
console.log(`- Time: ${avgNoSmartTime.toFixed(2)}ms`) | |
console.log(`- Size: ${(avgNoSmartSize / 1024).toFixed(2)}KB`) | |
console.log('\nWith smartSubsample:') | |
console.log(`- Time: ${avgSmartTime.toFixed(2)}ms`) | |
console.log(`- Size: ${(avgSmartSize / 1024).toFixed(2)}KB`) | |
} catch (error) { | |
console.error(`Input file not found: ${inputFile}`) | |
} | |
} | |
function average(array) { | |
return array.reduce((a, b) => a + b) / array.length | |
} | |
compareWebpOptions() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment