本文主要介紹Web窗體頁面中的使用方法,MVC中使用方法,大家自行百度。
一、簡單一行指令即可實現
<%@ OutputCache VaryByParam="none" Duration="300" %>
這樣整個頁面就被緩存了,由於我是首頁進行的緩存,沒有任何參數所以VaryByParam值設置為none,如果希望通過指定的參數來緩存內容可以設置"id;classid"這種形式,或者干脆就用"*",通過所有參數來緩存內容。
二、緩存前后性能對比
使用ab模擬100個用戶1000次並發,前后結果如下:
如上圖所示,加了緩存之后,吞吐量大約增大了10倍,每次請求的處理時間縮小到原來的十分之一左右,性能明顯提升。
三、OutputCache的BUG
這個bug伴隨.NET1.0到4.0,就是OutputCache會忽略瀏覽器的緩存,本人用的是.NET 4.0,微軟官方說已經完美解決,但是實測bug依然存在,具體表現是:
1.VaryByParam設置為none時,沒有bug,F5刷新狀態碼每次都是304
2.VaryByParam設置為*或其他值時,每次按F5刷新狀態碼每次都是200
注:這個時候雖然瀏覽器沒有幫助我們緩存頁面,每次請求都是從服務器請求,但是服務器端是將頁面緩存了的,所以用ab測試效率依然是很高的。當然如果瀏覽器幫助我們緩存,壓根就不會產生這次請求了。
3.解決方法就是在Page_Load中加如下代碼
Response.Cache.SetOmitVaryStar(true);
這樣客戶端瀏覽器就實現了緩存,除非強制刷新,會再次從服務器端請求數據。
四、局部緩存數據,使部分數據不被緩存
這個就太常見了,我們總不希望登錄狀態也被緩存吧,假設頁面沒做任何改進,你登錄之前是【登錄】【注冊】這種按鈕,當你登錄后依然顯示【登錄】【注冊】這肯定是不妥的,那么我們希望這部分內容不被緩存,那我們就要用到Substitution控件。
在頁面中放置Substitution控件
<asp:Substitution ID="subLoginStatus" runat="server" MethodName="GetLoginStatus"/>
在后台cs文件中添加函數GetLoginStatus
public static string GetLoginStatus(HttpContext context) { if (context.Session["usr"] != null) { return context.Session["usr"].ToString() + "歡迎您的登錄"; } else { return "【登錄】【注冊】"; } }
這樣頁面其他部分都被緩存,只有登錄狀態是每次都動態讀取的。
注:由於頁面中有一部分是動態的,所以每次請求的狀態碼都是200。
五、OutputCache失效的問題
網上有說Cookie和Cache沖突,大家自行檢查,我在做的時候也確實遇到了OutputCache失效的問題,排查代碼發現,包含如下代碼
<script language="C#" runat="server"> string siteId = "ab71a8cfda50fbfeb2d3f6ee182af524"; </script> <!-- #include file="hm.aspx" --> <% string ret = TrackPageView(); %> <div style="display:none;"><img src="<%= ret %>" width="0" height="0"/></div>
這段代碼是百度的統計代碼,去掉之后解決。如果確實想加百度的統計,可以替換如下類似代碼:
<div style="display:none;"> <script> var _hmt = _hmt || []; (function () { var hm = document.createElement("script"); hm.src = "//hm.baidu.com/hm.js?ab71a8cfda50fbfeb2d3f6ee182af524"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); </script> </div>