Sam*_*ley 4 coldfusion performance caching
我的一个客户不断抱怨他们的网站速度不够快......这对我来说有点奇怪,因为几个月前他们雇用我时,他们无法让服务器运行 24 小时,因为它也在缓存很多而且内存不足。所以我删除了大部分缓存,优化了他们的数据库,把它们放在一个新的服务器上,它的功能至少是原来的 5 倍(RAM 量和处理器速度——它们现在有 4 倍的处理器,每个处理器的时钟速度几乎相同) ,他们抱怨“我们的网站从来没有这么慢!”。
因此,我将列出 Google 所说的将提高性能的所有内容,希望最终他们要么对此感到满意,要么意识到他们的网站正在做大量工作并且存在限制在他们的服务器上,有些页面需要几秒钟才能加载,就像您无法在一个小时内手工制作一整辆车一样。我所做的所有研究表明,如果我指定了 Cache-Control、Expires 和 Last-Modified 标头,Firefox 应该使用其缓存,但无论我如何在 ColdFusion 中设置它们,Firefox 和 Chrome 都拒绝使用缓存。我可以手动设置 304 响应标头,如果 Firefox 尚未缓存图像,它似乎会导致 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)#" />
Run Code Online (Sandbox Code Playgroud)
鉴于 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>
Run Code Online (Sandbox Code Playgroud)
这可能比您需要的要简单一些。这个特定的代码实际上并没有检查图像是否已被修改,因为这不是我们真正担心的事情。这个应用程序只提供一组特定的图像,所以我们知道从这个应用程序提供的任何东西都是 PNG,所以我们可以安全地将内容类型标题设置为 image/png 并且因为图像真的不会改变,我不是打扰任何类型的实际日期检查。我可能真的可以让图像无限期地存在,但现在我让浏览器一次拥有它们一个星期。随着他们业务的增长,我可能会在以后增加这个持续时间。
工作的真正关键,使缓存工作的事情是 onRequest() 方法检查 if-modified-since 请求标头,并且当存在并且在所需的时间跨度内时,它通过不包括目标来截断整个请求page(因此剩余的页面代码都不会执行),而是仅设置 403 Not Modified 状态响应标头。
从长远来看,正如我所怀疑的那样,它实际上是一件非常简单的事情,显然只是被创建有关它的在线教程的人广泛误解。
要了解 HTTP,最好直接转到RFC 2616,或者至少是引用相关部分的教程。
在这种情况下,相关部分是响应头Last-Modified(第 14.29 节)、请求头If-Modified-Since(第 14.25 节)和状态304 Not Modified(第 10.3.5 节)。(不过,您可能还想阅读其他一些与缓存相关的内容。)
演示发生了什么的最好方法可能是查看 HTTP 请求/响应的样子。
所以这是对图像的第一个请求(为了清晰起见,去掉了一堆标题):
获取 /res/image.png HTTP/1.1 主机:mydomain.com 用户代理:我是浏览器 接受: */*
当 URL 为http://mydomain.com/res/image.png.
服务器解析它,找出合适的文件是什么,并以类似的方式响应:
HTTP/1.1 200 正常
日期:2014 年 5 月 6 日,星期二 22:33:44 GMT
最后修改时间:2014 年 5 月 3 日星期六 20:00:25 GMT
内容长度:4636
内容类型:图像/png;字符集=UTF-8
{图像数据}
当浏览器缓存内容时,它会记下 Last-Modified 日期,当它稍后发送请求时,它看起来像这样:
获取 /res/image.png HTTP/1.1 主机:mydomain.com If-Modified-Since:2014 年 5 月 3 日星期六 20:00:25 GMT 用户代理:我是浏览器 接受: */*
服务器根据文件的修改日期检查 If-Modified-Since,发现没有变化,并做出响应:
HTTP/1.1 304 未修改 日期:2014 年 5 月 6 日星期二 22:34:56 GMT
并且当然不返回图像数据。
(如果发生了更改,则响应将是 200(具有新的 Last-Modified 值)和新数据。)
| 归档时间: |
|
| 查看次数: |
716 次 |
| 最近记录: |