今天这篇文章咱们来聊一聊如何提高并优化ASP.NET Core应用程序的性能,本文的大部份内容来自翻译,固然中间穿插着本身的理解,但愿对你们有所帮助!话很少说开始今天的主题吧!
咱们都知道性能是公共网站取得成功的关键因素之一。若是一个网站的响应时间超过3秒,那么用户一般不会再此光顾(此网站)。谷歌,Bing,百度以及其余搜索引擎也更倾向于推荐优化后的,移动友好的以及响应速度更快的网站。css
做者:依乐祝html
原文地址:https://www.cnblogs.com/yilezhu/p/10507984.html算法
大部份内容翻译自:https://www.c-sharpcorner.com/article/10-tips-to-improve-performance-of-asp-net-core-application/数据库
这里咱们举一个例子:咱们有多个搜索引擎,如Google、Bing、百度、搜狗等等;然而,咱们更喜欢Google或Bing,由于这些搜索引擎速度很是快,能够在3-4秒内得到结果。若是这些搜索引擎的响应速度超过10秒,你还会使用它们吗?我认为大伙应该不会用了吧。现在的用户最不能容忍的想必就是等待了吧。编程
今天,咱们将学习一些有助于提升ASP.NET Core网站性能的一些小技巧。但愿你们可以有所收获。c#
咱们都知道ASP.NET Core是微软提供的一个免费的、开源的、跨平台的Web开发框架。它不是ASP.NET的升级版本,但它是一个从头开始彻底重写的框架,它附带了ASP.NET MVC和ASP.NET Web API的单一编程模型。缓存
在这里,我不打算讨论ASP.NET Core及其特性。若是您是ASP.NET Core的新手,您能够阅读个人ASP.NET Core实战教程《.NET Core实战项目之CMS 第一章 入门篇-开篇及整体规划》服务器
下面咱们就开始今天的主题,如何提高ASP.NET Core应用程序的性能的技巧开始吧。微信
ASP.NET Core的第一个版本是在2016年与VisualStudio 2015一块儿发布的,如今咱们有了ASP.NET Core3.0,每个新版本都愈来愈好。最新的ASP.NET Core 3.0的主要更新以下:网络
友情提示:在构建新的ASP.NET Core项目时,不要忘记选择最新版本。VisualStudio 2019预览版如今已经支持ASP.NET Core 3.0了。
在开发ASP.NET Core应用程序时,尽可能避免建立阻塞的调用。阻塞调用是指当前请求未完成以前会一直阻止下一个执行的调用。阻塞调用或同步调用能够是任何东西,能够是从API中获取数据,也能够是执行一些内部操做。您应该始终以异步方式执行调用。
异步编程模型是在C#5.0中引入的,并变得很是流行。ASP.NET Core使用相同的异步编程范例来使应用程序更可靠、更快和更稳定。
您应该在代码中使用端到端异步编程。
让咱们举一个例子;咱们有一个ASP.NET CoreMVC应用程序,中间有一些数据库的操做。正如咱们所知道的,它可能有不少分层结构,这都取决于用户的项目架构,可是让咱们举一个简单的例子,其中咱们有Controller》Repository 层等等。让咱们看看如何在控制器层编写示例代码。
[HttpGet] [Route("GetPosts")] public async Task GetPosts() { try { var posts = await postRepository.GetPosts(); if (posts == null) { return NotFound(); } return Ok(posts); } catch (Exception) { return BadRequest(); } }
接下来的代码然是了咱们如何在repository 层实现异步编程。
public async Task<List<PostViewModel>> GetPosts() { if (db != null) { return await (from p in db.Post from c in db.Category where p.CategoryId == c.Id select new PostViewModel { PostId = p.PostId, Title = p.Title, Description = p.Description, CategoryId = p.CategoryId, CategoryName = c.Name, CreatedDate = p.CreatedDate }).ToListAsync(); } return null; }
在使用异步编程时,我建议您避免使用Task.Wait和Task.Result并尝试使用WAIT,缘由以下:
下面让咱们分别演示下正确使用以及不建议使用Task.Wait 的例子,来加深理解吧!
// 正确的例子 Task task = DoWork(); await task; // 不建议使用的例子 Task task = DoWork(); task.Wait();
下面让咱们分别演示下正确使用以及不规范使用Task.Result 的例子,来加深理解吧!
// Good Performance on UI Task<string> task = GetEmployeeName(); txtEmployeeName.Text = await task; // Bad Performance on UI Task<string> task = GetEmployeeName(); txtEmployeeName.Text = task.Result;
了解更多关于异步编程的最佳实践.
在执行I/O操做时,您应该异步执行它们,这样就不会影响其余进程。I/O操做意味着对文件执行一些操做,好比上传或检索文件。它能够是任何操做如:图像上传,文件上传或其余任何操做。若是您试图以同步的方式完成它,那么它会阻塞主线程并中止其余后台执行,直到I/O完成为止。所以,从提高性能上来讲,您在对I/O进行操做时应该始终进行异步执行。
咱们有不少异步方法可用于I/O操做,如ReadAsync、WriteAsync、FlushAysnc等。下面是一个简单的例子,说明咱们如何异步建立一个文件的副本。
public async void CreateCopyOfFile() { string dir = @"c:\Mukesh\files\"; using (StreamReader objStreamReader= File.OpenText(dir + "test.txt")) { using (StreamWriter objStreamWriter= File.CreateText(dir+ "copy_test.txt")) { await CopyFileToTarget(objStreamReader, objStreamWriter); } } } public async Task CopyFileToTarget(StreamReader objStreamReader, StreamWriter objStreamWriter) { int num; char[] buffer = new char[0x1000]; while ((num= await objStreamReader.ReadAsync(buffer, 0, buffer.Length)) != 0) { await objStreamWriter.WriteAsync(buffer, 0, num); } }
若是咱们能在每次执行的时候减小减小对服务器的请求次数,那么咱们就能够提升应用程序的性能。这并不意味着您执行的时候不会请求服务器,而是意味着您不会每次执行都请求服务器。第一次,您将请求服务器并得到响应,此响应将在某个地方存储一段时间(将有一些到期),下一次当您对相同的响应进行调用时,您将首先检查您是否已经在第一个请求中得到了数据并存储在某个地方,若是是的话,您将检查是否已经得到了数据。使用存储的数据,而不是调用服务器。
将数据保存在某个位置并让下次请求从这个地方获取数据而不是从服务器获取是一种很好的作法。在这里,咱们可使用缓存。缓存内容有助于咱们再次减小服务器调用,并帮助咱们提升应用程序的性能。咱们能够在客户端缓存、服务器端缓存或客户机/服务器端缓存等位置的任意点执行缓存。
咱们能够在ASP.NET Core中使用不一样类型的缓存,好比咱们能够在内存中进行缓存,也可使用响应缓存,也可使用分布式缓存。更多关于ASP.NET Core 中的缓存
public async Task GetCacheData() { var cacheEntry = await _cache.GetOrCreateAsync(CacheKeys.Entry, entry => { entry.SlidingExpiration = TimeSpan.FromSeconds(120); return Task.FromResult(DateTime.Now); }); return View("Cache", cacheEntry); }
咱们还能够经过优化数据访问逻辑、数据库表和查询来提升应用程序的性能。众所周知,大多数应用程序都使用某种数据库,每次从数据库获取数据时,都会影响应用程序的性能。若是数据库加载缓慢,则整个应用程序将缓慢运行。这里咱们有一些建议:
除了业务逻辑和数据访问代码以外,应用程序中可能还有一些自定义代码。确保此代码也是优化的。这里有一些建议:
众所周知,EF Core是一个面向.NET开发人员的ORM,它帮助咱们处理数据库对象,而不像往常那样编写大量代码。它帮助咱们使用模型的数据库。数据访问逻辑代码在性能上起着相当重要的做用。若是您的代码没有优化,那么应用程序的性能一般就不会很好。
可是,若是您在EFCore中以优化的方式编写数据访问逻辑,那么确定会提升应用程序的性能。在这里,咱们有一些技巧来提升性能。
在获取只是用来只读显示的数据时不使用跟踪。它提升了性能。
尝试在数据库端过滤数据,不要使用查询获取整个数据,而后在您的末尾进行筛选。您可使用EF Core中的一些可用功能,能够帮助您在数据库端筛选数据的操做,如:WHERE,Select等。
使用Take和Skip来获取咱们所必需要显示的数量的记录。这里能够举一个分页的例子,在这个例子中,您能够在单击页码的同时使用Take和Skip来获取当前页面的数据。
让咱们以一个例子为例,了解如何使用Select和AsNoTracking优化EF Core的查询。
public async Task<PaginatedList> GetPagedPendingPosts(int pageIndex, int pageSize, List allowedCategories) { var allowedCatIds = allowedCategories.Select(x => x.Id); var query = _context.Post .Include(x => x.Topic.Category) .Include(x => x.User) .Where(x => x.Pending == true && allowedCatIds.Contains(x.Topic.Category.Id)) .OrderBy(x => x.DateCreated); return await PaginatedList.CreateAsync(query.AsNoTracking(), pageIndex, pageSize); }
这里咱们还有一些其余性能改进的东西能够在ASP.NET Core应用程序中进行实现。
编写优化和测试代码。您还可使用来自专业高级开发者的代码示例,包括产品文档。产品团队编写的代码(如C#团队)一般是优化的、现代化的,而且遵循最佳实践。
使用通过优化和良好测试的API和库。例如,在某些状况下,ADO.NET多是比 Entity Framework 或其余ORM库更好的选择。
若是您须要下载一个很大的文件的话,您可能须要考虑使用压缩算法。这里有几个内置的压缩库,如Gzip和Brotli。
public void ConfigureServices(IServiceCollection services) { services.AddResponseCompression(); services.Configure(options => { options.Level = CompressionLevel.Fastest; }); }
我想分享一些面向客户端的提高性能的技巧。若是您正在使用ASP.NET Core MVC建立网站,下面是一些提示:
捆绑和小型化
使用捆绑和小型化能够减小服务器请求次数。尝试一次加载全部客户端资源,如样式、js/css。您能够首先使用小型化缩小文件,而后将这些文件打包到一个文件中,这将加快加载速度并减小HTTP请求的数量。
最后加载 JavaScript
您应该始终尝试在页面尾部加载JavaScript文件,除非在此以前须要使用它们。若是您这样作,您的网站将显示的更快,而且用户也不须要等待并看到这些内容。
压缩图像
确保使用压缩技术缩小图像的大小。
使用 CDN
若是您只有几个样式和JS文件,那么能够从您的服务器加载。对于较大的静态文件,请尝试使用CDN。CDN一般能够在多个位置上使用,而且文件是从本地服务器提供的。从本地服务器加载文件能够提升网站性能。
今天,咱们学习了如何提高ASP.NET Core 应用程序的性能。很是但愿这篇文章对你有所帮助,若是您有任何问题或建议,能够在博客下面进行留言或者点赞!最后感谢大伙的阅读,若是你有兴趣的话能够加入ASP.NET Core实战项目交流群跟大伙进行交流,或者加我微信:jkingzhu,备注:合肥,我拉你进入合肥.NET技术社区进行交流!