我应该使用CDN的Bootstrap还是在服务器上进行复制?


140

使用Twitter Bootstrap,从CDN引用它或在我的服务器上进行本地复制的最佳实践是什么?

由于Bootstrap一直在发展,因此如果我提到CDN,恐怕用户会随着时间的推移看到不同的网页,甚至某些标签可能会损坏。大多数人的选择是什么?

Answers:


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>

更新

最佳实践

关于最佳做法的问题,有很多在生产环境中使用CDN的充分理由

  1. 它增加了可用的并行性
  2. 这增加了发生缓存命中的可能性。
  3. 它确保有效载荷将尽可能
  4. 它减少了服务器使用的带宽量。
  5. 它可以确保用户在地理位置上能获得接近的响应。

对于版本问题,任何值得一试的CDN都可以使您以特定版本的库为目标,因此您不会在每次发行时意外引入重大更改。

使用 document.write

根据mdn document.write

注意:在document.write写入文档流时document.write自动调用已关闭(已加载)的文档document.open这将清除文档

但是,此处的用法是有意的。需要在DOM完全加载之前并以正确的顺序执行代码。如果jQuery失败,我们需要在尝试加载依赖于jQuery的引导程序之前将其内联注入文档中。

加载后的HTML输出

示例输出

但是,在这两种情况下,我们都是在文档仍处于打开状态时调用的,因此应内联内容,而不是替换整个文档。如果等到最后,则必须替换为document.body.appendChild才能插入动态源。

另外:在MVC 6中,您可以使用链接和脚本标签帮助程序来完成此操作


1
硬编码rgb(51, 51, 51)似乎有风险-如果有人更改颜色而忘记更新颜色怎么办?有没有可以使用的更稳定的属性?
Flash

@Flash,是的,我同意这似乎很挑剔。很难在全局javascript变量中或直接通过CSS测试CSS更改。我们只需要测试元素,看看它们是否已经按照CSS可能描述它们的方式进行了样式设置,我们将始终有一个<body>元素。 此答案使用.hiddendiv 添加了一些标记,然后进行了测试以查看是否可见:$('#bootstrapCssTest').is(':visible')。该类随着时间的流逝发生重大变化的可能性要小得多。
KyleMit

@KyleMit,如何为Google材质图标执行此操作?
拉娜·德普托18-3-3

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,这意味着它功能强大且安全。


10
最后一个链接断开。
核弹手

@ Nuclearman,trends.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具有许多优点,例如快速下载而不会影响服务器和带宽。拥有本地副本有其自身的好处(作为后备安排)。在Intranet上,由于代理设置,安全策略,CDN链接可能不起作用,或者如果CDN链接断开,它可能不起作用。直接答案是两者兼而有之。


1

几乎所有公共CDN都非常可靠。但是,如果您担心CDN可能会停机的那部分时间,则可以从一个Bootstrap CDN加载Bootstrap ,然后在第一个CDN停机的情况下回退到备用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>

关于您的第二个问题: 这篇文章中的链接是bootstrap和jquery的硬编码版本。因此,即使bootstrap和jquery库不断开发并获得新功能,您的网站也会随着时间的推移保持不变。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.