¿Debo usar Bootstrap de CDN o hacer una copia en mi servidor?

140

¿Cuál es la mejor práctica de usar Twitter Bootstrap, consultarlo desde CDN o hacer una copia local en mi servidor?

Dado que Bootstrap sigue evolucionando, me temo que si me refiero a la CDN, el usuario verá diferentes páginas web con el tiempo, y algunas etiquetas pueden incluso romperse. ¿Cuál es la elección de la mayoría de la gente?

Shapeare
fuente

Respuestas:

204

¿Por qué no ambos ¯ \ _ (ツ) _ / ¯? Scott Hanselman tiene un gran artículo sobre el uso de una CDN para aumentar el rendimiento, pero recurre con gracia a una copia local en caso de que la CDN no funcione .

Específico para bootstrap, puede hacer lo siguiente para cargar desde un CDN con un respaldo local :

Demostración de trabajo en Plunker

<head>
  <!-- Bootstrap CSS CDN -->
  <link rel="stylesheet" href="~https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css">
  <!-- Bootstrap CSS local fallback -->
  <script>
    var test = document.createElement("div")
    test.className = "hidden d-none"

    document.head.appendChild(test)
    var cssLoaded = window.getComputedStyle(test).display === "none"
    document.head.removeChild(test)

    if (!cssLoaded) {
        var link = document.createElement("link");

        link.type = "text/css";
        link.rel = "stylesheet";
        link.href = "lib/bootstrap.min.css";

        document.head.appendChild(link);
    }
  </script>
</head>
<body>
    <!-- APP CONTENT -->

    <!-- jQuery CDN -->
    <script src="~https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
    <!-- jQuery local fallback -->
    <script>window.jQuery || document.write('<script src="lib/jquery.min.js"><\/script>')</script>

    <!-- Bootstrap JS CDN -->
    <script src="~https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    <!-- Bootstrap JS local fallback -->
    <script>if(typeof($.fn.modal) === 'undefined') {document.write('<script src="lib/bootstrap.min.js"><\/script>')}</script>
</body>

Actualizaciones

Mejores prácticas

Para su pregunta sobre las mejores prácticas, hay muchas razones muy buenas para usar un CDN en un entorno de producción :

  1. Aumenta el paralelismo disponible.
  2. Aumenta la posibilidad de que haya un golpe de caché .
  3. Asegura que la carga útil sea lo más pequeña posible .
  4. Reduce la cantidad de ancho de banda utilizado por su servidor.
  5. Asegura que el usuario obtendrá una respuesta geográficamente cercana .

Para su preocupación por el control de versiones, cualquier CDN que valga su peso en sal le permite apuntar a una versión específica de la biblioteca para que no introduzca accidentalmente cambios importantes con cada versión.

Utilizando document.write

Según el mdn en document.write

Nota : a medida que se document.writeescribe en la secuencia de documentos , la llamada document.writea un documento cerrado (cargado) llama automáticamente document.open, lo que borrará el documento .

Sin embargo, el uso aquí es intencional. El código debe ejecutarse antes de que el DOM esté completamente cargado y también en el orden correcto. Si jQuery falla, debemos inyectarlo en el documento en línea antes de intentar cargar bootstrap, que se basa en jQuery.

Salida HTML después de la carga :

Salida de ejemplo

Sin embargo, en ambos casos, estamos llamando mientras el documento aún está abierto, por lo que debería incluir los contenidos en línea, en lugar de reemplazar todo el documento. Si espera hasta el final, deberá reemplazarlo document.body.appendChildpara insertar fuentes dinámicas.

Aparte : en MVC 6, puede hacer esto con ayudantes de etiquetas de enlace y script

KyleMit
fuente
1
La codificación dura rgb(51, 51, 51)parece arriesgada: ¿qué sucede si alguien cambia el color y se olvida de actualizarlo? ¿Existe una propiedad más estable que se pueda usar?
Flash
@ Flash, sí, estoy de acuerdo en que parece meticuloso. Es difícil probar los cambios de CSS en las variables globales de JavaScript o directamente a través de CSS. Solo tenemos que probar los elementos para ver si han sido diseñados de la manera en que es probable que el CSS los describa, y siempre tendremos un <body>elemento. Esta respuesta añade un poco de margen de beneficio con un .hiddendiv y luego hace una prueba para ver si es visible: $('#bootstrapCssTest').is(':visible'). Esa clase es mucho menos probable que tenga cambios importantes con el tiempo.
KyleMit
@KyleMit, ¿cómo puedo hacer esto para los iconos de material de Google ?
Rana Depto
44
¡Gran respuesta! Solo una nota: si está usando Bootstrap 4, debe usar la clase "d-none" en lugar de "oculta" para permitir que el error funcione.
Deste
1
@JarrodW. Gran pregunta. Tuve que cavar un poco. deberíamos ser buenos para usarlo aquí - ver respuesta actualizada
KyleMit
9

Depende del sitio específico.

¿Tienes muchos usuarios? ¿Te importa el uso del ancho de banda? ¿Es el problema un problema (los CDN pueden acelerar las respuestas)?

Puede vincular a una versión específica:

//maxcdn.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css

O

//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css

De esa manera no tiene que preocuparse por las actualizaciones de la biblioteca, es una mejor práctica mantenerse actualizado.

No estoy seguro de cuáles son las estadísticas exactas sobre la elección de los desarrolladores, pero puede echar un vistazo aquí y ver miles de millones de solicitudes enviadas a Bootstrap CDN, lo que significa que es robusto y seguro de usar.

Ofiris
fuente
10
El último enlace está roto.
Nuclearman
@Nuclearman, trends.builtwith.com/cdn/StackPath-BootstrapCDN , también envío una edición.
its4zahoor
2

Traté de editar la respuesta de KyleMit, pero el foro estaba marcando como un código sangrado incorrecto, aunque no lo era, así que agrego mi contribución a continuación:

Como la pregunta está etiquetada como tema (y no solo ), quizás sea útil actualizar la respuesta para la versión más reciente de Bootstrap.

Como el marco agregó una nueva clase para ocultar elementos en su cuarta versión, deberíamos usarlo en .d-nonelugar de hacerlo .hiddenen este caso.

Todo lo demás permanece igual en ese caso, excepto la versión lib (¡por supuesto!)

André Rocha
fuente
1

Gracias a @KyleMit. Otra forma de retroceder es usar el objeto 'ventana' como debajo:

<script type="text/javascript" src="https://cdn.jsdelivr.net/jquery/latest/jquery.min.js"></script>
<script>
window.jQuery || document.write("<script src='js/jquery.min.js'><\/script>");
</script>

Funciona así: si el enlace CDN funciona, el objeto 'ventana' tendrá la propiedad 'jQuery' disponible; de ​​lo contrario, se ejecutará la segunda parte del script, es decir, document.write, que apunta a la copia local.

Respuesta a la pregunta original: tener CDN tiene muchos beneficios, como descargas rápidas sin afectar su servidor y ancho de banda. Tener una copia local tiene su propio beneficio (como una disposición alternativa). En la intranet, debido a la configuración del proxy, las políticas de seguridad, el enlace CDN puede no funcionar o si el enlace CDN está inactivo puede no funcionar. La respuesta directa es tener ambos.

Anand
fuente
1

Casi todas las CDN públicas son bastante confiables. Sin embargo, si le preocupa la fracción de tiempo en que una CDN podría estar inactiva, puede cargar Bootstrap desde una CDN de Bootstrap y recurrir a una CDN alternativa en caso de que la primera esté inactiva.

<html>
  <head>
    <!-- Bootstrap CSS CDN with Fallback -->
    <link rel="stylesheet" href="https://pagecdn.io/lib/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha256-YLGeXaapI0/5IgZopewRJcFXomhRMlYYjugPLSyNjTY=" crossorigin="anonymous">
    <script>
    var test = document.createElement("div")
    test.className = "hidden d-none"

    document.head.appendChild(test)
    var cssLoaded = window.getComputedStyle(test).display === "none"
    document.head.removeChild(test)

    if (!cssLoaded) {
        var link = document.createElement("link");

        link.type = "text/css";
        link.rel = "stylesheet";
        link.href = "https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css";

        document.head.appendChild(link);
    }
    </script>
  </head>
  <body>
    <!-- APP CONTENT -->

    <!-- jQuery CDN with Fallback -->
    <script src="https://pagecdn.io/lib/jquery/3.2.1/jquery.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
    <script>window.jQuery || document.write('<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"><\/script>');</script>

    <!-- Bootstrap JS CDN with Fallback -->
    <script src="https://pagecdn.io/lib/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha256-CjSoeELFOcH0/uxWu6mC/Vlrc1AARqbm/jiiImDGV3s=" crossorigin="anonymous"></script>
    <script>if(typeof($.fn.modal) === 'undefined') {document.write('<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"><\/script>')}</script>
  </body>
</html>

Acerca de su segunda preocupación: los enlaces en esta publicación son versiones codificadas de bootstrap y jquery. Por lo tanto, incluso si las bibliotecas bootstrap y jquery se desarrollan constantemente y obtienen nuevas funciones, su sitio permanecerá igual con el tiempo.

Hamid Sarfraz
fuente