Dois-je utiliser Bootstrap à partir de CDN ou en faire une copie sur mon serveur?

140

Quelle est la meilleure pratique pour utiliser Twitter Bootstrap, y faire référence à partir du CDN ou en faire une copie locale sur mon serveur?

Puisque Bootstrap continue d'évoluer, j'ai peur que si je fais référence au CDN, l'utilisateur verrait différentes pages Web au fil du temps, et certaines balises pourraient même être brisées. Quel est le choix de la plupart des gens?

forme
la source

Réponses:

204

Pourquoi pas les deux ¯ \ _ (ツ) _ / ¯? Scott Hanselman a un excellent article sur l'utilisation d'un CDN pour des gains de performances, mais revenant gracieusement à une copie locale au cas où le CDN serait en panne .

Spécifique au bootstrap, vous pouvez effectuer les opérations suivantes pour charger à partir d'un CDN avec une solution de secours locale :

Démo de travail dans 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>

Mises à jour

Les meilleures pratiques

Pour répondre à votre question sur les bonnes pratiques, il existe de nombreuses très bonnes raisons d'utiliser un CDN dans un environnement de production :

  1. Cela augmente le parallélisme disponible.
  2. Cela augmente les chances qu'il y ait un coup de cache .
  3. Cela garantit que la charge utile sera aussi petite que possible .
  4. Cela réduit la quantité de bande passante utilisée par votre serveur.
  5. Il garantit que l'utilisateur obtiendra une réponse géographiquement proche .

Pour votre problème de version, tout CDN qui vaut son pesant de sel avec vous permet de cibler une version spécifique de la bibliothèque afin de ne pas introduire accidentellement des changements de rupture avec chaque version.

En utilisant document.write

Selon le MDN sur document.write

Remarque : lors de l' document.writeécriture dans le flux de documents , l'appel document.writed'un document fermé (chargé) appelle automatiquement document.open, ce qui effacera le document .

Cependant, l'utilisation ici est intentionnelle. Le code doit être exécuté avant le chargement complet du DOM et également dans le bon ordre. Si jQuery échoue, nous devons l'injecter dans le document en ligne avant d'essayer de charger bootstrap, qui repose sur jQuery.

Sortie HTML après chargement :

Exemple de sortie

Dans ces deux cas cependant, nous appelons alors que le document est encore ouvert, il doit donc intégrer le contenu, plutôt que de remplacer le document entier. Si vous attendez la fin, vous devrez remplacer par document.body.appendChildpour insérer des sources dynamiques.

En plus : dans MVC 6, vous pouvez le faire avec des assistants de lien et de balise de script

KyleMit
la source
1
Le codage en dur rgb(51, 51, 51)semble risqué - que faire si quelqu'un change la couleur et oublie de la mettre à jour? Y a-t-il une propriété plus stable que l'on pourrait utiliser?
Flash le
@Flash, Ouais, je suis d'accord que cela semble capricieux. Il est difficile de tester les changements CSS dans les variables javascript globales ou via le CSS directement. Nous devons juste tester des éléments pour voir s'ils ont été stylés de la manière dont le CSS est susceptible de les décrire, et nous aurons toujours un <body>élément. Cette réponse ajoute quelques balises avec un .hiddendiv et puis fait un test pour voir si elle est visible: $('#bootstrapCssTest').is(':visible'). Cette classe est probablement beaucoup moins susceptible d'avoir des changements de rupture avec le temps.
KyleMit
@KyleMit, comment puis-je faire cela pour les icônes matérielles Google ?
Rana Depto
4
Très bonne réponse! Seulement une note: si vous utilisez Bootstrap 4, vous devez utiliser la classe "d-none" au lieu de "hidden" afin de laisser basculer les travaux.
deste
1
@JarrodW. - excellente question. J'ai dû creuser. nous devrions être bon de l'utiliser ici - voir la réponse mise à jour
KyleMit
9

Dépend du site spécifique.

Avez-vous de nombreux utilisateurs? Vous souciez-vous de l'utilisation de la bande passante? La performance est-elle un problème (les CDN peuvent accélérer les réponses)?

Vous pouvez créer un lien vers une version spécifique:

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

Ou

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

De cette façon, vous n'avez pas à vous soucier des mises à jour de la bibliothèque, il est préférable de rester à jour.

Je ne sais pas quelles sont les statistiques exactes sur le choix des développeurs, mais vous pouvez jeter un œil ici et voir des milliards de demandes sont envoyées à Bootstrap CDN, ce qui signifie qu'il est robuste et sûr à utiliser.

Ofiris
la source
10
Le dernier lien est rompu.
Nuclearman
@Nuclearman, trends.builtwith.com/cdn/StackPath-BootstrapCDN , je soumets également une modification.
its4zahoor le
2

J'ai essayé de modifier la réponse de KyleMit mais le forum marquait comme un mauvais code en retrait, même si ce n'était pas le cas, donc j'ajoute ma contribution juste en dessous:

Comme la question est étiquetée comme un sujet (et pas seulement ), il est peut-être utile de mettre à jour la réponse de la nouvelle version de Bootstrap.

Comme le framework a ajouté une nouvelle classe pour masquer des éléments sur sa quatrième version, nous devrions utiliser à la .d-noneplace de .hiddendans ce cas.

Tout le reste reste le même dans ce cas, sauf la version lib (bien sûr!)

André Rocha
la source
1

Merci à @KyleMit. Une autre façon de se replier est d'utiliser l'objet 'window' comme sous -

<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>

Cela fonctionne comme ceci - Si le lien CDN fonctionne, l'objet 'window' aura la propriété 'jQuery' disponible, sinon la deuxième partie du script, c'est-à-dire document.write sera exécutée qui pointe vers la copie locale.

Réponse à la question initiale - Avoir CDN présente de nombreux avantages tels que des téléchargements rapides sans impact sur votre serveur et votre bande passante. Avoir une copie locale a son propre avantage (en tant qu'arrangements de secours). Sur l'intranet, en raison des paramètres de proxy, des politiques de sécurité, la liaison CDN peut ne pas fonctionner ou si la liaison CDN est en panne, elle peut ne pas fonctionner. La réponse directe est d'avoir les deux.

Anand
la source
1

Presque tous les CDN publics sont assez fiables. Cependant, si vous vous inquiétez de cette fraction du temps où un CDN pourrait être en panne, vous pouvez charger Bootstrap à partir d'un CDN Bootstrap et revenir sur un CDN alternatif au cas où le premier serait en panne.

<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>

À propos de votre deuxième préoccupation: les liens dans cet article sont des versions codées en dur de bootstrap et jquery. Ainsi, même si les bibliothèques bootstrap et jquery sont constamment développées et bénéficient de nouvelles fonctionnalités, votre site restera le même au fil du temps.

Hamid Sarfraz
la source