O volume de mudanças que a nova especificação do HTML propõe para tag <script> é pequeno, mas chama atenção por resolver antigos problemas de performance.

Nesse artigo vamos entender quais são esses problemas e dar uma passada geral nas mudanças que o HTML5 propõe para essa tag.

type

Pra começar, lembra do famoso type=text/javascript?

Então, pode esquecer ele. A declaração desse MIME type antes obrigatório no HTML4, se tornou opcional no HTML5, isso é claro, se você utilizar javascript ali dentro.

language

O antigo atributo language, ainda visto em sistemas legados, agora está depreciado devido a nunca ter se tornado um padrão de fato.

O velho problema de performance dos scripts

Quaisquer arquivos javascript quando carregados utilizando a tag <script> são bloqueantes por natureza.

Enquanto é feito o download e execução do script todo o processo de parser do DOM é bloqueado, impedindo a renderização do resto da página. E olha que isso se aplicada a cada tag de script contida na página.

A especificação do HTTP/1.1 diz que os navegadores não devem proceder com downloads de mais de 2 componentes em paralelo por host.

Uma famosa técnica de otimização de velocidade é servir imagens em múltiplos hosts, assim você consegue mais de dois downloads ocorrendo em paralelo. Entretanto, quando se trata de script o browser não irá iniciar nenhum outro download, enquanto o script é baixado, mesmo que em hosts diferentes.

Navegadores antigos, fazem o carregamento dos scripts um após o outro, veja como funciona no Firefox 3.0.

Alguns browsers já fazem downloads em paralelo, mas o problema de renderização persiste.

async & defer

Os atributos booleanos async e defer vêm para gerenciar exatamente esse tipo de problema. Ou seja, scripts bloqueantes nunca mais.

Para facilitar o entendimento, vou explicar como seria o funcionamento na prática de cada uma dessas linhas:

<script src="exemplo.js"></script>

A página aguarda o script terminar de carregar antes de continuar sua renderização e sua execução é feita imediatamente após. Isso pode aumentar significativamente o tempo de carregamento da página.

<script async src="exemplo.js"></script>

O download do script é feito de forma assíncrona enquanto o processo de renderização da página continua a ser feito. O script é executado depois que o download estiver completo.

<script defer src="exemplo.js"></script>

Assim como o exemplo acima, o download do script é feito de forma assíncrona. Mas sua execução se dá apenas quando todo o processo de renderização estiver concluído.

<script async defer src="exemplo.js"></script>

Nesse caso, o async prevalece e o defer é ignorado. Isso possibilita que os desenvolvedores possam usar async em browsers que o suportam, mas proporciona um fallback com defer para os browsers que não suportam o async.

Compatibilidade

A implementação do atributo async continua lenta em alguns navegadores. A Microsoft, por exemplo, só anunciou o suporte para este atributo na versão 10 que nem foi lançada ainda. Melhor do que o Opera que nem previsão de suporte oferece. Já para o atributo defer a história é outra, sua implementação pela Microsoft é antiga e outros players têm se adaptado há pouco tempo.

Conclusão

Com essa possibilidade de carregar scripts de forma assíncrona, seria a morte dos famosos script loaders, como HeadJS e o LABjs? Essa é uma questão interessante, pois eles chegaram no mercado justamente com o intuito de resolver o problema dos scripts bloqueantes, mas sua permanência ainda deve continuar por um bom tempo. Primeiro por conta do suporte precário de alguns browsers para essas propriedades e segundo porque eles propõe outras funcionalidades bem interessantes. Por exemplo, alguns já combinam todos seus scripts em um só, assim apenas uma requisição HTTP é feita ao servidor, outros possibilitam controles de dependência. O fato é que, acabando ou não com os scripts loaders, esses atributos por mais simples que pareçam vão proporcionar aplicações com muito mais performance para todos nós. HTML5 sem javascript, é como assistir o Tom sem o Jerry, por isso que uma forma otimizada de fazer seu carregamento se mostra tão relevante.

Referências