将javascript放在一个.js文件中或将其分解为多个.js文件?

问题描述 投票:45回答:10

我的Web应用程序使用jQuery和一些jQuery插件(例如验证,自动完成)。我想知道是否应该将它们粘贴到一个.js文件中,以便可以更轻松地缓存它,或者将它们分解为单独的文件,并且只包含我需要的给定页面。

我还要提一下,我关注的不仅是下载.js文件所需的时间,还包括根据加载的.js文件的内容减慢页面的速度。例如,添加自动完成插件往往会使我的基本测试的响应时间缩短100ms,即使在缓存时也是如此。我的猜测是它必须扫描DOM中导致此延迟的元素。

javascript
10个回答
45
投票

我认为这取决于他们改变的频率。我们来看这个例子:

  • JQuery:每年更换一次
  • 第三方插件:每6个月更换一次
  • 您的自定义代码:每周更改一次

如果您的自定义代码仅代表总代码的10%,则您不希望用户每周下载其他90%的代码。你会分成至少2个js:JQuery +插件和你的自定义代码。现在,如果您的自定义代码占完整大小的90%,那么将所有内容放在一个文件中会更有意义。

在选择如何组合JS文件(和CSS相同)时,我平衡:

  • 文件的相对大小
  • 预期的更新数量

0
投票

我基本上已经达到了将整个Web应用程序减少到3个文件的程度。

  • vendor.js
  • app.js
  • app.css

供应商很整洁,因为它也有各种风格。即我将我的所有供应商CSS转换为缩小的CSS然后我将其转换为javascript并将其包含在vendor.js文件中。那之后它也被改变了。

因为我的供应商的东西不经常更新,一旦投入生产,这是非常罕见的。当它确实更新时,我只需将其重命名为vendor_1.0.0.js。

还有这些文件的缩小版本。在开发中我加载未分类的版本,在生产中我加载缩小版本。

我用gulp来处理所有这些。使这成为可能的主要插件是......

  • 一饮而尽,包括
  • 一饮而尽,css2js
  • 一饮而尽,CONCAT
  • 一饮而尽,CSSO
  • 吞掉-HTML到JS
  • 一饮而尽模式
  • 一饮而尽,重命名
  • 一饮而尽,丑化
  • 节点SASS波浪线进口商

现在这也包括我的图像,因为我使用sass并且我有一个sass函数,它将图像编译成我的css表中的data-urls。

function sassFunctions(options) {
options = options || {};
options.base = options.base || process.cwd();

var fs = require('fs');
var path = require('path');
var types = require('node-sass').types;

var funcs = {};

funcs['inline-image($file)'] = function (file, done) {
    var file = path.resolve(options.base, file.getValue());
    var ext = file.split('.').pop();
    fs.readFile(file, function (err, data) {
        if (err) return done(err);
        data = new Buffer(data);
        data = data.toString('base64');
        data = 'url(data:image/' + ext + ';base64,' + data + ')';
        data = types.String(data);
        done(data);
    });
};

return funcs;
}

所以我的app.css将把我的所有应用程序图像都放在css中,我可以将图像添加到我想要的任何一种样式中。通常我会为独特的图像创建类,如果我希望它拥有该图像,我将只使用该类。我完全避免使用Image标签。

另外,使用html到js插件我将我的所有html编译成js文件到一个模板对象,通过html文件的路径进行哈希,即'html \ templates \ header.html'然后使用类似敲门的东西我可以数据 - 将该html绑定到一个元素或多个元素。

最终结果是我最终得到了一个完整的Web应用程序,该应用程序从一个“index.html”中旋转出来但没有任何内容,但是:

<html>
<head>
    <script src="dst\vendor.js"></script>
    <script src="dst\app.css"></script>
    <script src="dst\app.js"></script>
</head>
<body id="body">
    <xyz-app params="//xyz.com/api/v1"></xyz-app>
    <script>
        ko.applyBindings(document.getTagById("body"));
    </script>
</body>
</html>

这将启动我的组件“xyz-app”,这是整个应用程序,它没有任何服务器端事件。它不是在PHP,DotNet Core MVC,MVC或任何其他东西上运行。它只是用Gulp这样的构建系统管理的基本html,它需要数据的所有内容都是其余的api。

  • 身份验证 - >休息Api
  • 产品 - >休息Api
  • 搜索 - > Google Compute Engine(python apis用于索引从rest apis返回的内容)。

所以我从来没有从服务器回来的任何html(只是静态文件,这是疯狂的快速)。并且只有3个文件可以缓存而不是index.html本身。 Web服务器支持默认文档(index.html),因此您只需在URL中看到“blah.com”以及用于维护状态的任何查询字符串或散列片段(用于为URL添加书签的路由等)。

疯狂快速,所有正在等待运行它的JS引擎。

搜索优化比较棘手。这只是思考事物的另一种方式。即你有谷歌抓取你的api,而不是你的物理网站,你告诉谷歌如何到达你的网站每个结果。

所以说你有一个产品页面为ABC Thing,产品ID为129.谷歌将抓取你的产品api来浏览你的所有产品并为它们编制索引。在那里你api返回一个url,结果告诉谷歌如何在网站上获得该产品。即“http://blah#products/129”。

因此,当用户搜索“ABC事物”时,他们会看到列表并单击它将它们带到“http://blah#products/129”。

我认为搜索引擎需要开始像这样聪明,这是未来的imo。

我喜欢建立这样的网站,因为它摆脱了所有后端的复杂性。您不需要RAZOR,PHP,Java或ASPX Web表单,也不需要摆脱整个堆栈....您只需要编写一个休息api的方法(WebApi2,Java Spring,或者w / e等等)。

这将Web设计分为UI工程,后端工程和设计,并在它们之间创建一个干净的分离。您可以让一个UX团队构建整个应用程序,一个架构团队完成所有其他的api工作,不需要这样的完整堆栈开发人员。

安全性也不是问题,因为您可以在ajax请求上传递凭据,如果您的所有内容都在同一个域中,您只需在根域和presto上创建身份验证cookie(自动,无缝SSO,其余所有api) 。

更不用说服务器场设置有多简单了。负载平衡需求要少得多。交通能力要高很多。与整个网站相比,在负载均衡器上集中rest api服务器更容易。

只需设置1个nginx反向代理服务器即可提供索引.html,并将api请求定向到4个其他api服务器之一。

  • Fire Server 1
  • Fire Server 2
  • Fire Server 3
  • Fire Server 4

你的sql box(复制)只是从4个其他api服务器(如果可能的话都使用SSD)进行负载平衡

  • Sql Box 1
  • Sql Box 2

您的所有服务器都可以在没有公共IP的内部网络上,只需将反向代理服务器公开,所有请求都会进入。

您可以在循环DNS上对反向代理服务器进行负载平衡。

这意味着您只需要1个SSL证书,因为它是一个公共域。

如果您正在使用Google Compute Engine进行搜索和搜索引擎优化,那么它就在云中,因此无需担心,只需$。


30
投票

常见但相关的答案:

这取决于项目。

如果您有一个相当有限的网站,其中大部分功能在网站的多个部分重复使用,那么将所有脚本放在一个文件中是有意义的。

然而,在我参与过的几个大型Web项目中,将通用站点范围的功能放在一个文件中并将更多特定于部分的功能放入自己的文件中更有意义。 (我们在这里讨论大型脚本文件,针对几个不同的Web应用程序的行为,所有这些都在同一个域下提供。)

将脚本拆分为单独文件的好处是,您不必为用户提供不使用的不必要内容和带宽。 (例如,如果他们从不访问网站上的“App A”,他们将永远不需要“App A”部分的100K脚本。但他们需要通用的站点范围功能。)

将脚本保存在一个文件中的好处是简单。服务器上的点击次数减少。用户下载次数减少。

像往常一样,YMMV。没有严格的规则。根据用户的用途,根据项目的结构,为用户做最有意义的事情。


2
投票

如果每个页面都需要这些文件,请将它们放在一个文件中。这将减少HTTP请求的数量,并将改善响应时间(对于大量访问)。

有关其他提示,请参阅Yahoo best practice


2
投票

我非常赞同bigmattyh说的,它确实依赖。

作为一般规则,我尝试尽可能地聚合脚本文件,但如果你有一些脚本仅用于网站的一些区域,特别是那些在加载时执行大型DOM遍历的脚本,那么它是有意义的将它们留在单独的文件中。 例如如果您只在联系页面上使用验证,为什么要在主页上加载?

顺便说一句,你有时可以将这些文件隐藏到插页式页面,其中没有其他内容正在进行,所以当用户登陆需要它的其他非常繁重的页面时,它应该已经缓存 - 谨慎使用 - 但可以当你有人对你进行基准测试时,这是一个方便的技巧。

因此,尽可能少的脚本文件,在合理范围内。

如果你要发送一个100K的整体块,但只有20%的它用于80%的页面,可以考虑拆分它。


1
投票

如果人们要访问您网站中的多个页面,最好将它们全部放在一个文件中,以便缓存它们。他们会在前面采取一个打击,但这将是他们在您的网站上花费的整个时间。


1
投票

在一天结束时,这取决于你。

但是,每个网页包含的信息越少,终端查看器下载的速度就越快。

如果您只包含每个页面所需的js文件,那么您的网站似乎更有效率和简化


1
投票

如果您喜欢用于开发的单独文件中的代码,您可以始终编写一个快速脚本,以便在缩小之前将它们连接到单个文件中。

其他海报已经指出,一个大文件更适合减少HTTP请求。


1
投票

这在很大程度上取决于用户与您网站的互动方式。

一些问题供您考虑:

  • 您的第一页加载速度非常快有多重要?
  • 用户通常将大部分时间花在网站的不同部分,并使用功能子集吗?
  • 您是否需要在页面准备就绪时准备好所有脚本,或者可以在页面加载后通过将<script>元素插入页面来加载一些脚本?

如果您真的想要提高性能,那么很好地了解用户如何使用您的网站以及您希望优化的内容是一个好主意。

但是,我的默认方法是将我的所有javascript连接并缩小为一个文件。 jQuery和jQuery.ui很小,开销很低。如果您使用的插件对页面加载时间有100ms的影响,则可能出现问题。

要检查的一些事项:

  • 是否在HTTP服务器上启用了gzipping?
  • 您是否在部署过程中生成具有唯一名称的静态文件?
  • 您是否正在提供永不停止缓存过期的静态文件?
  • 您是在页面顶部包含CSS还是在底部包含脚本?
  • 是否有更好的(更小,更快)的jQuery插件可以做同样的事情?

0
投票

我也认为你应该采用单文件路线,正如其他人所建议的那样。但是,仅仅通过包含在您的大型js文件中,插件就会占用周期:

在执行昂贵的操作之前,请使用一些检查以确保您甚至在需要操作的页面上。也许您可以在运行自动完成插件之前检测dom节点的存在(或不存在),并且只在必要时初始化插件。没有必要在永远不需要某些功能的页面或部分上浪费dom遍历的开销。

在昂贵的代码块之前的简单条件将为您提供您所决定的两种方法的好处。

© www.soinside.com 2019 - 2024. All rights reserved.