Czy powinienem użyć Bootstrap z CDN, czy zrobić kopię na moim serwerze?

140

Jaka jest najlepsza praktyka używania Twitter Bootstrap, odwoływania się do niego z CDN lub tworzenia kopii lokalnej na moim serwerze?

Ponieważ Bootstrap wciąż się rozwija, obawiam się, że jeśli odwołam się do CDN, z czasem użytkownik zobaczy różne strony internetowe, a niektóre tagi mogą nawet się zepsuć. Jaki jest wybór większości ludzi?

shapeare
źródło

Odpowiedzi:

204

Dlaczego nie oba ¯ \ _ (ツ) _ / ¯? Scott Hanselman ma świetny artykuł na temat korzystania z CDN w celu zwiększenia wydajności, ale wdzięczny powrót do lokalnej kopii na wypadek awarii CDN .

W przypadku ładowania początkowego możesz wykonać następujące czynności, aby załadować z CDN z lokalną rezerwą :

Działające demo w 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>

Aktualizacje

Najlepsze praktyki

Jeśli chodzi o Twoje pytanie dotyczące sprawdzonych metod, jest wiele bardzo dobrych powodów, dla których warto używać CDN w środowisku produkcyjnym :

  1. Zwiększa dostępną równoległość .
  2. Zwiększa szansę na trafienie w pamięci podręcznej .
  3. Zapewnia to, że ładunek będzie jak najmniejszy .
  4. Zmniejsza przepustowość używaną przez serwer.
  5. Gwarantuje, że użytkownik otrzyma bliską geograficznie odpowiedź.

W trosce o wersje, każda CDN warta swojej wagi, pozwala na wybranie określonej wersji biblioteki, aby nie wprowadzać przypadkowo istotnych zmian przy każdym wydaniu.

Za pomocą document.write

Według mdn on document.write

Uwaga : jak document.writepisze do strumienia dokumentów , wywołanie document.writezamkniętego (załadowanego) dokumentu powoduje automatyczne wywołanie document.open, co spowoduje wyczyszczenie dokumentu .

Jednak użycie tutaj jest celowe. Kod musi zostać wykonany, zanim DOM zostanie w pełni załadowany, a także we właściwej kolejności. Jeśli jQuery zawiedzie, musimy wstrzyknąć go do dokumentu inline, zanim spróbujemy załadować bootstrap, który opiera się na jQuery.

Wyjście HTML po załadowaniu :

Przykładowe dane wyjściowe

Jednak w obu tych przypadkach dzwonimy, gdy dokument jest nadal otwarty, więc powinien zawierać treść zamiast zastępować cały dokument. Jeśli czekasz do końca, musisz zamienić na, document.body.appendChildaby wstawić dynamiczne źródła.

Poza tym : w MVC 6 możesz to zrobić za pomocą pomocników linków i tagów skryptu

KyleMit
źródło
1
Hardcoding rgb(51, 51, 51)wydaje się ryzykowny - co jeśli ktoś zmieni kolor i zapomni go zaktualizować? Czy istnieje bardziej stabilna właściwość, której można by użyć?
Flash
@Flash, tak, zgadzam się, to wydaje się wybredne. Trudno jest przetestować zmiany CSS w globalnych zmiennych javascript lub bezpośrednio przez CSS. Musimy tylko przetestować elementy, aby zobaczyć, czy zostały zaprojektowane w taki sposób, w jaki CSS prawdopodobnie je opisał, i zawsze będziemy mieć <body>element. Ta odpowiedź dodaje trochę znaczników z .hiddendiv i następnie wykonuje test, aby sprawdzić, czy jest widoczny: $('#bootstrapCssTest').is(':visible'). Prawdopodobieństwo, że klasa ta będzie miała istotne zmiany w czasie, jest prawdopodobnie znacznie mniejsze.
KyleMit
@KyleMit, jak mogę to zrobić dla ikon materiałów Google ?
Rana Depto
4
Świetna odpowiedź! Tylko uwaga: jeśli używasz Bootstrap 4, powinieneś użyć klasy „d-none” zamiast „hidden”, aby pozwolić na pracę w trybie failover.
deste
1
@JarrodW. - świetne pytanie. Musiałem trochę kopać. powinniśmy być dobrzy, aby go tutaj użyć - zobacz zaktualizowaną odpowiedź
KyleMit
9

Zależy od konkretnej witryny.

Czy masz wielu użytkowników? Czy zależy Ci na wykorzystaniu przepustowości? Czy problemem jest wydajność (sieci CDN mogą przyspieszyć odpowiedzi)?

Możesz utworzyć link do określonej wersji:

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

Lub

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

W ten sposób nie musisz się martwić o aktualizacje biblioteki, lepiej jest być na bieżąco.

Nie jestem pewien, jakie są dokładne statystyki dotyczące wyboru programistów, ale możesz zajrzeć tutaj i zobaczyć, że miliardy żądań są wysyłane do Bootstrap CDN, co oznacza, że ​​jest solidny i bezpieczny w użyciu.

Ofiris
źródło
10
Ostatni link jest uszkodzony.
Nuclearman
@Nuclearman, trends.builtwith.com/cdn/StackPath-BootstrapCDN , również przesyłam edycję .
its4zahoor
2

Próbowałem edytować odpowiedź KyleMit, ale forum było oznaczane jako zły kod z wcięciem , nawet nie było, więc dodaję swój wkład poniżej:

Ponieważ pytanie jest oznaczone jako temat (i nie tylko ), może warto zaktualizować odpowiedź dla nowszej wersji Bootstrap.

Ponieważ framework dodał nową klasę do ukrywania elementów w swojej czwartej wersji, powinniśmy w tym przypadku użyć .d-nonezamiast .hidden.

Wszystko inne pozostaje takie samo w tym przypadku, z wyjątkiem wersji lib (oczywiście!)

André Rocha
źródło
1

Dzięki @KyleMit. Innym sposobem wycofania jest użycie obiektu „window” jako pod -

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

Działa to w ten sposób - jeśli łącze CDN działa, obiekt „okno” będzie miał właściwość „jQuery”, w przeciwnym razie zostanie wykonana druga część skryptu, tj. Document.write, co wskazuje na lokalną kopię.

Odpowiedź na pierwotne pytanie - posiadanie CDN ma wiele zalet, takich jak szybkie pobieranie bez wpływu na serwer i przepustowość. Posiadanie lokalnej kopii ma swoje zalety (jako rozwiązanie awaryjne). W intranecie, ze względu na ustawienia proxy, zasady bezpieczeństwa, łącze CDN może nie działać lub jeśli łącze CDN nie działa, może nie działać. Prosta odpowiedź brzmi: mieć jedno i drugie.

Anand
źródło
1

Prawie wszystkie publiczne sieci CDN są dość niezawodne. Jeśli jednak martwisz się o ten ułamek czasu, w którym CDN może nie działać, możesz załadować Bootstrap z jednego CDN Bootstrap i wrócić do alternatywnego CDN na wypadek, gdyby pierwszy z nich nie działał.

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

O twoim drugim problemie: linki w tym poście to zakodowane na stałe wersje bootstrap i jquery. Tak więc, nawet jeśli biblioteki bootstrap i jquery są stale rozwijane i otrzymują nowe funkcje, witryna pozostanie niezmieniona przez cały czas.

Hamid Sarfraz
źródło