在线采购 js 脚本和最佳实践有多稳健

How robust is online sourcing of js scripts, and best practices

我来自 R 背景,我开始学习一些 javascript 用于数据可视化目的(想想 leafletd3chart ,...).

我试图解决这样一个事实,即许多教程和模板建议加载包,CSS,甚至直接从在线资源中加载数据。例如,https://leafletjs.com/examples/quick-start/ 推荐:

Before writing any code for the map, you need to do the following preparation steps on your page:

Include Leaflet CSS file in the head section of your document:

 <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
   integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
   crossorigin=""/>

Include Leaflet JavaScript file after Leaflet’s CSS:

 <!-- Make sure you put this AFTER Leaflet's CSS -->
 <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"
   integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
   crossorigin=""></script>

并不是说在 R 中也不能这样做。但是,来自“R 文化”,我已经习惯了我拥有代码所依赖的每个包和数据的本地“硬拷贝”的感觉。然后,当我发布我的代码时(例如,当我发布一个 Shiny 应用程序时),所有必需的依赖项都会立即随它一起发布,因此它可以独立运行。 我理解服务器存储 space 方面的缺点,但我的感觉是这可能会更快但更不可靠。

我想知道的是我对 javascript 中在线采购及其权衡的理解是否正确,如果是这样,解决潜在缺点的最佳做法是什么。特别是:

Do I understand correctly that dependencies like https://unpkg.com/leaflet@1.7.1/dist/leaflet.js or https://unpkg.com/leaflet@1.7.1/dist/leaflet.css are reloaded every time I refresh the page?

没有。 HTTP 客户端执行 caching.

The page is therefore dependent on those links not breaking, right?

是的。 (其中“破坏”包括“被防火墙阻止”(对于中国用户来说是一个特殊问题,他们经常发现他们可以访问网站但 JS 不起作用,因为它托管在被防火墙阻止的地方)和“ CDN 服务器被恶意接管")

do people just live with the risk of links breaking down?

是的。风险是相对的。一般选择 CDN 是因为提供者值得信赖。


潜在的好处包括利用 edge servers 通过 CDN 更快地访问 JS,以及(至少对于流行的库)客户端可能已经缓存了数据,因为另一个站点使用了同一个图书馆。

您还使用 CDN 主机的带宽而不是您自己的带宽来为 JS 提供服务,这可以节省成本。

Do I understand correctly that dependencies like https://unpkg.com/leaflet@1.7.1/dist/leaflet.js or https://unpkg.com/leaflet@1.7.1/dist/leaflet.css are reloaded every time I refresh the page?

是也不是。这里重要的是缓存。浏览器会缓存已经加载的资源。因此,如果用户进入页面并反复点击刷新,他们只会下载这些资源一次,并且每次重新加载都将使用缓存的版本。因此 no 它们不会每次都重新加载。

但是,只要用户清除缓存或新用户进来时缓存中没有资源,就会下载文件。浏览器的缓存过期不是完全可预测的,因为它在很大程度上由用户控制。但是,如果用户今天访问并在下周使用相同的浏览器再次访问,他们的缓存中可能仍会保留该项目。但是,如果他们的缓存被刷新,或者他们使用不同的浏览器,或者不同的机器,或者访问的是完全不同的用户,那么 yes - 他们将再次加载资源。

The page is therefore dependent on those links not breaking, right? Or are there some inner mechanics I am not aware of that avoid this kind of wasteful reloading and risky dependency?

内部机制是从上面缓存的。但是,如果资源 link 由于某种原因被关闭,则该页面将无法使用它。这可能是因为:

  • link 的来源不再有效。
  • 源被防火墙或其他机制阻止,因此用户无法访问它。
  • 用户使用了一些阻止机制,例如广告拦截器或脚本拦截器扩展,这意味着他们已选择阻止对某些资源的请求。

在所有这些情况下,结果都是相似的:如果用户拥有所需资源的缓存副本,则他们可能可以访问页面的全部功能。否则,他们不能使用它们。不执行脚本文件,不应用样式表,不显示图片等

解决这些问题的方法各不相同:

  • 对于 non-working link,您需要寻找新的来源,甚至可能自己托管。
  • 对于被阻止的资源,您可能需要找到阻止机制可接受的托管站点。 Self-hosting 可能是一个选项。
  • 如果用户阻止了您的脚本,他们很可能需要取消阻止。尽管上述两种方法的组合也可能有效 - 在不以广告闻名的域上托管可能会避免被阻止,并且 self-hosting 也可能有效。至少在 uMatrix 的情况下——插件 默认 阻止页面外部的所有脚本(极少数例外)。如果脚本来自同一个域,那么 uMatrix 默认会允许它们。

If there are not, do people just live with the risk of links breaking down? Or is it best practice to keep a local copy of scripts like https://unpkg.com/leaflet@1.7.1/dist/leaflet.js and source them locally instead?

这里基本上有两种方法。每个都有自己的优点和缺点。快速细分是:

  • 您可以接受外部托管资源。

    • 优点:有几个大型内容分发网络 (CDN),例如 unpkg 或 jsdelivr。它们因其可靠性而被广泛使用。此外,一些图书馆可能会提供他们自己的 CDN - 例如,jQuery 就是这样做的。从 CDN 获取资源可以节省 you badwidth 和 space 但也可以提高加载速度。 CDN 的速度可能比您的托管服务更快。此外,对于广泛使用的图书馆,CDN 副本很可能会缓存在用户站点上,因为用户访问了与您使用相同 CDN 副本的另一个站点。
    • 缺点:它确实会让您依赖您无法控制的资源。大型 CDN 是可靠的,但如果发生任何事情,您仍然无法直接控制。如果您使用较小的 CDN(例如,库特定或其他),那么您没有关于其可靠性的数据。如果外部 link 死机,您的网站将无法运行,直到它被修复,这可能需要几天时间 - 您必须了解它,弄清楚发生了什么变化,希望如此寻找替代品 link,更新网站。如果找不到 drop-in 替代品,您可能需要进行更多更改。
  • 您可以自己托管资源。

    • 优点:您可以完全控制何时以及如何存储内容。您甚至可以以某种方式处理资源以帮助您的应用程序。可以缩小脚本,可以缩放图像并将其大小调整为几种不同的大小,以优化不同位置的显示(例如,图标、小图像和全尺寸图像)。
    • 缺点:占用更多space,占用更多带宽。此外,现在您必须管理所有这些资源并确保它们存在、可用等。

当然也可以混合使用。托管一些资源,从外部使用其他资源。取决于您希望对您的应用程序做什么以及您希望保留何种级别的控制权以及您希望付出多少额外的努力和成本。

综上所述,对于许多小型项目而言,选择哪条路径并不重要。如果您只使用少数几个库,那么是否无关紧要您可以从 CDN 使用它们或自己托管它们。只要选择了可靠的 CDN 提供商,中断的可能性就很小。如果您托管这些资源,它们很可能会占用几百 KB(如果那样的话)。

如果您的项目增长并且您拥有的依赖项列表开始变得越来越大,可能是时候进行评估并决定如何托管它们以及如何使用它们了。这个问题没有单一的答案,它可能取决于你已经拥有的东西。也许您的主机很少 space。或者您按下载的兆字节付费。在这种情况下,外部托管会更有意义。或者,也许您有适合自己的强大存储选项,并且您有信心可以确保应用程序的可用性,在这种情况下,self-hosting 可能更可取