第七節:框架搭建之頁面靜態化的剖析


一. 前言

拋磚引玉: 提到項目性能優化,大部分人第一時間就會想到緩存,針對“讀多寫少”的數據,可以放到緩存里,設置個過期時間,這樣就不用每次都去數據庫中查詢了, 減輕了數據庫的壓力,比如:商城項目的物品分類目錄,不會經常變化,就可以放到緩存里。

詳細分析:緩存的引入減輕了數據庫的壓力,但還是要訪問服務器端的接口,需要執行接口中的代碼,需要從緩存中讀取數據,我們有沒有辦法直接訪問一個頁面,不再執行服務器端代碼的業務呢?
答案是顯然的,肯定有,那就是頁面靜態化

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 : 原創博客請在轉載時保留原文鏈接或在文章開頭加上本人博客地址,否則保留追究法律責任的權利。
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM