प्रदर्शन अनुकूलन उदाहरण
यहां Sharp प्रदर्शन अनुकूलन के कुछ उदाहरण और सर्वोत्तम अभ्यास दिए गए हैं।
मेमोरी अनुकूलन
बड़ी फ़ाइलों के लिए स्ट्रीम प्रसंस्करण
javascript
import sharp from 'sharp';
import fs from 'fs';
// स्ट्रीम प्रसंस्करण, पूरी फ़ाइल को मेमोरी में लोड करने से बचें
fs.createReadStream('large-image.jpg')
.pipe(sharp().resize(800, 600))
.pipe(fs.createWriteStream('output.jpg'));फ़ाइल के बजाय Buffer का उपयोग
javascript
// छोटी फ़ाइलों के लिए, Buffer का उपयोग अधिक कुशल है
const inputBuffer = fs.readFileSync('input.jpg');
const outputBuffer = await sharp(inputBuffer)
.resize(300, 200)
.jpeg({ quality: 80 })
.toBuffer();
fs.writeFileSync('output.jpg', outputBuffer);समय पर संसाधन मुक्त करना
javascript
// प्रसंस्करण पूर्ण होने के बाद समय पर मुक्त करें
const image = sharp('input.jpg');
await image.resize(300, 200).toFile('output.jpg');
// image इंस्टेंस स्वचालित रूप से गार्बेज कलेक्ट हो जाएगासमवर्ती नियंत्रण
समवर्ती संख्या सीमित करना
javascript
// अधिकतम समवर्ती संख्या सेट करें
sharp.concurrency(4);
// बैच प्रसंस्करण के दौरान समवर्ती नियंत्रण
async function batchProcess(files) {
const batchSize = 4;
const results = [];
for (let i = 0; i < files.length; i += batchSize) {
const batch = files.slice(i, i + batchSize);
const batchPromises = batch.map(file =>
sharp(file).resize(300, 200).jpeg().toFile(`output_${file}`)
);
await Promise.all(batchPromises);
results.push(...batch);
}
return results;
}कतार प्रसंस्करण का उपयोग
javascript
class ImageProcessor {
constructor(concurrency = 4) {
this.concurrency = concurrency;
this.queue = [];
this.running = 0;
}
async add(task) {
return new Promise((resolve, reject) => {
this.queue.push({ task, resolve, reject });
this.process();
});
}
async process() {
if (this.running >= this.concurrency || this.queue.length === 0) {
return;
}
this.running++;
const { task, resolve, reject } = this.queue.shift();
try {
const result = await task();
resolve(result);
} catch (error) {
reject(error);
} finally {
this.running--;
this.process();
}
}
}
// उपयोग उदाहरण
const processor = new ImageProcessor(4);
for (const file of files) {
processor.add(async () => {
await sharp(file).resize(300, 200).jpeg().toFile(`output_${file}`);
});
}कैश अनुकूलन
प्रसंस्करण परिणाम कैश करना
javascript
const cache = new Map();
async function processWithCache(inputPath, width, height) {
const key = `${inputPath}_${width}_${height}`;
if (cache.has(key)) {
return cache.get(key);
}
const result = await sharp(inputPath)
.resize(width, height)
.jpeg({ quality: 80 })
.toBuffer();
cache.set(key, result);
return result;
}Sharp कैश साफ़ करना
javascript
// मेमोरी मुक्त करने के लिए नियमित रूप से कैश साफ़ करें
setInterval(() => {
sharp.cache(false);
}, 60000); // प्रति मिनट एक बार साफ़ करेंएल्गोरिदम चयन
उपयुक्त आकार समायोजन एल्गोरिदम चुनना
javascript
// छोटा करने के लिए तेज़ एल्गोरिदम का उपयोग करें
await sharp('input.jpg')
.resize(300, 200, { kernel: sharp.kernel.cubic })
.toFile('output.jpg');
// बढ़ाने के लिए उच्च गुणवत्ता एल्गोरिदम का उपयोग करें
await sharp('input.jpg')
.resize(1200, 800, { kernel: sharp.kernel.lanczos3 })
.toFile('output.jpg');बैच प्रसंस्करण अनुकूलन
javascript
async function optimizedBatchProcess(files) {
// आकार के अनुसार समूहीकरण प्रसंस्करण
const smallFiles = [];
const largeFiles = [];
for (const file of files) {
const metadata = await sharp(file).metadata();
if (metadata.width * metadata.height < 1000000) {
smallFiles.push(file);
} else {
largeFiles.push(file);
}
}
// छोटी फ़ाइलें तेज़ एल्गोरिदम का उपयोग करती हैं
await Promise.all(smallFiles.map(file =>
sharp(file)
.resize(300, 200, { kernel: sharp.kernel.cubic })
.jpeg({ quality: 80 })
.toFile(`output_${file}`)
));
// बड़ी फ़ाइलें उच्च गुणवत्ता एल्गोरिदम का उपयोग करती हैं
await Promise.all(largeFiles.map(file =>
sharp(file)
.resize(800, 600, { kernel: sharp.kernel.lanczos3 })
.jpeg({ quality: 90 })
.toFile(`output_${file}`)
));
}नेटवर्क अनुकूलन
स्ट्रीम प्रतिक्रिया
javascript
// Express.js उदाहरण
app.get('/image/:filename', async (req, res) => {
const filename = req.params.filename;
try {
const imageStream = sharp(`images/${filename}`)
.resize(300, 200)
.jpeg({ quality: 80 });
res.set('Content-Type', 'image/jpeg');
imageStream.pipe(res);
} catch (error) {
res.status(404).send('Image not found');
}
});सशर्त प्रसंस्करण
javascript
app.get('/image/:filename', async (req, res) => {
const { filename } = req.params;
const { width, height, quality = 80 } = req.query;
try {
let image = sharp(`images/${filename}`);
if (width || height) {
image = image.resize(parseInt(width), parseInt(height));
}
if (req.headers.accept?.includes('image/webp')) {
image = image.webp({ quality: parseInt(quality) });
res.set('Content-Type', 'image/webp');
} else {
image = image.jpeg({ quality: parseInt(quality) });
res.set('Content-Type', 'image/jpeg');
}
image.pipe(res);
} catch (error) {
res.status(404).send('Image not found');
}
});निगरानी और डीबगिंग
प्रदर्शन निगरानी
javascript
async function processWithTiming(inputPath, outputPath) {
const startTime = Date.now();
try {
await sharp(inputPath)
.resize(800, 600)
.jpeg({ quality: 80 })
.toFile(outputPath);
const endTime = Date.now();
console.log(`प्रसंस्करण समय: ${endTime - startTime}ms`);
} catch (error) {
console.error('प्रसंस्करण विफल:', error.message);
}
}मेमोरी उपयोग निगरानी
javascript
const process = require('process');
function logMemoryUsage() {
const usage = process.memoryUsage();
console.log('मेमोरी उपयोग:', {
rss: `${Math.round(usage.rss / 1024 / 1024)} MB`,
heapTotal: `${Math.round(usage.heapTotal / 1024 / 1024)} MB`,
heapUsed: `${Math.round(usage.heapUsed / 1024 / 1024)} MB`,
external: `${Math.round(usage.external / 1024 / 1024)} MB`
});
}
// प्रसंस्करण से पहले और बाद में मेमोरी उपयोग रिकॉर्ड करें
logMemoryUsage();
await sharp('input.jpg').resize(800, 600).toFile('output.jpg');
logMemoryUsage();त्रुटि प्रबंधन और पुन: प्रयास
पुन: प्रयास तंत्र
javascript
async function processWithRetry(inputPath, outputPath, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
await sharp(inputPath)
.resize(800, 600)
.jpeg({ quality: 80 })
.toFile(outputPath);
console.log(`प्रसंस्करण सफल, प्रयास संख्या: ${attempt}`);
return;
} catch (error) {
console.error(`प्रयास ${attempt} विफल:`, error.message);
if (attempt === maxRetries) {
throw new Error(`प्रसंस्करण विफल, ${maxRetries} बार पुन: प्रयास किया गया`);
}
// कुछ समय प्रतीक्षा करने के बाद पुन: प्रयास करें
await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
}
}
}त्रुटि वर्गीकरण प्रसंस्करण
javascript
async function robustProcess(inputPath, outputPath) {
try {
await sharp(inputPath)
.resize(800, 600)
.jpeg({ quality: 80 })
.toFile(outputPath);
} catch (error) {
if (error.code === 'VipsForeignLoad') {
console.error('असमर्थित छवि प्रारूप');
} else if (error.code === 'VipsForeignLoadLimit') {
console.error('छवि बहुत बड़ी है, छोटा करने का प्रयास करें');
// छोटे संस्करण को संसाधित करने का प्रयास करें
await sharp(inputPath, { limitInputPixels: 268402689 })
.resize(400, 300)
.jpeg({ quality: 80 })
.toFile(outputPath);
} else if (error.code === 'ENOSPC') {
console.error('डिस्क स्थान अपर्याप्त');
} else {
console.error('अज्ञात त्रुटि:', error.message);
}
}
}सर्वोत्तम अभ्यास सारांश
1. उपयुक्त प्रसंस्करण विधि चुनना
javascript
// छोटी फ़ाइलें: सीधे प्रसंस्करण
if (fileSize < 1024 * 1024) {
await sharp(file).resize(300, 200).toFile(output);
}
// बड़ी फ़ाइलें: स्ट्रीम प्रसंस्करण
else {
fs.createReadStream(file)
.pipe(sharp().resize(300, 200))
.pipe(fs.createWriteStream(output));
}2. बैच प्रसंस्करण अनुकूलन
javascript
// समवर्ती प्रसंस्करण के लिए Promise.all का उपयोग करें
const promises = files.map(file =>
sharp(file).resize(300, 200).jpeg().toFile(`output_${file}`)
);
await Promise.all(promises);3. मेमोरी प्रबंधन
javascript
// नियमित रूप से कैश साफ़ करें
setInterval(() => {
sharp.cache(false);
}, 300000); // हर 5 मिनट में एक बार साफ़ करें4. त्रुटि प्रबंधन
javascript
// हमेशा try-catch का उपयोग करें
try {
await sharp(input).resize(300, 200).toFile(output);
} catch (error) {
console.error('प्रसंस्करण विफल:', error.message);
// बैकअप समाधान प्रदान करें
}