JavaScript no está muriendo, está más vivo que nunca. Erick Wendel, desarrollador brasileño con casi diez años de experiencia, demuestra en vivo cómo procesar siete gigabytes de datos directamente en el navegador, sin backend, sin Node.js, usando únicamente APIs nativas del lenguaje. La charla rompe mitos sobre las limitaciones de JavaScript y presenta herramientas concretas para construir aplicaciones capaces de manejar volúmenes masivos de información.
¿Por qué Node.js cambió la forma de construir software?
Desde su aparición en 2009, Node.js transformó la manera en que los servidores manejan conexiones. Antes, cada cliente requería un bloque dedicado de memoria y CPU; si llegaba un Black Friday, había que escalar con más servidores de forma proporcional, algo costoso e ineficiente.
Node.js introdujo un modelo basado en Async I/O [4:50], donde un grupo de recursos en memoria se reutiliza entre todos los usuarios. No importa cuántos clientes se conecten: el runtime pide más memoria al sistema operativo solo cuando lo necesita y la libera cuando deja de ser útil. La lección central es que no es necesario asignar memoria para cada cliente, y por eso Node.js soporta miles de conexiones concurrentes con muy pocos recursos.
Un error frecuente es afirmar que Node.js no es multithreaded [6:00]. En realidad, desde su primer día utiliza al menos cuatro threads internos y un thread pool conocido como libuv worker. Lo que ocurre es que esos hilos eran internos al runtime; solo recientemente existe una API pública para que los desarrolladores creen sus propios worker threads. La única parte single threaded es el event loop, lo cual es una ventaja: evita manejar condiciones de carrera entre variables, algo habitual en Java o C++.
¿Cómo procesar archivos enormes sin agotar la memoria?
El patrón clásico consiste en descargar un archivo, guardarlo en disco y luego cargarlo completo en memoria para procesarlo. Con archivos de varios gigabytes, Node.js rechazará esa operación porque excede los límites del heap [7:40].
La solución es convertir el archivo en un buffer y dividirlo en pedazos pequeños llamados chunks. Cada fragmento se procesa de forma individual:
- Si es un CSV, cada línea se mapea, transforma o almacena por separado.
- No importa el tamaño del archivo porque siempre se trabaja bajo demanda.
- La memoria se libera después de procesar cada chunk.
Este concepto se materializa con JavaScript generators e iterators [8:30]. Usando la sintaxis for await, JavaScript busca un async iterator y recibe datos solo cuando están disponibles. Es como un grifo: el agua fluye conforme se necesita, no de golpe.
¿Qué son las Web Streams y por qué importan?
Node.js tiene readable streams y writable streams desde 2010, pero las Web Streams [9:40] son su equivalente para el navegador, disponibles desde 2013 en evolución constante. La demostración lo prueba: un archivo de casi un millón de líneas se procesa en el browser sin congelar la pantalla.
El truco está en que los archivos del navegador pueden consumirse como streams. Se usa un transform stream para:
- Recibir la primera línea disponible y procesarla de inmediato.
- Comunicar el progreso al usuario mientras el archivo sigue leyéndose.
- Generar un producto final que puede ser otro archivo, una llamada a una API o una actualización visual.
¿Qué error cometen los full stacks al consumir APIs?
Un problema muy común ocurre cuando el backend envía datos bajo demanda, escribiendo cada ítem individual, pero el frontend espera a que toda la respuesta esté completa antes de renderizar [10:50]. La página se congela y el usuario no ve nada.
La corrección es consumir la respuesta del backend también bajo demanda: cuando un ítem está listo, se renderiza de inmediato. El mismo código de Web Streams funciona tanto en frontend como en backend, logrando una aplicación mucho más responsiva.
¿Cuándo usar Web Workers para procesamiento pesado?
Los Web Workers [12:10] permiten ejecutar lógica pesada en un hilo separado del navegador. Sin ellos, cualquier cálculo intensivo congela la interfaz por completo.
Para implementarlos se necesita:
- Crear un archivo aparte con la lógica de procesamiento.
- Escuchar mensajes con
onmessage y responder con postMessage.
- El navegador principal sigue respondiendo mientras el worker hace el trabajo pesado.
Cualquier tarea que implique procesamiento de archivos grandes, streaming de vídeo, manipulación de imágenes o inferencia de modelos de IA en el navegador debería combinar Web Workers con Web Streams. Todo lo que pueda procesarse bajo demanda se beneficia de estas dos APIs trabajando juntas.
Si ya usas JavaScript en tu día a día, experimenta con estos patrones en los repositorios que Erick compartió en GitHub. ¿Cuál de estas técnicas vas a probar primero en tu próximo proyecto?