• 第七节:框架搭建之页面静态化的剖析


    一. 前言

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

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

    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 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
     
  • 相关阅读:
    C++中的extern "C"【转】
    无题
    MATLAB中文件的读写和数据的导入导出【转】
    逝去的2012
    C/C++语言中Static的作用详述
    C++:源文件与头文件有什么区别【转】
    Bash,后台与nohup
    关于include 和 extern
    python易错点
    android实现点击两次返回键实现退出功能
  • 原文地址:https://www.cnblogs.com/yaopengfei/p/9707385.html
Copyright © 2020-2023  润新知