2014-05-06 62 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/