Node.js se ha consolidado como una de las plataformas más populares para desarrollo backend. Aquí te comparto algunos tips y trucos esenciales que pueden mejorar significativamente la calidad y rendimiento de tus aplicaciones.
1. Utiliza Variables de Entorno de Forma Segura
Nunca hagas commit de credenciales en tu código. Utiliza el paquete dotenv para manejar variables de entorno:
require('dotenv').config();
const dbPassword = process.env.DB_PASSWORD;
Para producción, considera usar herramientas como AWS Secrets Manager o HashiCorp Vault.
2. Implementa Manejo de Errores Asíncrono Robusto
Usa async/await con bloques try-catch para un manejo de errores más limpio:
async function fetchData() {
try {
const data = await apiCall();
return data;
} catch (error) {
console.error('Error fetching data:', error);
throw error;
}
}
No olvides manejar promesas rechazadas no capturadas:
process.on('unhandledRejection', (reason, promise) => {
console.error('Unhandled Rejection:', reason);
// Registra el error y considera terminar el proceso
});
3. Optimiza el Rendimiento con Clustering
Aprovecha todos los núcleos de CPU usando el módulo cluster:
const cluster = require('cluster');
const os = require('os');
if (cluster.isMaster) {
const numCPUs = os.cpus().length;
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
} else {
// Código de tu servidor
app.listen(3000);
}
4. Usa Streams para Archivos Grandes
En lugar de cargar archivos completos en memoria, utiliza streams:
const fs = require('fs');
const readStream = fs.createReadStream('archivo-grande.txt');
const writeStream = fs.createWriteStream('copia.txt');
readStream.pipe(writeStream);
Esto es especialmente importante para operaciones con archivos grandes o procesamiento de datos en tiempo real.
5. Implementa Caché Inteligente
Reduce la carga de tu base de datos implementando caché con Redis:
const redis = require('redis');
const client = redis.createClient();
async function getUserData(userId) {
const cached = await client.get(`user:${userId}`);
if (cached) return JSON.parse(cached);
const user = await db.query('SELECT * FROM users WHERE id = ?', [userId]);
await client.setex(`user:${userId}`, 3600, JSON.stringify(user));
return user;
}
6. Valida Entradas con Middleware
Siempre valida y sanitiza las entradas del usuario:
const { body, validationResult } = require('express-validator');
app.post('/user', [
body('email').isEmail(),
body('password').isLength({ min: 8 })
], (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
// Procesar solicitud
});
7. Monitorea el Event Loop
Previene bloqueos del event loop evitando operaciones síncronas pesadas:
// Evita esto:
const data = fs.readFileSync('archivo.txt'); // ❌
// Mejor usa esto:
fs.readFile('archivo.txt', (err, data) => { // ✅
if (err) throw err;
console.log(data);
});
Para tareas CPU-intensivas, considera usar worker threads o servicios externos.
8. Implementa Rate Limiting
Protege tu API contra abusos:
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutos
max: 100 // límite de 100 requests
});
app.use('/api/', limiter);
9. Usa Compression Middleware
Reduce el tamaño de las respuestas HTTP:
const compression = require('compression');
app.use(compression());
Esto puede reducir significativamente el tiempo de carga, especialmente para respuestas JSON grandes.
10. Mantén las Dependencias Actualizadas
Revisa regularmente las vulnerabilidades de seguridad:
npm audit
npm audit fix
Considera usar herramientas como Dependabot o Snyk para automatizar este proceso.
¿Qué otros tips de Node.js han sido útiles en tu experiencia? ¡Comparte tus recomendaciones en los comentarios!
