Должен ли я использовать Bootstrap из CDN или сделать копию на моем сервере?

140

Как лучше всего использовать Twitter Bootstrap, обратиться к нему из CDN или сделать локальную копию на моем сервере?

Так как Bootstrap продолжает развиваться, я боюсь, если я обращусь к CDN, пользователь со временем увидит разные веб-страницы, и некоторые теги могут даже сломаться. Какой выбор у большинства людей?

shapeare
источник

Ответы:

204

Почему не оба ¯ \ _ (ツ) _ / ¯? Скотт Хансельман (Scott Hanselman) написал отличную статью об использовании CDN для повышения производительности, но изящно прибегает к локальной копии на случай, если CDN не работает .

В зависимости от начальной загрузки вы можете выполнить следующие действия для загрузки из CDN с локальным резервом :

Рабочая демонстрация в 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>

Обновления

Лучшие практики

На ваш вопрос о Best Practices есть много очень веских причин для использования CDN в производственной среде :

  1. Это увеличивает доступность параллелизма .
  2. Это увеличивает вероятность попадания в кеш .
  3. Это гарантирует, что полезная нагрузка будет как можно меньше .
  4. Это уменьшает количество полосы пропускания, используемой вашим сервером.
  5. Это гарантирует, что пользователь получит географически близкий ответ.

Что касается вашей работы с версиями, то любой CDN, достойный своего веса, позволяет вам ориентироваться на конкретную версию библиотеки, чтобы случайно не вносить критические изменения в каждом выпуске.

С помощью document.write

Согласно МДН на document.write

Примечание : при document.writeзаписи в поток документов , вызов document.writeзакрытого (загруженного) документа автоматически вызывает document.open, что приведет к очистке документа .

Тем не менее, использование здесь является намеренным. Код должен быть выполнен до полной загрузки DOM, а также в правильном порядке. Если jQuery дает сбой, нам нужно вставить его в документ, прежде чем мы попытаемся загрузить начальную загрузку, которая опирается на jQuery.

HTML-вывод после загрузки :

Пример вывода

В обоих случаях мы звоним, пока документ еще открыт, поэтому он должен включать содержимое, а не заменять весь документ. Если вы ждете до конца, вам придется заменить на, document.body.appendChildчтобы вставить динамические источники.

Кроме того : в MVC 6 это можно сделать с помощью помощников по ссылкам и тегам скриптов.

KyleMit
источник
1
Жесткое кодирование rgb(51, 51, 51)кажется рискованным - что если кто-то изменит цвет и забудет обновить его? Есть ли более стабильное свойство, которое можно использовать?
Флэш
@ Флэш, да, я согласен, что кажется привередливым. Трудно проверить изменения CSS в глобальных переменных javascript или напрямую через CSS. Нам просто нужно протестировать элементы, чтобы увидеть, были ли они стилизованы так, как их может описать CSS, и у нас всегда будет <body>элемент. Этот ответ добавляет некоторую разметку с .hiddenDIV , а затем делает тест , чтобы увидеть , если это видно: $('#bootstrapCssTest').is(':visible'). Этот класс, вероятно, гораздо реже будет иметь серьезные изменения с течением времени.
KyleMit
@KyleMit, как я могу сделать это для Google Material Icons ?
Рана Депто
4
Отличный ответ! Только примечание: если вы используете Bootstrap 4, вы должны использовать класс «d-none» вместо «hidden», чтобы позволить аварийному переключению работать.
Deste
1
@JarrodW. - отличный вопрос. Я должен был покопаться. мы должны хорошо использовать его здесь - см. обновленный ответ
KyleMit
9

Зависит от конкретного сайта.

У вас много пользователей? Вы заботитесь об использовании пропускной способности? Является ли производительность проблемой (CDN могут ускорить ответы)?

Вы можете сослаться на конкретную версию:

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

Или

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

Таким образом, вам не нужно беспокоиться об обновлениях библиотеки, поэтому рекомендуется постоянно обновляться.

Я не уверен, какова точная статистика по выбору разработчиков, но вы можете посмотреть здесь и увидеть, что миллиарды запросов отправляются в Bootstrap CDN, что означает, что он надежен и безопасен в использовании.

Ofiris
источник
10
Последняя ссылка не работает.
Атомник
@ Nuclearman, trend.builtwith.com/cdn/StackPath-BootstrapCDN , я также отправляю изменения.
its4zahoor
2

Я пытался отредактировать ответ KyleMit, но форум отмечался как неправильный код с отступом, даже это не так, поэтому я добавляю свой вклад прямо ниже:

Поскольку вопрос помечен как тема (и не только ), возможно, полезно обновить ответ для более новой версии Bootstrap.

Поскольку платформа добавила новый класс для сокрытия элементов в своей четвертой версии, мы должны использовать .d-noneвместо этого .hiddenв этом случае.

Все остальное остается тем же в этом случае, кроме версии lib (конечно!)

Андре Роша
источник
1

Благодаря @KyleMit. Другой способ отступить - использовать объект 'window', как показано ниже:

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

Это работает так: если ссылка CDN работает, объект 'window' будет иметь свойство 'jQuery', доступное, иначе будет выполнена вторая часть скрипта, т.е. document.write, которая указывает на локальную копию.

Ответ на оригинальный вопрос. Наличие CDN имеет много преимуществ, таких как быстрая загрузка без ущерба для вашего сервера и пропускной способности. Наличие локальной копии имеет свою выгоду (как запасной вариант). В интрасети из-за настроек прокси-сервера, политик безопасности ссылка CDN может не работать или если связь CDN не работает, она может не работать. Прямой ответ - иметь оба.

Ананд
источник
1

Почти все общедоступные CDN довольно надежны. Однако, если вы беспокоитесь о той части времени, когда CDN может быть недоступен, вы можете загрузить Bootstrap из одного CDN Bootstrap и перейти к альтернативному CDN в случае, если первый не работает.

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

О вашей второй проблеме: ссылки в этом посте - это жестко запрограммированные версии начальной загрузки и jquery. Таким образом, даже если библиотеки начальной загрузки и jquery постоянно развиваются и получают новые функции, ваш сайт со временем останется прежним.

Хамид Сарфраз
источник