一. 前言

抛砖引玉: 提到项目性能优化,大部分人第一时间就会想到缓存,针对“读多写少”的数据,可以放到缓存里,设置个过期时间,这样就不用每次都去数据库中查询了, 减轻了数据库的压力,比如:商城项目的物品分类目录,不会经常变化,就可以放到缓存里。

详细分析:缓存的引入减轻了数据库的压力,但还是要访问服务器端的接口,需要执行接口中的代码,需要从缓存中读取数据,我们有没有办法直接访问一个页面,不再执行服务器端代码的业务呢?
答案是显然的,肯定有,那就是页面静态化

1. 什么是页面静态化?

  针对每个用户看到的页面显示的数据都是一样的情况,可以考虑把该页面直接生成一个html页面,存放到服务器的硬盘中,该html页面中是有数据的,其他用户直接访问该页面地址即可,这样既减轻了数据库的

压力,还不需要执行服务器端业务代码,显然是要比缓存好的。(通俗点说就是把原先要从数据库查询的数据写死到html中保存,用户直接通过服务器存放的地址进行访问)

案例:比如博客园,博主发表一篇文章,文章的内容对每个用户来说看到的内容都是一样的,这样的话新增文章的时候,内容固然要存到数据库,但同时将内容写到一个html页面里,保存到服务器硬盘上, 博主更新博客的时候,同样要更新原先的html静态页面,这样其他用户访问的时候,直接通过这个页面的地址进行访问即可。

PS:分享一个博客地址,https://www.cnblogs.com/yaopengfei/p/9216229.html 可以看出来最后都是 xxx.html ,显然是静态页面。

2. 页面静态化的适用范围?
   首先静态页的性能比缓存好,在条件适用的情况下,能用静态页就用静态页,静态页适用于相同地址所有人看到的内容都是一样的这种情况。

 

二. 案例剖析

   模拟一个简单的blog案例,来说明页面静态化在实际项目中的使用,该案例分为列表页和详情页面,包含的功能有:增加信息、修改信息、查看详情功能,同时简单的设计一下数据库,数据库内容如下:表blogs,表信息分别是:主键、博客标题、博客内容、博客其它信息、添加时间。

 

核心剖析: 

   事先准备一个查看详情页面的模板,每次增加信息或者修改信息的时候,调用【页面渲染为html字符串的方法】和【写入文件的方法】,将最新的信息保存到html中,进而存到硬盘上,供用户直接访问。

 渲染Html页面为字符串的方法如下,注意收藏哦:

 1        /// <summary>
 2         /// 将页面渲染成html字符串
 3         /// </summary>
 4         /// <param name="context">传入this.ControllerContext</param>
 5         /// <param name="viewPath">静态页面的模板路径</param>
 6         /// <param name="model">往模板中传入实体,进行赋值</param>
 7         /// <returns></returns>
 8         static string RenderViewToString(ControllerContext context, string viewPath, object model = null)
 9         {
10             ViewEngineResult viewEngineResult = ViewEngines.Engines.FindView(context, viewPath, null);
11             if (viewEngineResult == null)
12             {
13                 throw new FileNotFoundException("View" + viewPath + "cannot be found.");
14             }
15             var view = viewEngineResult.View;
16             context.Controller.ViewData.Model = model;
17             using (var sw = new StringWriter())
18             {
19                 var ctx = new ViewContext(context, view, context.Controller.ViewData, context.Controller.TempData, sw);
20                 view.Render(ctx, sw);
21                 return sw.ToString();
22             }
23         }

调用时候的代码:(修改与之类似)

 

三. 详细步骤和效果展示

 1. 主页面展示列表、包含查看详情、增加信息、修改信息三个操作。

前端代码分享

  1 @{
  2     Layout = null;
  3 }
  4 
  5 <!DOCTYPE html>
  6 
  7 <html>
  8 <head>
  9     <meta name="viewport" content="width=device-width" />
 10     <title>Index</title>
 11     <style>
 12         .mydiv1 {
 13             height: 400px;
 14             width: 800px;
 15             border: 1px solid black;
 16         }
 17 
 18         .myTitle {
 19             border-bottom: 1px solid black;
 20             height: 40px;
 21         }
 22 
 23         .myTitle div {
 24             float: left;
 25             width: 24%;
 26             border-right: 1px solid black;
 27             height: 40px;
 28             text-align: center;
 29             line-height: 40px;
 30         }
 31 
 32         .myTitle .lastdiv {
 33             border-right: 0px solid black;
 34         }
 35 
 36         .myContent div {
 37             float: left;
 38             width: 24%;
 39             height: 40px;
 40             text-align: center;
 41             line-height: 40px;
 42         }
 43     </style>
 44     <script src="~/Scripts/jquery-3.3.1.min.js"></script>
 45     <script>
 46         $(function () {
 47             //1. 加载信息
 48             $.post("/Home/InitInfor", {}, function (data) {
 49                 var myHtml = "";
 50                 for (var i = 0; i < data.length; i++) {
 51                     var newHtml = "<div class='myContent'>" +
 52                         "<div>" + data[i].id + "</div>" +
 53                         "<div>" + data[i].blogTitle + "</div>" +
 54                         "<div>" + data[i].blogContent + "</div>" +
 55                         "<div>" +
 56                         "<button data-id='" + data[i].id + "'>查看</button>" +
 57                         "</div>" +
 58                         "</div>";
 59                     myHtml = myHtml + newHtml;
 60                 }
 61                 $(".mydiv1").append(myHtml);
 62                 //给所有的查看按钮添加事件
 63                 $(".mydiv1").on("click", "button", function () {
 64                     var id = $(this).attr("data-id");
 65 
 66                     //1.传统的访问接口进行页面查看
 67                     //window.location.href = "/Home/DetilsViews?id=" + id;
 68 
 69                     //2.直接访问静态页面
 70                     window.location.href = "http://localhost:4482/StaticHtml/" + id + ".html";
 71 
 72                 });
 73 
 74             });
 75 
 76             //2. 增加事件
 77             $("#j_Add").on("click", function () {
 78                 var id = $("#j_id").val();
 79                 var blogTitle = $("#j_title").val();
 80                 var blogContent = $("#j_Content").val();
 81                 var blogOther = $("#j_Other").val();
 82 
 83                 $.post("/Home/AddBlog", { "id": id, "blogTitle": blogTitle, "blogContent": blogContent, "blogOther": blogOther }, function (data) {
 84                     if (data == "ok") {
 85                         var myHtml = "<div class='myContent'>" +
 86                             "<div>" + id + "</div>" +
 87                             "<div>" + blogTitle + "</div>" +
 88                             "<div>" + blogContent + "</div>" +
 89                             "<div>" +
 90                             "<button data-id='" + id + "'>查看</button>" +
 91                             "</div>" +
 92                             "</div>";
 93                         $(".mydiv1").append(myHtml);
 94 
 95                         alert("添加成功");
 96                     } else {
 97                         alert("添加失败");
 98                     }
 99                 });
100             });
101 
102             //3. 修改事件
103             $("#j_Edit").on("click", function () {
104                 var id = $("#j_id").val();
105                 var blogTitle = $("#j_title").val();
106                 var blogContent = $("#j_Content").val();
107                 var blogContent = $("#j_Other").val();
108 
109                 $.post("/Home/EditBlog", { "id": id, "blogTitle": blogTitle, "blogContent": blogContent, "blogOther": blogContent }, function (data) {
110                     if (data == "ok") {
111                         var myHtml = "<div class='myContent'>" +
112                             "<div>" + id + "</div>" +
113                             "<div>" + blogTitle + "</div>" +
114                             "<div>" + blogContent + "</div>" +
115                             "<div>" +
116                             "<button data-id='" + id + "'>查看</button>" +
117                             "</div>" +
118                             "</div>";
119                         $(".mydiv1").append(myHtml);
120 
121                         alert("修改成功");
122                         window.location.reload();
123                     } else {
124                         alert("修改失败");
125                     }
126                 });
127             });
128 
129 
130 
131         })
132     </script>
133 </head>
134 <body>
135     <div class="mydiv1">
136         <div class="myTitle">
137             <div>ID</div>
138             <div>题目</div>
139             <div>内容</div>
140             <div class="lastdiv">操作</div>
141         </div>
142         @*<div class="myContent">
143                 <div>1</div>
144                 <div>.Net学习</div>
145                 <div>技术部分语言</div>
146                 <div>
147                     <button>查看</button>
148                 </div>
149             </div>*@
150     </div>
151 
152     <div>
153         <p>ID:<input type="text" value="" id="j_id" /></p>
154         <p>题目:<input type="text" value="" id="j_title" /></p>
155         <p>内容:<input type="text" value="" id="j_Content" /></p>
156         <p>其他:<input type="text" value="" id="j_Other" /></p>
157         <p>
158             <button id="j_Add">增加</button>
159         </p>
160         <p>
161             <button id="j_Edit">修改</button>
162         </p>
163     </div>
164 </body>
165 </html>

View Code

服务端代码分享

 1         /// <summary>
 2         /// 主页面
 3         /// </summary>
 4         /// <returns></returns>
 5         public ActionResult Index()
 6         {
 7             return View();
 8         }
 9         /// <summary>
10         /// 获取所有数据
11         /// </summary>
12         /// <returns></returns>
13         public ActionResult InitInfor()
14         {
15             List<blogs> blogslist = db.blogs.OrderByDescending(u => u.addTime).ToList();
16             return Json(blogslist);
17         }

View Code

效果展示

 2. 增加信息,比如依次输入:66、.Net多线程、很神奇、敬请期待,点击增加按钮,插入数据库的同时,会生成一个以id来命名静态页面存放StaticHtml文件夹下。

后台代码分享:

 1         /// <summary>
 2         /// 增加博客
 3         /// </summary>
 4         /// <returns></returns>
 5         public ActionResult AddBlog(blogs b)
 6         {
 7             try
 8             {
 9                 //1.数据库保存操作
10                 b.addTime = DateTime.Now;
11                 db.blogs.Add(b);
12                 db.SaveChanges();
13 
14                 //2. 生成静态页面操作
15                 string myHtmls = RenderViewToString(this.ControllerContext, @"~/Views/Home/TempIndex.cshtml", b);
16                 System.IO.File.WriteAllText(Server.MapPath(@"~/StaticHtml/" + b.id + ".html"), myHtmls);
17                 return Content("ok");
18             }
19             catch (Exception)
20             {
21                 return Content("error");
22             }
23         }
24         /// <summary>
25         /// 获取所有数据
26         /// </summary>
27         /// <returns></returns>
28         public ActionResult InitInfor()
29         {
30             List<blogs> blogslist = db.blogs.OrderByDescending(u => u.addTime).ToList();
31             return Json(blogslist);
32         }

模板页面代码

 1 @{
 2     Layout = null;
 3 }
 4 
 5 <!DOCTYPE html>
 6 
 7 <html>
 8 <head>
 9     <meta charset="UTF-8">
10     <meta name="viewport" content="width=device-width" />
11     <title>详情页面</title>
12 </head>
13 <body>
14     <div>
15         <p>id:@Model.id</p>
16         <p>题目:@Model.blogTitle</p>
17         <p>内容:@Model.blogContent</p>
18         <p>其他:@Model.blogOther</p>
19         <p>时间:@Model.addTime</p>
20         
21     </div>
22 </body>
23 </html>

运行结果

 

3. 修改信息,修改数据库数据的同时,进行修改静态页面的内容。

 代码分享

 1        /// <summary>
 2         /// 编辑博客
 3         /// </summary>
 4         /// <param name=""></param>
 5         /// <returns></returns>
 6         public ActionResult EditBlog(blogs b)
 7         {
 8             try
 9             {
10                 //1.数据库修改操作
11                 blogs b1 = db.blogs.Where(u => u.id == b.id).FirstOrDefault();
12                 if (b1 == null)
13                 {
14                     return Content("error");
15                 }
16                 b1.blogTitle = b.blogTitle;
17                 b1.blogContent = b.blogContent;
18                 b1.blogOther = b.blogOther;
19                 b1.addTime = DateTime.Now;
20                 db.SaveChanges();
21 
22                 //2. 生成静态页面操作
23                 string myHtmls = RenderViewToString(this.ControllerContext, @"~/Views/Home/TempIndex.cshtml", b1);
24                 System.IO.File.WriteAllText(Server.MapPath(@"~/StaticHtml/" + b.id + ".html"), myHtmls);
25 
26                 return Content("ok");
27             }
28             catch (Exception)
29             {
30                 return Content("error");
31             }
32         } 

4. 查看详情,在没做页面静态化的时候,是这样处理的:获取该条数据的id→传到控制器的Action中→进行数据查询→页面渲染并显示页面。

 

而有了页面静态化后,直接通过地址打开页面即可。

 

 

 

 

 

 

 

!

  • 作       者 : Yaopengfei(姚鹏飞)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 声     明1 : 本人才疏学浅,用郭德纲的话说“我是一个小学生”,如有错误,欢迎讨论,请勿谩骂^_^。
  • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 

版权声明:本文为yaopengfei原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/yaopengfei/p/9707385.html