Reduzir o tamanho de sites

Além de poder deixar seu site pré-gerado (texto aqui), existem outras formas de melhorar o tempo de resposta na hora de acessar algum site. Podemos configurar o servidor HTTP para compactar tudo o trafego em gzip, porém podemos reduzir o site ainda mais antes de compactá-lo. Quando acessamos um site, normalmente temos um arquivo HTML, alguns CSS e JavaScript e várias imagens, cada um desses tipos de arquivos pode ser otimizado.

As imagens irão compor a maio parte do tráfego normalmente, como dizem que uma imagem vale mais que mil palavras, também pode refletir no tamanho da mesma. Existem algoritmos que tentam gerar a mesma imagem de várias formas para buscar uma onde o arquivo final seja o menor possível, podendo ter uma perca normalmente imperceptível ao olho humano ou com a qualidade exatamente igual ao original. Esses algoritmos serão diferentes para cada tipo de imagem, para PNG temos o OptiPNG, que pode ser instalado com apt-get install optipng no Debian. Um exemplo que posso contar aqui, tinha cerca de 400 imagens PNG, totalizando 699 MB no diretório, depois de utilizar o OptiPNG, o diretório ficou com 286 MB, aproximadamente 41% do tamanho inicial e mantendo a mesma qualidade.

Para JPEG além de buscar uma forma de reduzir as imagens, existe o modo progressivo, que quando a conexão é mais lenta, permite exibir uma imagem inicialmente em baixa qualidade e ir melhorando conforme o arquivo é recebido. Para isto utilizei o jpegtran, que pode ser instalado com apt-get install libjpeg-progs no Debian.

Algumas vezes pego pacotes de imagens na internet compactadas em algum formato, após descompactá-las e otimizá-las, tenho um tamanho menor no diretório sem compactar que no arquivo compactado, e recompactando fica menor ainda. Recomendo utilizar esses programas mesmo no computador local para economizar espaço. Para facilitar ainda mais fiz um script para GNU/Linux que identifica o tipo de imagem e executa o programa correto com os parâmetros necessários, quem quiser pode dar uma olhada no meu GitHub. Também configurei como uma ação personalizada no Thunar, então basta um click com o botão direito, selecionar a ação e já tenho o arquivo ou arquivos selecionados otimizado.

Para otimizar o CSS e JavaScript, primeiro é bom reduzir o número de arquivos visando reduzir o número de requisições HTTP. Outro ponto importante é que para executar o JavaScript no navegador é necessário parar todos os demais processos do navegador, ou seja, dois códigos JavaScript não são executados em paralelo, nem um código JavaScript e renderizar o HTML, por este motivo existe a prática de colocar as tags script antes de fechar o body, para termos a página renderizada primeiro.

Agora para reduzir o tamanho do CSS e JavaScript existe uma técnica chamada minify, que consistem em reduzir espaços em branco, quebra de linhas e utilizar nome de variáveis menores em JavaScript. Uma ferramenta que conheço para esta tarefa é o YUI Compressor, escrito em Java, então funciona em qualquer plataforma. Porém se forem editar os arquivos posteriormente recomendo manter uma cópia do original.

O HTML segue os mesmos princípios do CSS e JavaScript de reduzir espaços em branco, que são colocados principalmente quando a página é gerada dinamicamente ou indentada, que faz sentido para quem está vendo o código, porém não faz diferença para o navegador. Quando é aplicado em cima de páginas dinâmicas, esse processo, diferente dos descritos anteriormente, precisa ser refeito para cada página, aumentando o processamento necessário para gerar a página e por isso muitas vezes é deixado de lado. Para páginas estáticas, como pode ser aplicado apenas uma vez, volta a ser interessante. Para fazer essa otimização, ela segue as mesmas regras de arquivos XML, ou seja, também pode ser aplicada em feeds RSS.

Também para reduzir o processamento, podemos deixar os arquivos já compactados no servidor, não necessitando recompactá-los a cada requisição. Um exemplo desta configuração para NGIX pode ser vista no texto do Magnum quando ele estava configurando o servidor para o seu site feito no Pelican (http://mindbending.org/pt/servindo-sites-estaticos-com-o-nginx#configurando-um-site).

Anúncios

MX Reverse e escolhas de frameworks

Se alguém deu uma olhada recentemente no meu GitHub, pode ter visto um repositório chamado mxreverse, que é um site que desenvolvi para validar o DNS reverso de servidores de e-mail. Apesar do código ser simples, tomei algumas decisões que gostaria de compartilhar.

Primeiramente a linguagem escolhida foi Python principalmente por ser a qual tenho mais domínio e facilidade, também achei uma biblioteca para fazer as pesquisas do DNS, possibilitando o desenvolvimento. Inicialmente pensei em criar uma função para fazer a validação com algumas funções auxiliares, que depois de alguns testes e tempo de desenvolvimento estava pronta.

Agora até aqui foi algo bem normal do qualquer projeto. Porém como disponibilizar esta função? Como utilizei uma biblioteca externa, além do meu código seria necessário também instalá-la para executar local, ou poderia disponibilizar um webservice, que possibilitaria reutilizá-lo com linguagens também. Como o código é Python, a forma mais simples, e provavelmente a mais recomendada é usar a especificação do WSGI, sendo uma única página, com apenas um parâmetro (o domínio a ser verificado), retornando um JSON, não tive necessidade de utilizar outros frameworks. Apesar de conhecer e gostar de Django e Bottle, o projeto não teria vantagens ao utilizar qualquer um dos dois, além de possibilitar fazer algo mais otimizado e simples sem um framework no caminho.

Com a API definida e funcional, era necessário um cliente que consuma a API e mostre as informações, caso contrário perderia a praticidade que gostaria, exigindo que cada um desenvolvesse seu código. Com as atuais aplicações em JavaScript no navegador, interessei me pela ideia de fazer uma página estática, utilizar AJAX para comunicar com a API e JavaScript para mostrar a resposta. Um framework JavaScript que tinha vontade de testar a algum tempo e aproveitei para fazê-lo neste projeto é o AngularJS. A principal ideia é atualizar um template HTML a partir de variáveis do JavaScript, ou seja, bastava ler o JSON e guardá-lo numa variável que o resultado seria mostrado na página.

O mais importante deste projeto é que mesmo que você conheça e goste de algum framework, ele pode não ser o melhor para a aplicação que está sendo desenvolvida. Abandonei a montagem do HTML em Python, passando para o JavaScript, deixei o código no servidor muito mais simples e aproveitei para conhecer outra forma de desenvolver aplicações, que poderei reutilizar em outros projetos onde ela se adapte melhor.

Resumo saia de sua zona de conforto, conhecer outros frameworks, por mais que superficialmente, pode ajudar na hora de montar uma aplicação, escolhendo uma arquitetura mais adequada.

Aprendendo JavaScript com exercícios TDD e críticas a esse modelo

Com as novas tecnologias, principalmente cloud e busca por sistemas que consumam menos recursos, estou interessado em tecnologias de API REST e consumi-la no navegador. Quando se fala em navegador sempre temos o JavaScript, no MongoDB temos documentos JSON e um terminal, que se não for JavaScript, tem várias semelhanças, além do Node.js no lado do servidor. Com todas essas tecnologias a única que não tenho conhecimento para identificar se ela pode ser aplicada com vantagens e quais seriam é o Node.js, então andei pesquisando para aprender.

Achei um link no site oficial muito bom do nodeschool.io. O tutorial presente no site segue um esquema TDD, ou seja, você tem um exercício para fazer e para validar o mesmo, basta rodar o teste, isso tudo via Node.js e npm. Pode ser um pouco complicado para quem não tem contato nenhum, porém não é muito complicado instalar essas duas dependências e para iniciar o tutorial basta seguir os comandos do site.

Como eu já conheço programação em JavaScript no navegador, esse tutorial a primeira vista pareceu muito interessante, e bem legal a forma de aprender. Porém eu já sabia JavaScript e conheço algumas de suas características, como uso de callbacks e prototype. Também temos um curso específico de JavaScript, infelizmente ainda não tive tempo para dar uma conferida no mesmo para falar sobre o mesmo.

Olhando esse modelo de aprendizado, com textos curtos e um exercício estilo TDD para resolver, lembrei do Codeacademy e que outros sites oferecem conteúdo desta forma. As vantagens são obviamente a rapidez para quem inicia, todo seu aprendizado já vai ser em cima da linguagem, já é possível iniciar uma filosofia de TDD, além da resposta muito mais rápida se o código funciona ou não. Porém não sei se quem tem um mínimo conhecimento de JavaScript, com pouco ou nenhum domínio de callbacks e outras características da linguagem teria o mesmo aproveitamento do material.

Com certeza “cursos TDDs” não irão substituir o material escrito, ainda prefiro um texto explicativo que um exercício para aprender novos conceitos, pelo menos acho que o conhecimento que consigo obter seria maior. Recentemente li o livro Padrões JavaScript e mesmo sem ter feito nenhum exercício aprendi várias boas práticas e formas de escrever um código melhor, obviamente apliquei depois nos códigos para fixar o aprendizado. Só lembrando que essa foi minha forma de aprender.

Recentemente também estive querendo dar uma olhada em Ruby, porém não achei um bom material, que com certeza existem, porém não quero algo que me ensine a fazer uma condição, laço de repetição simples ou o básico de orientação a objetos, tenho esse conhecimento de outras linguagens, gostaria de algo que me ensinasse Ruby e sua forma de resolver os problemas (filosofia), provavelmente o ideal seria algo mostrando um projeto ou parte dele, que possa utilizar como referência. Porém após o fim do mesmo ficaria perdido novamente, somado aos açucares sintéticos que levam a várias formas de escrever exatamente o mesmo código.

Achei no site do Ruby um link de Ruby a partir de outras linguagens (https://www.ruby-lang.org/pt/documentation/ruby-from-other-languages/), li o de Python, aprendi algumas diferenças, porém não sabia fazer uma linha sequer e não consegui ler nenhum código mais específico de Ruby, que simplesmente não entendia a sintaxe do que eram certas partes.

Não tive esse problema com Python, pois quando aprendi fazia algum tempo que não programava, servindo como revisão, além do tutorial presente na documentação ser bem objetivo. Porém acredito que isso irá acontecer com qualquer linguagem, e principalmente a dificuldade de perder o “sotaque”. Gostaria de saber se mais alguém passou por isso e o que fizeram, também seriam interessantes links de material classificados para os diferentes níveis de conhecimento para se aprender alguma linguagem. Deixem nos comentários, depois posso organizar em uma página separada, ou se souberem algum lugar que já tenha isso, melhor ainda.