在改善頁面性能的同時,可能會採用靜態化的策略,對於不能實時靜態化的內容,則採用緩存。本文主要討論如何實現cshtml的靜態化(實際上還不是徹底的html文件,由於還有一些沒法實時靜態化的內容須要再嵌入C#代碼,此處暫不討論),以及靜態化所帶來的一些問題。
對於一個搜索頁面,如租房,有幾個地區、價格、戶型的分類搜索,這些分類搜索是容許疊加使用的,而且,一個組合的搜索結果中可能還有好幾頁的內容,因此,咱們要作的靜態化,就是要窮盡全部的組合,並生成相應靜態文件(通常來講,用戶輸入的自定義關鍵詞並不做靜態化處理,由於難以窮盡,除非針對一些搜索頻率比較大的關鍵詞)。
通常就是使用數學中的組合方法,即地區有n個,價格區間有m個,戶型有k個,分頁有s個,那麼,生成的靜態頁面就有total=n*m*k*s個。還有一個問題就是生成的頻率,是天天生成一次,仍是多長時間生成一次。而且生成的過程是須要時間的,在未生成時,若是有請求,此時應該如何處理等等也須要考慮。
調用通常的var tt = View("Index","Test");並不能在變量tt中如願的獲得最終的html代碼,仍是須要做必定的處理的。能夠參考如下代碼:
protected static string RenderViewToString(Controller controller, string viewName, string masterName)
{
if (System.Web.HttpContext.Current != null)
wrapper = new HttpContextWrapper(System.Web.HttpContext.Current);
throw new InvalidOperationException(
"Can't create Controller Context if no "+
"active HttpContext instance is available.");
routeData = new RouteData();
// add the controller routing if not existing
if (!routeData.Values.ContainsKey("controller") &&
!routeData.Values.ContainsKey("Controller"))
routeData.Values.Add("controller",
.Name.ToLower() .Replace("controller", ""));
controller.ControllerContext = new ControllerContext(wrapper, routeData, controller);
IView view = ViewEngines.Engines.FindView(controller.ControllerContext, viewName, masterName).View;
using (StringWriter writer = new StringWriter())
{
ViewContext viewContext = new ViewContext(controller.ControllerContext, view, controller.ViewData, controller.TempData, writer);
viewContext.View.Render(viewContext, writer);
return writer.ToString();
}
}
這段代碼僅供參考,由於老是會提示controller.ControllerContext爲空而報錯,因此,能夠粗略地加上上面一段來給controller.ControllerContext賦值。上面的代碼,並非最終實現了的版本,還須要改進,而且最好實現成Controller的擴展方法的形式比較方便。
調用時,以下:
var controller = new TestController();
var tt = RenderViewToString(controller,"Index",null);
不出錯的話,就能夠如願獲得相應的html代碼,接着就是將代碼保存在相應的目錄下。
3 出現的一些問題。
當一個搜索頁面須要生成成百上千個cshtml代碼時,則網站這個靜態化過的頁面,第一次打開時,會經歷一個比較長的搜索時間,有時是幾秒鐘,有時是幾十秒上分鐘,第二次打開時,則不會再出現這種狀況。此時,能夠作的事情主要有以下幾個:
(1)把生成的cshtml代碼以文件夾分開,由於第一次打開時間較長主要適用的單位是文件夾,若有兩個文件夾A,B,而且兩個文件夾內均有1000個cshtml文件,則第一次訪問A中的任何文件時,會比較慢,以後再訪問A中的任何文件則不會,而打開A中文件,實際上是不影響B中文件夾的,因此,要使B中文件訪問速度加快,則也要至少訪問B中的一個文件。
(2)訪問文件的操做能夠使用HttpGet的方法模擬進行,而且最好使用異步進行,否則可能會致使請求超時。異步的方法主要有ajax和多線程。
(3)曾經查找過多cshtml文件第一次加載時慢的問題,但沒有找到相關機制,最理想的方式,是經過代碼主動去更新相關信息(如緩存)等,而不是模擬用戶的點擊行爲。可能的途徑是去查看asp.net mvc源代碼。
注:對於cshtml靜態化,能夠徹底的靜態化,生成最終的html代碼,也能夠部分靜態化,即還容許Layout的正常加載。對於第一種形式,還須要考慮相應的_Layout.cshtml以及_Layout.cshtml中的分部視圖。