Nos últimos anos diversos serviços surgiram para facilitar a vida não só de desenvolvedores, mas também de equipes de marketing, publicidade e experiência de usuário. Temos hoje bibliotecas para tudo, algumas sendo utilizadas em praticamente todo site, do mais simples ao mais complexo: Google Analytics, Google Fonts, Google Hosted Libraries, Facebook Connect, Twitter Widgets, Gravatar, entre outros.

    Embora ofereçam praticidade e agilizem o desenvolvimento e manutenção de sites, utilizar tantos serviços externos também gera alguns problemas. O tempo de carregamento do site aumenta consideravelmente, afinal, para cada recurso externo o usuário vai precisar fazer uma nova requisição de DNS para pegar um arquivo de outro domínio. Além disso, temos também o problema de concorrência entre as requisições podendo bloquear o carregamento do seu site. Quando você utiliza serviços externos para entregar partes vitais do site, o navegador não consegue definir a prioridade e essas requisições passam a competir por recursos com as requisições do seu domínio, afetando negativamente a experiência do usuário, que vai ficar encarando uma tela em branco por alguns segundos até que algo seja renderizado.

    Ao interceptar todos esses scripts externos e entregá-los por conta própria, você elimina o problema gerado por múltiplas resoluções de DNS e ao mesmo tempo consegue se aproveitar da conexão HTTP/2 única, tirando vantagens dos recursos de priorização e paralelismo do protocolo. :)

    Normalmente os mais interessados em melhorar a performance do site começam hospedando os scripts do Google Analytics por conta própria. O Google não recomenda fazer isso, mas acredite, MUITA GENTE faz! O problema é que esses scripts são constantemente atualizados, e ao hospedar por conta própria você corre o risco de ficar com uma versão antiga, quebrando suas estatísticas. Alguns resolvem isso configurando um cron (tarefa agendada) para atualizar os scripts de tempos em tempos, mas isso ainda me parece um trabalho manual demais. E chato. E você precisa sair alterando o código do Analytics em todo lugar que tiver no site.... mais trabalho manual, argh! Esse não é nosso estilo. Nós gostamos de automatizar tudo, não é? E é aí que surgiu a ideia de utilizar o nginx para fazer todo o serviço para nós de forma automática.

    Antes de mais nada, vamos precisar de um nginx com o módulo "sub" compilado nele. Esse módulo é oficial do nginx, mas não vem compilado por padrão. Você pode checar se o seu nginx tem esse módulo com um "nginx -V" e olhar na lista de módulos habilitados durante a compilação. Se não encontrar, então esse guia não vai funcionar para você até que recompile o nginx habilitando o módulo: https://nginx.org/en/docs/http/ngx_http_sub_module.html

Tendo em mãos um nginx com o módulo sub, vamos começar! Como quase todo mundo utiliza o Google Analytics, nosso primeiro exemplo será com ele. Dentro da configuração do seu site no nginx, adicione o seguinte:

# Criamos uma zona de cache para nossos recursos externos, assim não precisaremos ficar baixando toda hora do servidor oficial do recurso, melhorando ainda mais a performance

proxy_cache_path /var/cache/nginx/cache levels=1:2 keys_zone=externalresources:8m max_size=1g inactive=7d;

proxy_temp_path /var/cache/nginx/temp;

# Primeiro definimos qual DNS o nginx deve utilizar. Minha preferência é por sempre utilizar o DNS do Google e do Cloudflare, respectivamente. Em seguida, a parte responsável por reescrever automaticamente o HTML do nosso site, substituindo o script original pela versão que queremos entregar localmente

resolver 8.8.8.8 1.1.1.1 ipv6=off;

sub_filter 'https://www.google-analytics.com/analytics.js' '$scheme://$host/cloudez.www.google-analytics.com/analytics.js';

sub_filter 'https://www.googletagmanager.com/gtag/' '$scheme://$host/cloudez.www.googletagmanager.com/gtag/';

sub_filter_types application/javascript text/css;

sub_filter_once off;

# Aqui fazemos uma proxy da nossa requisição para o destino original, cacheando na nossa zona de cache o arquivo por 20 minutos, que é o tempo de expiração definido pelo Google no Analytics. Normalmente, após esses 20 minutos nosso servidor precisaria baixar novamente o arquivo original, mas com a diretiva "proxy_cache_revalidate on", nós conseguimos renovar o arquivo por mais 20 minutos automaticamente caso não haja alterações no original.

# Nós também não faremos nenhuma alteração nas headers do arquivo, nem mesmo para corrigir o "Levarage browser caching" que o PageSpeed sempre reclama, pois isso poderia novamente acarretar todos os problemas de dados errados no Analytics!

location ^~ /cloudez.www.google-analytics.com/analytics.js {

    proxy_pass https://www.google-analytics.com/analytics.js;

    proxy_http_version 1.1;

    proxy_set_header Accept-Encoding "";

    proxy_cache externalresources;

    proxy_cache_valid 200 304 206 20m;

    proxy_cache_revalidate on;

    proxy_cache_key "$host$request_uri$args";

}

location ^~ /cloudez.www.googletagmanager.com/gtag/ {

    proxy_pass https://www.googletagmanager.com/gtag/;

    proxy_http_version 1.1;

    proxy_set_header Accept-Encoding "";

    proxy_cache externalresources;

    proxy_cache_valid 200 304 206 20m;

    proxy_cache_revalidate on;

    proxy_cache_key "$host$request_uri$args";

}

E... pronto. É só isso. Você pode só colocar o código do Analytics no site e o nginx vai interceptar seu HTML e alterar a requisição para vir do seu domínio, ou até mesmo da sua CDN. 

E claro, isso não para por aí. No momento, meus clientes estão utilizando essa técnica para os seguintes serviços: Gravatar, Facebook Connect, Google Fonts, Google Hosted Libraries, Twitter, e sempre requisitam que mais algo seja adicionado. Minha recomendação é que você faça algo semelhante pelo menos com o Google Fonts, pois apesar de prático, ele é EXTREMAMENTE LENTO e vai MATAR sua nota do PageSpeed!

Aqui vai a configuração básica que utilizamos para interceptar e cachear o Google Fonts:

sub_filter 'https://fonts.googleapis.com' '$scheme://$host/cloudez.fonts.googleapis.com';

sub_filter '//fonts.googleapis.com' '$scheme://$host/cloudez.fonts.googleapis.com';

# Google Fonts

location ^~ /cloudez.fonts.gstatic.com/ {

    proxy_pass https://fonts.gstatic.com/;

    proxy_http_version 1.1;

    proxy_set_header Accept-Encoding "";

    proxy_cache externalresources;

    proxy_cache_valid 200 304 206 24h;

    proxy_cache_revalidate on;

    proxy_cache_key "$host$request_uri$args";

}

# Esse host nós não vamos cachear, pois é ele quem gera o CSS personalizado das fontes, e esse CSS pode mudar de acordo com o browser que o requisita. Note que dentro dele, nós inserimos outro sub_filter para reescrever a resposta entregando as fontes pelo nosso domínio :D

location ^~ /cloudez.fonts.googleapis.com/ {

    proxy_pass https://fonts.googleapis.com/;

    proxy_http_version 1.1;

    proxy_set_header Accept-Encoding "";

    sub_filter_types application/javascript text/css;

    sub_filter 'https://fonts.gstatic.com' '$scheme://$host/cloudez.fonts.gstatic.com';

    sub_filter_once off;

}

E novamente... pronto! Não precisa se preocupar mais. Quer um exemplo de site utilizando essa técnica? O PodCaster: https://podcaster.net.br/

É um site simples em Wordpress, porém extremamente rápido. Em sites mais complexos e com várias dependencias externas, nós conseguimos reduzir o tempo de carregamento de 8 segundos (!!!) para em torno de 1 segundo apenas fazendo isso com o Google Fonts! Massa, né? :D

Tags

comentários (0)

Sem comentários