优化javascript和css请求

时间:2010-11-03 17:51:40

标签: javascript optimization minify

我需要优化几个现有网站的加载速度。我遇到的一个问题是每页请求的数量。这些网站有7种或更多不同类型的页面,它们应该加载不同的css和javascripts集合,因为它们包含不同的小部件或功能。目前,每个小部件或功能都有自己的javascript文件。我打算合并并缩小文件以减少请求。

  1. 将每种类型页面上所需的所有javascripts组合并缩小为一个文件(并为css执行相同操作)是否是一个好习惯?例如
    • 主页只有一个homepage.js
    • 列表页面只有listing.js
    • 详情页面只有detail.js
  2. 最好只合并那些一直使用的文件吗?例如
    • jquery.js + jquery.cookie.js + common.js
    • list.js + paging.js + favorite.js
    • detail.js + favorite.js
  3. 如果所有javascripts都有一个文件应该加载到头部,一个文件应该加载到主体末端的所有javascripts,例如:
    • init.js转到<head>do.js转到<body>
  4. 如果用户具有特定权限,那么如果有一个常用功能文件和一个用于管理功能的文件呢?
  5. 是否有任何策略如何在1.,2.,3。和4之间取得平衡。?
  6. 页面的javascript和css请求的推荐量是多少?
  7. 我正在考虑大型网站a.k.a.门户网站或社交网络。

    (顺便说一下,有些图书馆要求我无法控制,例如TinyMCE或谷歌地图)。

11 个答案:

答案 0 :(得分:10)

通常您可以使用以下模式:

  1. main.js - 捆绑多个页面使用的所有脚本 在网站上。
  2. page.js - 特定于该页面的所有js。这意味着捆绑     一起js的所有小部件     页。
  3. 通过这种做法,您可以在每个页面上为您的JS提供 2个请求,并在JS中获得清晰的分离/结构。对于除第一个页面之外的所有页面,它只是一个请求,因为 main.js 将被缓存。

    您也可以对CSS使用相同的原则。这是有效的,但正如另一个答案所提到的,你实际上可以进一步采取这种做法并将所有内容捆绑在1 js中。它的偏好或风格。我喜欢将它分解为2,因为它让我的事情符合逻辑。

    确保以下内容:

    1. 您的JS命名空间当您将它们捆绑在一起时,您可能会遇到错误。
    2. 帮助您的网页,并将其推送到页面底部。

    3. 修改 我想我会更新答案,回答你的一些观点。

      第2点:仅合并那些一直使用的文件会更好吗?

      答:就个人而言,我不这么认为。如果您正在为一起使用的所有文件提供服务,那么它们属于哪个组或者它们如何登陆页面无关紧要。这是因为我们将JS文件组合在一起以减少HTTP请求的数量。

      一旦你的JS结合起来&amp;缩小的在PROD中,您不希望调试或理解它。因此,将逻辑相关的JS文件绑定在一起是一个有争议的问题。它在您的DEV环境中,您希望将所有这些逻辑相关的代码文件放在一起。

      第3点:如果所有javascripts都有一个文件应该加载到头部,一个文件应该加载到主体末端的所有javascripts呢?

      Ans:在某些情况下,您某某被迫在 HEAD 中注入JS。理想情况下,您不应该这样做,因为 SCRIPT 标记本质上是阻止的。因此,除非您确实需要,否则将所有JS(1个或多个文件)放在 BODY 标记的末尾。

      第4点:如果用户具有特定权限,那么为常用功能设置一个文件,为管理功能设置一个文件?

      Ans:这似乎是分割JS代码的合理方法。根据用户权限,您可以分叉JS代码。

      第6点:页面的javascript和css请求数量是多少?

      答:这是一个非常主观的问题。这取决于你正在建设什么。如果您担心在页面加载时加载过多的JS,您可以随时拆分它并使用按需 SCRIPT 注入方法来分割负载。

答案 1 :(得分:3)

正如其他人所说的那样,将多用于一页的脚本放在一起main.js然后如果有特定于页面的脚本:home.js,{{1}等等。

我真正想要添加的唯一内容是,对于像jQuery这样的库,你应该使用Google的Libraries API之类的东西。

  • 如果您的用户访问了其他网站,该网站也使用Google的服务器作为库,那么他们将使用已准备好的缓存到达!赢了!
  • 我打算在这里走出困境并打赌Google的服务器比你的服务器快。
  • 由于请求将转发到不同的服务器,因此客户端可以同时处理对Google服务器的两个请求(例如:jQuery和jQuery UI)以及对服务器的两个请求(main.js&amp; main.css)< / LI>

哦,最后 - 别忘了在服务器上打开gzipping!

答案 2 :(得分:2)

根据您的开发环境,您可以考虑自动执行该过程。这是一个相当多的工作,但从长远来看,我发现它是值得的。你将如何做到这一点在很大程度上取决于你的项目和环境。有几个选项,但我会解释(高级别)我们做了什么。

在我们的案例中,我们有几个基于ASP.NET的网站。我编写了一个ASP.NET控件,它只包含一个静态依赖项列表 - CSS和JavaScript。每个页面列出了它需要的内容。我们有一些页面有7或8个JS依赖项和4或5个CSS依赖项,具体取决于正在使用的共享库/控件。第一次加载页面时,我创建了一个新的后台工作线程来评估所有静态资源,将它们组合成一个文件(1个用于CSS,1个用于JS),然后使用Yahoo Yui Compressor对它们进行缩小。 (可以同时执行JS和CSS)。然后我将文件输出到一个新的“合并”或“优化”目录。

下次有人加载该页面时,ASP.NET控件会看到资源的优化版本,并加载该资源而不是10-12个其他资源的列表。

此外,它设计为仅在项目以“RELEASE”模式运行时加载优化资源(与Visual Studio中的DEBUG模式相反)。这很棒,因为我们可以将不同的类,页面,控件等分开来进行组织(以及跨项目共享),但我们仍然可以获得优化加载的好处。这是一个完全透明的过程,无需额外注意(一旦工作)。如果在需要验证/复制生产中的错误的情况下在URL的查询字符串中指定了“debug = true”,我们甚至返回并添加了加载非优化资源的条件。

答案 3 :(得分:2)

我认为有必要执行以下优化:

  • 服务器端:

    1. 如果还没有使用js和css文件,请使用像nginx或lighttpd这样的快速网络服务器。
    2. 为文件启用缓存和gziping。
  • 客户端:

    1. 将所有常见的js文件放入缩小的文件中并启用硬核缓存。如果您的页面在“onload”之前不需要运行它们,则可以动态地向页面添加一个页面。它会加快装载速度。
    2. 将每页代码放入单独的文件中,如果没有必要执行smth。在onload事件之前,动态添加它。
    3. 如果它的css超过几千克,只需将其合并为一个。否则,您应该将其拆分为常见和每页样式。
    4. 如果您需要在客户端获得最佳性能,请将常用css文件放入适用于所有页面的常见样式。仅在页面上加载您需要的规则,它将加快渲染速度。
    5. 将js和css缩小到一起的最简单方法是使用YUI Compress。如果你想要更好的加速,你可以删除所有的evals和其他“动态”代码并使用Google Closure Compiler。

如果它没有帮助,那么一切都很糟糕,你需要更多服务器来提供js和css文件。

答案 4 :(得分:1)

一如既往:这取决于。特定于页面的文件越大,将它们分开就越有意义。如果它们不大(想想10 kB缩小),那么加入,最小化和压缩它们可能更有意义,因此你可以保存一些请求并依赖缓存。

答案 5 :(得分:1)

在决定如何组合JS和CSS文件时,需要考虑很多事情。

  1. 您是否使用CDN来提供资源?如果这样做,您可能会在每页上获得更多请求,否则就会失败。多次下载的最大性能杀手是延迟。 CND将降低您的延迟。

  2. 您的目标浏览器是什么?如果你是观众主要使用IE8 +,FF3和WebKit浏览器,它们允许6个以上的同时连接到给定的子域,你可以获得更多的CSS文件(但不是JS)。更重要的是,在现代浏览器的情况下,你实际上希望避免将所有CSS组合成一个大文件,因为即使下载1个大文件所花费的总时间也会比下载6个较小文件的时间要短。按顺序排列相同的sumed大小,您可以同时下载多个文件,下载6个较小的文件将在下载一个大文件之前完成(因为您的用户不会单独使用CSS文件下载带宽)。

    < / LI>
  3. 您在同一个域中投放了多少其他资产。图像,Flash等都将计入每个子域的浏览器的连接限制。如果可能,您希望将它们移动到单独的子域。

  4. 您是否非常依赖缓存?决定如何组合文件总是在连接数和缓存之间进行权衡。如果您将一个页面上的所有文件合并,并且其他页面上使用了90%的文件,那么您的用户将被迫在网站的每个页面上重新下载合并文件,因为最近10%不断变化。

  5. 您使用域拆分吗?如果你这样做,再次使用CSS,如果你从多个子域提供文件,你可以获得更多文件。更多可用连接 - 更快下载。

  6. 在网站生效后,您多久更新一次网站。如果你每隔几天做一次修改CSS / JS文件的补丁,那么你肯定希望避免将所有东西合并到一个文件中,因为它会破坏缓存。

  7. 总的来说,我的通用建议,不知道你的情况的所有事实,是将所有页面上使用的文件(jquery,jquery-ui等)合并到一个文件中,之后如果有多个小部件在所有页面或几乎所有页面上使用的都将这些组合在一起。然后组合对页面唯一的文件,或仅在一两页上用于另一组的文件。这应该给你最大的收益,而不必求助于计算每个文件的大小,点击每页上的数字和用户在网站上的预计标准路径,以实现最终的组合策略(是的,我必须做所有以上为非常大的网站。)

    此外,还有一条与您的问题无关的评论,但关于您提到的内容。避免将Javascript文件添加到文档的头部。 Javascript下载,解析和执行将阻止浏览器中的所有其他激活(我相信IE9除外),因此您希望尽可能早地将CSS包含在页面中,并且您希望将JavaScripts包括在内可能,在关闭身体标签之前,如果可能的话。

    还有一条评论,如果您对从您的网站获得最佳性能如此感兴趣,我建议您查看一些更加模糊的优化技术,例如在页面完成后为下一页预加载资源,或者可能更加模糊,比如使用Comet只在需要时提供所需的javascript文件(或js代码块)。

答案 6 :(得分:1)

假设它在apache上,如果没有,请忽略答案:)

我自己还没试过,但你可能想看一下谷歌的mod_pagespeed

您想要手动执行的功能很多,请查看here

答案 7 :(得分:1)

我正在同一个区域开展一个非常大的项目,该项目有很多样式定义和不同的JS-Scripts,用于项目中的不同任务。该网站有同样的问题=&gt;请求太多了。基本上,我们已经实现了如下修复:

  • 应用程序的渲染组件会记住每个必要的js包含文件并将它们放在一起,在渲染过程结束时缩小。客户端通过缓存标头和HTTP ETag
  • 缓存生成的输出
  • 给定应用程序的样式表相互依赖。有一个巨大的基本样式表关注基本格式和页面对象(大小,浮点等),它们通过基本配色方案进行扩展,可以通过自定义覆盖样式表扩展,以便为不同的客户启用自定义颜色,布局,图标等.... 所有这些样式表放在一起可以超过例如300k的大小,因为有很多图标作为背景图像...每个图标有两个定义 - 一个作为IE6的GIF和一个用于所有其他浏览器的PNG图像。

在这里,我们来到问题 ..起初,Stylesheets使用了 @import 规则。我们编写了一个包装器脚本,它解析了所有样式并将它们组合成一个文件。结果是,当样式表的大小超过250-270k时,所有IE版本都破坏了布局。格式化看起来像垃圾。所以我们改回来了,所以我们的包装器只将两个样式表放在一起,并将所有其他表单作为 @import 规则写在顶部。此外,包装器使用缓存头和ETag。

这解决了我们的装载问题。

此致

(请不要咆哮我,因为我们有300k样式表。相信我,它只是出于各种原因。:D)

答案 8 :(得分:1)

您应该做的一件事是优化.htaccess文件以正确压缩和缓存文件:

# compress text, html, javascript, css, xml:  
AddOutputFilterByType DEFLATE text/plain  
AddOutputFilterByType DEFLATE text/html  
AddOutputFilterByType DEFLATE text/xml  
AddOutputFilterByType DEFLATE text/css  
AddOutputFilterByType DEFLATE application/xml  
AddOutputFilterByType DEFLATE application/xhtml+xml  
AddOutputFilterByType DEFLATE application/rss+xml  
AddOutputFilterByType DEFLATE application/javascript  
AddOutputFilterByType DEFLATE application/x-javascript

# cache media files
<FilesMatch ".(flv|gif|jpg|jpeg|png|ico|swf|js|css|pdf)$">  
Header set Cache-Control "max-age=2592000"  
</FilesMatch> 

答案 9 :(得分:0)

通常,我连接并缩小网站上的所有脚本并仅提供两个请求 - 一个用于JS,一个用于CSS。该规则的例外情况是,如果某个页面具有仅在那里运行的大小非常大的脚本 - 在这种情况下,它应该单独加载。

将所有JS脚本加载到页面底部,以防止脚本阻止页面加载。

答案 10 :(得分:0)

缩小和组合JS只是战斗的一部分。文件的放置更重要。 Obtrustive javascript应该是页面上最后一个加载的东西,因为它将暂停页面加载,直到它完成加载。

整合你可以做的事情,但命名空间和使用闭包可能有助于保持DOM清理你的函数调用,直到需要它们为止。

有些工具可以测试页面加载速度。

Firebug中的Net Panel以及Yslow是可用于帮助调试页面加载速度的便捷工具。

祝你好运,快乐的javascripting!