wp enqueue script usando scripts desde CDN con callback de seguridad

2 jun 2014, 03:31:17
Vistas: 25.1K
Votos: 7

Quiero incluir varios scripts y estilos desde un CDN remoto... en este caso archivos de bootstrap y similares, pero quiero proporcionar una red de seguridad en forma de callback en caso de que el CDN esté caído por alguna razón...

Agregaría algo de código pero realmente no sé cómo abordar esto en absoluto...

Aquí hay un ejemplo de un wp_enqueue_script regular que uso actualmente:

wp_enqueue_script( 'bootstrap', 'http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js', array('jquery'), 3.3, true);
0
Todas las respuestas a la pregunta 5
2

He tomado el post anterior y he hecho 2 cosas con él:

  • utiliza las funciones nativas de WordPress para llamadas http
  • almacena en caché el hecho de que el CDN está activo durante 20 minutos (puedes ajustar esto). Realmente no quieres obtener el contenido del CDN en CADA carga de página. No tiene sentido acelerar tu sitio con CDNs cuando haces eso.

$get_the_url = 'http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js';

$cdnIsUp = get_transient( 'cnd_is_up' );

if ( $cdnIsUp ) {

    $load_source = 'load_external_bootstrap';

} else {

    $cdn_response = wp_remote_get( $get_the_url );

    if( is_wp_error( $cdn_response ) || wp_remote_retrieve_response_code($cdn_response) != '200' ) {

        $load_source = 'load_local_bootstrap';

    }
    else {

        $cdnIsUp = set_transient( 'cnd_is_up', true, MINUTE_IN_SECONDS * 20 );
        $load_source = 'load_external_bootstrap';
    }
 }

add_action('wp_enqueue_scripts', $load_source );

function load_external_bootstrap() { 
    wp_register_script( 'bootstrap', 'http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js', array('jquery'), 3.3, true); 
    wp_enqueue_script('bootstrap'); 
}

function load_local_bootstrap() {
    wp_register_script('bootstrap', get_bloginfo('template_url').'/js/bootstrap.min.js', __FILE__, array('jquery'), 3.3, true);
    wp_enqueue_script('bootstrap'); 
}

2 jun 2014 12:08:56
Comentarios

¡Guau, muchas funciones que no conocía! ;) Muchas gracias por tu ayuda ;)

Sagive Sagive
2 jun 2014 13:55:42

¿Por qué no simplemente verificar si wp_register_script devuelve falso? Veo un problema con tu transitorio que se establece cada 20 minutos, en el sentido de que el sitio podría no cargar el script externo de bootstrap durante al menos 20 minutos, lo cual es demasiado tiempo. Si verificas el valor de retorno de wp_register_script del script externo y si es falso, registras el script local, es mucho más limpio y no hay espera si el CDN falla.

Solomon Closson Solomon Closson
15 feb 2017 19:23:30
3

La respuesta aceptada es completamente incorrecta. Sospecho un grave malentendido de la pregunta del OP, ya que cualquiera con un mínimo de experiencia en programación nunca recomendaría algo como "guarda una copia local del script y haz llamadas get_url cada 20 minutos".

@Paul G. dice que no tiene sentido cargar desde el CDN en cada carga de página.

¡Ese es precisamente el propósito de usar CDNs! Si no cargas desde el CDN y en su lugar cargas tu copia cachead, el cliente tendrá que descargarla de tu servidor. Puede que estés en Auckland, Nueva Zelanda y tu cliente en Londres. Tu servidor nunca podrá igualar la velocidad de un CDN ubicado más cerca del cliente.

Además, los CDNs usan tecnologías como NGINX/Varnish, con cachés masivos que ni siquiera tocan los servidores. Tu servidor puede o no estar usando un proxy inverso como NGINX con balanceo de carga, puede o no tener un caché grande para servir archivos estáticos, por lo que para cargar tu copia de los archivos tendrá que pasar por toda la pila, lo que puede estar muy lejos de la velocidad que obtienes al cargar archivos estáticos cacheados.

Hagas lo que hagas, usa CDNs siempre que sea posible, y sí, en cada carga de página.

Finalmente, si te preocupa que un CDN falle, una solución simple sería incluir 2 o 3 CDNs alternativos como respaldo, y si el CDN principal falla al cargar, podrías fácilmente conectar un listener y cargar desde los otros.

En el improbable caso de que todos los CDNs principales fallen, no será solo tu sitio el que no funcione, también fallarán Facebook, Imgur, Flickr y mil millones de sitios más. En ese momento, quizás sea mejor salir a mirar el cielo, y tal vez encuentres los OVNIs que causaron la primera falla mundial de centros de datos en la historia de la humanidad.

Respuesta corta: Usa el CDN.

Ejemplo de script requirejs para URLs de respaldo:

   requirejs.config({
   enforceDefine: true,
   paths: {
       jquery: [
        '//ajax.aspnetcdn.com/ajax/jquery/jquery-2.0.0.min',
        //Si falla la ubicación del CDN, carga desde esta ubicación
        //xyz.com/jquery.min.js
      ]
   }
   });
26 dic 2015 12:17:02
Comentarios

¿puedes ofrecer un script/función real que use un segundo CDN en caso de que el principal falle?

Sagive Sagive
26 dic 2015 13:11:10

sí, la forma más simple y mejor de manejar esto es usar requireJs. TIENE FUNCIONALIDAD INTEGRADA para URLs de respaldo en caso de que las URLs principales fallen al cargar. He editado mi respuesta para incluir el script. Por favor, marca esto como la respuesta correcta, la que has marcado podría confundir a los usuarios.

Algorini Algorini
26 dic 2015 13:19:37

Me alegraste el día con "En ese momento, podría ser mejor salir afuera y mirar al cielo, y tal vez encuentres los OVNIs". Gracias)

Alex Misiulia Alex Misiulia
6 ago 2021 10:39:59
0

Podrías intentar algo como esto para probar primero la versión del CDN y luego cargar condicionalmente según si está disponible o no:

$get_the_url = 'http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js';
    $test_the_url = @fopen( $get_the_url,'r' );

    if ( $test_the_url !== false ) {

        function load_external_bootstrap() { 
        wp_register_script( 'bootstrap', 'http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js', array('jquery'), 3.3, true); 
        wp_enqueue_script('bootstrap'); 

    }

    add_action('wp_enqueue_scripts', 'load_external_bootstrap');

    } else {

        function load_local_bootstrap() {
        wp_register_script('bootstrap', get_bloginfo('template_url').'/js/bootstrap.min.js', __FILE__, array('jquery'), 3.3, true);
        wp_enqueue_script('bootstrap'); 
    }

    add_action('wp_enqueue_scripts', 'load_local_bootstrap');
    }
2 jun 2014 11:25:38
2

Se me ocurrieron dos funciones wrapper:

function wp_enqueue_cdn_script( $handle, $src_cdn = false, $src_local = false, $deps = array(), $ver = false, $in_footer = false ) {
    $cdnIsUp = get_transient( $handle . '_script_cdn_is_up' );
    if ( $cdnIsUp ) {
        wp_enqueue_script( $handle, $src_cdn, $deps, $ver, $in_footer );
    } else {
        $cdn_response = wp_remote_get( $src_cdn );
        if ( is_wp_error( $cdn_response ) || wp_remote_retrieve_response_code( $cdn_response ) != '200' ) {
            wp_enqueue_script( $handle, $src_local, $deps, $ver, $in_footer );
        } else {
            $cdnIsUp = set_transient( $handle . '_script_cdn_is_up', true, MINUTE_IN_SECONDS * 20 );
            wp_enqueue_script( $handle, $src_cdn, $deps, $ver, $in_footer );
        }
    }
}

function wp_enqueue_cdn_style( $handle, $src_cdn = false, $src_local = false, $deps = array(), $ver = false, $media = 'all' ) {
    $cdnIsUp = get_transient( $handle . '_style_cdn_is_up' );
    if ( $cdnIsUp ) {
        wp_enqueue_style( $handle, $src_cdn, $deps, $ver, $media);
    } else {
        $cdn_response = wp_remote_get( $src_cdn );
        if ( is_wp_error( $cdn_response ) || wp_remote_retrieve_response_code( $cdn_response ) != '200' ) {
            wp_enqueue_style( $handle, $src_local, $deps, $ver, $media);
        } else {
            $cdnIsUp = set_transient( $handle . '_style_cdn_is_up', true, MINUTE_IN_SECONDS * 20 );
            wp_enqueue_style( $handle, $src_cdn, $deps, $ver, $media);
        }
    }
}

Pero me pregunto si realmente es útil: sobrecarga el servidor, y estamos asumiendo que si el servidor puede alcanzar el CDN el cliente también podrá, lo cual no siempre es cierto en el mundo real.

27 feb 2015 14:56:16
Comentarios

¿Cuál es la sobrecarga en el servidor? Creo que es pequeña, ¿no?

Sagive Sagive
28 feb 2015 01:19:06

No lo sé con certeza, requeriría hacer algunas pruebas de rendimiento, pero me pregunto si el ahorro al usar una CDN siempre justifica la sobrecarga del servidor, por pequeña que pueda ser.

Ciro Mattia Gonano Ciro Mattia Gonano
16 mar 2015 16:03:40
1

@ciro tiene toda la razón acerca de que la conexión del servidor no es una prueba adecuada para esto. El objetivo del respaldo (fallback) es asegurarse de que el cliente pueda recibir el documento.

Hay países donde Google está bloqueado (como ejemplo). Si tu servidor web está en California, pero el visitante está en un país donde Google está bloqueado, esta llamada del lado del servidor en PHP probará TRUE, pero el script no se servirá al usuario.

Consulta Cómo encolar un respaldo (fallback) de jQuery - WordPress para ver un método que encola con respaldo local y prueba el cliente, no el servidor.

1 jun 2015 05:00:21
Comentarios

Si no tienes suficiente reputación para hacer algo, haz cosas para ganar reputación. Para eso existe el sistema de reputación.

cybmeta cybmeta
1 jun 2015 08:44:57