在改善页面性能的同时,可能会采用静态化的策略,对于不能实时静态化的内容,则采用缓存。本文主要讨论如何实现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中的分部视图。