两次包含同一个 JavaScript 库有什么危险?
我正在使用的 Web 应用程序之一由许多部分 HTML 文件组成。如果部分需要 JavaScript 库(例如 YUI),则 YUI 库将包含在部分中。
当在运行时组合部分时,生成的 HTML 通常会多次包含 YUI 库。
<html>
...
<script type="text/javascript" src="/js/yahoo/yahoo-min.js"></script>
...
<script type="text/javascript" src="/js/yahoo/yahoo-min.js"></script>
...
<script type="text/javascript" src="/js/yahoo/yahoo-min.js"></script>
...
</html>
我多次看到包含 jQuery 的奇怪行为,尤其是在使用 AJAX 时。具体来说,为什么多次包含同一个 JavaScript 库是一个坏主意?为什么它只是有时会引起问题?
One of the webapps I'm working in is made up of many partial HTML files. If the partial requires a JavaScript library such as YUI, the YUI library is included in the partial.
When the partials are combined at runtime, the resulting HTML often includes the YUI library several times.
<html>
...
<script type="text/javascript" src="/js/yahoo/yahoo-min.js"></script>
...
<script type="text/javascript" src="/js/yahoo/yahoo-min.js"></script>
...
<script type="text/javascript" src="/js/yahoo/yahoo-min.js"></script>
...
</html>
I've seen strange behavior from including jQuery several times, especially when using AJAX. Why, specifically, is including the same JavaScript library more than once a bad idea? Why does it only sometimes cause problems?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
根据库的不同,多次包含它可能会产生不良影响。
可以这样想,如果您有一个将单击事件绑定到按钮的脚本,并且您包含该脚本两次,则单击按钮时这些操作将运行两次。
您可以编写一个简单的函数,调用该函数来加载脚本并让它跟踪已加载的文件。或者,我确信您可以使用预先存在的 JS 加载器(例如 LabJS)并对其进行修改。
Depending on the library, including it more than once could have undesired effects.
Think of it like this, if you have a script that binds a click event to a button, and you include that script twice, those actions will be ran twice when the button is clicked.
You could write a simple function that you call to load a script and have it keep track of files that have already been loaded. Or, I'm sure you could probably use a pre-existing JS loader such as LabJS and modify it.
您应该采用我在检查 HTML5 Boilerplate 的源代码时学到的方法:
我不使用 YUI,因此替换
!window.YAHOO
与全局 YUI 使用的任何内容。如果该库尚不存在于全局范围内,则此方法只会加载该库。
You should take an approach I learned examining the source of HTML5 Boilerplate:
I don't use YUI, so replace
!window.YAHOO
with whatever global YUI uses.This approach will only load the library if it does not yet exist in the global scope.
浏览器将缓存该文件,仅下载一次。然而,它将被执行多次。因此,性能影响可以忽略不计,但正确性影响可能不可忽略。
The browser will cache the file, downloading it only once. It will be executed more than once however. So the performance impact is negligible, but the correctness impact might not be.
它每次都会执行。根据文件的不同,这可能是不受欢迎的。例如,如果文件包含
alert("hello")
,则每次引用该文件时都会显示警报框,而您可能希望只显示一次。编写安全库:
如果您只想一次性执行,则可以按以下方法解决此问题。假设您正在编写一个库
foobar.js
,它导出一个全局foobar
:您可以确保该文件的任何重复执行都变为无操作,使用像这样的代码:
更现代的方法是使用 相反,JavaScript 模块。 JavaScript 模块最多只执行一次:
使用不安全的库:
如果您无法修改库的源代码,并且您确定它不安全,那么有一种方法可以解决它,即仅加载库一次。创建一个全局变量并每次使用它来检查脚本是否已加载。您必须将全局设置为真实的自己。
It gets executed each time. Dependending on the file, this may be undesirable. For instance, if the file contains
alert("hello")
, it will display the alert box for every time the file is referenced, and you may have intended for it to be only displayed once.Writing safe libraries:
Here's how you work around it if you only want a one-time execution. Let's say you're writing a library
foobar.js
, which exports one global,foobar
:You could make sure that any repeat executions of the file become no-ops, using code like this:
A more modern approach would be to use JavaScript modules instead. JavaScript modules are only ever executed at most once:
Using unsafe libraries:
If you can't modify the source code of the library, and you've determined it's unsafe, here's one way to work around it to load the library only once. Create a global and use it each time to check if the script has already been loaded. You'll have to set the global to true yourself.