A internet como vemos hoje exige cada vez mais performance e cada vez melhor usabilidade. Nunca tivemos tanto apreço à experiência do usuário, assim produtos, ferramentas, serviços e frameworks são bem vindos para ajudar a entregar performance. Com o aumento nos recursos de interface, e a facilidade com que conseguimos hardware, chegamos em um momento em que a renderização passa a ser um ponto chave na obtenção de performance, já que do aspecto de processamento do server, nunca vimos tanto hardware (barato), nunca vimos tantos patterns, tantas soluções para facilitar nossa vida.
Mas e quando você não tem controle sobre todo o que foi desenvolvido? Seja ao fazer deploy de um WordPress, Magento, ou soluções maiores, como SiteCore, Evoq, o que fazer quando você precisa melhorar a experiência do seu usuário? Esse problema é comum quando usamos soluções prontas, em que sua customização não necessariamente abrange detalhes tão técnicos. É sobre esse tipo de problema que quero falar e vou aproveitar para apresentar o Google PageSpeed Module for Nginx, falar um pouco sobre Nginx e como ambos podem te ajudar no seu próximo projeto.
Nginx
O nginx [engine x] é um servidor HTTP e um servidor proxy, um servidor proxy de email e um servidor proxy genérico TCP / UDP, escrito originalmente por Igor Sysoev. Por um longo tempo, ele foi executado em muitos sites russos muito acessados, incluindo Yandex, Mail.Ru, VK, e Rambler. De acordo com a Netcraft, nginx é responsável por 28,16% dos sites mais acessados do mundo, em agosto de 2016. Estão no hall de histórias de sucesso, gigantes como: Netflix, WordPress.com e FastMail.FM.
Poderoso, simples e eficiente, o Nginx ganhou espaço no mercado e sua utilização é recomendada sempre que se fala em performance e servidores HTTP.
Google PageSpeed Module for Nginx
O Google é o maior portal de busca há muitos anos. O know-how adquirido fazendo buscas e analisando milhões de sites diariamente, possibilita à gigante oferecer soluções com o que há de mais relevante sobre performance web, e o Google PageSpeed Module é um dos projetos que dá suporte ao Speed portal dedicado à otimização de performance na web. O Google PageSpeed é uma ferramenta web de análise, enquanto o Google PageSpeed Module é um projeto que oferece módulos para Nginx e Apache.
No caso do Apache, a instalação dos módulos é baseada em pacotes pré-compilados, disponíveis para download. Já no Nginx, para utilizarmos o Google PageSpeed e qualquer outro módulo, precisamos recompilar o projeto a partir dos fontes, e esse trabalho, embora simples, pode assustar muitos.
A imagem
Para facilitar a minha própria vida, criei uma imagem Docker contendo o Nginx, compilado com o Google PageSpeed no início de 2016. Essa imagem desde sua criação foi utilizada em produção, em projetos pessoais, e agora, no feriado de 7 de Setembro, resolvi parar para enfim: documentar, atualizar e publicar no GitHub o projeto.
Alguns clientes privados estão usando essa imagem com o PageSpeed ativo, usei por conta de algumas limitações, como falta de acesso aos fontes, etc. O resultado é uma camada que otimiza um site ou app mal feita. Custa processamento, mas muito pouco, dado o volume de acesso. Aconselho, para os casos em que o http server opera com mais de load elevado, utilizar uma camada de cache, que pode ser implementada habilitando caching no Nginx, ou adicionando um novo item no stack, como um CDN ou um Varnish.
Exemplo
Criando o container
Vou me basear em uma pasta hipotética “C:_dockernginx”, todo o exemplo se baseará nela.
Execute o comendo docker run abaixo:
docker run --name customNginx -d --hostname customNginx -p 80:80 -v C:_dockernginxconfig:/etc/nginx/ luizcarlosfaria/nginx-pagespeed
Agora você tem um NGINX padrão funcionando, essa versão foi compilada com os plugins que citei no início do post.
Se tudo estiver certo, você verá na pasta “C:_dockernginxconfig” os seguintes arquivos:
Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 12/09/2016 02:45 1077 fastcgi.conf -a---- 12/09/2016 02:45 1077 fastcgi.conf.default -a---- 12/09/2016 02:45 1007 fastcgi_params -a---- 12/09/2016 02:45 1007 fastcgi_params.default -a---- 12/09/2016 02:45 2837 koi-utf -a---- 12/09/2016 02:45 2223 koi-win -a---- 12/09/2016 02:45 3957 mime.types -a---- 12/09/2016 02:45 3957 mime.types.default -a---- 12/09/2016 02:47 2656 nginx.conf -a---- 12/09/2016 02:45 2656 nginx.conf.default -a---- 12/09/2016 02:45 2656 nginx.confx -a---- 12/09/2016 02:45 636 scgi_params -a---- 12/09/2016 02:45 636 scgi_params.default -a---- 12/09/2016 02:45 664 uwsgi_params -a---- 12/09/2016 02:45 664 uwsgi_params.default -a---- 12/09/2016 02:45 3610 win-utf
Configurando as Transformações
Esta é a versão original das configurações. Você precisará editar o arquivo nginx.conf para prosseguir, ou caso queira, mapear uma pasta local e hospedar seus arquivos AS-IS. Mas, nosso propósito é demonstrar o Google Page Speed em ação, portanto, vamos modificar o arquivo nginx.conf por uma versão do arquivo que possui configurações exclusivas para teste da funcionalidade.
Pare o container:
docker stop customNginx
Edite o arquivo C:_dockernginxconfignginx.conf substituindo todo o conteúdo por:
#user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent" "$http_x_forwarded_for"'; #access_log logs/access.log main; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; #gzip on; pagespeed GlobalStatisticsPath /ngx_pagespeed_global_statistics; pagespeed GlobalAdminPath /pagespeed_global_admin; server { listen 80; server_name localhost; #################################################################################################### pagespeed on; # Needs to exist and be writable by nginx. Use tmpfs for best performance. pagespeed FileCachePath /var/ngx_pagespeed_cache/; pagespeed MessagesPath /ngx_pagespeed_message; pagespeed ConsolePath /pagespeed_console; pagespeed AdminPath /pagespeed_admin; pagespeed StatisticsPath /pagespeed_statistics; # Ensure requests for pagespeed optimized resources go to the pagespeed handler # and no extraneous headers get set. location ~ ".pagespeed.([a-z].)?[a-z]{2}.[^.]{10}.[^.]+" { add_header "" ""; } location ~ "^/pagespeed_static/" { } location ~ "^/ngx_pagespeed_beacon$" { } #################################################################################################### #location /ngx_pagespeed_statistics { allow all; } #location /ngx_pagespeed_global_statistics { allow all; } #location /ngx_pagespeed_message { allow all; } #location /pagespeed_console { allow all; } #location ~ ^/pagespeed_admin { allow all; } #location ~ ^/pagespeed_global_admin { allow all; } #################################################################################################### #charset koi8-r; #access_log logs/host.access.log main; #location / { # root html; # index index.html index.htm; #} location / { pagespeed EnableFilters move_css_to_head; pagespeed EnableFilters combine_javascript; pagespeed MaxCombinedJsBytes 999999999; pagespeed CombineAcrossPaths on; pagespeed MaxSegmentLength 2048; pagespeed EnableFilters responsive_images,resize_images; pagespeed EnableFilters responsive_images_zoom; pagespeed EnableFilters collapse_whitespace; proxy_pass https://www.docker.com:443/; proxy_set_header X-Real-IP $remote_addr; } } }
Testando e comparando
Agora execute o comando docker start para subir o container novamente, com as novas configurações carregadas:
docker start customNginx
Voilà!
Ao navegar para http://localhost/ (ou ip do seu container), você verá um proxy para https://www.docker.com/ que transforma o HTML do site.
O resultado está disponível aqui aqui.
É muito legal ver as transformações no html e perceber que tudo continua funcionando.
A mágica acontece graças a essa parte da configuração
... location / { pagespeed EnableFilters move_css_to_head; pagespeed EnableFilters combine_javascript; pagespeed MaxCombinedJsBytes 999999999; pagespeed CombineAcrossPaths on; pagespeed MaxSegmentLength 2048; pagespeed EnableFilters responsive_images,resize_images; pagespeed EnableFilters responsive_images_zoom; pagespeed EnableFilters collapse_whitespace; proxy_pass https://www.docker.com:443/; proxy_set_header X-Real-IP $remote_addr; } ...
Nessa configuração temos algumas features utilizadas:
- Mover CSS para o Head
- Combinar Javascripts
- Remover espaços em branco
- Manipulação de imagens (resize, responsividade, zoom)
O resultado desse teste descompromissado, foi muito interessante:
- De 9.4s para 7.9s
- De 139 requests para 141 requests
- De 512k transferido para 302k transferido
- De 10.18s de load e renderização para 8.32s
Como eu não tinha exemplos públicos para demonstrar, utilizei esse por considerar simples de demonstrar o potencial do Google Page Speed com Nginx. Vale lembrar que para o Apache, é muito mais simples, pois não há necessidade de recompilar.
A documentação do Google PageSpeed apresenta uma infinidade de opções de customização, todas baseadas no ganho de performance. É extremamente interessante olhar essa documentação para entender o que você quer ou deverá usar em seu projeto, para poder optar pelo melhor setup.
Próximas versões e Outras imagens
Penso em trabalhar na imagem para disponibilizar uma versão baseada no alpine, muito mais enxuta. Enquanto isso, essa aqui vem me atendendo perfeitamente e espero que atenda vocês também!
Há outras imagens disponíveis no hub, são elas:
- luizcarlosfaria/wordpress-apache-php7/ – WordPress sob PHP 7
- luizcarlosfaria/varnish/ – Varnish Cache
Aqui no blog venho tentando apresentar esses utilitários, na medida que me sobra tempo, mas acredito que nas próximas semanas possamos falar muito mais sobre esses mecanismos.
Um grande abraço, e não se esqueça de comentar, compartilhar com a galera da empresa, enfim, é sempre bom poder ajudar.
Qualquer dúvida, não exite em entrar em contato, seja por email, twiter, telegram, whatsapp… há mil maneiras de falar comigo, e respondo todas!
Grande abraço
0 comentários