Como fornecer um substituto local para o Font Awesome se o CDN falhar?

11

Estou tentando desenvolver um tema Wordpress e descobrir como fornecer um fallback local para o Font Awesome se o CDN falhar ou desenvolver meu tema em um servidor local sem conexão com a Internet.

A solução que tenho em mente é algo assim (pseudo código):

if ( $CDN_IS_AVAILABLE ) { 
        wp_enqueue_style( 'font-awesome', '//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css', false );
    } else {
        wp_enqueue_style('font-awesome', get_template_directory_uri() . '/css/font-awesome/css/font-awesome.min.css', false, '4.0.3' );
    }

Obrigado!

    
por Knott 24.04.2014 / 09:58

2 respostas

14

O problema é que eu tenho certeza que é impossível checar se o CSS foi efetivamente adicionado a uma página via PHP: CSS é analisado pelo navegador, então, do lado do cliente, e não tem nenhum efeito no lado do servidor.

Claro, no PHP é possível verificar se o CDN é responsivo ou não ...

Opção 1

Envie uma solicitação e, se ela responder com o status HTTP 200, use-a. Algo como:

function font_awesome_css() {
    $url = 'http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css';
    $cdn = wp_remote_get( $url );
    if ( (int) wp_remote_retrieve_response_code( $cdn) !== 200 ) {
        $url = get_template_directory_uri() . '/css/font-awesome/css/font-awesome.min.css';
    }
    wp_enqueue_style( 'font-awesome', $url, false );
}

que resulta em 2 solicitações HTTP, uma para a verificação, a segunda para CSS incorporado: muito ruim .

Opção 2

function font_awesome_css() {
    $url = 'http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css';
    $cdn = wp_remote_get( $url );
    if ( (int) wp_remote_retrieve_response_code( $cdn ) === 200 ) {
        $css = wp_remote_retrieve_body( $cdn );
        add_action( 'wp_head', function() use( $css ) {
            $absolute = "//netdna.bootstrapcdn.com/font-awesome/4.0.3/fonts/";
            $css = str_replace( "../fonts/", $absolute, $css );
            echo '<style type="text/css">' . $css . '</style>';
        } );
    } else {
        $url = get_template_directory_uri() . '/css/font-awesome/css/font-awesome.min.css';
        wp_enqueue_style( 'font-awesome', $url, false );
    }
}

Isso é até pior :

  • Ele estraga o fluxo de trabalho wp_enqueue_style : se um plug-in adicionar a Impressionante de fonte, ele será adicionado duas vezes.
  • O número de solicitações HTTP é o mesmo, mas normalmente as duas solicitações são executadas em paralelo , portanto, a geração de páginas do PHP fica mais lenta porque precisa aguardar a primeira resposta de solicitação. / li>
  • Isso também impede que o navegador armazene em cache o CSS, portanto, se você usar o mesmo estilo em páginas diferentes, forçará a solicitação de CDN em todas as páginas visitadas. Ao usar o fluxo de trabalho normal, as páginas após o primeiro CSS são retiradas do cache.

Então, realmente, não faça isso em casa.

O que realmente importa é que, usando PHP, você pode verificar a solicitação de CDN, mas não verificar CSS, então todos os seus esforços acabam em um desempenho pior, em vez de melhor.

Atenciosamente, se o seu for um tema público, sugiro que você use apenas a cópia local, oferecendo aos usuários uma maneira de escolher um CDN:

if ( ! function_exists( 'font_awesome_css' ) ) {
    function font_awesome_css() {
        $_url = get_template_directory_uri() . '/css/font-awesome/css/font-awesome.min.css';
        $url = apply_filters( 'font_awesome_css_url', $_url );
        wp_enqueue_style( 'font-awesome', $url, false );
    }
}

Assim, os usuários podem substituir completamente a função usando um tema filho e também podem usar o filtro 'font_awesome css_url' para alterar o URL.

Considere também que alguns provedores de hospedagem high-end convertem automaticamente os recursos locais para os CDN, e há plugins que permite ao CDN todas as coisas; esta é a razão pela qual um tema público não deve usar o CDN.

Se o tema for para você, faça uma escolha. Considere que os CDNs mais famosos têm um% de tempo de inatividade muito baixo (e o bootstrapcdn é um dos mais confiáveis, de acordo com cdnperf.com ) . Tenho certeza de que sua hospedagem tem um tempo de inatividade maior que bootstrapcdn, então as pessoas têm mais probabilidade de não ver seu site, do que vê-lo com ícones quebrados.

O caminho sujo

Como dito, o PHP não pode verificar CSS, porque a renderização CSS acontece no lado do cliente, mas você pode usar a verificação do lado do cliente: JavaScript.

Primeiro, incorpore o CSS usando o CDN:

function font_awesome_css() {
    $url =  '//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css';
    wp_enqueue_style( 'font-awesome', $url, false );
} 

Depois disso, adicione um pouco de JavaScript ao seu rodapé:

/*
Normally the JS should be properly enqueued and the URL
passed via wp_enqueue_script, but this is a proof of concept,
more than real code.
*/
add_action( 'wp_footer', function() {
    $cssurl = get_template_directory_uri() . '/css/';
    ?>
    <span id="facheck" data-cssuri="<?php echo $cssurl; ?>" class="fa" style="display:none">
    </span>
    <script>
        jQuery(document).ready(function($) {
            var $check = $('#facheck');
            if ( $check.css('fontFamily') !== 'FontAwesome' ) {
                // Font Awesome not loaded!
                // Remove current CSS link
                $('#font-awesome-css').remove;
                // Add the local version
                var local = '<link rel="stylesheet" type="text/css" href="' +
                    $check.data('cssuri') + // This is the theme CSS folder URL
                    'font-awesome/css/font-awesome.min.css" />';
                $('head').append( local );
            }
        });
    </script>
    <?php
});

Este código é executado quando a página é carregada e verifica se a extensão invisível adicionada ao rodapé com a classe 'fa' tem a propriedade font-family definida como 'FontAwesome'. Isso é definido pelo Font Awesome, então se não for verdade, significa que o CSS não está carregado. Se isso acontecer, o código usa JavaScript para anexar o CSS local à cabeça.

(Para testar esse código, você pode incorporar via wp_enqueue_style uma URL CDN incorreta e ver o que acontece)

Assim, no caso raro de um CDN não estar disponível, todos os estilos serão mostrados como esperado (por alguns milissegundos os usuários verão ícones CSS 'quebrados', porque o CSS é adicionado depois que a página é carregada).

Agora, considerando que os CDNs são muito confiáveis, vale a pena fazer este hack para o < 1% das pessoas que verão ícones quebrados? Responder a esta pergunta é deixado para você.

    
por gmazzap 24.04.2014 / 21:52
1

Uma verificação do lado do servidor não é à prova de balas. Se o seu servidor estiver localizado na Califórnia, o seu cheque usará o Data Center do California CDN. Se seu usuário estiver na China, provavelmente usaria um data center completamente diferente. Pelo menos, é assim que eu acho que funciona.

De qualquer forma, aqui está uma solução de jquery aprimorada:

enlace

<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
<script>
    (function($){
        var $span = $('<span class="fa" style="display:none"></span>').appendTo('body');
        if ($span.css('fontFamily') !== 'FontAwesome' ) {
            // Fallback Link
            $('head').append('<link href="/css/font-awesome.min.css" rel="stylesheet">');
        }
        $span.remove();
    })(jQuery);
</script>
    
por skibulk 14.10.2014 / 17:28

Tags