# Como usar .ready() antes de incluir a jQuery

> Técnica inteligente para usar jQuery .ready() antes de incluir a biblioteca. Melhore performance colocando scripts no fim do documento HTML. Otimize!

URL: https://dpw.dev/javascript/como-usar-ready-antes-de-incluir-jquery/  
Publicado em: 2012-03-30  
Categoria: javascript  
Tags: jquery, performance  
Autor: Tárcio Zemel

Uma das mais "tradicionais" regras de **performance de sites** é colocar as chamadas para javascripts externos no final do documento HTML, antes do fechamento da tag `body`. Mas não são raras as ocasiões em que nós, desenvolvedores web, precisamos inserir códigos que dependem da jQuery no meio do documento (posição que fica **antes** do indicado para se chamar a própria jQuery). Como proceder?

> Artigo baseado em [Safely Using .ready() Before Including jQuery](http://blog.colin-gourlay.com/blog/2012/02/safely-using-ready-before-including-jquery/).

Antes de continuarmos, é importante saber que existem diferentes sintaxes possíveis para "ativar" o jQuery:

```javascript
$(handler) // "handler" é a função a ser vinculada

$(document).ready(handler);

$().ready(handler) // maneira não recomendada

$(document).bind('ready', handler);
```

## E existe solução para usar .ready() antes de incluir o jQuery?

Sim, existe solução para usar `.ready()` antes de incluir o jQuery e, felizmente, a solução é eficaz em todas essas possibilidades apresentadas - e, talvez, até em algumas outras, quem sabe...

Em termos práticos, a solução é:

```typescript

(function(w,d,u){w.readyQ=[];w.bindReadyQ=[];function p(x,y){if(x=="ready"){w.bindReadyQ.push(y);}else{w.readyQ.push(x);}};var a={ready:p,bind:p};w.$=w.jQuery=function(f){if(f===d||f===u){return a}else{p(f)}}})(window,document)

(function($,d){$.each(readyQ,function(i,f){$(f)});$.each(bindReadyQ,function(i,f){$(d).bind("ready",f)})})(jQuery,document)

```

Claro que não dá pra entender a lógica olhando script comprimidos. Vejamos o de `head`:

```typescript
(function (w, d, u) {

    // Define duas queues para os handlers
    w.readyQ = [];
    w.bindReadyQ = [];

    // Insere um handler na queues correta
    function pushToQ(x, y) {
        if (x == "ready") {
            w.bindReadyQ.push(y);
        } else {
            w.readyQ.push(x);
        }
    }

    // Define um objeto alias (para uso posterior)
    var alias = {
        ready: pushToQ,
        bind: pushToQ
    }

    // Definir a função jQuery "fake" para capturar os handlers
    w.$ = w.jQuery = function (handler) {
        if (handler === d || handler === u) {
            // Coloca na queue $(document).ready(handler), $().ready(handler)
            // e $(document).bind("ready", handler), retornando um objeto com
            // os métodos de "alias" para pushToQ
            return alias;
        } else {
            // Queue $(handler)
            pushToQ(handler);
        }
    }

})(window, document);

```

O script de `body` (imediatamente depois da jQuery):

```javascript
(function ($, doc) {

    $.each(readyQ, function (index, handler) {
        $(handler);
    });

    $.each(bindReadyQ, function (index, handler) {
        $(doc).bind("ready", handler);
    });

})(jQuery, document);

```

Usa-se o [`$.each()`](http://api.jquery.com/jQuery.each/) para associar corretamente todos os handlers na fila para o DOM pronto, mas, porque $(document).bind("ready", handler) pode ter sido chamado antes, é preciso dar um `bind`, também, da maneira correta.

## Exemplo de uso

OK, realmente é um pouco confuso de se entender de primeira, por isso, vejamos este exemplo de como usar o `$.ready()` antes da jQuery, seguido de suas respectivas saídas num console.

Exemplo:

```typescript

    
        Example
        (function(w,d,u){w.readyQ=[];w.bindReadyQ=[];function p(x,y){if(x=="ready"){w.bindReadyQ.push(y);}else{w.readyQ.push(x);}};var a={ready:p,bind:p};w.$=w.jQuery=function(f){if(f===d||f===u){return a}else{p(f)}}})(window,document)
    
    
        
            $(document).bind("ready", function () {
                console.log("Examplo D: $(document).bind("ready", handler)");
            });
            $(document).ready(function () {
                console.log("Examplo A: $(document).ready(handler)");
            });
            $().ready(function () {
                console.log("Examplo B: $().ready(handler)");
            });
            $(function(){
                console.log("Examplo C: $(handler)");
            });
        
        
        (function($,d){$.each(readyQ,function(i,f){$(f)});$.each(bindReadyQ,function(i,f){$(d).bind("ready",f)})})(jQuery,document)
    

```

Console:

```javascript
Example A: $(document).ready(handler)
Example B: $().ready(handler)
Example C: $(handler)
Example D: $(document).bind("ready", handler)

```

Haha! Viu, só? Apesar de, no código, o scripts do "Exemplo D" ter sido o primeiro, na saída do console os exemplos executaram perfeitamente na ordem "A, B, C, D"!

## Conclusão

E, com isso, vimos que é perfeitamente possível - e relativamente simples - usarmos chamadas ao `.ready()` da jQuery de forma "não ordenada". Isso faz abrir um leque de possibilidades interessante, pense bem!

Se gostou e/ou tem alguma ideia de como usar isso para melhorar seus scripts, comente e compartilhe! Ajude a **desenvolver a web**!

---

Fonte: [dpw - desenvolvimento para web](https://dpw.dev/) (pt-BR).
Guia para agentes: https://dpw.dev/llms.txt
Índice completo: https://dpw.dev/sitemap-index.xml
Feed: https://dpw.dev/rss.xml
