当前位置: 首页 > news >正文

赣州市南康建设局网站wordpress站点很慢

赣州市南康建设局网站,wordpress站点很慢,苏州网站建设哪家好,网上营销活动介绍响应压缩技术是目前Web开发领域中比较常用的技术#xff0c;在带宽资源受限的情况下#xff0c;使用压缩技术是提升带宽负载的首选方案。我们熟悉的Web服务器#xff0c;比如IIS、Tomcat、Nginx、Apache等都可以使用压缩技术#xff0c;常用的压缩类型包括Brotli、Gzip… 介绍    响应压缩技术是目前Web开发领域中比较常用的技术在带宽资源受限的情况下使用压缩技术是提升带宽负载的首选方案。我们熟悉的Web服务器比如IIS、Tomcat、Nginx、Apache等都可以使用压缩技术常用的压缩类型包括Brotli、Gzip、Deflate它们对CSS、JavaScript、HTML、XML 和 JSON等类型的效果还是比较明显的但是也存在一定的限制对于图片效果可能没那么好因为图片本身就是压缩格式。其次对于小于大约150-1000 字节的文件具体取决于文件的内容和压缩的效率压缩小文件的开销可能会产生比未压缩文件更大的压缩文件。在ASP.NET Core中我们可以使用非常简单的方式来使用响应压缩。使用方式    在ASP.NET Core中使用响应压缩的方式比较简单。首先在ConfigureServices中添加services.AddResponseCompression注入响应压缩相关的设置比如使用的压缩类型、压缩级别、压缩目标类型等。其次在Configure添加app.UseResponseCompression拦截请求判断是否需要压缩,大致使用方式如下public class Startup {public void ConfigureServices(IServiceCollection services){services.AddResponseCompression();}public void Configure(IApplicationBuilder app, IHostingEnvironment env){app.UseResponseCompression();} } 如果需要自定义一些配置的话还可以手动设置压缩相关public void ConfigureServices(IServiceCollection services) {services.AddResponseCompression(options {//可以添加多种压缩类型程序会根据级别自动获取最优方式options.Providers.AddBrotliCompressionProvider();options.Providers.AddGzipCompressionProvider();//添加自定义压缩策略options.Providers.AddMyCompressionProvider();//针对指定的MimeType来使用压缩策略options.MimeTypes ResponseCompressionDefaults.MimeTypes.Concat(new[] { application/json });});//针对不同的压缩类型设置对应的压缩级别services.ConfigureGzipCompressionProviderOptions(options {//使用最快的方式进行压缩单不一定是压缩效果最好的方式options.Level CompressionLevel.Fastest;//不进行压缩操作//options.Level CompressionLevel.NoCompression;//即使需要耗费很长的时间也要使用压缩效果最好的方式//options.Level CompressionLevel.Optimal;}); }关于响应压缩大致的工作方式就是当发起Http请求的时候在Request Header中添加Accept-Encoding:gzip或者其他你想要的压缩类型可以传递多个类型。服务端接收到请求获取Accept-Encoding判断是否支持该种类型的压缩方式如果支持则压缩输出内容相关并且设置Content-Encoding为当前使用的压缩方式一起返回。客户端得到响应之后获取Content-Encoding判断服务端是否采用了压缩技术并根据对应的值判断使用了哪种压缩类型然后使用对应的解压算法得到原始数据。源码探究通过上面的介绍相信大家对ResponseCompression有了一定的了解接下来我们通过查看源码的方式了解一下它大致的工作原理。AddResponseCompression首先我们来查看注入相关的代码具体代码承载在ResponseCompressionServicesExtensions扩展类中[点击查看源码????]public static class ResponseCompressionServicesExtensions {public static IServiceCollection AddResponseCompression(this IServiceCollection services){services.TryAddSingletonIResponseCompressionProvider, ResponseCompressionProvider();return services;}public static IServiceCollection AddResponseCompression(this IServiceCollection services, ActionResponseCompressionOptions configureOptions){services.Configure(configureOptions);services.TryAddSingletonIResponseCompressionProvider, ResponseCompressionProvider();return services;} } 主要就是注入ResponseCompressionProvider和ResponseCompressionOptions,首先我们来看关于ResponseCompressionOptions[点击查看源码????]public class ResponseCompressionOptions {// 设置需要压缩的类型public IEnumerablestring MimeTypes { get; set; }// 设置不需要压缩的类型public IEnumerablestring ExcludedMimeTypes { get; set; }// 是否开启https支持public bool EnableForHttps { get; set; } false;// 压缩类型集合public CompressionProviderCollection Providers { get; } new CompressionProviderCollection(); } 关于这个类就不做过多介绍了比较简单。ResponseCompressionProvider是我们提供响应压缩算法的核心类具体如何自动选用压缩算法都是由它提供的。这个类中的代码比较多我们就不逐个方法讲解了具体源码可自行查阅[点击查看源码????]首先我们先看ResponseCompressionProvider的构造函数public ResponseCompressionProvider(IServiceProvider services, IOptionsResponseCompressionOptions options) {var responseCompressionOptions options.Value;_providers responseCompressionOptions.Providers.ToArray();//如果没有设置压缩类型默认采用Br和Gzip压缩算法if (_providers.Length 0){_providers new ICompressionProvider[]{new CompressionProviderFactory(typeof(BrotliCompressionProvider)),new CompressionProviderFactory(typeof(GzipCompressionProvider)),};}//根据CompressionProviderFactory创建对应的压缩算法Provider比如GzipCompressionProviderfor (var i 0; i _providers.Length; i){var factory _providers[i] as CompressionProviderFactory;if (factory ! null){_providers[i] factory.CreateInstance(services);}}//设置默认的压缩目标类型默认为text/plain、text/css、text/html、application/javascript、application/xml//text/xml、application/json、text/json、application/wasvar mimeTypes responseCompressionOptions.MimeTypes;if (mimeTypes null || !mimeTypes.Any()){mimeTypes ResponseCompressionDefaults.MimeTypes;}//将默认MimeType放入HashSet_mimeTypes new HashSetstring(mimeTypes, StringComparer.OrdinalIgnoreCase);_excludedMimeTypes new HashSetstring(responseCompressionOptions.ExcludedMimeTypes ?? Enumerable.Emptystring(),StringComparer.OrdinalIgnoreCase);_enableForHttps responseCompressionOptions.EnableForHttps; } 其中BrotliCompressionProvider、GzipCompressionProvider是具体提供压缩方法的地方咱们就看比较常用的Gzip的Provider的大致实现[点击查看源码????]public class GzipCompressionProvider : ICompressionProvider {public GzipCompressionProvider(IOptionsGzipCompressionProviderOptions options){Options options.Value;}private GzipCompressionProviderOptions Options { get; }// 对应的Encoding名称public string EncodingName { get; } gzip;public bool SupportsFlush true;// 核心代码就是这句 将原始的输出流转换为压缩的GZipStream// 我们设置的Level压缩级别将决定压缩的性能和质量public Stream CreateStream(Stream outputStream) new GZipStream(outputStream, Options.Level, leaveOpen: true); } 关于ResponseCompressionProvider其他相关的方法咱们在讲解UseResponseCompression中间件的时候在具体看用到的方法因为这个类是响应压缩的核心类现在提前说了到中间件使用的地方可能会忘记了。接下来我们就看UseResponseCompression的大致实现。UseResponseCompressionUseResponseCompression具体也就一个无参的扩展方法也比较简单因为配置和工作都由注入的地方完成了所以我们直接查看中间件里的实现找到中间件位置ResponseCompressionMiddleware[点击查看源码????]public class ResponseCompressionMiddleware {private readonly RequestDelegate _next;private readonly IResponseCompressionProvider _provider;public ResponseCompressionMiddleware(RequestDelegate next, IResponseCompressionProvider provider){_next next;_provider provider;}public async Task Invoke(HttpContext context){//判断是否包含Accept-Encoding头信息不包含直接大喊一声抬走下一个if (!_provider.CheckRequestAcceptsCompression(context)){await _next(context);return;}//获取原始输出Bodyvar originalBodyFeature context.Features.GetIHttpResponseBodyFeature();var originalCompressionFeature context.Features.GetIHttpsCompressionFeature();//初始化响应压缩Bodyvar compressionBody new ResponseCompressionBody(context, _provider, originalBodyFeature);//设置成压缩Bodycontext.Features.SetIHttpResponseBodyFeature(compressionBody);context.Features.SetIHttpsCompressionFeature(compressionBody);try{await _next(context);await compressionBody.FinishCompressionAsync();}finally{//恢复原始Bodycontext.Features.Set(originalBodyFeature);context.Features.Set(originalCompressionFeature);}} } 这个中间件非常的简单就是初始化了ResponseCompressionBody。看到这里你也许会好奇并没有触发调用压缩相关的任何代码ResponseCompressionBody也只是调用了FinishCompressionAsync都是和释放相关的不要着急我们来看ResponseCompressionBody类的结构internal class ResponseCompressionBody : Stream, IHttpResponseBodyFeature, IHttpsCompressionFeature { }这个类实现了IHttpResponseBodyFeature我们使用的Response.Body其实就是获取的HttpResponseBodyFeature.Stream属性。我们使用的Response.WriteAsync相关的方法其实内部都是在调用PipeWriter进行写操作而PipeWriter就是来自HttpResponseBodyFeature.Writer属性。可以大致概括为输出相关的操作其核心都是在操作IHttpResponseBodyFeature。有兴趣的可以自行查阅HttpResponse相关的源码可以了解相关信息。所以我们的ResponseCompressionBody其实是重写了输出操作相关方法。也就是说只要你调用了Response相关的Write或Body相关的其实本质都是在操作IHttpResponseBodyFeature由于我们开启了响应输出相关的中间件所以会调用IHttpResponseBodyFeature的实现类ResponseCompressionBody相关的方法完成输出。和我们常规理解的还是有偏差的一般情况下我们认为其实只要针对输出的Stream做操作就可以了但是响应压缩中间件竟然重写了输出相关的操作。    了解到这个之后相信大家就没有太多疑问了。由于ResponseCompressionBody重写了输出相关的操作代码相对也比较多就不逐一粘贴出来了我们只查看设计到响应压缩核心相关的代码关于ResponseCompressionBody源码相关的细节有兴趣的可以自行查阅[点击查看源码????]输出的本质其实都是在调用Write方法我们就来查看一下Write方法相关的实现public override void Write(byte[] buffer, int offset, int count) {//这是核心方法有关于压缩相关的输出都在这OnWrite();//_compressionStream初始化在OnWrite方法里if (_compressionStream ! null){_compressionStream.Write(buffer, offset, count);if (_autoFlush){_compressionStream.Flush();}}else{_innerStream.Write(buffer, offset, count);} } 通过上面的代码我们看到OnWrite方法是核心操作我们直接查看OnWrite方法实现private void OnWrite() {if (!_compressionChecked){_compressionChecked true;//判断是否满足执行压缩相关的逻辑if (_provider.ShouldCompressResponse(_context)){//匹配Vary头信息对应的值var varyValues _context.Response.Headers.GetCommaSeparatedValues(HeaderNames.Vary);var varyByAcceptEncoding false;//判断Vary的值是否为Accept-Encodingfor (var i 0; i varyValues.Length; i){if (string.Equals(varyValues[i], HeaderNames.AcceptEncoding, StringComparison.OrdinalIgnoreCase)){varyByAcceptEncoding true;break;}}if (!varyByAcceptEncoding){_context.Response.Headers.Append(HeaderNames.Vary, HeaderNames.AcceptEncoding);}//获取最佳的ICompressionProvider即最佳的压缩方式var compressionProvider ResolveCompressionProvider();if (compressionProvider ! null){//设置选定的压缩算法放入Content-Encoding头的值里//客户端可以通过Content-Encoding头信息判断服务端采用的哪种压缩算法_context.Response.Headers.Append(HeaderNames.ContentEncoding, compressionProvider.EncodingName);//进行压缩时将 Content-MD5 删除该标头因为正文内容已更改且哈希不再有效。_context.Response.Headers.Remove(HeaderNames.ContentMD5); //进行压缩时将 Content-Length 删除该标头因为在对响应进行压缩时正文内容会发生更改。_context.Response.Headers.Remove(HeaderNames.ContentLength);//返回压缩相关输出流_compressionStream compressionProvider.CreateStream(_innerStream);}}} }private ICompressionProvider ResolveCompressionProvider() {if (!_providerCreated){_providerCreated true;//调用ResponseCompressionProvider的方法返回最合适的压缩算法_compressionProvider _provider.GetCompressionProvider(_context);}return _compressionProvider; } 从上面的逻辑我们可以看到在执行压缩相关逻辑之前需要判断是否满足执行压缩相关的方法ShouldCompressResponse这个方法是ResponseCompressionProvider里的方法这里就不再粘贴代码了本来就是判断逻辑我直接整理出来大致就是一下几种情况如果请求是Https的情况下是否设置了允许Https情况下压缩的设置即ResponseCompressionOptions的EnableForHttps属性设置Response.Head里不能包含Content-Range头信息Response.Head里之前不能包含Content-Encoding头信息Response.Head里之前必须要包含Content-Type头信息返回的MimeType里不能包含配置的不需要压缩的类型即ResponseCompressionOptions的ExcludedMimeTypes返回的MimeType里需要包含配置的需要压缩的类型即ResponseCompressionOptions的MimeTypes如果不满足上面的两种情况返回的MimeType里包含*/*也可以执行响应压缩接下来我们查看ResponseCompressionProvider的GetCompressionProvider方法看它是如何确定返回哪一种压缩类型的public virtual ICompressionProvider GetCompressionProvider(HttpContext context) {var accept context.Request.Headers[HeaderNames.AcceptEncoding];//判断请求头是否包含Accept-Encoding信心if (StringValues.IsNullOrEmpty(accept)){Debug.Assert(false, Duplicate check failed.);return null;}//获取Accept-Encoding里的值判断是否包含gzip、br、identity等并返回匹配信息if (!StringWithQualityHeaderValue.TryParseList(accept, out var encodings) || !encodings.Any()){return null;}//根据请求信息和设置信息计算匹配优先级var candidates new HashSetProviderCandidate();foreach (var encoding in encodings){var encodingName encoding.Value;//Quality涉及到一个非常复杂的算法有兴趣的可以自行查阅var quality encoding.Quality.GetValueOrDefault(1);//quality需大于0if (quality double.Epsilon){continue;}//匹配请求头里encodingName和设置的providers压缩算法里EncodingName一致的算法//从这里可以看出匹配的优先级和注册providers里的顺序也有关系for (int i 0; i _providers.Length; i){var provider _providers[i];if (StringSegment.Equals(provider.EncodingName, encodingName, StringComparison.OrdinalIgnoreCase)){candidates.Add(new ProviderCandidate(provider.EncodingName, quality, i, provider));}}//如果请求头里EncodingName是*的情况则在所有注册的providers里进行匹配if (StringSegment.Equals(*, encodingName, StringComparison.Ordinal)){for (int i 0; i _providers.Length; i){var provider _providers[i];candidates.Add(new ProviderCandidate(provider.EncodingName, quality, i, provider));}break;}//如果请求头里EncodingName是identity的情况则不对响应进行编码if (StringSegment.Equals(identity, encodingName, StringComparison.OrdinalIgnoreCase)){candidates.Add(new ProviderCandidate(encodingName.Value, quality, priority: int.MaxValue, provider: null));}}ICompressionProvider selectedProvider null;//如果匹配的只有一个则直接返回if (candidates.Count 1){selectedProvider candidates.FirstOrDefault().Provider;}else{//如果匹配到多个则按照Quality倒序和Priority正序的负责匹配第一个selectedProvider candidates.OrderByDescending(x x.Quality).ThenBy(x x.Priority).First().Provider;}//如果没有匹配到selectedProvider或是identity的情况直接返回nullif (selectedProvider null){return null;}return selectedProvider; } 通过以上的介绍我们可以大致了解到响应压缩的大致工作方式简单总结一下首先设置压缩相关的算法类型或是压缩目标的MimeType其次我们可以设置压缩级别这将决定压缩的质量和压缩性能通过响应压缩中间件我们可以获取到一个优先级最高的压缩算法进行压缩这种情况主要是针对多种压缩类型的情况。这个压缩算法与内部机制和注册压缩算法的顺序都有一定的关系最终会选择权重最大的返回。响应压缩中间件的核心工作类ResponseCompressionBody通过实现IHttpResponseBodyFeature重写输出相关的方法实现对响应的压缩不需要我们手动进行调用相关方法而是替换掉默认的输出方式。只要设置了响应压缩并且请求满足响应压缩那么有调用输出的地方默认都是执行ResponseCompressionBody里压缩相关的方法而不是拦截具体的输出进行统一处理。至于为什么这么做目前我还没有理解到设计者真正的考虑。总结    在查看相关代码之前本来以为关于响应压缩相关的逻辑会非常的简单看过了源码才知道是自己想的太简单了。其中和自己想法出入最大的莫过于在ResponseCompressionMiddleware中间件里本以为是通过统一拦截输出流来进行压缩操作没想到是对整体输出操作进行重写。因为在之前我们使用Asp.Net相关框架的时候是统一写Filter或者HttpModule进行处理的所以存在思维定式。可能是Asp.Net Core设计者有更深层次的理解可能是我理解的还不够彻底不能够体会这样做的好处究竟是什么如果你有更好的理解或则答案欢迎在评论区里留言解惑。????欢迎扫码关注我的公众号????
http://www.yutouwan.com/news/311750/

相关文章:

  • php做商城网站怎么做好域名解析教程
  • 官方网站开发公司排名做网站的时候网站的第一个字母怎么在网站标题前面显示 比如谷歌g一样
  • 河南手机网站制作公司搭建视频播放网站
  • 网络营销模式和电子商务模式是一对紧密相关抖音seo排名系统公司
  • 域名费用和网站服务器费用是同样的吗免费永久网站建设
  • 公司的网站建设费入什么科目有的域名怎样做网站
  • php做的网站收录视频网站开发是什么
  • 网站开发分前台后台个人wordpress 主题
  • 宣传类的网站怎么做免费企业建站模板
  • 正规网站开发文案网站建设物理架构
  • 中 网站建设 扬州网易企业邮箱是什么意思
  • 百度站长工具seo手机排行榜2022最新
  • 浏览器怎么打开网站服务器下载建筑行业一般在哪个网站招聘
  • 从seo角度做网站流量网站域名没有实名认证
  • 个人简历模板网站自己做网站需要备份么
  • 网站架构拓扑图网站文章正文可以做内链吗
  • 易语言wordpress发布优化推广网站淄博
  • 如何做求婚网站电商一件代发平台
  • 北京网站建设华大浙江短视频seo优化网站
  • 建湖网站优化公司上海黄页企业名录电话
  • 做网站公司合同建设银行淮安招聘网站
  • 自己如何做家政网站做网站为何要续费
  • 优秀网络广告案例分析wordpress优化检测
  • 石家庄信息门户网站定制费用跨平台 移动网站开发
  • 国内买机票最便宜网站建设本地访问wordpress
  • 网站网站建设的原则有哪些旅游公网站如何做
  • 东道设计公司待遇如何百度推广seo是什么意思
  • 做预算的网站域名最新通知
  • 给房地产公司做网站的公司网站建设中长出现的问题
  • 平台网站怎么做的好大学生html网页设计作业