📜 ⬆️ ⬇️

Several ways to speed up an application on ASP.NET WebForms

There is a widespread belief that ASP.NET WebForms applications are very slow, heavy, suitable only for corporate portals and mostly work on intranets. However, there are several ways to significantly increase the speed of your application. Most of these methods are not new, used by many developers. Here we have collected those of them that have worked well in developing the AdVantShop.NET Ultimate engine.

1. We refuse from UpdatePanel


One of the most important factors hindering the work of a web site on ASP.NET WebForms is the use of UpdatePanel. For his work is required to place on the ScriptManager page. This is the first problem.
Let's try to create an aspx-page and put a simple Label inside the UpatePanel
<asp:ScriptManager runat="server" /> <asp:UpdatePanel ID="Updatepanel1" runat="server"> <ContentTemplate> <asp:Label runat="server" Text="Hello world!" /> </ContentTemplate> </asp:UpdatePanel> 


Run the project, see what it has become:
 <script src="/WebSite1/WebResource.axd?d=ddsVPpuyrEEfoBbqjFYV9oHZ-YB8armGl03nreWb8sxbdd0MXlSne0kVoo7mheRQ1cxLip1L_44SDmzKsEIHZW930AWZ2Zs_ae9a9NTgNck1&t=634790730663322540" type="text/javascript"></script> 

')
 <script src="/WebSite1/ScriptResource.axd?d=x2K70A_qh5LLRPvqydlLAwONxKroPWgAGdmlhYHXFoXfUrRwcjMDwh9AgTRQkLVd0gEj8C6MhbyA_hq2RLgNpJxsoak2SQ5Dsi8RIcHR-k72-HxC0Vc2GfaaM_NqOWGS6pN4O31eNf9cYeLVlOWAro2fu6lKP46_8vn-OGH5mmN_8TmV6BQKdue5UaNBp45o0&t=ffffffff940d030f" type="text/javascript"></script> <script type="text/javascript"> //<![CDATA[ if (typeof(Sys) === 'undefined') throw new Error('ASP.NET Ajax client-side framework failed to load.'); //]]> </script> ScriptResource.axd? d = x2K70A_qh5LLRPvqydlLAwONxKroPWgAGdmlhYHXFoXfUrRwcjMDwh9AgTRQkLVd0gEj8C6MhbyA_hq2RLgNpJxsoak2SQ5Dsi8RIcHR-k72-HxC0Vc2GfaaM_NqOWGS6pN4O31eNf9cYeLVlOWAro2fu6lKP46_8vn-OGH5mmN_8TmV6BQKdue5UaNBp45o0 & t = ffffffff940d030f" type = "text / javascript"> </ script> <script src="/WebSite1/ScriptResource.axd?d=x2K70A_qh5LLRPvqydlLAwONxKroPWgAGdmlhYHXFoXfUrRwcjMDwh9AgTRQkLVd0gEj8C6MhbyA_hq2RLgNpJxsoak2SQ5Dsi8RIcHR-k72-HxC0Vc2GfaaM_NqOWGS6pN4O31eNf9cYeLVlOWAro2fu6lKP46_8vn-OGH5mmN_8TmV6BQKdue5UaNBp45o0&t=ffffffff940d030f" type="text/javascript"></script> <script type="text/javascript"> //<![CDATA[ if (typeof(Sys) === 'undefined') throw new Error('ASP.NET Ajax client-side framework failed to load.'); //]]> </script> 


 <script src="/WebSite1/ScriptResource.axd?d=JmrJ_HQ4TGD_jchBEWNRb8OenR4k6OQ7VRyH_toBPQT3JUiqiQs3R0jW7v7zXJ2kEQZHsBtgkthfErRPRvwOKI-uadU-pRHAfl5iwxP1hhqLZX5DmrmatAe9-DtrY8UpvLZcFvWHClUe3sQQzRVLcMCbnpjYQ_AnnrUMVfpTPXHnstGsM4ZnlODzOKmhM5LU0&t=ffffffff940d030f" type="text/javascript"></script> <script type="text/javascript"> //<![CDATA[ Sys.WebForms.PageRequestManager._initialize('ctl02', 'form1', ['tUpdatepanel1','Updatepanel1'], [], [], 90, ''); //]]> </script> ScriptResource.axd? d = JmrJ_HQ4TGD_jchBEWNRb8OenR4k6OQ7VRyH_toBPQT3JUiqiQs3R0jW7v7zXJ2kEQZHsBtgkthfErRPRvwOKI-uadU-pRHAfl5iwxP1hhqLZX5DmrmatAe9-DtrY8UpvLZcFvWHClUe3sQQzRVLcMCbnpjYQ_AnnrUMVfpTPXHnstGsM4ZnlODzOKmhM5LU0 & t = ffffffff940d030f" type = "text / javascript"> </ script> <script src="/WebSite1/ScriptResource.axd?d=JmrJ_HQ4TGD_jchBEWNRb8OenR4k6OQ7VRyH_toBPQT3JUiqiQs3R0jW7v7zXJ2kEQZHsBtgkthfErRPRvwOKI-uadU-pRHAfl5iwxP1hhqLZX5DmrmatAe9-DtrY8UpvLZcFvWHClUe3sQQzRVLcMCbnpjYQ_AnnrUMVfpTPXHnstGsM4ZnlODzOKmhM5LU0&t=ffffffff940d030f" type="text/javascript"></script> <script type="text/javascript"> //<![CDATA[ Sys.WebForms.PageRequestManager._initialize('ctl02', 'form1', ['tUpdatepanel1','Updatepanel1'], [], [], 90, ''); //]]> </script> 


 <div id="Updatepanel1"> <span>Hello world!</span> </div> 


image

We see that to display simple text inside UpdatePanel it took 2 kb html and another almost 100 kb of scripts. The same without UpdatePanel takes about 500 bytes.
The second problem is the life cycle of the page. That which is completely absent in ASP.NET MVC, and that has to get along with in ASP.NET WebForms. More differences are here .
For any event inside UpdatePanel, PostBack occurs and all page events are performed on which difficult calculations or database queries can occur. If you do not use a circle like:
  if(!Page.IsPostBack) { Do something… } 


then the application will not work as fast as we would like.

A simple example:

The user enters the order number and you need to display its current status, without reloading the entire page.

image

How can this be done without using UpdatePanel.
Create a class http request handler
 public class CheckOrder : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "application/json"; Order order = OrderService.GetOrder(context["number"]); if(order != null) { var statusResult = new { Status = order.Status, Comment = order.Comment }; context.Response.Write(JsonConvert.SerializeObject( statusResult)); } } public bool IsReusable { get { return true;} } } 


Here, the Newtonsoft.Json library is also useful for serializing objects in JSON. But you can do without it just returning the text.
Next, we create a js function, which, using jquery, when you click on the “Check” button, will send a request for status via ajax get.

 function CheckOrder(ordernum) { $.ajax({ async: false, dataType: "json", cache: false, url: "checkorder.ashx", data: { number: ordernum }, success: function (status) { $("#orderStatus").text(status.Status); $("#orderComment").text(status.Comment); }, error: function () { $("#orderStatus").text("  ")); } }); } 


Everything is very simple, but effective. Also, instead of httphandler, you can get away with the static method in the page class. To do this, simply mark it with the attribute [WebMethod].

2. Getting rid of ViewState



ViewState is another feature of WebForms. It has its pros and cons, which are well described in this article . However, in most cases you can do without it. In older versions of AdvantShop.Net, ViewState on different pages ranged from 15 to 30 kb, which was very unpleasant, since these kilobytes were sent on every page to the page. How can this, if not avoided, then at least minimize the risks?
It is enough just to register on the Master Page.

 <%@ Master Language="C#" CodeFile="MasterPage.master.cs" Inherits="MasterPage" EnableViewState="false" ViewStateMode="Disabled" %> 


However, problems will begin with such controls that require a ViewState to store its state — for example, a DropDownList or ListView. In such cases, ViewState will have to be enabled, but it can be disabled for each control that does not use it. Link for those interested.

3. We leave from standard and AjaxControlToolkit



It so happened that in Microsoft, when developing controls for ASP.NET, they didn’t particularly think about the cleanliness and optimality of the layout, the number of requests and the speed of these controls. GridView is very slow, TreeView generates a terrible layout, Calendar is difficult to set up and clutters up html. Those who used them could see for themselves.
Easy way out is to use jquery plugins or any other js frameworks .

4. Minimize page content



To increase the speed of the site, it is necessary to reduce the number of http requests to the server and compress the static content of the pages as much as possible: images, css and js files. With images here everything is clear - use the above compression ratio and sprites. Css and js files can be compressed using special minimizers . However, this is inconvenient, you have to store two versions: full - for editing and debug, and minimized - for production.
Another way is to use the SquishIt library. How to do this, you can read here . As a result, we combine and minimize all js and css into two files, reduce the number of requests and increase the page load time by about two seconds.
Before use:

image
After:

image

5. Compress HTML


Most browsers support content compression GZip or Deflate. Create a class that will perform compression.

 namespace AdvantShop.Core.Compress { public class CompressContent : IHttpModule { public void Dispose() { // Nothing to dispose; } public void Init(HttpApplication context) { context.PreRequestHandlerExecute += PreRequestHandlerExecute; } private static void PreRequestHandlerExecute(object sender, EventArgs e) { var app = (HttpApplication)sender; HttpRequest request = app.Context.Request; HttpResponse response = app.Context.Response; if (request.FilePath.Contains(".aspx") || request.FilePath.Contains(".js") || request.FilePath.Contains(".css")) { if (!(request.Browser.IsBrowser("IE") && request.Browser.MajorVersion <= 6)) // IE6 does not support compression { string acceptEncoding = request.Headers[HttpConstants.HttpAcceptEncoding]; if (!string.IsNullOrEmpty(acceptEncoding)) { acceptEncoding = acceptEncoding.ToLower(CultureInfo.InvariantCulture); if (acceptEncoding.Contains(HttpConstants.HttpContentEncodingGzip)) { response.Filter = new HttpCompressStream(response.Filter, CompressionMode.Compress, HttpCompressStream.CompressionType.GZip); response.AddHeader(HttpConstants.HttpContentEncoding, HttpConstants.HttpContentEncodingGzip); } else if (acceptEncoding.Contains(HttpConstants.HttpContentEncodingDeflate)) { response.Filter = new HttpCompressStream(response.Filter, CompressionMode.Compress, HttpCompressStream.CompressionType.Deflate); response.AddHeader(HttpConstants.HttpContentEncoding, HttpConstants.HttpContentEncodingDeflate); } } } else { response.Filter = new HttpCompressStream(response.Filter, CompressionMode.Compress, HttpCompressStream.CompressionType.None); } } } } } 

Then, in order to connect this module to your application, we simply add lines to the web.config:
 <modules> <add name="CompressContent" type="AdvantShop.Core.Compress.CompressContent"/> </modules> 


We get a very good result - text compression four times. And not only html is compressed, but also js and css.
Before:
image
After:
image

6. We cache UserControls


To cache User Control, it is enough to put a line like this in the control header:
 <%@ OutputCache Duration="60" VaryByParam="CategoryID" %> 

Thus, we indicate that the control will be stored in the cache for 60 seconds and its own version of the cache will be created depending on the parameter from Request [“CategoryID”].
Instead of conclusion
These are only basic acceleration techniques that are more applicable to WebForms. However, do not forget about other methods, especially those pointed out by this useful tool - PageSpeed .

Source: https://habr.com/ru/post/155985/


All Articles