🌱 Por que eu gosto de Node.js? Streams FTW

Devaneios sobre a evolução da experiência de desenvolvimento no JavaScript e porque eu gosto de Node.

devaneios #javascript #node #streams

A primeira vez que eu trabalhei com JavaScript foi uma experiência tenebrosa. Era um grande ecommerce construído em Java, com as famosas JSPs servindo HTML, JS e ~~só alegria~~ tristeza.

📥 [side-topic] a página era "responsiva" – carregava as duas versões (mobile e web) para o cliente, testava o agente do navegador e então utilizava o famoso $("#element").hide() do JQuery para escondar uma versão ou outra.

Nem tão bons tempos assim, mas definitivamente nostálgico.

O fato é que essa era a cena do ecossistema JavaScript na época e, como uma boa Dev BackEnd, eu clamava que não gostava de JavaScript. Na época, eu costumava explicar que o problema do JavaScript era a facilidade com que a comunidade aceitava gambiarra, a ausência de padronização na sintaxe, APIs pouco amigáveis, framework hell, etc.

Então esse conjunto de APIs Também tem o fato da facilidade da linguagem para programadores iniciantes, o ônus e o bônus. Um tempo depois nesse memso projeto tivemos a oportunidade de

Mas aí experimentei aprender de verdade, e veio o EcmaScript 6, e mudei bastante de ideia, de tal forma que JS se tornou minha principal linguagem, em que me especializo até hoje.

📥 [side-topic] por sinal essa ausência de padronização no design core da linguagem é – na minha humilde opinião – o grande vilão do PHP. Mas isso fica para outro dia =)

EcmaScript 6 e a nova era

As mudanças foram enormes, especialmente para projetos em que o paradigma funcional não fazia sentido. Codificar orientado a objetos com JavaScript se tornou mais decente, e com Typescript se tornou uma delícia.

A comunidade começou a olhar para aqueles papos de BackEnd: código limpo, padrões de projeto. O surgimento de frameworks como Angular, React e Vue também ditaram muito dessa mudança. A linguagem amadureceu.

Enfim, de volta ao Node. Recordo de como era anunciado como algo quase mágico: O motor que consegue executar JavaScript no seu BackEnd!, como todas as novas tecnologias fazem. Lembro também de um amigo que comentava que JS estava virando o que o Java prometeu ser e rodar em qualquer coisa (o que não é necessariamente uma coisa boa, mas chama atenção).

Sob Demanda

Eu aprendi Streams quando resolvi me aprofundar no estudo da plataforma, realmente entender como funcionava e o que atraia tanto as pessoas.

Quando eu era criança utilizava o Tumblr e foi lá eu aprendi o básico gambiarrento de CSS e HTML. Me sentia a própria hackerwoman quando conseguia colocar um efeito de mouse na tela.

Independente da plataforma de blog utilizada, eu recordo de uma mudança massiva de páginas em que você apertava "próxima página" para páginas que possuíam Rolagem Infinita. O conceito de scroll infinito é controverso, mas a ideia é que você não deixe para o usuário a responsabilidade de paginar os resultados... Eles aparecem sob demanda, para ele, quando ele precisa ler. Quando bem implementado faz uma boa diferença na experiência.

Por trás ainda é a mesma paginação, mas o efeito psicológico nos usuários foi de uma página mais rápida, otimizada, que funcionava tão rápido quanto ele podia ler e nunca era recarregada².

Sob demanda.

E as Node.js Streams causam esse mesmo efeito 🤯 em que, em vez de paginar os resultados em um número mágico¹, você lida com eles sob demanda. ~~Mas no caso das streams o efeito não é só psicologico, realmente economiza a memória e é mais rápido 😅~~

Então, Streams são apenas sobre isso, lidar com os dados sob demanda, dispensa-los da memória assim que forem utilizados, sem ficar esperando uma fila enorme.

É quase mágico. Do jeito mágico em que as coisas simplesmente fazem sentido, não que não sabemos como acontece.

É claro que processamento de dados sob demanda existe em outras linguagens, mas o modelo não bloquante de Node.js pulveriza o recurso por toda a plataforma, além das APIs serem muito simples de trabalhar.

Show, Don't Tell

Bom, vamos ver se isso é verdade, bora codar:

Situação: Precisamos consumir uma API de playlists e escrever os dados em um arquivo, substituindo todas as ocorrências de "a" por "Nicolas Cage". Ou todas as primeiras letras por maiúsculas, você quem sabe.

Requisitos

Garanta que você tenha instalado:

Comum, em memória

  1. Crie um arquivo, on-memory.js

  2. Faça requisição a API (listed...)

  3. Converta todas as ocorrências de "a" por "Nicolas Cage" e todos os

  4. Escreva num arquivo (bem bonito, mantendo tudo em um loop só e usando "os novos MAP/REDUCE/FILTER" :))

Se executarmos essa função com um timer, levou aproximadamente X segundos aqui. E inspecionando o consumo de memória, ~400mb.

Agora, vamos ver do que eu estava falando:

Delicia, * streaming* (sob-demanda)

  1. Crie um arquivo on-demand.js

  2. Faça a requisição para a API, mas armazene a stream

3.

Tcharam! Metade do tempo, e 1/3 da memória!

É sobre isso e tá tudo ótimo.


Com a ascenção de arquiteturas orientadas a eventos (depois que tudo virou microserviços e as pessoas lembraram que infra + tráfego de rede são caros) ter em nossas caixas de ferramentas recursos que permite agir sob demanda não só em nível arquitetural, mas em nível programático, é imprescindível.

Pessoalmente minha parte favorita é pegar um código bem lento e bagunçado, limpar ele e deixar performático :). Gosto de desafios com alta volumetria, mas isso não significa que Streams sejam a bala de prata, nada é.

E essa foi mais uma anotação feita as 3am pelo celular e publicada quase diretamente. Fiz esse teste com um amigo hoje no trabalho, então não tenho o código aqui, mas volto para colocar. Obrigada pela sua paciência e carinho lendo meus devaneios até aqui.

Dale!


¹ Não trabalhe com números mágicos, teste! 👁️👄👁️
² O consumo de memória: 🤡


🌱 Seedlings são ideias que recém tive e precisam de cultivo, não foram revisadas ou refinadas. Saiba mais.