¿Cómo proporcionar un respaldo local para Font Awesome si falla el CDN?

11

Estoy intentando desarrollar un tema de Wordpress y descubrir cómo proporcionar un respaldo local para Font Awesome si CDN falla o desarrollo mi tema en un servidor local sin conexión a Internet.

La solución que tengo en mente es algo como esto (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' );
    }

¡Gracias!

    
pregunta Knott 24.04.2014 - 09:58

2 respuestas

14

El problema es que estoy bastante seguro de que es imposible verificar si CSS se agrega efectivamente a una página a través de PHP: CSS es analizado por el navegador, por lo que el lado del cliente no tiene ningún efecto. en el lado del servidor.

Por supuesto, en PHP es posible verificar si CDN responde o no ...

Opción 1

Envíe una solicitud y, si responde con el estado HTTP 200, utilícelo. 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 da como resultado 2 solicitudes HTTP, una para la verificación, la segunda para CSS incrustado: realmente malo .

Opción 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 );
    }
}

Esto es incluso peor :

  • Arruina el flujo de trabajo wp_enqueue_style : si un complemento agrega Fuente impresionante, se agregará 2 veces.
  • El número de solicitudes HTTP es el mismo, sin embargo, normalmente las 2 solicitudes se ejecutan en paralelo , por lo que de esta manera la generación de páginas de PHP se ralentiza porque debe esperar la primera respuesta de la solicitud.
  • Esto también evita que el navegador almacene en caché el CSS, por lo que si usa el mismo estilo en diferentes páginas, fuerza la solicitud de CDN en cada página visitada. Cuando se usa el flujo de trabajo normal, las páginas después del primer CSS se toman de la memoria caché.

Entonces, realmente, no haga esto en casa.

Lo que realmente importa es que al usar PHP puede verificar la solicitud de CDN, pero no verificar CSS, por lo que todos sus esfuerzos terminan en un peor rendimiento, en lugar de mejor.

Sinceramente, si el tuyo es un tema público, te sugiero que uses solo la copia local, brindando a los usuarios una forma de elegir un 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 );
    }
}

Por lo tanto, los usuarios pueden anular completamente la función utilizando un tema secundario y también pueden usar el filtro 'font_awesome css_url' para cambiar la URL.

También tenga en cuenta que algunos proveedores de alojamiento de alto nivel convierten automáticamente los activos locales en CDN, y hay complementos que permiten a CDN todas las cosas; esta es la razón por la que un tema público no debe usar CDN en absoluto.

Si el tema es para ti, haz una elección. Considere que los CDN más famosos tienen un% de tiempo de inactividad muy bajo (y bootstrapcdn es uno de los más confiables, según cdnperf.com ) . Estoy bastante seguro de que su alojamiento tiene un% de inactividad mayor que bootstrapcdn, por lo que las personas tienen más probabilidades de no ver su sitio en absoluto, que de verlo con iconos rotos.

El camino sucio

Como se dijo, PHP no puede verificar CSS, porque la representación de CSS ocurre en el lado del cliente, pero puede usar la verificación del lado del cliente: JavaScript.

Primero incrusta CSS usando 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 );
} 

Después de eso, agrega un poco de JavaScript a tu pie de página:

/*
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 se ejecuta cuando se carga la página y comprueba si el intervalo invisible agregado al pie de página con la clase 'fa' tiene la propiedad de la familia de fuentes establecida en 'FontAwesome'. Esto lo establece Font Awesome, por lo que si no es cierto, significa que CSS no está cargado. Si sucede, el código usa JavaScript para agregar el CSS local para encabezar.

(Para probar este código, puede incrustar a través de wp_enqueue_style una URL de CDN incorrecta, y ver qué sucede)

Por lo tanto, en el caso poco frecuente de que un CDN no esté disponible, todos los estilos se mostrarán como se esperaba (durante algunos milisegundos los usuarios verán iconos CSS "rotos", porque CSS se agrega después de que se cargue la página).

Ahora, considerando que los CDN son muy confiables, ¿vale la pena hacer este truco para el < 1% de las personas que verán íconos rotos? Responder a esta pregunta es para usted.

    
respondido por el gmazzap 24.04.2014 - 21:52
1

Una verificación del lado del servidor tampoco es a prueba de balas. Si su servidor se encuentra en California, su cheque utilizará el Centro de datos de California CDN. Si su usuario se encuentra en China, es probable que esté utilizando un Centro de datos completamente diferente. Al menos, así es como creo que funciona.

De todos modos, aquí hay una solución jquery mejorada:

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>
    
respondido por el skibulk 14.10.2014 - 17:28

Lea otras preguntas en las etiquetas