zoukankan      html  css  js  c++  java
  • 高性能页面加载技术(流水线加载)BigPipe的C#简单实现(附源码)

    一,BigPipe简介

        BigPipe是一个重新设计的基础动态网页服务体系。大体思路是,分解网页成叫做Pagelets的小块,然后通过Web服务器浏览器建立管道并管理他们在不同阶段的运行。这是类似于大多数现代微处理器的流水线执行过程:多重指令管线通过不同的处理器执行单元,以达到性能的最佳。虽然BigPipe是对现有的服务网络基础过程的重新设计,但它却不需要改变现有的网络浏览器或服务器,它完全使用PHPJavaScript来实现。(来源百度百科

      BigPipe可以简单理解为:将网页分为若干个块(pagelet),请求到达服务器后先初始化pagelet布局并Response.Write(这时用户能看到网页的大致布局),然后使用多线程并行执每个pagelet 的业务逻辑,每个pagelet线程执行完后立即Response.Write,对于用户来说,他看到的网页是一块块同时或先后呈现出来,和ajax异步加载比较类似。

    二,实现思路

        1, 前端实现:需要一个js接收服务端输出的HTML,并显示到对应的pagelet中,每个pagelet是一个局部视图(partialView), 代码如下:

       

     1 var PageLet = PageLet || {};
     2 
     3 PageLet = (function () {
     4     var LoadCss = function (css) {
     5         var c = document.createElement("link");
     6         c.setAttribute("type", "text/css");
     7         c.setAttribute("rel", "stylesheet");
     8         c.setAttribute("href", css);
     9         document.getElementsByTagName("head")[0].appendChild(c);
    10     }
    11     var LoadJs = function (js) {
    12         var s = document.createElement("script");
    13         s.setAttribute("type", "text/javascript");
    14         s.setAttribute("src", js);
    15         document.getElementsByTagName("head")[0].appendChild(s);
    16     }
    17     //PageLet对象公开InitHtml方法,在后台的输出HTML时会带上该方法。
    18 
    19 var InitHtml = function (json) { $('#' + json.Pid).html(json.Html); LoadCss(json.Css); LoadJs(json.Js); } return { InitHtml: InitHtml } })();

      

            2,服务端实现:先初始化页面pagelet布局并输出,然后用多线程并行执行没个pagelet里的业务,执行完后立即输出,这里需要注意的是:输出的HTML代码(partailView)需要做一个JS包裹,只有这样这段HTML代码才能在对应的pagelet显示。代码如下:

    HomeController.cs

      1 using MyBigPipe.Common;
      2 using MyBigPipe.Models;
      3 using Newtonsoft.Json;
      4 using System;
      5 using System.Collections.Generic;
      6 using System.Linq;
      7 using System.Threading;
      8 using System.Threading.Tasks;
      9 using System.Web;
     10 using System.Web.Mvc;
     11 
     12 namespace MyBigPipe.Controllers
     13 {
     14     public class HomeController : Controller
     15     {
     16         private static readonly object _sysRoot = new object();
     17 
     18         public void Index()
     19         {
     20             InitHomeHtml();
     21 
     22             Parallel.Invoke(() =>
     23             {
     24                 //模拟操作1秒
     25                 Thread.Sleep(500);
     26                 //头部块
     27                 InitTop();
     28 
     29             }, () =>
     30             {
     31                 Thread.Sleep(500);
     32                 InitLeft();
     33 
     34             }, () =>
     35             {
     36                 Thread.Sleep(1000);
     37                 //右边块
     38                 InitRight();
     39 
     40             }, () =>
     41             {
     42                 Thread.Sleep(1000);
     43                 //底部块
     44                 InitFoot();
     45             });
     46         }
     47 
     48         private void InitTop()
     49         {
     50             ViewBag.Top = "TopTopTopTopTopTopTopTopTopTopTopTopTopTopTopTopTopTopTopTopTopTopTopTopTopTopTop";
     51 
     52             Pagelet pagelet = new Pagelet()
     53             {
     54                 Css = "",
     55                 Html = Helper.RenderPartialViewToString(this, "TopPartial"),
     56                 //Js = "/Scripts/BigPipeT1.js",
     57                 Js = "",
     58                 Pid = "topId"
     59             };
     60             lock (_sysRoot)
     61             {
     62                 Response.Write("<script type='text/javascript'>PageLet.InitHtml(" + JsonConvert.SerializeObject(pagelet) + ");</script>");
     63                 Response.Flush();
     64                 Response.Clear();
     65             }
     66         }
     67 
     68         private void InitLeft()
     69         {
     70             ViewBag.Left = "bbbbbbbbbbbbbbbbbbbbbbb";
     71 
     72             Pagelet pagelet = new Pagelet()
     73             {
     74                 Css = "",
     75                 Html = Helper.RenderPartialViewToString(this, "LeftPartial"),
     76                 Js = "",
     77                 Pid = "leftId"
     78             };
     79             lock (_sysRoot)
     80             {
     81                 Response.Write("<script type='text/javascript'>PageLet.InitHtml(" + JsonConvert.SerializeObject(pagelet) + ");</script>");
     82                 Response.Flush();
     83                 Response.Clear();
     84             }
     85         }
     86 
     87         private void InitRight()
     88         {
     89            
     90             Pagelet pagelet = new Pagelet()
     91             {
     92                 Css = "",
     93                 Html = Helper.RenderPartialViewToString(this, "RightPartial"),
     94                 Js = "",
     95                 Pid = "rightId"
     96             };
     97             lock (_sysRoot)
     98             {
     99                 Response.Write("<script type='text/javascript'>PageLet.InitHtml(" + JsonConvert.SerializeObject(pagelet) + ");</script>");
    100                 Response.Flush();
    101                 Response.Clear();
    102             }
    103         }
    104 
    105         private void InitFoot()
    106         {
    107             lock (_sysRoot)
    108             {
    109                 Response.Write(
    110                 new Pagelet()
    111                 {
    112                     Css = "",
    113                     Html = Helper.RenderPartialViewToString(this, "FootPartial"),
    114                     Js = "",
    115                     Pid = "footId",
    116                     PartialViewName = "FootPartial"
    117 
    118                 }.RenderHtml(this));
    119                 Response.Flush();
    120                 Response.Clear();
    121             }
    122         }
    123 
    124         /// <summary>
    125         /// 初始化HTML网页框架
    126         /// </summary>
    127         private void InitHomeHtml()
    128         {
    129             var str = Helper.RenderPartialViewToString(this, "Index");
    130             Response.Write(str);
    131             Response.Flush();
    132             Response.Clear();
    133         }
    134     }
    135 }
    View Code

         

    三,总结

        BigPipe和Ajax二者区别:对于一个分成若干个块的页面而言,如果使用Ajax的话,每一块都需要单独发送一个HTTP请求,而如果使用BigPipe的话,不管有多少块,都仅有一个HTTP请

                                         求。所以Ajax对服务器造成的压力会是BigPipe的若干倍。

         BigPipe优点:速度快,将页面分割成多个pagelet,后台代码会为每个pagelet开启线程执行代码逻辑,执行完后立即输出到前端

         BigPipe缺点:不利于SEO, 对于这点可以写两份代码,一份使用bigpipe,一份不使用, 用User Agen判断访问者是用户还是搜索引擎,分别执行对应的那份代码。当然这样工作量增加了。

    下载源码

  • 相关阅读:
    java基础_面试题笔记
    ACM-ICPC 2018 Xuzhou Online Contest题解
    覆盖点问题总结
    2018icpc沈阳网络赛题解(转发)
    树链剖分
    树状数组
    线段树板子
    sdoi2016生成魔咒
    洛谷3804
    大佬博文收集
  • 原文地址:https://www.cnblogs.com/wangjun1234/p/4468107.html
Copyright © 2011-2022 走看看