Soll ich Bootstrap von CDN verwenden oder eine Kopie auf meinem Server erstellen?

140

Was ist die beste Vorgehensweise bei der Verwendung von Twitter Bootstrap, beim Abrufen von CDN oder beim Erstellen einer lokalen Kopie auf meinem Server?

Da sich Bootstrap weiterentwickelt, befürchte ich, dass der Benutzer im Laufe der Zeit unterschiedliche Webseiten sehen würde, wenn ich mich auf das CDN beziehe, und einige Tags könnten sogar beschädigt sein. Welche Wahl haben die meisten Menschen?

Shapeare
quelle

Antworten:

204

Warum nicht beide ¯ \ _ (ツ) _ / ¯? Scott Hanselman hat einen großartigen Artikel über die Verwendung eines CDN für Leistungssteigerungen, greift jedoch auf eine lokale Kopie zurück, falls das CDN ausfällt .

Speziell für Bootstrap können Sie Folgendes tun, um von einem CDN mit lokalem Fallback zu laden :

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

Aktualisierung

Empfohlene Vorgehensweise

Für Ihre Frage zu Best Practices gibt es viele sehr gute Gründe, ein CDN in einer Produktionsumgebung zu verwenden :

  1. Es erhöht die verfügbare Parallelität .
  2. Es erhöht die Wahrscheinlichkeit, dass es zu einem Cache-Treffer kommt .
  3. Es stellt sicher, dass die Nutzlast so klein wie möglich ist .
  4. Dies reduziert die von Ihrem Server verwendete Bandbreite .
  5. Es stellt sicher, dass der Benutzer eine geografisch enge Antwort erhält .

Für Ihr Versionsproblem können Sie mit jedem CDN, das sein Gewicht in Salz wert ist, eine bestimmte Version der Bibliothek auswählen, damit Sie nicht versehentlich mit jeder Version Änderungen vornehmen.

Verwenden von document.write

Nach dem mdn auf document.write

Hinweis : als document.writeSchreibvorgänge in dem Dokument Strom , Aufruf document.writeauf einem geschlossenen (geladen) Dokument automatisch aufruft document.open, die das Dokument klar wird .

Die Verwendung hier ist jedoch beabsichtigt. Der Code muss ausgeführt werden, bevor das DOM vollständig geladen ist und auch in der richtigen Reihenfolge. Wenn jQuery fehlschlägt, müssen wir es inline in das Dokument einfügen, bevor wir versuchen, Bootstrap zu laden, das auf jQuery basiert.

HTML-Ausgabe nach dem Laden :

Beispielausgabe

In beiden Fällen rufen wir jedoch auf, während das Dokument noch geöffnet ist, sodass der Inhalt eingefügt werden sollte, anstatt das gesamte Dokument zu ersetzen. Wenn Sie bis zum Ende warten, müssen Sie diese ersetzen document.body.appendChild, um dynamische Quellen einzufügen.

Nebenbei : In MVC 6 können Sie dies mit Hilfe von Link- und Skript-Tags tun

KyleMit
quelle
1
Hardcodierung rgb(51, 51, 51)scheint riskant - was ist, wenn jemand die Farbe ändert und vergisst, sie zu aktualisieren? Gibt es eine stabilere Eigenschaft, die man nutzen könnte?
Flash
@Flash, Ja, ich stimme zu, das scheint pingelig. Es ist schwierig, CSS-Änderungen in globalen Javascript-Variablen oder direkt über das CSS zu testen. Wir müssen nur Elemente testen, um festzustellen, ob sie so gestaltet wurden, wie das CSS sie wahrscheinlich beschreibt, und wir haben immer ein <body>Element. Diese Antwort fügt ein Markup mit einem .hiddendiv hinzu und führt dann einen Test durch, um festzustellen, ob es sichtbar ist : $('#bootstrapCssTest').is(':visible'). Es ist wahrscheinlich viel weniger wahrscheinlich, dass diese Klasse im Laufe der Zeit brechende Veränderungen aufweist.
KyleMit
@KyleMit, wie kann ich das für Google Material Icons tun ?
Rana Depto
4
Gute Antwort! Nur ein Hinweis: Wenn Sie Bootstrap 4 verwenden, sollten Sie die Klasse "d-none" anstelle von "hidden" verwenden, damit das Failover funktioniert.
deste
1
@ JarrodW. - tolle Frage. Ich musste etwas graben. Wir sollten gut sein, es hier zu verwenden - siehe aktualisierte Antwort
KyleMit
9

Hängt von der jeweiligen Site ab.

Haben Sie viele Benutzer? Interessieren Sie sich für die Bandbreitennutzung? Ist die Leistung ein Problem (CDNs können die Antworten beschleunigen )?

Sie können auf eine bestimmte Version verlinken:

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

Oder

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

Auf diese Weise müssen Sie sich keine Gedanken über Bibliotheksaktualisierungen machen. Es ist besser, auf dem neuesten Stand zu bleiben.

Ich bin nicht sicher, wie die genauen Statistiken zur Auswahl der Entwickler lauten, aber Sie können hier einen Blick darauf werfen , wie Milliarden von Anforderungen an Bootstrap CDN gesendet werden, was bedeutet, dass es robust und sicher zu verwenden ist.

Ofiris
quelle
10
Der letzte Link ist defekt.
Nuclearman
@ Nuclearman, Trends.builtwith.com/cdn/StackPath-BootstrapCDN , ich reiche auch eine Bearbeitung ein.
its4zahoor
2

Ich habe versucht, die Antwort von KyleMit zu bearbeiten , aber das Forum wurde als falsch eingerückter Code markiert, auch wenn dies nicht der Fall war. Deshalb füge ich meinen Beitrag unten hinzu:

Da die Frage als markiert ist Thema (und nicht nur ), vielleicht ist es hilfreich, die Antwort für die neuere Version von Bootstrap zu aktualisieren.

Da der Rahmen eine neue Klasse für das Verstecken Elemente auf ihrer vierten Version hinzugefügt, sollten wir verwenden , .d-noneanstatt .hiddenin diesem Fall.

Alles andere bleibt in diesem Fall gleich, außer der lib-Version (natürlich!)

André Rocha
quelle
1

Danke an @KyleMit. Eine andere Möglichkeit zum Zurückgreifen ist die Verwendung des 'Fenster'-Objekts wie unter -

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

Dies funktioniert folgendermaßen: Wenn die CDN-Verknüpfung funktioniert, steht für das Objekt 'window' die Eigenschaft 'jQuery' zur Verfügung, andernfalls wird der zweite Teil des Skripts, dh document.write, ausgeführt, der auf die lokale Kopie verweist.

Antwort auf die ursprüngliche Frage - CDN bietet viele Vorteile, z. B. schnelle Downloads, ohne den Server und die Bandbreite zu beeinträchtigen. Eine lokale Kopie zu haben, hat seinen eigenen Vorteil (als Ersatzvereinbarung). Im Intranet funktioniert die CDN-Verbindung aufgrund von Proxy-Einstellungen und Sicherheitsrichtlinien möglicherweise nicht. Wenn die CDN-Verbindung unterbrochen ist, funktioniert sie möglicherweise nicht. Die klare Antwort ist, beides zu haben.

Anand
quelle
1

Fast alle öffentlichen CDNs sind ziemlich zuverlässig. Wenn Sie sich jedoch Sorgen über den Bruchteil der Zeit machen, in der ein CDN möglicherweise nicht verfügbar ist, können Sie Bootstrap von einem Bootstrap-CDN laden und auf ein alternatives CDN zurückgreifen, falls das erste nicht verfügbar ist.

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

Zu Ihrem zweiten Anliegen: Die Links in diesem Beitrag sind fest codierte Versionen von Bootstrap und JQuery. Selbst wenn die Bootstrap- und JQuery-Bibliotheken ständig weiterentwickelt werden und neue Funktionen erhalten, bleibt Ihre Site im Laufe der Zeit dieselbe.

Hamid Sarfraz
quelle