Skip to content

Instantly share code, notes, and snippets.

@KoenRijpstra
Created January 31, 2025 13:54
Show Gist options
  • Save KoenRijpstra/71f02b95497f4c59132c6c5d284410f5 to your computer and use it in GitHub Desktop.
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
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