Qualquer vantagem de usar wp_scripts e is_IE ao enfileirar scripts

8

Eu li sobre os documentos do WP, que apontavam para essa essência que a maneira correta de enfileirar estilos para o IE é por usando o $wp_styles . Eu estou supondo que isso seria verdade para scripts também.

Tome esses exemplos, por exemplo ...

Opção 1 - usando wp_scripts

add_action('wp_print_scripts', function() {
    global $wp_scripts;
    wp_enqueue_script( 'html5shiv', 'https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js', array( 'bootstrap' )  );
    $wp_scripts->add_data( 'html5shiv', 'conditional', 'lt IE 9' );
} );

Opção Dois - Use wp_scripts junto com is_IE

add_action('wp_print_scripts', function() {
    global $wp_scripts, $is_IE;
    if($is_IE) {
        wp_enqueue_script( 'html5shiv', 'https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js', array( 'bootstrap' )  );
        $wp_scripts->add_data( 'html5shiv', 'conditional', 'lt IE 9' );
    }
} );

Opção Três - Apenas faça um eco na cabeça:

add_action('wp_head', function(){
    echo '<!--[if lt IE 9]><script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script><![endif]-->'."\n";
});

Opção Quatro - Enfileire na cabeça:

add_action('wp_print_scripts', function(){
        wp_enqueue_script( 'html5shiv', 'https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js', array( 'bootstrap' )  );
});

A segunda opção. parece legal porque parece um pouco mais limpo em navegadores não-IE. Mas eu não tenho certeza se realmente tem alguma vantagem de velocidade ou se apenas a checagem reduz a velocidade. Além disso, não consigo descobrir qualquer razão pela qual a opção um é melhor que a opção 3 ou 4.

O motivo dessa pergunta

Estou usando a estrutura do Gênesis e eles incluem HTML5shiv como no exemplo abaixo, o que não parece correto eu:

add_action( 'wp_head', 'genesis_html5_ie_fix' );
/**
 * Load the html5 shiv for IE8 and below. Can't enqueue with IE conditionals.
 */
function genesis_html5_ie_fix() {
    if ( ! genesis_html5() )
        return;
    echo '<!--[if lt IE 9]><script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->' . "\n";
}
    
por Bryan Willis 05.01.2016 / 13:30

3 respostas

5

Para estender a sugestão de @gmazzap sobre não usar globais quando você pode usar wp_scripts() , há um atalho para wp_scripts() para adicionar comentários condicionais chamados wp_script_add_data e igualmente wp_style_add_data para estilos condicionais.

Assim, a maneira correta de usar condicionais do Wordpress 4.2 é assim:

/**
 * IE enqueue HTML5shiv with conditionals
 * @link http://tiny.cc/html5shiv
 */
function wpse_213701_enqueue_html5shiv()  {
    wp_enqueue_script( 'html5shiv',
        'https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js',
        array(),
        false,
        false
    );
    wp_script_add_data( 'html5shiv', 'conditional', 'lt IE 9' );
}
add_action('wp_enqueue_scripts', 'wpse_213701_enqueue_html5shiv');

No entanto, o exemplo acima está usando HTML5shiv , que é uma situação única. Uma vez que tem que ser carregado na cabeça você poderia fazer algo como este próximo exemplo se você está preocupado com um plugin como Roots Soil removendo todos os scripts da cabeça.

O mais provável é que você não encontre uma situação como essa. É uma coisa muito instável, já que muitos scripts precisam ser carregados na cabeça. Colocar scripts no rodapé deve ser feito definindo a variável $in_footer como true ao enfileirar scripts. Então, se você usa raízes ou qualquer plugin de cache, não pense em tudo que está funcionando exatamente da maneira que você quer.

Aqui está um exemplo feio do que você pode fazer:

add_action( 'wp_head', 'wpse_213701_check_html5shiv', 1 );
function wpse_213701_check_html5shiv() {
    remove_action( 'wp_head', 'genesis_html5_ie_fix' );
    if ( !has_filter( 'wp_head', 'wp_enqueue_scripts' ) && !wp_script_is( 'html5shiv', 'done' ) ) {
        add_action('wp_head', 'wpse_213701_echo_html5shiv');
        wp_dequeue_script('html5shiv');
    }
}
function wpse_213701_echo_html5shiv() {
    echo '<!--[if lt IE 9]><script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script><![endif]-->'."\n";
}

Isso é um exagero e ainda não é uma garantia de que funcionará. Nos últimos 4 anos, html5shiv assumiu vários nomes que fizeram com que ele fosse registrado / enfileirado com vários identificadores diferentes (html5, html5shiv, html5shim, themename-html5shiv, html5-ie-fix e html5 -polyfill só para citar alguns). Além disso, muitas vezes é empacotado com modernizr . Com isso em mente, se você acha que o exemplo acima é ridículo, você também está adicionando o script a wp_head em seu tema filho, já que um identificador de plugins html5shiv provavelmente nomeará outra coisa .

Atualizar (Movendo scripts para o rodapé com essa abordagem):

Isso provocou algumas ações na página Roots / Soil do Github. Aqui está provavelmente a melhor maneira de fazer isso (como sugerido por @grappler ) e ainda mover scripts para o rodapé. Uma abordagem semelhante foi publicada em @ kaiser

unserkaiser.com/blog/2013/10/08/how-to-move-wordpress-core-javascript-to-the-footer/">blog
function grappler_move_js_to_footer() 
    $scripts = wp_scripts();
    foreach( $scripts->registered as $script ) {
        if ( 'html5' == $script->handle ) {
            wp_script_add_data( $script->handle, 'group', 0 );
        } else {
            wp_script_add_data( $script->handle, 'group', 1 );
        }
    }
}
add_action( 'wp_enqueue_scripts', 'grappler_move_js_to_footer', 99 );

Quanto ao que Mark Kaplan sugeriu e que toscho mencionado aqui , > você não deveria estar usando o método $ is_IE da opção 2 . Aparentemente, se o cabeçalho HTTP Vary: User-Agent não for enviado, você enviará a saída errada para os usuários por trás de um cache, fazendo com que ele seja interrompido para esses usuários. No que diz respeito à detecção do lado do navegador aqui está uma longa lista de exemplos sobre como isso pode ser feito. Mesmo a detecção do lado do cliente tem suas armadilhas.

No final das contas, talvez a melhor resposta seja não usar nenhum desses métodos e esquecer os navegadores herdados, já que A Microsoft deixou cair o suporte para eles a partir de 12 de janeiro .

    
por Bryan Willis 13.01.2016 / 15:12
5

A opção 5 é detectar no navegador qual é o navegador e criar um elemento de script para o seu script diretamente no dom, como o Google Analytics do FB SDK faz.

Isso tem a vantagem de fazer a detecção do navegador no único local em que deve ser feito, o navegador e o carregamento dos scripts específicos do IE somente quando necessário.

Em espírito, é muito semelhante à sua terceira opção, apenas mais genérica.

Sidenote: is_IE , como todas as outras detecções de navegador do lado do servidor, devem ser evitadas, pois eles quebrarão o cache.

    
por Mark Kaplun 05.01.2016 / 13:56
5

Em geral, scripts e estilos nunca devem ser impressos diretamente na página.

O motivo é que outro plug-in ou tema pode adicionar o mesmo script novamente e você recebe o mesmo script adicionado 2 ou mais vezes.

Se você enfileirar o recurso da maneira correta, se outro código enfileirar o mesmo recurso novamente, ele será adicionado uma vez.

Por esse motivo, você deve pular as opções 3 e 4.

Em relação à opção 2, como Mark Kaplun apontou , ela faz uso de detecção de navegador do lado do servidor, que nunca é muito acessível, e mesmo se fosse, não deixe que você selecione a versão do navegador e, no seu caso, ele incluirá o script mesmo nas versões modernas do IE, que não precisam dele .

Então, na verdade, a opção 1 é a melhor entre as que você propôs.

As únicas alterações que eu faria:

  • use 'wp_enqueue_scripts' action, em vez de 'wp_print_scripts'
  • use a função wp_scripts() para acessar global

Algo como:

add_action('wp_enqueue_scripts', function() {
    wp_enqueue_script(
       'html5shiv',
       'https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js',
       array( 'bootstrap' ),
       '3.7.2',
       false
    );
    wp_scripts()->add_data( 'html5shiv', 'conditional', 'lt IE 9' );
} );

Se você fizer isso, se outro script de enfileiramento 'html5shiv' for carregado novamente, ele será adicionado apenas uma vez.

Observe que, usando o snippet acima, o que é impresso na página é:

<!--[if lt IE 9]>
<script type='text/javascript' src='https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js'></script>
<![endif]-->

Esta condicional é analisada pelo navegador (lado do cliente) e não pelo lado do servidor, por isso é acessível e permite adicionar o script apenas para a versão do IE que você deseja segmentar.

Se você precisar saber mais sobre a plataforma do cliente (sistema operacional, tipo de tela e resolução, versão detalhada específica do navegador ...), a única maneira é usar algum javascript para detectar esses detalhes e adicionar dinamicamente o script ao DOM (como por Mark Kaplun solução), mas se conhecer a "família de navegadores" e versão principal é o suficiente para você, minha sugestão é usar essa solução.

    
por gmazzap 05.01.2016 / 18:55