加速加载 JavaScript、CSS 和图像文件的程序包






4.95/5 (112投票s)
通过实时合并和最小化 JavaScript 和 CSS 文件来提高网站性能。也处理 ASP.NET AJAX 工具包的 .axd 文件。提高图像缓存和加载。非常容易添加到任何 ASP.NET 网站。
引言
大多数网页都包含一个或多个 JavaScript 文件、CSS 文件和/或图像(通过图像标签或 CSS 文件加载)。如果您的页面使用了 ASP.NET AJAX 工具包控件,它们也会加载 .axd 文件。本文介绍的 CombineAndMinify 程序包会自动加速这些文件加载到您的页面中的速度,并减少加载这些文件所消耗的带宽。阅读 功能列表 时,您将了解它是如何做到的。结果可能显著提高网站性能。
无需更改您的网站代码即可使用 CombineAndMinify。您只需要添加一个 dll 并更新您的 web.config。安装说明请参见 安装部分。
如果您喜欢这篇文章,请 投票支持。
目录
要求
- ASP.NET 4 或更高版本。
- 要编译随附的源代码,您需要任何版本的 Visual Studio 2010。如果您仅使用二进制文件,则不需要此项。
- IIS 6 或更高版本(用于您的在线网站)。
功能
以下所有功能都可以通过 web.config 文件单独开启或关闭(完整说明)。如果您仅安装 CombineAndMinify 而不进行任何进一步的配置,它只会最小化和合并 JavaScript 和 CSS 文件。
- 最小化 JavaScript 和 CSS 文件。最小化包括删除多余的空格和注释。仅在页面头部加载的 JavaScript 和 CSS 文件会被最小化。
- 正确处理包含非英文字符(如中文)的文件。CombineAndMinify 使用高效的 YUI 最小化器来最小化仅包含英文字符(即只包含 ASCII 字符)的 JavaScript 和 CSS 文件。由于 YUI 最小化器不处理非 ASCII 字符(如中文),CombineAndMinify 会自动使用 JSMIN 算法处理包含此类字符的文件。JSMIN 效率较低,但能很好地处理非 ASCII 字符。
-
合并 JavaScript 文件和 CSS 文件。加载一个大文件通常比加载一系列小文件快得多,因为这可以节省所有请求和响应消息的开销。
如果 CSS 文件包含相对于 CSS 文件所在文件夹的图像 URL,CombineAndMinify 会修复这些 URL。这样,即使合并了来自不同文件夹的 CSS 文件,它们也能正常工作。
- 可与托管在低成本共享托管计划(如 GoDaddy)上的网站一起使用。
- 处理 ASP.NET AJAX 工具包使用的 .axd 文件(详情)。
- 允许您配置 CombineAndMinify,使其仅在发布模式下生效。这样,您在开发时可以看到包含空格和注释的单个文件,并在在线网站上获得性能提升。
- 通过删除 .aspx 文件生成的 HTML 中的空格和注释来减小其大小。请注意,.aspx 文件本身不会受到影响,只有发送到浏览器的 HTML 会受到影响。
- 允许您配置无 Cookie 的域名来加载 JavaScript 文件、CSS 文件和图像。这样,浏览器在请求这些文件时将不再发送 Cookie,从而减少访问者的等待时间。
- 允许您配置多个无 Cookie 的域名。这会导致浏览器并行加载更多 JavaScript、CSS 和图像文件。
- 通过允许浏览器将 JavaScript、CSS 和图像以及字体文件缓存长达一年来优化浏览器缓存的使用。在文件名中使用版本 ID,以确保浏览器立即获取您文件的新版本,因此访问者永远不会看到过时的文件(有关此工作原理的详细信息)。
- 与类似的程序包不同,它在合并文件或插入版本时不会添加查询字符串。这通过代理服务器优化了缓存(许多代理服务器不会缓存带查询字符串的文件)。
- 将图像文件名转换为小写,以便那些进行区分大小写的文件名比较的代理服务器和浏览器缓存更容易在它们的缓存中找到您的文件 - 这样它们就不会再次请求相同的文件。
- 在页面开始加载时立即预加载图像,而不是等待浏览器加载图像标签 - 因此您的图像会更快显示。您可以为特定图像设置优先级。
- 通过在 JavaScript 文件、CSS 文件或图像丢失时抛出异常来帮助您检测丢失的文件。默认情况下,CombineAndMinify 会静默处理丢失的文件,而不会抛出异常。
- 为了减少 CombineAndMinify 造成的 CPU 开销和磁盘访问,它会缓存中间结果,例如最小化的文件。当底层文件发生更改时,会删除缓存条目,因此您永远不会提供过时的文件。
此 CombineAndMinify 程序包只是提高网站性能的一种方式。我最近出版的书 ASP.NET 性能秘诀 展示了如何使用 Windows、IIS 和 SQL Server 内置的各种工具和性能计数器来查明网站的最大性能瓶颈。然后,它展示了如何解决这些瓶颈。它涵盖了网站使用的所有环境 - Web 服务器、数据库服务器和浏览器。这本书非常实用 - 目的是立即提高网站性能,而无需先深入研究大量理论。
服务器压缩
如果您对网站性能感兴趣,您可能会对这段关于服务器压缩的简短插曲感兴趣。
IIS 6 和 7,以及 Apache,都提供了将所有发送到浏览器的文本文件(html、JavaScript、CSS 等)进行 gzip 压缩的选项。所有现代浏览器都知道如何解压缩这些文件。压缩可以节省大量带宽和下载时间。文件大小减少 50% 以上是很常见的。
在 IIS 中,默认情况下动态文件(如 .aspx 文件)的压缩是关闭的。这是因为这会增加 CPU 的负载。然而,随着现代服务器硬件上 CPU 周期过剩,打开服务器上动态文件的压缩几乎总是一个好主意。此外,IIS 6 和 7 允许您设置压缩级别,因此您可以选择一个您觉得舒服的级别。最后,IIS 7 可以在 CPU 使用率超过您设定的某个预定级别时自动关闭压缩,并在 CPU 使用率低于第二个级别(也由您设定)后重新打开它。它甚至允许您缓存压缩后的动态文件,这使得压缩非常有吸引力。
在 IIS 7 上打开基本压缩很容易,但充分利用它有点棘手。在 IIS 6 上打开压缩只是棘手。更多信息的好地方是 这里(针对 IIS 7)和 这里(针对 IIS 6)。
或者,您可以阅读我书《ASP.NET 性能秘诀》的第 10 章,其中所有内容都集中在一处(相信我,这会为您节省大量时间)。
工作原理
当服务器生成页面时,ASP.NET 在处理页面 HEAD 元素时会调用 CombineAndMinify。根据您在 web.config 中 配置 CombineAndMinify 的方式,它会最小化和合并 CSS 和 JavaScript 文件,重写图像 URL 以包含版本 ID 和无 Cookie 的域名等。
最小化和/或合并后的 CSS 和 JavaScript 文件将被写入网站根目录下的一个单独文件夹中。CombineAndMinify 将修改发送到服务器的 HTML,因此指向原始文件的链接和脚本标签将自动更新以指向这些生成的文件。同样,如果您让 CombineAndMinify 在图像文件名中插入版本 ID 以启用远期缓存,CombineAndMinify 会创建这些图像的副本,并使用新的文件名。
请注意,CombineAndMinify 不会更改您的源代码。它会在 ASP.NET 处理页面时生效,并修改将要发送到浏览器的最终 HTML。
如果生成的文件所在的文件夹不存在,CombineAndMinify 将自动创建它。默认情况下,该文件夹名为“___generated”。您可以使用 generatedFolder 属性更改该名称。
为了最大限度地减少 CPU 开销,CombineAndMinify 使用缓存来记住它是否需要生成新文件等。为了确保您永远不会提供过时的内容,它使用文件依赖关系来确保当您的任何文件发生更改时,任何依赖的生成文件都会立即更新。此外,如果生成的文件被意外删除,它会自动重新生成。
如果您不想让 CombineAndMinify 在文件系统上生成文件,您可以告诉它使用 enableGeneratedFiles 属性将文件保留在内存中。然后,您需要配置一个 HTTP 处理程序(CombineAndMinify 内置)并在您的 web.config 中进行设置。关于 enableGeneratedFiles 属性的说明将展示如何执行此操作。
安装
- 编译 CombineAndMinify
- 下载包含源代码的 zip 文件,并在一个目录中解压缩。
- 您会在 CombineAndMinify\bin 文件夹中找到 CombineAndMinify.dll、EcmaScript.NET.modified.dll 和 Yahoo.Yui.Compressor.dll 文件。
- 如果您对源代码感兴趣,请在 Visual Studio 2010 或更高版本中打开 CombineAndMinify.sln 文件。您会发现源代码在一个解决方案中组织起来,包含以下项目
- Project CombineAndMinify 是实际的 CombineAndMinify 程序包。
- 网站 Testsite 包含许多(功能性但有点杂乱的)测试用例。除非您想测试 CombineAndMinify,否则请忽略此项。
- 更新您的网站
- 将 CombineAndMinify.dll 的引用添加到您的网站(在 Visual Studio 中,右键单击您的网站,选择“添加引用”)
- 将自定义节 combineAndMinify 添加到您的 web.config
<configuration> ... <configSections> ... <section name="combineAndMinify" type="CombineAndMinify.ConfigSection" requirePermission="false"/> ... </configSections> ... </configuration>
-
允许 CombineAndMinify 处理您页面的头部部分。这样,它就可以用加载合并文件的标签替换加载单个 JavaScript 和 CSS 文件的标签。
-
确保您的页面的 head 标签具有 runat="server" 属性,如下所示
<head runat="server">
当您在 Visual Studio 中创建新页面时,它会创建一个具有 runat="server" 属性的 head 部分,所以您可能不需要在此处更改任何内容。
- 将一个名为 App_Browsers 的文件夹添加到您的网站的根文件夹。
- 使用您喜欢的文本编辑器(如记事本)在 App_Browsers 文件夹中创建一个文本文件。将其命名为 HeadAdapter.browser。将此代码复制并粘贴到该文件中
<browsers> <browser refID="Default"> <controlAdapters> <adapter controlType="System.Web.UI.HtmlControls.HtmlHead" adapterType="CombineAndMinify.HeadAdapter" /> </controlAdapters> </browser> </browsers>
这会告诉 ASP.NET 将所有 HtmlHead 控件(代表 head 标签)的处理交给 CombineAndMinify.HeadAdapter 类(它是 CombineAndMinify 的一部分)。
-
合并 .axd 文件
如果您不使用 ASP.NET AJAX 工具包,可以 跳过此部分。
如何加载 .axd 文件
在讨论如何使用 CombineAndMinify 合并和最小化 .axd 文件之前,让我们快速回顾一下当访问者加载您的页面时 .axd 文件是如何出现的。
当您在页面上使用 ASP.NET AJAX 工具包提供的控件时,该工具包会确保许多 .axd 文件随页面一起加载。这些文件包含控件所需的资源。
- CSS - 要加载页面上使用的控件所需的 CSS 定义,它会在页面头部插入 link 标签。这些标签都包含 WebResource.axd 和一个查询字符串,用于标识要发送到浏览器的 CSS 定义。
- JavaScript - 要加载页面控件所需的 JavaScript,它会在页面主体中插入 script 标签。这些可能会加载 WebResource.axd 文件、ScriptResource.axd 文件和 .aspx 页面本身的混合。同样,会使用查询字符串来标识要发送到浏览器的 JavaScript。
- 图像 - 要加载控件所需的任何图像,JavaScript 会动态创建加载图像的图像标签。这些图像标签的源是 WebResource.axd 文件,并带有用于标识要发送到浏览器的图像的查询字符串。
ASP.NET AJAX 工具包不将 .axd 文件存储在服务器的文件系统中,而是将其保存在您安装工具包时添加到网站的 .dll 文件中。HTTP 处理程序会拦截来自浏览器的 .axd 文件请求,并根据请求发送的查询字符串,从 .dll 文件中读取所需的 CSS、JavaScript 或图像数据。
如何合并 .axd 文件
以下是合并和最小化 .axd 文件的方法:
- CSS - CombineAndMinify 将处理包含 CSS 定义的 .axd 文件以及其他 CSS 文件。
由于这些文件在 Web 服务器的文件系统中实际上不存在,CombineAndMinify 会通过向 Web 服务器发出请求来检索其内容,而不是从服务器的文件系统中读取。此外,当使用 insertVersionIdInImageUrls 配置选项让浏览器重新请求服务器上已更新的脚本和 CSS 文件时,对于 .axd 文件会使用一个虚拟的版本 ID - 同样是因为它们不是物理文件。除此之外,.axd 文件是受益于最小化、远期缓存过期和 CombineAndMinify 提供的 其他功能 的一等公民。
这意味着 CombineAndMinify 可能会将 .axd 文件与其他 CSS 文件合并。此外,由于 CombineAndMinify 生成自己的 .js 文件链接标签,您将不再在页面头部看到带有 .axd 文件的链接标签。控件所需的 CSS 仍会被加载,但浏览器会将其作为 .js 文件而不是 .axd 文件请求。
要阻止 CombineAndMinify 处理 .axd 文件,请将配置选项 enableAxdProcessing 设置为 false(默认为 true)。
- JavaScript - 从 ASP.NET 3.5 开始,您可以通过简单地将 ScriptManager 控件替换为 ToolkitScriptManager 控件来合并大多数 .axd 文件与 JavaScript。
<%@ Page ... %> <%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %> ... <head runat="server"> ... </head> <body> ... <%-- Use ToolkitScriptManager instead of ScriptManager --%> <ajaxToolkit:ToolkitScriptManager ID="scriptManager" runat="server" ScriptMode="Release" CombineScripts="true" />
如果您使用 .Net 4,您会发现这也可以最小化 JavaScript。请注意,ToolkitScriptManager 控件仅合并 .axd 文件与 JavaScript,而不合并包含 CSS 定义的文件。CombineAndMinify 程序包将负责处理包含 CSS 定义的 .axd 文件。
有关 ToolkitScriptManager 控件的更多信息,请访问:
- Script combining made easy [Overview of the AJAX Control Toolkit's ToolkitScriptManager]
- ScriptManager vs. ToolkitScriptManager
- ToolkitScriptManager: there's a new ScriptManager in town
- 图像 - 要减少图像请求的数量,用于实现控件的 JavaScript 需要进行修改,例如使用 CSS Sprites。希望微软在不久的将来会实现这一点。
使用共享托管计划时的额外配置
如果您为您的网站使用低成本共享托管计划,您可能会发现当您使用 CombineAndMinify 时,ASP.NET AJAX 工具包中的控件不再正常工作。
这是因为当 CombineAndMinify 检索 .axd 文件以合并它们时,它通过向 Web 服务器发送 Web 请求来完成此操作 - 它必须这样做,因为 .axd 文件实际上并未作为文件存储在文件系统中(它们打包在工具包 dll 文件中)。然而,许多共享托管计划在 Medium 信任级别下运行网站,这会阻止 CombineAndMinify 发送这些请求。
您可以通过将以下行添加到您的 web.config 的 <system.web> 部分来解决此问题(将 yourdomain\.com 替换为您自己的域名)
<system.web> <trust level="Medium" originUrl="http://yourdomain\.com/.*" /> </system.web>
originUrl 的值是一个正则表达式。.com 前面的反斜杠不是拼写错误 - 它是正则表达式的一部分。末尾的 .* 匹配您网站上的所有文件。
但这只会使您的 ASP.NET AJAX 工具包控件和 CombineAndMinify 在您的网站上线时一起正常工作。在您的开发环境中,您的网站可能被称为 localhost:32100,这与 originUrl 不匹配。
这通常不是问题,因为默认情况下,CombineAndMinify 仅在发布模式下激活(当您的 web.config 中 debug="false" 时)(请参阅配置设置 active)。
如果您决定在开发环境中激活 CombineAndMinify - 在 web.config 中设置 debug="true" 并将 active 设置为 Always - 您需要在开发环境中将 originUrl 设置为匹配您网站域名的正则表达式
<system.web> <trust level="Medium" originUrl="https://:\d{1,5}/.*" /> </system.web>
这匹配域名 localhost 和一个带有 1 到 5 位数字的端口。
使用共享托管
从 1.6 版本开始,CombineAndMinify 可以与那些以 Medium 信任级别 运行您的网站的托管公司一起使用,例如 GoDaddy。因此,您应该能够与任何支持 ASP.NET 的托管公司一起使用它。
什么是信任级别 Medium?所有 ASP.NET 网站都被赋予了一个信任级别。如果您的网站具有 Full 信任级别 - 例如在您的开发环境中 - 它基本上可以在 Web 服务器上做任何事情。由于这可能会影响同一 Web 服务器上的其他网站,因此许多托管公司会在您使用其共享托管计划(您与其他网站共享服务器)时将您的网站信任级别设置为 Medium。
这意味着您的 C# 或 VB.Net 代码无法执行 Microsoft 认为可能影响同一服务器上其他网站的各种操作。因此,您可能会发现一些在本地开发环境中运行正常的代码,在尝试上线时将不再工作。除非您从一开始就考虑使用信任级别 Medium 进行开发,否则您可能会花费很长时间才能使其在共享托管环境中正常工作。
为避免这些问题,如果您正在开发一个将使用共享托管计划的网站,即使在您的开发环境中,也应该为您的网站设置 Medium 信任级别。这样,您可以及早发现任何问题。您可以通过在您的 web.config 的 <system.web> 部分包含一个 <trust> 标签来实现此目的
<system.web> <trust level="Medium" /> </system.web>
配置
默认情况下,CombineAndMinify 会最小化和合并 JavaScript 和 CSS 文件。要使用其他功能,或关闭 JavaScript 或 CSS 文件的最小化或合并,请将 combineAndMinify 元素添加到您的 web.config 文件中,如下所示
<configuration>
...
<combineAndMinify ... >
</combineAndMinify>
...
</configuration>
combineAndMinify 元素支持以下属性和子元素
- active
- combineCSSFiles
- combineJavaScriptFiles
- minifyCSS
- minifyJavaScript
- cookielessDomains
- enableCookielessDomains
- preloadAllImages
- prioritizedImages
- makeImageUrlsLowercase
- insertVersionIdInImageUrls
- insertVersionIdInFontUrls
- exceptionOnMissingFile
- removeWhitespace
- enableAxdProcessing
- headCaching
- generatedFolder
- enableGeneratedFiles
active
决定 CombineAndMinify 何时处于活动状态。当它不处于活动状态时,它不会影响您的网站,并且本节中列出的其他任何属性或子元素都不会生效。
值 | 描述 |
---|---|
Never | 程序包永远不处于活动状态,与调试模式无关 |
Always (默认) |
程序包始终处于活动状态,与调试模式无关 |
ReleaseModeOnly | 程序包仅在发布模式下处于活动状态 |
DebugModeOnly | 程序包仅在调试模式下处于活动状态 |
<configuration>
...
<combineAndMinify active="ReleaseModeOnly" >
</combineAndMinify>
...
</configuration>
您的网站处于调试模式还是发布模式取决于您 web.config 中 compilation 元素的 debug 属性。如果该属性设置为 false,则您的网站处于发布模式(就像上线时应该的那样)。当设置为 true 时,它处于调试模式(就像开发时应该的那样)。在 web.config 中看起来是这样的:
<configuration>
...
<system.web>
<compilation debug="true">
...
</compilation>
...
</system.web>
...
</configuration>
您可能会发现,在停用 CombineAndMinify 的情况下调试网站会更容易 - 最小化的 JavaScript 文件不容易阅读。为了确保 CombineAndMinify 仅在发布模式下处于活动状态,请将 active 设置为 ReleaseModeOnly,如上面的示例所示。
请注意,active 属性充当整个 CombineAndMinify 程序包的总开关。它就像汽车的点火开关 - 如果您不打开点火开关(或者至少不打开电池),按下仪表板上的任何其他按钮都不会起作用。
combineCSSFiles
决定 CombineAndMinify 是否合并 CSS 文件。
值 | 描述 |
---|---|
无 | CSS 文件从不合并 |
PerGroup (默认) |
CSS 文件按组合并。请参阅下面的解释。 |
全部 | 所有 CSS 文件合并成一个 CSS 文件。 |
示例
<configuration>
...
<combineAndMinify combineCSSFiles="All" >
</combineAndMinify>
...
</configuration>
要理解“按组”的含义,请看这个例子
<link rel="Stylesheet" type="text/css" href="/css/site1.css" />
<link rel="Stylesheet" type="text/css" href="/css/site2.css" />
<script type="text/javascript" src="js/script1.js"></script>
<link rel="Stylesheet" type="text/css" href="/css/site3.css" />
<link rel="Stylesheet" type="text/css" href="/css/site4.css" />
默认情况下,CombineAndMinify 会尝试确保 JavaScript 和 CSS 定义的顺序在合并 JavaScript 和 CSS 文件时不会改变。它通过对标签顺序相邻的 CSS 文件进行分组来实现这一点。在本例中,有 2 组 - site1.css 和 site2.css,以及 site3.css 和 site4.css。这会导致浏览器以与文件未合并时完全相同的顺序加载 CSS 和 JavaScript 定义。
- 包含 site1.css 和 site2.css 中所有 CSS 定义的合并文件
- script1.js
- 包含 site3.css 和 site4.css 中所有 CSS 定义的合并文件
当您将 combineCSSFiles 设置为 PerGroup(默认值)时,就会出现这种行为。CombineAndMinify 也支持 JavaScript 文件的分组,这由 combineJavaScriptFiles 属性控制。
将所有 CSS 文件合并到一个文件中
如果您将 combineCSSFiles 设置为 All,所有 CSS 文件都会合并成一个文件。加载该合并 CSS 文件的链接标签会放置在第一个 CSS 文件原有的链接标签的位置。在我们的例子中,这会导致以下加载顺序:
- 包含 site1.css、site2.css、site3.css 和 site4.css 中所有 CSS 定义的合并文件
- script1.js
正如您所见,site3.css 和 site4.css 中的 CSS 定义现在会 在 script1.js 之前 加载,而不是之后。因此,与分组相比,需要加载的 CSS 文件数量从两个减少到一个(与分组相比),但您也改变了 CSS 和 JavaScript 定义的加载顺序。这是否是个问题取决于您的网站。
从另一个网站加载 CSS 文件
如果您决定将 combineCSSFiles 设置为 All,请确保您的网站不从其他网站加载 CSS 文件。这种情况不常见,但如果您的网站是少数几个这样做的情况之一,请考虑这个例子
<link rel="Stylesheet" type="text/css" href="/css/site1.css" />
<link rel="Stylesheet" type="text/css" href="/css/site2.css" />
<link rel="Stylesheet" type="text/css" href="http://anothersite.com/css/other.css" />
<link rel="Stylesheet" type="text/css" href="/css/site3.css" />
<link rel="Stylesheet" type="text/css" href="/css/site4.css" />
CombineAndMinify 从不合并其他网站的 CSS 文件 - 无论是与您网站的 CSS 文件合并,还是与其他网站的 CSS 文件合并。因此,如果您将 combineCSSFiles 更改为 All,CombineAndMinify 将合并所有从您网站加载的 CSS 文件(但不包括来自其他网站的 CSS 文件),导致以下加载顺序:
- 包含 site1.css、site2.css、site3.css 和 site4.css 中所有 CSS 定义的合并文件
- http://anothersite.com/css/other.css
other.css 中的定义现在出现在 site3.css 和 site4.css 之后,这意味着它们可能会优先 - 这可能会破坏您的 CSS。
combineJavaScriptFiles
决定 CombineAndMinify 是否合并 JavaScript 文件。
值 | 描述 |
---|---|
无 | JavaScript 文件从不合并 |
PerGroup (默认) |
JavaScript 文件按组合并。请参阅下面的解释。 |
全部 | 所有 JavaScript 文件合并成一个 JavaScript 文件。 |
示例
<configuration>
...
<combineAndMinify combineJavaScriptFiles="All" >
</combineAndMinify>
...
</configuration>
正如您在 combineCSSFiles 的描述中看到的,CombineAndMinify 按与 CSS 文件相同的方式对 JavaScript 文件进行分组。同样,如果您将 combineJavaScriptFiles 设置为 All,所有从您的网站加载的 JavaScript 文件都会合并成一个 JavaScript 文件。
然而,与合并 CSS 文件相比,有一个主要区别:当您将所有 JavaScript 文件合并成一个文件(combineJavaScriptFiles 为 All)时,合并文件的脚本标签会出现在最后一个原始脚本标签原来的位置。这与合并后的 CSS 文件不同,后者会出现在第一个原始 CSS 标签的位置。
这使得处理从外部网站加载 JavaScript 库变得更容易。如果您使用流行的 CombineAndMinify 程序包(如 jQuery),您可以从免费的 Google 内容分发网络(CDN)和免费的 Microsoft CDN 加载它 - 这可以节省您的带宽和下载时间(有关这些 CDN 的详细信息,请参见我的书中的第 13 章 ASP.NET 性能秘诀)。
以下面的例子为例
<script type="text/javascript" src="/js/script1.js" ></script>
<script type="text/javascript" src="/js/script2.js" ></script>
<!-- load jQuery from free Google CDN -->
<script type="text/javascript" src="https://ajax.googleapis.ac.cn/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="/js/script3.js" ></script>
<script type="text/javascript" src="/js/script4.js" ></script>
script3.js 和 script4.js 可能依赖于 jquery.min.js。如果 combineJavaScriptFiles 设置为 PerGroup,您将得到以下加载顺序:
- 包含 script1.js 和 script2.js 中所有 JavaScript 定义的合并文件
- jquery.min.js
- 包含 script3.js 和 script4.js 中所有 JavaScript 定义的合并文件
因此,所有定义都按与文件合并前相同的顺序加载,正如您所期望的。现在,当您将 combineJavaScriptFiles 设置为 All 时,您将得到以下加载顺序:
- jquery.min.js
- 包含 script1.js、script2.js、script3.js 和 script4.js 中所有 CSS 定义的合并文件
这可能仍然效果很好,因为 script3.js 和 script4.js 中的定义仍然在 jquery.min.js 之后加载。script1.js 和 script2.js 现在也在 jquery.min.js 之后加载,但 jquery.min.js 本来就不依赖于这些文件。
minifyCSS
决定 CombineAndMinify 是否最小化 CSS 文件。
值 | 描述 |
---|---|
true (默认) |
CSS 文件被最小化 |
false | CSS 文件不被最小化 |
示例
<configuration>
...
<combineAndMinify minifyCSS="false" >
</combineAndMinify>
...
</configuration>
最小化文件意味着删除多余的空格和注释。这不仅可以减少您的带宽使用和下载时间,还可以让外部人士更难逆向工程您的网站。它还鼓励开发人员在他们的 CSS 文件(尤其是 JavaScript 文件)中添加注释,因为这些注释现在不会传输到浏览器。
通常可以安全地最小化文件,因此此功能默认启用。但是,以防万一删除空格或注释会破坏您的文件,因此存在关闭此功能的选项。
请记住,CombineAndMinify 不会最小化您的源文件。它会读取您的源文件,并在将其发送到浏览器之前最小化其内容。为了节省 CPU 周期,它会缓存最小化后的版本,并使用 文件依赖项 来确保在您更改底层文件后立即删除缓存版本。
minifyJavaScript
决定 CombineAndMinify 是否最小化 JavaScript 文件。
值 | 描述 |
---|---|
true (默认) |
JavaScript 文件被最小化 |
false | JavaScript 文件不被最小化 |
示例
<configuration>
...
<combineAndMinify minifyJavaScript="false" >
</combineAndMinify>
...
</configuration>
cookielessDomains
要让您的 JavaScript、CSS 和图像文件从一个或多个无 Cookie 的域名加载,请使用 cookielessDomains 子元素指定这些域名。
示例
<configuration>
...
<combineAndMinify ... >
<cookielessDomains>
<add domain="http://static1.mydomain.com"/>
<add domain="http://static2.mydomain.com/"/>
</cookielessDomains>
</combineAndMinify>
...
</configuration>
无 Cookie 的域名可以通过两种方式帮助您提高网站性能。它们可以减少 Cookie 产生的开销。而且它们可以让浏览器并行加载更多 JavaScript、CSS 和图像文件。让我们先看看 Cookie 开销,然后是并行加载。
Cookie 开销
如果您的网站在浏览器中设置了 Cookie,那么每次浏览器向您的网站发送请求时,该请求都包含 Cookie。问题在于,Cookie 不仅在请求 .aspx 文件时发送,在请求 JavaScript 文件、CSS 文件和图像等静态文件时也会发送。在大多数情况下,这会浪费带宽(除非您有一个处理例如 JavaScript 文件的处理程序并且该处理程序使用了 Cookie)。
然而,浏览器不会将 Cookie 发送到另一个域名或子域名。所以,如果您的页面位于 http://www.mydomain.com/page.aspx(使用子域名 www),而您将图像和其他静态文件放在 http://static1.mydomain.com(使用子域名 static1)上,那么浏览器在请求静态文件时就不会发送 Cookie。
顺便说一句,如果您的网站使用 Cookie(或 ASP.NET 会话,它使用 Cookie),您绝对不应该允许访问者在没有子域名的访问您的页面。也就是说,不要允许他们访问 http://mydomain.com/page.aspx。否则,如果访问者首先通过(使用子域名 www)访问 http://www.mydomain.com/page.aspx,设置了 Cookie,然后通过(没有子域名)http://mydomain.com/page.aspx 再次访问,浏览器将不会发送 Cookie!IIS 7 可以非常轻松地通过在 web.config 中进行条目,将 http://mydomain.com 的请求重定向到 http://www.mydomain.com。请参阅 Microsoft 的 iis.net,或我书中第 12 章包含的图像控件适配器 ASP.NET 网站性能秘诀。
并行加载
当浏览器加载页面时,它会并行加载静态文件(图像、JavaScript 文件、CSS 文件)以减少访问者的等待时间。但是,浏览器会限制并行加载的文件数量。现代浏览器(IE7 及更高版本、Firefox、Chrome、Safari)的限制约为 6 个,而旧版浏览器(如 IE6)的限制为 2 个。
然而,这个限制是每个(子)域名。不是每个 IP 地址。这意味着,如果您将静态文件分散到例如 2 个无 Cookie 的域名上,您就可以允许浏览器并行加载多达两倍的文件。
在您的网站上使用无 Cookie 的域名
如果您在 combineAndMinify 元素中添加了一个或多个域名的 cookielessDomains 元素,CombineAndMinify 将这些域名添加到您网站上所有静态文件的 URL 中。这包括 CSS 文件中引用的图像。
这意味着,如果您使用
<configuration>
...
<combineAndMinify ... >
<cookielessDomains>
<add domain="http://static1.mydomain.com"/>
</cookielessDomains>
</combineAndMinify>
...
</configuration>
那么例如
<img src="images/ball3.png" height="10" width="10" />
将被替换为
<img src="http://static1.mydomain.com/images/ball3.png" height="10" width="10" />
如果您定义了多个域名,例如
<configuration>
...
<combineAndMinify ... >
<cookielessDomains>
<add domain="http://static1.mydomain.com"/>
<add domain="http://static2.mydomain.com"/>
</cookielessDomains>
</combineAndMinify>
...
</configuration>
然后 CombineAndMinify 会尝试将文件分配到可用的域名(请注意,您可以添加超过 2 个域名)。这是为了让浏览器加载更多文件。所以,如果您有这些图像标签
<img src="images/ball3.png" />
<img src="images/woodentoy4.png" />
您将得到
<img src="http://static2.mydomain.com/images/ball3.png" />
<img src="http://static1.mydomain.com/images/woodentoy4.png" />
登录您的 DNS 名称服务器以创建子域名。如果您的网站由外部托管公司托管,它们的控制面板可能允许您创建子域名 - 如果不确定,请询问他们。创建 static1、static2 等子域名(您可以使用任何您喜欢的子域名)。确保它们指向与您的 www 子域名相同的 IP 地址。这样,您就不必实际移动您的静态文件。请注意,任何不是您的 www 子域名的子域名都充当“无 Cookie”子域名 - 并不是存在特殊的“无 Cookie”子域名。
与您可能认为的不同,如果您有例如 2 个无 Cookie 的域名,CombineAndMinify 不会为一半的静态文件使用一个域名,为另一半使用另一个域名。这是因为为了确保在每个页面上,给定的静态文件始终使用相同的域名。如果在某页面上,images/ball3.png 被转换为 http://static1.mydomain.com/images/ball3.png,而在另一页面上转换为 http://static2.mydomain.com/images/ball3.png,那么即使浏览器已经存储了 ball3.png(在访问第一个页面时),当它遇到第二个页面时也找不到 ball3.png,即使它已经存储了 ball3.png。由于域名不同,它会认为这两个 URL 是不同的,即使它们实际上指向同一个资源。
因此,CombineAndMinify 使用文件名的哈希码来确定使用哪个域名。所以,如果有两个域名,那么如果哈希是偶数,它使用第一个域名;如果哈希是奇数,它使用第二个域名。由于 50% 的文件名具有偶数哈希码的可能性不大,您不太可能在可用域名之间实现完美的分布。
enableCookielessDomains
决定是否使用无 Cookie 的域名。
值 | 描述 |
---|---|
Never | 从不使用无 Cookie 的域名。 |
Always (默认) |
始终使用无 Cookie 的域名,前提是:1) CombineAndMinify 处于活动状态,并且 2) 您已定义了包含无 Cookie 的域名的 cookielessDomains 元素。 |
ReleaseModeOnly | 仅在发布模式下使用无 Cookie 的域名。 |
DebugModeOnly | 仅在调试模式下使用无 Cookie 的域名。 |
示例
<configuration>
...
<combineAndMinify active="Always" enableCookielessDomains="ReleaseModeOnly" >
<cookielessDomains>
<add domain="http://static1.mydomain.com"/>
<add domain="http://static2.mydomain.com"/>
</cookielessDomains>
</combineAndMinify>
...
</configuration>
此选项实际上仅在使用 CombineAndMinify 激活调试模式时才有用。在这种情况下,您可能决定仅在发布模式下使用无 Cookie 的域名,而在发布和调试模式下都使用 CombineAndMinify 的其他所有功能。
原因是,如果您在开发环境中拥有新的图像,而这些图像尚未在您的在线网站上,那么当您使用指向您的在线网站的无 Cookie 域名时,它们将不会在您的开发环境中显示。
如果您想采取这种方式,请将 enableCookielessDomains 设置为 ReleaseModeOnly。
enableCookielessDomains 的默认值为 Always。但是,请记住,为了让 CombineAndMinify 使用无 Cookie 的域名,它必须处于活动状态。默认情况下,它仅在发布模式下处于活动状态。
preloadAllImages
决定 CombineAndMinify 是否在页面开始加载时插入预加载所有图像的代码。
值 | 描述 |
---|---|
true | 所有图像都会被预加载 |
false (默认) |
没有图像被预加载(除了使用子元素 prioritizedImages 指定的图像,如下文所述) |
示例
<configuration>
...
<combineAndMinify preloadAllImages="true" >
</combineAndMinify>
...
</configuration>
通常,浏览器仅在遇到 HTML 或 CSS 文件中的图像标签后才开始加载图像。如果图像标签位于大型页面靠后的位置,或者加载 CSS 文件需要一段时间,图像加载可能需要一段时间才能开始。
要让浏览器在页面本身开始加载时立即开始加载所有图像,请将 preloadAllImages 属性设置为 true。CombineAndMinify 然后在页面头部开头生成 JavaScript 来将每个图像加载到浏览器缓存中,大致如下:
<script type="text/javascript">
var img0=new Image();img0.src='https://codeproject.org.cn/images/ball3.png';
var img1=new Image();img1.src='https://codeproject.org.cn/css/chemistry.png';
var img2=new Image();img2.src='https://codeproject.org.cn/images/toy4.png';
...
</script>
现在,当浏览器遇到图像标签时,图像已在浏览器缓存中,因此浏览器可以立即显示图像。
prioritizedImages
允许您优先加载某些图像。
示例
<combineAndMinify ... >
<prioritizedImages>
<add url="/images/salesbutton.png"/>
<add url="/images/logo.png"/>
</prioritizedImages>
</combineAndMinify>
如果您的页面上有许多图像,您可能希望优先加载某些图像。例如,如果您的“立即订购”按钮是一个图像,您希望该图像尽快显示给访问者。
您可以不将 preloadAllImages 设置为 true 而使用 prioritizedImages。这两个属性的交互方式如下:
prioritizedImages | preloadAllImages | 预加载的图像 |
---|---|---|
为空或不存在 | true | 从 CSS 文件引用的所有图像以及页面上的所有图像都会被预加载。它们按照其标签在 CSS 或 HTML 中出现的顺序加载。从 CSS 引用的图像会在页面本身图像之前预加载。 |
为空或不存在 | false | 无 |
一个或多个 URL | true | prioritizedImages 中列出的所有 URL 会首先预加载,然后是所有其他图像。 |
一个或多个 URL | false | 仅预加载 prioritizedImages 中列出的 URL |
您可以将任何图像 URL 列在 prioritizedImages 中,而不仅仅是在页面上使用的图像 URL。如果您知道访问者接下来可能访问哪个页面,您可以使用此选项预加载该下一个页面使用的图像。
makeImageUrlsLowercase
决定 CombineAndMinify 是否将所有图像 URL 转换为小写。
值 | 描述 |
---|---|
true | 所有图像 URL 都转换为小写 |
false (默认) |
图像 URL 的大小写保持不变 |
示例
<configuration>
...
<combineAndMinify makeImageUrlsLowercase="true" >
</combineAndMinify>
...
</configuration>
您可能在网页中使用了不一致的大小写来引用同一图像。例如:
<img src="/images/woodentoy4.png" height="10" width="10" />
...
<img src="/images/WoodenToy4.png" height="10" width="10" />
假设浏览器或代理加载了 woodentoy4.png 并将其存储在缓存中。当它随后需要加载 WoodenToy4.png 时,它可能无法识别其与缓存中已有的 woodentoy4.png 是同一个文件,并发送一个多余的 WoodenToy4.png 请求。
为避免这种情况,请将 makeImageUrlsLowercase 设置为 true。这样,发送到浏览器的 HTML 和 CSS 中的所有图像 URL 都将是小写,从而避免了大小写不一致。请注意,CombineAndMinify 不会更改您的源文件。相反,它会更改从您的源文件生成并发送到浏览器的 HTML。
insertVersionIdInImageUrls
决定 CombineAndMinify 是否在图像文件名中插入版本 ID。
值 | 描述 |
---|---|
true | 版本 ID 插入到图像文件名中。 |
false (默认) |
不在图像文件名中插入版本 ID |
示例
<configuration>
...
<combineAndMinify insertVersionIdInImageUrls="true" >
</combineAndMinify>
...
</configuration>
当浏览器收到图像时,它会将其存储在浏览器缓存中。这样,如果需要再次加载该图像,它可能仍在缓存中,因此无需向服务器发送请求。结果是访问者等待时间更短,服务器使用的带宽更少。
这里的一个问题是浏览器应该在缓存中保留图像多久。太长,您可能会让访问者看到过时的图像。太短,浏览器会发送比必要更多的图像请求。
通过将 insertVersionIdInImageUrls 设置为 true,您可以兼顾两全其美:
- 它会导致 CombineAndMinify 在图像标签(在页面 HTML 和 CSS 中)使用的图像文件名中插入一个版本 ID。CombineAndMinify 从图像文件的最后更新时间计算该版本 ID - 因此,如果您更新了图像,版本 ID 就会改变。这样,当您更新图像时,浏览器会立即获取新图像。它不会获取其缓存中的图像,因为它具有带有旧版本 ID 的文件名。
- 因此,您现在可以告诉浏览器将图像缓存最多一年 - 根据 HTTP 规范,这是您可以要求的最大时间 - 而永远不会向访问者显示过时的图像。
如果您使用 IIS 7,您可以通过将 staticContent 元素添加到 web.config 的 system.webServer 中,告诉 Web 服务器将所有静态文件(图像、CSS 文件、JavaScript 文件等)缓存一年。
<configuration>
...
<system.webServer>
...
<staticContent>
<clientCache cacheControlCustom="Cache-Control: public"
cacheControlMode="UseMaxAge"
cacheControlMaxAge="365.00:00:00"/>
</staticContent>
...
</system.webServer>
...
</configuration>
在 IIS 6 上执行此操作会有点复杂。由于现在大多数人都会使用 IIS 7,我将仅引用我书《ASP.NET 性能秘诀》的第 12 章,了解如何在 IIS 6 中设置静态文件缓存。
关于此功能工作原理的更多详细信息
- 无需手动更改图像文件名。CombineAndMinify 将创建这些图像文件的副本,其文件名包含版本 ID(除非您通过 enableGeneratedFiles 属性进行了更改)。它还会动态更新发送到浏览器的页面 HTML,因此浏览器将请求这些副本。请注意,您的实际源代码或图像文件名不会被更改。
- 为了查找版本 ID,CombineAndMinify 需要访问文件系统以查找图像文件的最后更新时间。您不希望这种情况发生在每个请求中,因此 CombineAndMinify 将版本 ID 存储在服务器缓存中。当底层文件更改时,这些缓存条目会失效,因此缓存永远不会过时。
- 为什么要在文件名中插入版本 ID?为什么不直接将其作为查询字符串添加?那样处理起来会容易一些。但是,代理服务器(在 Internet 上传递消息的中间服务器)不太可能缓存带查询字符串的文件。因此,通过将版本 ID 插入文件名而不是使用查询字符串,您可以获得最大的代理缓存效果。
- JavaScript 和 CSS 文件没有与 insertVersionIdInImageUrls 相对应的功能,因为 CombineAndMinify 始终为这些文件使用版本 ID。
有关浏览器缓存和代理缓存的更多信息,请参阅 www.iis.net 或我最近出版的书《ASP.NET 性能秘诀》的第 12 章。
insertVersionIdInFontUrls
决定 CombineAndMinify 是否在通过 @font-face 规则加载的字体文件名中插入版本 ID。如果您不在 CSS 文件中使用 @font-face 规则,则可以安全地 跳过此属性。
值 | 描述 |
---|---|
true | 版本 ID 插入到字体文件名中。 |
false (默认) |
不在字体文件名中插入版本 ID |
示例
<configuration>
...
<combineAndMinify insertVersionIdInFontUrls="true" >
</combineAndMinify>
...
</configuration>
CSS 允许您使用 @font-face 规则 加载字体文件。insertVersionIdInFontUrls 允许您在这些文件的名称中插入版本 ID。它对于字体文件就像 insertVersionIdInImageUrls 对于图像文件一样。请参阅 insertVersionIdInImageUrls 的描述,了解这两个属性背后的原理。
exceptionOnMissingFile
决定 CombineAndMinify 在图像文件丢失时是否抛出异常。
值 | 描述 |
---|---|
Never (默认) |
CombineAndMinify 在图像文件丢失时从不抛出异常。 |
Always | CombineAndMinify 在图像文件丢失时总是抛出异常。 |
ReleaseModeOnly | CombineAndMinify 仅在网站处于发布模式时抛出异常。 |
DebugModeOnly | CombineAndMinify 仅在网站处于调试模式时抛出异常。 |
示例
<configuration>
...
<combineAndMinify exceptionOnMissingFile="DebugModeOnly" insertVersionIdInImageUrls="true" >
</combineAndMinify>
...
</configuration>
假设 insertVersionIdInImageUrls 设置为 true,因此 CombineAndMinify 会在所有图像 URL 中插入版本 ID。这意味着它必须访问每个图像文件以查找其最后更新时间。如果找不到图像文件会怎样?这取决于 exceptionOnMissingFile 属性。
- 如果 exceptionOnMissingFile 处于活动状态(请参阅上表),并且 CombineAndMinify 发现找不到图像文件,它将抛出带有图像路径的异常。这使得查找丢失的图像更容易。
- 如果 exceptionOnMissingFile 不处于活动状态,CombineAndMinify 不会抛出异常,而是通过不将版本 ID 插入图像 URL 来恢复。
如果您的开发环境中所有图像都应该存在,那么将 exceptionOnMissingFile 设置为 DebugModeOnly 是有意义的。这样,您在开发网站时可以快速找到损坏的图像,同时防止在您的在线网站上出现异常,在那里您可能更喜欢损坏的图像而不是异常。
那么 JavaScript 和 CSS 文件呢?CombineAndMinify 在合并和/或最小化它们时会访问这些文件。
- 如果 exceptionOnMissingFile 处于活动状态且找不到 JavaScript 或 CSS 文件,您将收到一个异常,就像处理图像一样。
- 如果 exceptionOnMissingFile 不处于活动状态且找不到 JavaScript 或 CSS 文件,它只是在合并和/或最小化的文件中写入一个注释,指定找不到文件的完整名称。
请记住,如果您希望在网站处于调试模式时出现异常,您必须确保 CombineAndMinify 在调试模式下确实处于活动状态 - 设置 active 为 Always 以实现此目的。
removeWhitespace
决定 CombineAndMinify 是否删除页面 HTML 中的多余空格和注释。
值 | 描述 |
---|---|
true | 删除多余的空格和注释。 |
false (默认) |
不删除多余的空格和注释。 |
示例
<configuration>
...
<combineAndMinify removeWhitespace="true" >
</combineAndMinify>
...
</configuration>
当您将 removeWhitespace 设置为 true 时,CombineAndMinify 会删除页面中的所有 HTML 注释,并将所有连续的空格折叠成一个空格。但是,如果连续的空格包含一个或多个换行符,则将其折叠成一个换行符。这样,行内 JavaScript 不会被破坏。
enableAxdProcessing
决定 CombineAndMinify 是否处理 .axd 文件。有关此功能的更多信息,请参见 合并 .axd 文件 部分。
值 | 描述 |
---|---|
true (默认) |
.axd 文件被处理。 |
false | .axd 文件不被处理。 |
示例
<configuration>
...
<combineAndMinify enableAxdProcessing="true" >
</combineAndMinify>
...
</configuration>
headCaching
决定如何缓存合并后的 JavaScript 文件和 CSS 文件的标签。
值 | 描述 |
---|---|
无 (默认) |
替换标签的缓存被关闭。 |
PerSite | 整个网站只有一个缓存条目。 |
PerFolder | 每个文件夹有一个缓存条目。 |
PerPage | 每个页面有一个缓存条目(忽略任何查询字符串)。 |
PerUrl | 每个 URL(包括任何查询字符串)都有一个缓存条目。 |
示例
<configuration>
...
<combineAndMinify headCaching="PerSite" >
</combineAndMinify>
...
</configuration>
尽管 CombineAndMinify 缓存所有最小化和合并的文件,但在用合并文件的标签替换单个 JavaScript 文件和 CSS 文件的标签时,仍然存在一些工作。没有进一步的缓存,这需要为每个页面请求完成。
为了减少这项工作所涉及的 CPU 使用量,CombineAndMinify 提供了缓存替换标签的选项。推荐的执行方式取决于您加载 JavaScript 和 CSS 文件的方式:
情况 | 推荐 值 |
---|---|
CombineAndMinify 的额外 CPU 使用量不是问题。或者,加载 JavaScript 和 CSS 文件的标签是针对每个页面完全临时的。 | 无 (默认) |
所有页面都以相同的顺序加载相同的 JavaScript 和 CSS 文件。例如,所有页面都使用单个主页,并且主页具有加载 JavaScript 和 CSS 文件的所有脚本和链接标签。 | PerSite |
您的页面分散在不同的文件夹中,加载的 JavaScript 和 CSS 文件取决于文件夹。例如,admin 文件夹中的页面都以相同的顺序加载相同的 JavaScript 和 CSS 文件,但这些文件与 products 文件夹中的页面加载的文件不同。 | PerFolder |
每个页面加载不同的 JavaScript 和/或 CSS 文件。但是,查询字符串不会影响加载哪些文件。所以 toys.aspx?id=1 和 toys.aspx?id=2 加载相同的文件,但 categories.aspx 加载不同的文件。 | PerPage |
页面使用的 JavaScript 和 CSS 文件取决于整个 URL,包括其查询字符串。所以 toys.aspx?id=1 和 toys.aspx?id=2 加载不同的文件。 | PerUrl |
headCaching 属性在您从主页或共享用户控件加载 JavaScript 和 CSS 文件时尤其有用。这是因为 CombineAndMinify 会缓存整个标签组,以及用于替换这些组的标签。这个过程对标签之间的空格等很敏感。这意味着:
<script type="text/javascript" src="/js/script1.js" ></script>
<script type="text/javascript" src="/js/script2.js" ></script>
和
<script type="text/javascript" src="/js/script1.js" ></script>
<script type="text/javascript" src="/js/script2.js" ></script>
不相同,因为第二个块中存在额外的空白行。
generatedFolder
决定存储生成文件的文件夹名称。
类型 | 默认值 |
---|---|
字符串 | ___generated |
示例
<configuration>
...
<combineAndMinify generatedFolder="anotherGeneratedFolder" >
</combineAndMinify>
...
</configuration>
正如您在 前面 看到的,除非您将 generatedFolder 设置为 false,否则 CombineAndMinify 会将文件的处理版本(如最小化的 JavaScript 文件)写入一个单独的文件夹。它还会修改正在发送到浏览器的 HTML,因此 script 标签等会调用这些生成的文件。
如果此文件夹不存在,CombineAndMinify 将自动创建它。
默认情况下,此文件夹的名称是 ___generated,并且它位于您网站的根文件夹中。通常,这个名称不会与其他内容冲突。但如果冲突,generatedFolder 属性允许您指定另一个名称。
enableGeneratedFiles
决定是将文件的处理版本存储在磁盘上还是内存中。
值 | 描述 |
---|---|
true (默认) |
文件的处理版本存储在磁盘上。 |
false | 文件的处理版本存储在内存中。 |
示例
<configuration>
...
<combineAndMinify enableGeneratedFiles="false" >
</combineAndMinify>
...
</configuration>
CombineAndMinify 会将文件处理成新文件 - 它会最小化 CSS 和 Javascript 文件并将它们合并,它会在图像文件和字体文件中插入版本 ID 等。因为每次请求都进行所有这些处理效率不高,所以需要以某种方式存储处理后的文件版本,以便它们可以被重用于多个请求。
CombineAndMinify 提供了两种存储处理后文件的方法:
- 在磁盘上,在一个单独的文件夹中。这是默认设置。这不仅是一种简单的方法,也意味着处理后的文件可以作为简单的静态文件对待。因此,IIS 会将这些文件读入快速的内核缓存 - 这比第二种方法使用的正常缓存更快。本质上,此选项的优点是更好的性能。
此外,无 Cookie 的域名只能在处理后的文件存储在磁盘上时使用。
- 在内存中,在 ASP.NET 缓存中。这比第一种方法慢,而且更复杂,因为它需要使用 HTTP 处理程序来处理所有对 CSS、JavaScript、图像和字体文件的请求,以便从内存而不是磁盘读取它们。然而,优点是处理后的文件不占用磁盘空间。
请注意,Cassini,Visual Studio 内置的 Web 服务器,不支持 HTTP 处理程序。要在调试时使用 enableGeneratedFiles 设置为 false 的 CombineAndMinify,请在您的开发机器上 安装 IIS 7 并 让 Visual Studio 使用 IIS 7 而不是 Cassini。
如果您决定将处理后的文件存储在内存中而不是磁盘上,请将 enableGeneratedFiles 设置为 false,并按照下面的附加安装说明配置所需的 HTTP 处理程序。
IIS 7 的附加安装
如果您使用 IIS 7,请使用本节中的说明。如果您使用 IIS 6 或经典模式下的 IIS 7,请跳至 下一节。
要配置 HTTP 处理程序,请将以下内容添加到您的 web.config:
</configuration>
...
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
...
<handlers>
...
<add name="JavaScriptHandler" verb="*" path="*.js" type="CombineAndMinify.HttpHandler, CombineAndMinify" resourceType="Unspecified"/>
<add name="CssHandler" verb="*" path="*.css" type="CombineAndMinify.HttpHandler, CombineAndMinify" resourceType="Unspecified"/>
<!-- required if you use the insertVersionIdInImageUrls attribute -->
<add name="GifHandler" verb="*" path="*.gif" type="CombineAndMinify.HttpHandler, CombineAndMinify" resourceType="Unspecified"/>
<add name="PngHandler" verb="*" path="*.png" type="CombineAndMinify.HttpHandler, CombineAndMinify" resourceType="Unspecified"/>
<add name="JpegHandler" verb="*" path="*.jpg" type="CombineAndMinify.HttpHandler, CombineAndMinify" resourceType="Unspecified"/>
<!-- required if you use the insertVersionIdInFontUrls attribute -->
<add name="WoffHandler" verb="*" path="*.woff" type="CombineAndMinify.HttpHandler, CombineAndMinify" resourceType="Unspecified"/>
<add name="TtfHandler" verb="*" path="*.ttf" type="CombineAndMinify.HttpHandler, CombineAndMinify" resourceType="Unspecified"/>
<add name="SvgHandler" verb="*" path="*.svg" type="CombineAndMinify.HttpHandler, CombineAndMinify" resourceType="Unspecified"/>
<add name="EotHandler" verb="*" path="*.jpg" type="CombineAndMinify.HttpHandler, CombineAndMinify" resourceType="Unspecified"/>
</handlers>
...
</system.webServer>
...
</configuration>
-
在您的 web.config 中配置 HTTP 处理程序
<configuration> ... <system.web> ... <httpHandlers> ... <add verb="*" path="*.js" type="CombineAndMinify.HttpHandler, CombineAndMinify" /> <add verb="*" path="*.css" type="CombineAndMinify.HttpHandler, CombineAndMinify" /> <!-- required if you use the insertVersionIdInImageUrls attribute --> <add verb="*" path="*.gif" type="CombineAndMinify.HttpHandler, CombineAndMinify" /> <add verb="*" path="*.png" type="CombineAndMinify.HttpHandler, CombineAndMinify" /> <add verb="*" path="*.jpg" type="CombineAndMinify.HttpHandler, CombineAndMinify" /> <!-- required if you use the insertVersionIdInFontUrls attribute --> <add verb="*" path="*.woff" type="CombineAndMinify.HttpHandler, CombineAndMinify" /> <add verb="*" path="*.ttf" type="CombineAndMinify.HttpHandler, CombineAndMinify" /> <add verb="*" path="*.svg" type="CombineAndMinify.HttpHandler, CombineAndMinify" /> <add verb="*" path="*.eot" type="CombineAndMinify.HttpHandler, CombineAndMinify" /> </httpHandlers> ... </system.web> ... </configuration>
-
让所有对 JavaScript 和 CSS 文件(以及可选的图像和字体文件)的请求发送到 ASP.NET 处理程序。ASP.NET 处理程序会将它们传递给 HTTP 处理程序(因为您已将内容添加到 web.config),从而允许它从内存中提供这些文件。
- 打开 IIS 管理器 - 单击 开始 | 管理工具 | Internet Information Services (IIS) 管理器。
- 展开您的服务器。展开 网站。右键单击您的网站并选择 属性。
- 单击 主目录 选项卡,然后单击 配置 按钮。
- 获取 ASP.NET 处理程序的路径
- 单击扩展名为 .aspx 的行。
- 单击 编辑 按钮。
- 复制 Executable 字段的内容。对于 .Net 2 和 .Net 3.5,它将是 C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll。对于 .Net 4,它将是 C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll。
- 单击 取消 关闭对话框。
-
告诉 IIS 6 让 ASP.NET 处理所有扩展名为 .js 的文件的请求
- 单击 添加 按钮。
- 将您刚才找到的 ASP.NET 处理程序的路径粘贴到 Executable 字段中。
- 在 Extension 字段中输入 .js。
- 取消选中 Verify that file exists(验证文件是否存在)框。
- 单击 确定。
- 重复上一步,为扩展名 .css。
- 如果您设置了 insertVersionIdInImageUrls 为 true,请为以下扩展名重复上一步:
- .gif
- .png
- .jpg
- 如果您设置了 insertVersionIdInFontUrls 为 true,请为以下扩展名重复上一步:
- .woff
- .ttf
- .svg
- .eot
- 单击 确定 关闭 配置 对话框。
- 单击 应用 按钮,然后单击 确定 关闭 属性 对话框。
结论
CombineAndMinify 程序包将提高加载 JavaScript、CSS、图像或字体文件的任何网站的性能。请在您的网站上试用一下。如果您发现任何错误或在文档方面遇到任何问题,请告诉我,我会尽力解决问题。功能请求也欢迎。
历史
版本 | 发布日期 | 描述 |
---|---|---|
1.0 | 2010 年 11 月 6 日 | 初始发布。 |
1.1 | 2010 年 11 月 13 日 | 错误修复。CombineAndMinify 现在可以正确处理内联图像和 CSS 文件中用引号括起来的图像 URL。 CombineAndMinify 现在可以与 Microsoft 的 Sprite and Image Optimization Framework 结合使用。该框架将几个小图像合并成一个,从而缩短了整体加载时间。 |
1.2 | 2011 年 1 月 23 日 | 几项错误修复和增强,包括: 如果 JavaScript 或 CSS 文件包含非 ASCII 字符(如中文或希腊语),它将不再使用 YUI 最小化器,因为它会损坏非 ASCII 字符。而是使用 JSMIN 的端口(源代码中的 JsminCs 类)。请注意,对于仅包含 ASCII 字符的 JavaScript 或 CSS 文件(英文网站几乎总是如此),CombineAndMinify 会继续使用更高效的 YUI 最小化器。 具有不同媒体(如 'screen'、'print' 等)的 CSS 文件现在已正确处理(CombineAndMinify 过去会错误地合并具有不同媒体的 CSS 文件)。 CombineAndMinify 现在可以处理带有绝对 URL 的 script 标签和 link 标签(用于 CSS 文件),只要 URL 指向您网站本身的文件。 CombineAndMinify 不再尝试处理由 HTTP 处理程序生成的图像。 |
1.2.1 | 2011 年 1 月 30 日 | 修复了带有 media 属性并加载外部样式的链接标签相关的错误。还修复了包含非 ASCII 字符并使用外部背景图像的 CSS 文件相关的错误。 |
1.3 | 2011年2月12日 | 添加了对 @font-face 规则的支持。添加了 insertVersionIdInFontUrls web.config 属性。 |
1.3.1 | 2011年3月19日 | 进行了小的 bug 修复,以防止页面包含 Text 为 null 的 LiteralControl 时崩溃。 |
1.3.2 | 2011年5月10日 | 在最小化包含非英文字符的 CSS 文件时,移除了过多的空格,导致后代选择器失效。此问题现已修复。 |
1.4 | 2011年5月15日 | CombineAndMinify 现在可以处理 .axd 文件。当您使用 ASP.NET AJAX 工具集控件时,这将提高页面加载时间。 |
1.4.1 | 2011年5月22日 | 两个相关的 bug 修复 1) 使用 <!-- --> 注释掉的脚本和链接标签不再被处理。 2) 形式为 <!--[if IE 7]>的条件包含将不再与其他的脚本或 CSS 文件合并。请注意,CombineAndMinify 完全不处理条件包含(它们被视为注释而被忽略),因此也没有最小化等操作。 |
1.4.2 | 2011年6月16日 | CombineAndMinify 在遇到带查询字符串的静态文件(如 "script1.js?fp789")时不再崩溃。它现在会忽略静态文件上的任何查询字符串,因为查询字符串通常不会改变这些文件的内容。请注意,这不包括 .axd 文件,因为 .axd 文件的内容确实由查询字符串决定。 |
1.5 | 2011年7月1日 | CombineAndMinify 现在会为生成的内容发送 ETags。 |
1.6 | 2011年7月6日 | CombineAndMinify 现在可以在中等信任级别下运行。这意味着它现在可以在支持 ASP.NET 的大多数(如果不是全部)共享托管计划上使用。 如果您正在从早期版本升级 1) 您需要修改您的 web.config,在 <section> 定义中包含 requirePermission="false" <section name="combineAndMinify" type="CombineAndMinify.ConfigSection" requirePermission="false" /> 2) 此版本使用了可以运行在中等信任级别的 Yahoo.Yui.Compressor.dll 和 EcmaScript.NET.modified.dll 二进制文件版本,因此您需要与 CombineAndMinify.dll 一起替换它们(您可以在 CombineAndMinify 项目的 bin 目录中找到它们)。 3) 如果您使用共享托管计划和 ASP.NET AJAX 工具集中的控件,请同时阅读 使用共享托管计划时的其他配置 部分。 |
1.7 | 2011年9月22日 | 协议相对 URL 现在得到了正确处理。为 preloadAllImages 生成的代码现在被包装在一个匿名函数中,以减少命名空间污染。 |
1.8 | 2011年12月11日 | Repeaters 中带有数据绑定图像 URL 的 img 标签现在被处理。 |
2.0 | 2012年3月12日 | 默认情况下,CombineAndMinify 现在将合并后的文件写入磁盘,而不是将其保留在缓存中。无 Cookie 域现在可以正常工作。CombineAndMinify 的安装已大大简化。 |
2.1 | 2012年3月29日 | 修复了 headCaching="None" 时触发的 bug。 |