ASP.NET Core文件压缩最佳实践
前言
在微软官方文档中,未明确指出文件压缩功能的使用误区。
本文将对 ASP.NET Core 文件响应压缩的常见使用误区做出说明。
误区1:未使用 Brotil 压缩
几乎不需要任何额外的代价,Brotil 压缩算法可以帮助你的网站提升约 20% 静态资源加载性能。
同时启用 Gzip / Brotil 压缩
Gzip 有更好的 user-agent 兼容性,而 Brotli 有更好的性能。
所以我们通常需要在 ASP.NET Core 网站中同时启用这两种压缩。
如何区分 Gzip 压缩和 Brotli 压缩
网站启用 Brotli 压缩时,服务器请求返回头 Content-Encoding 中会包含 br 字样,否则是 gzip。
误区2:使用 Fastest 级别的 Brotli 压缩
如果你阅读并参考了微软官方文档或者其他中文资源,比如:
ASP.NET Core 中的响应压缩 - MS Doc
在ASP.NET Core中使用brotli压缩 - Cnblogs
那么你可能会在代码中像下面这样使用压缩功能:
写法1:使用默认的压缩行为(框架将隐式添加 Brotli 和 Gzip 功能)
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCompression();
} public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseResponseCompression();
}
}
写法2:显式添加压缩功能
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCompression(options =>
{
options.Providers.Add<BrotliCompressionProvider>();
options.Providers.Add<GzipCompressionProvider>();
options.Providers.Add<CustomCompressionProvider>();
options.MimeTypes =
ResponseCompressionDefaults.MimeTypes.Concat(
new[] { "image/svg+xml" });
});
services.Configure<BrotliCompressionProviderOptions>(options =>
{
options.Level = CompressionLevel.Fastest;
});
}
写法3:自定义 BrotliCompressionProvider
public class BrotliCompressionProvider : ICompressionProvider
{
public string EncodingName => "br";
public bool SupportsFlush => true
public Stream CreateStream(Stream outputStream)
{
return new BrotliStream(outputStream,CompressionLevel.Fastest);
}
}
不幸的是,以上三种写法都没有发挥出 Brotil 压缩算法的优势。
它们的共同点是均使用了 CompressionLevel.Fastest 压缩级别。
而在 CompressionLevel.Fastest 级别时,Brotil 与 Gzip 压缩性能几乎无异。
参考:Introducing Support for Brotli Compression
图 2-1 Fastest 模式下,三种算法的压缩率等同
误区3:使用 Optimal 级别的 Brotli 压缩
CompressionLevel 只有三个枚举值:Fastest / NoCompression / Optimal。
既然 Fastest 级别没有用,那我们只能换成 Optimal 了。
图 3-1 压缩级别枚举
非常不幸,Brotil 的 Optimal 压缩级别存在严重的性能问题,在实际网站应用中几乎没有适用的场景。
图 3-2 Optimal 压缩耗时对比
最佳实践:使用 4 或 5 级别的 Brotli 压缩
在 Introducing Support for Brotli Compression 这篇文章中,作者对不同级别 Brotil 的压缩耗时做了评测,也就是下面这幅图。
图 4-1 不同压缩级别下 Brotli 的压缩耗时
观察这副图,Brotil 的压缩质量其实有 1~11 个级别。
那我们如何自定义 Brotli 的压缩级别呢,答案是直接将级别对应的整数转成 CompressionLevel 枚举。
参考:Setting a specific Brotli compression level when using response compression in ASP.NET Core
图 4-2 指定 Brotli 的压缩级别
尽管这种写法看起来十分古怪,但通过考察 .NET 源码,可以确凿这种写法是可行的。
参考:System.IO.Compression.BrotliUtils.cs
图 4-3 CompressionLevel 枚举强制转换整数
现在我们可以自定义压缩级别了,但注意上方源码,只能指定 3 以上的级别,3 包括 3 以下的值有其他对应的转换逻辑。
回到本节第一副图 4-1,通过实测,发现在 4 / 5 级别下,Brotli 确实可以获得最佳的压缩率和较低的压缩损耗。
总结
在 ASP.NET Core 中,我们应该同时启用 Gzip 和 Brotil 压缩功能,其中 Brotil 的压缩级别应该自定义到 4 或 5。
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCompression(options =>
{
options.Providers.Add<BrotliCompressionProvider>();
options.Providers.Add<GzipCompressionProvider>();
options.MimeTypes =
ResponseCompressionDefaults.MimeTypes.Concat(
new[] { "image/svg+xml" });
}); services.Configure<BrotliCompressionProviderOptions>(options =>
{
options.Level = (CompressionLevel)4; // 4 or 5 is OK
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseResponseCompression();
}
ASP.NET Core文件压缩最佳实践的更多相关文章
- ASP.NET Core 性能优化最佳实践
本文提供了 ASP.NET Core 的性能最佳实践指南. 译文原文地址:https://docs.microsoft.com/en-us/aspnet/core/performance/perfor ...
- ASP.NET Core Web API 最佳实践指南
原文地址: ASP.NET-Core-Web-API-Best-Practices-Guide 介绍 当我们编写一个项目的时候,我们的主要目标是使它能如期运行,并尽可能地满足所有用户需求. 但是,你难 ...
- ASP.NET Core 依赖注入最佳实践与技巧
ASP.NET Core 依赖注入最佳实践与技巧 原文地址:https://medium.com/volosoft/asp-net-core-dependency-injection-best-pra ...
- [转]ASP.NET Core Web API 最佳实践指南
原文地址: ASP.NET-Core-Web-API-Best-Practices-Guide 转自 介绍# 当我们编写一个项目的时候,我们的主要目标是使它能如期运行,并尽可能地满足所有用户需求. 但 ...
- ASP.NET Core 依赖注入最佳实践——提示与技巧
在这篇文章,我将分享一些在ASP.NET Core程序中使用依赖注入的个人经验和建议.这些原则背后的动机如下: 高效地设计服务和它们的依赖. 预防多线程问题. 预防内存泄漏. 预防潜在的BUG. 这篇 ...
- ASP.NET Core依赖注入最佳实践,提示&技巧
分享翻译一篇Abp框架作者(Halil İbrahim Kalkan)关于ASP.NET Core依赖注入的博文. 在本文中,我将分享我在ASP.NET Core应用程序中使用依赖注入的经验和建议. ...
- [转载]ASP.NET Core文件上传与下载(多种上传方式)
ASP.NET Core文件上传与下载(多种上传方式) 前言 前段时间项目上线,实在太忙,最近终于开始可以研究研究ASP.NET Core了. 打算写个系列,但是还没想好目录,今天先来一篇,后面在 ...
- vue 单文件组件最佳实践
vue 单文件组件最佳实践 生命周期 template <template> <section> <h1>vue single file components te ...
- ASP.NET Core文件上传IFormFile于Request.Body的羁绊
前言 在上篇文章深入探究ASP.NET Core读取Request.Body的正确方式中我们探讨了很多人在日常开发中经常遇到的也是最基础的问题,那就是关于Request.Body的读取方式问题,看是简 ...
随机推荐
- 13 条高效实用的 JavaScript 单行代码
JavaScript可以实现很多令人惊奇的事! 从复杂的框架到处理API,有太多的东西可以学习. 甚至,仅用一行代码,它也能完成一些很棒的工作. 不信?那么请看这13条JavaScript单行代码,用 ...
- 前端 | JS Promise:axios 请求结果后面的 .then() 是什么意思?
Promise 是JS中一种处理异步操作的机制,在现在的前端代码中使用频率很高.Promise 这个词可能有点眼生,但你肯定见过 axios.get(...).then(res => {...} ...
- 痞子衡嵌入式:MCUXpresso IDE下在线调试时使用不同复位策略的现象总结
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是MCUXpresso IDE下在线调试时使用不同复位策略的现象总结. 本篇实际上是<IAR在线调试时设不同复位类型可能会导致i.M ...
- java面试一日一题:java线程池
问题:请讲下java中的线程池 分析:在面试中经常问到线程池的问题,要掌握其基本概念,使用方法,注意事项等,引申下tomcat中默认的线程数是多少 回答要点: 主要从以下几点去考虑, 1.为什么要使用 ...
- 京东效率专家带你快速落地DevOps
行业内的公司纷纷在招聘DevOps工程师,企业的DevOps转型看起来迫在眉睫,公司内部也要设计和开发DevOps平台,DevOps已经成为了所有IT从业人员应知应会的必备技能. 为你提供一套清晰的D ...
- HTML5与CSS3新增特性笔记
HTML5 HTML5和HTML事件 注意:行内代码的为H5新增事件 Window事件属性: 针对 window 对象触发的事件(应用到 标签) onafterprint 文档打印之后运行的脚本 on ...
- 关于Maven中<packaging>产生的一些问题
关于Maven中产生的一些问题 一.项目的打包类型 jar 默认的打包格式 war 打包成需要部署的项目 pom 父类型为pom类型 二. pom 简单来说,一个多模块项目通过一个父POM 引用一个或 ...
- 日志收集之filebeat使用介绍
此系列文章一共分为三部分,分为filebeat部分,logstash部分,es部分.这里会按照每天几百亿条的数据量来考虑,去设计.部署.优化这个日志系统,来最大限度的利用资源,并达到一个最优的性能.本 ...
- (十五)VMware Harbor 标签管理
1. Harbor提供两种标签用来隔离各种资源(目前只有镜像): 全局级别标签: 由系统管理员管理,用于管理整个系统的镜像.它们可以添加到任何项目下的镜像中. 项目级别标签: 由项目管理员或者系统管理 ...
- JDK8接口新关键字default和static
JDK8及以后,允许我们在接口中定义static方法和default方法. public interface InterfaceDemo { // static修饰符定义静态方法 static voi ...