我的一位客户不断抱怨他们的网站不够快......这对我来说有点奇怪,因为几个月前他们雇用我时,他们无法让服务器保持运行状态24小时,因为它缓存太多而内存不足。因此,我删除了大部分缓存,优化了他们的数据库,将它们放在一台功能强大至少5倍的新服务器上(RAM的数量和处理器的速度 - 它们的处理器数量是目前处理器数量的4倍)相同的时钟速度),他们抱怨说,#34;我们的网站从来没有如此低调!"。
因此,我要浏览Google所说的所有可以改善效果的内容列表,希望最终他们能够对此感到满意,或者他们会意识到他们的网站是做了很多工作,他们的服务器有限制,有些页面需要几秒钟才能加载,就像你不能在一小时内手工制造整辆汽车一样。我所做的所有研究都表明,如果我已经指定了Cache-Control,Expires和Last-Modified标头,Firefox应该使用它的缓存,但无论我如何在ColdFusion中设置它们,Firefox和Chrome都拒绝使用缓存。我可以手动设置304响应标头,这似乎会导致Firefox没有返回任何内容,如果它还没有缓存图像。 (?!!)
所以我有这个代码。很简单。几乎所有文档都应该是这样的。 FireBug始终报告(尽管重新启动,缓存清除,强制重新加载等)内容是在几秒钟之前创建的,而不是像我在cfheader中设置的那样在7天前创建的。另一方面,Chrome会在一周前报告上次修改日期,但会报告请求标头中的max-age为0。 (?!!)(在Chrome devtools中启用了缓存,所以我知道它不是。)Chrome的响应标头显示正确的max-age值。 (编辑:我对FireBug和Chrome的开发人员工具中的数据显示感到困惑 - 事实证明,两个浏览器都正确地收到了响应标头。)
<cfheader name="Content-Type" value="image/png" />
<cfheader name="Cache-Control" value="max-age=604800, private, must-revalidate" />
<cfheader name="Expires" value="#getHTTPTimeString(dateadd('d', 1, now()))#" />
<cfheader name="Last-Modified" value="#getHTTPTimeString(dateadd('d', -7, now()))#" />
....
<cfcontent type="image/png" variable="#toBinary(img)#" />
鉴于Chrome正确报告了响应标头,这似乎并不像我读过的 HTTP标准教程那样工作(声称基于标准)说它应该工作......但我无法确定。我当然不是HTTP的专家,所以我可能会忽略一些东西。这不是一个复杂的应用程序。因此,我为什么如此沮丧和撕裂我的头发。
非常感谢任何帮助。谢谢!
修改
因此,要提供有关已接受答案的更多信息,请参阅ColdFusion中我的解决方案。上面的代码基本上保持在页面中(例如index.cfm)。然后,为了利用浏览器返回的缓存提示,我在Application.cfc中有类似的东西
<cfcomponent output="false">
<cffunction name="onRequest" access="public" output="true">
<cfargument name="targetPage" type="string" required="true" />
<cfset var modDate = getIfMOdifiedSince() />
<cfif isDate(modDate) and datediff('d', modDate, now()) lte 7>
<!--- the browser has a cached copy that's less than a week old, let the browser use it --->
<cfheader name="Content-Type" value="image/png" />
<cfheader statuscode="304" statustext="Not Modified" />
<cfelse>
<!--- the browser hasn't seen it in 7 days (or possibly ever), return the image --->
<cfheader name="Last-Modified" value="#getHTTPTimeString(now())#" />
<cfinclude template="#targetPage#" />
</cfif>
</cffunction>
<cffunction name="getIfModifiedSince" access="private" output="false" returntype="string">
<cfset var head = getHTTPRequestData().headers />
<cfreturn iif(structKeyExists(head, "if-modified-since"), "head['if-modified-since']", de("")) />
</cffunction>
</cfcomponent>
这可能比您需要的要简单一些。此特定代码实际上并未检查图像是否已被修改,因为这不是我们真正担心的事情。这个应用程序只提供一组特定的图像,因此我们知道从这个应用程序提供的任何内容都将是PNG,因此我们可以安全地将内容类型标题设置为image / png,因为图像确实没有改变,我&# 39; m不打扰任何实际的日期检查。我可能真的可以让图像无限期地存在,但是现在我让浏览器一次让它们持续一周。随着业务的增长,我可能会延长这段时间。
工作的真正关键在于,使缓存工作的是onRequest()方法检查if-modified-since请求标头,并且当存在并且在期望的时间范围内时,它会截断整个请求。包括目标页面(因此没有剩余的页面代码将执行),而只是设置403 Not Modified状态响应头。
从长远来看,就像我怀疑的那样,它实际上是一件非常简单的事情,显然只是被创建在线教程的人误解了。
答案 0 :(得分:4)
要理解HTTP,最好直接转到RFC 2616,或者至少引用相关部分的教程。
在这种情况下,相关部分是响应标头Last-Modified
(第14.29节),请求标头If-Modified-Since
(第14.25节)和状态304 Not Modified
(第10.3.5节)。 (你可能也想阅读其他一些与缓存相关的东西。)
通过查看HTTP请求/响应的样子,可能是演示正在发生的事情的最佳方式。
所以这是第一个图像请求(为了清晰起见,一堆标题被删除):
GET /res/image.png HTTP/1.1 Host: mydomain.com User-Agent: I'm a browser Accept: */*
这基本上是当您的网址为http://mydomain.com/res/image.png
时从浏览器获得的内容。
服务器解析它,找出适当的文件是什么,并用以下内容作出响应:
HTTP/1.1 200 OK Date: Tue, 06 May 2014 22:33:44 GMT Last-Modified: Sat, 03 May 2014 20:00:25 GMT Content-Length: 4636 Content-Type: image/png;charset=UTF-8 {image data}
当浏览器执行缓存时,它会记录Last-Modified日期,以及稍后发送请求时它看起来像这样:
GET /res/image.png HTTP/1.1 Host: mydomain.com If-Modified-Since: Sat, 03 May 2014 20:00:25 GMT User-Agent: I'm a browser Accept: */*
服务器根据文件的修改日期检查If-Modified-Since,看到没有变化,并回复:
HTTP/1.1 304 Not Modified Date: Tue, 06 May 2014 22:34:56 GMT
当然不会返回图像数据。
(如果HAD发生变化,则响应为200(带有新的Last-Modified值)和新数据。)
答案 1 :(得分:1)
如果对CFContent交付的Web资产有大量请求,则可能发生拒绝服务。如果访问者,机器人或黑客连接速度较慢(或限制其带宽),您的ColdFusion线程将很快填满并排队。
为什么无法使用网络服务器从添加了特殊“7天过期”标题规则的子目录中提供图像的原因?
如果图像是唯一的,您可以在脱机临时目录中生成它们,设置目录映射,然后使用唯一或基于会话的文件名,并使用计划任务来清理过时的图像。
网站的页面加载时间也可能因延迟加载图像而受益。这将加载网页,只加载“首屏”中的可见图像。这可以使用javascript完成。如果您使用jQuery,这是一个不错的插件:http://www.appelsiini.net/projects/lazyload
您是否将ColdFusion处理时间添加到生成的HTML中?我们在开始时使用GetTickCount()&amp;结束然后将生成时间作为HTML中的注释发布(执行:163毫秒)。如果你看到最短的时间,那么瓶颈就不是ColdFusion。
关于网页效果,我使用Google PageSpeed取得了巨大成功。 (我在IIS7上,所以我不得不使用IISpeed http://www.iispeed.com/)在我的一个网站上,带有许多产品图像的网页的感知加载时间从13秒变为7.2(-5.8秒/快了44%)。
https://www.youtube.com/watch?v=VwEGGB-4sMw
我只使用ColdFusion测试了IISpeed。在每个站点的基础上,我们使用IISpeed在ColdFusion 9生成的页面上自动执行以下优化:
要测试网站的网页加载速度,请使用http://www.webpagetest.org/