2014-05-06 61 views
3
交付

我的一个客户不断抱怨说,他们的网站是不够快......这是一种奇怪的我,因为当他们在几个月前聘请我,他们不能保持服务器运行24小时,因为它缓存太多,内存不足。所以我删除了大部分的缓存,优化他们的数据库,得到了他们一个新的服务器的至少5倍的强大上(的处理器,RAM和速度都量 - 他们有4倍之多的处理器现在每几乎相同的时钟速度) ,他们抱怨说“我们的网站从来没有这么烂!”。广东话缓存图像内容cfcontent

所以我经历的所有事情的清单,谷歌表示,将提高性能,同时希望在最终要么他们会很乐意与它或它们会意识到,他们的网站是做了很多工作,并且他们的服务器上有限制,并且有些页面需要几秒钟才能加载,就像你无法在一个小时内手动建立整辆汽车一样。所有我做过的研究表明,如果我指定的Cache-Control,Expires和的Last-Modified头,但无论我怎么设置他们的ColdFusion,Firefox和Chrome都拒绝使用缓存的Firefox应该使用它的缓存。我可以手动设置304响应标题,这似乎会导致Firefox在没有缓存图像时不返回任何内容。 (?!)

所以我有这样的代码。很简单。几乎所有的文件都说它应该是。 FireBug一直报告(尽管重新启动,缓存清除,强制重新加载等)内容是在几秒前创建的,而不是像7天前在cfheader中设置的那样。另一方面,Chrome会在一周前报告上次修改日期,但会报告请求标头中的最大年龄为0。 (?!!)(缓存在Chrome开发工具中启用,所以我知道不是这样。)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,因为图像确实不会改变,我不会麻烦任何一种实际的日期检查。我可能真的可以让图像无限期地生活,但现在我让浏览器每次都有一周的时间。随着业务的增长,我可能会延长这段时间。onRequest()方法检查if-modified-since请求头,当存在并在所需的时间范围内时,它通过以下方式截断整个请求:不包括目标页面(所以剩下的页面代码都不会执行),而是只设置403 Not Modified状态响应头。

从长远来看,正如我所怀疑的那样,这实际上是一件非常简单的事情,它显然被创建在线教程的人们广泛误解。

+0

你试过像HTTP成形工具://www.fusion -reactor.com/ - 他们有14天免费试用 - 这可以帮助解决原始错误,允许您删除缓存标头 – Antony

+0

我们正在服务器上运行聚变反应堆......但没有错误被抛出来自CF,所以我不确定这有什么帮助? –

+0

关于“聚变反应堆”的建议是,如果你修复了网站性能不佳的情况,那么你就不需要缓存标题,这会让你感到悲伤。修复缓存头并不能真正修复服务器性能,它只是掩盖了它。 – Antony

回答

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}

当浏览器它的缓存的东西,它使笔记的最后修改日期,而当后来发来的请求它看起来像这样:

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-由于对文件的修改日期,认为没有变化,并回应:

HTTP/1.1 304 Not Modified 
Date: Tue, 06 May 2014 22:34:56 GMT

并且当然不返回图像数据。

(如果出现了变化,他们的回应是200(用新的Last-Modified值)和新数据)

1

如果有足够多的CFContent交付的Web资源请求,可能会发生拒绝服务。如果访问者,僵尸程序或黑客处于缓慢连接(或限制其带宽),您的ColdFusion线程将很快填满并排入队列。

为什么图像无法通过添加特殊“7天过期”标题规则的子目录使用Web服务器提供?

如果图像是唯一的,您可以在脱机临时目录中生成它们,设置目录映射,然后使用唯一的或基于会话的文件名,并使用计划任务清理过时的图像。

该网站的页面加载时间也可以通过延迟加载图像获益。这将加载网页,并且只在“上方”显示可见图像。这可以使用JavaScript来完成。如果你使用jQuery,这里有一个像样的插件:http://www.appelsiini.net/projects/lazyload

你是否将ColdFusion处理时间添加到生成的HTML中?我们在开始&结束时使用GetTickCount(),然后将生成时间作为HTML(Execution:163毫秒)中的注释发布。如果你看到时间不多,那么瓶颈就不是ColdFusion。

关于网页性能,我使用Google PageSpeed获得了巨大成功。 (我在IIS7上,所以我不得不使用IISpeed http://www.iispeed.com/)在我的其中一个网站上,具有许多产品图像的网页的感知加载时间从13秒增加到7.2(加快-5.8s/44%) 。

https://www.youtube.com/watch?v=VwEGGB-4sMw

我只使用ColdFusion测试IISpeed。在每个站点的基础上,我们使用IISpeed上的ColdFusion 9生成的页面自动执行以下优化:

  • 结合&优先考虑关键CSS
  • 移动CSS以上脚本到头部
  • 合并,缩减大小&推迟JavaScript的&移到头
  • 扩展缓存(使用哈希缓存资源为1年,除非改变)
  • 延迟加载图片,雪碧图片&转换JPE克至逐行
  • 优化图像(大小调整为更小的设备屏幕图像&提供的WebP到Chomr浏览器)
  • 压缩空白&删除评论

测试您的网站的页面加载速度,使用http://www.webpagetest.org/