使用gzip优化页面加载遇到的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用gzip优化页面加载遇到的问题相关的知识,希望对你有一定的参考价值。

参考技术A

我司目前项目已经经过了很多次优化了,期间通过webpack打包实践了很多种方式,包括样式文件通过 gulp 实现命令行级别输出到static目录下,避免了此类css的打包,通过 equire 插件实现了echarts的按需引入,换掉了momentjs替换成了轻量的dayjs,还有一些比较细的优化,在此就不一一列举了。

但是由于多页面配置,每个页面的js都挺大的,导致进入页面不是很流畅。期间曾经尝试了gzip,栽坑里了,由于需求原因又搁置了,近期手头工作比较少,又开始了踩坑的路途。

gzip是一种通用的压缩算法,可以降低网络传输的数据量,从而提高客户端浏览器的访问速度。由于浏览器向服务器发送请求,加载服务器响应的静态资源,当资源文件过大,会导致用户感受的加载时间较长,影响用户体验。

虽然浏览器还需要解压gzip文件,但这速度跟加载一个未压缩的文件相比,简直少得不要不要的了。

当然,我们可以通过采用其他优化方式并用提高页面加载速度,实在无济于事了,也可以加一朵旋转的 小菊花 [狗头],但gzip的使用能大幅降低加载时间,何乐而不为呢?

由于项目是基于vue开发,在 vue.config.js 中添加下列配置即可。(react也大同小异)

然后你就可以通过执行,查看 /dist/ 文件夹下的变化了。

如果你需要比较详细的配置gzip打包,请移步 https://www.npmjs.com/package/compression-webpack-plugin
配置里中有一个 deleteOriginalAssets 属性,意思是删除源文件,一般为 false 即可,同时保留源文件和压缩后的 .gz 后缀文件。
当然这不是本篇文章的重点。重点是什么?当然是 了!

由于现在的浏览器默认支持gzip压缩,你可以在请求头里看到 Accept-Encoding: gzip, deflate 得以确认。

我司服务器使用nginx做请求转发和实现简单的负载均衡。在网上,不乏有如何在nginx上开启gzip配置的博客或文章。其实蛮简单的,类似一下命令键入打开nginx配置文件:

再在 http 模块下添加这么几行配置:

命令行中报错,内容如下显示:

意思是“gzip_static”指令未知,无法被识别。

由于安装nginx时缺少了相应配置,需要添加 with-http_gzip_static_module 配置,在此之前需要先执行以下命令:

再在nginx安装目录下,重新编译和安装nginx,具体方式如下:

然后等待进程执行完,重新启动nginx即可。

通过以上的方式,nginx已经支持了 gzip_static 模块,以便nginx优先匹配 .gz 后缀文件返回。执行以下命令重新nginx:

好吧,正常情况下,是这样的。

但是...

如果你打开浏览器F12,刷新页面查看资源请求,发现静态资源的 Response Headers 属性中却没有 Content-Encoding: gzip 。喔豁...显然配置没有生效啊!

我们现在的问题发生在重启了nginx,新添加的模块却没有生效,浏览器还是获取的源文件。此时,我就开始百度了,百度大法好啊,各种回答都出来了。

nginx没有生效,可能是你的配置有误,语法不合法?检查一下:

结果命令行出现以下信息:

显示语法ok了,测试也通过了,说明正常启动了吧?打开浏览器,又查看了一遍资源加载......

第一种试过了,哭了。
那么nginx重启没生效,会不会是重启没成功啊?软的不行,来硬的呗。键入:

此时,进程中如果没有nginx, kill 命令生效了。此时,我重新在命令行中进入nginx命令行目录,运行 nginx -s reload ,意想不到的问题出来了。

我又重新试了kill命令又报错:

杀掉了主进程,却没有启动成功!
吓得我一个激灵看了一下页面,咦?
正常情况下,刷新页面,页面会由于nginx进程被 kill 导致页面无法访问。但是,页面依然能正常打开,俺不信邪,又试了好几个页面,果不其然都行。(不知道是该开心,还是该难过?)

查看进程列表中是否 nginx 的占用?

果不其然,的确有这个进程,再次通过 kill 命令删除PID进程号,再次执行之前命令,发现列表中nginx进程不复存在了。点此查看 彻底删除nginx进程

此时,我们刷新浏览器页面,地址访问不了了,确定nginx已经被彻底删除,此时执行 nginx重启命令 ,测试 gzip_static 测试是否成功应用。不出意外,nginx应用gzip应该是成功了。此时,你应该能成功看到 Request Headers 中的 Content-Encoding: gzip 了,明显能感到页面加载的速度变快了。

这次记录就到这了,希望对你能有帮助~Skr

前端性能优化 – 资源预加载

导语     当提到前端性能优化时,我们首先会联想到文件的合并、压缩,文件缓存和开启服务器端的 gzip 压缩等,这使得页面加载更快,用户可以尽快使用我们的 Web 应用来达到他们的目标。  资源预加载是另一个性能    

 

当提到前端性能优化时,我们首先会联想到文件的合并、压缩,文件缓存和开启服务器端的 gzip 压缩等,这使得页面加载更快,用户可以尽快使用我们的 Web 应用来达到他们的目标。

  资源预加载是另一个性能优化技术,我们可以使用该技术来预先告知浏览器某些资源可能在将来会被使用到。

  引用 Patrick Hamann 的解释:

  预加载是浏览器对将来可能被使用资源的一种暗示,一些资源可以在当前页面使用到,一些可能在将来的某些页面中被使用。作为开发人员,我们比浏览器更加了解我们的应用,所以我们可以对我们的核心资源使用该技术。

  这种做法曾经被称为 prebrowsing,但这并不是一项单一的技术,可以细分为几个不同的技术:DNS-prefetch、subresource 和标准的 prefetch、preconnect、prerender。

  DNS 预解析 DNS-Prefetch

  通过 DNS 预解析来告诉浏览器未来我们可能从某个特定的 URL 获取资源,当浏览器真正使用到该域中的某个资源时就可以尽快地完成 DNS 解析。例如,我们将来可能从 example.com 获取图片或音频资源,那么可以在文档顶部的 标签中加入以下内容:

  1. <link rel="dns-prefetch" href="//www.aseoe.com/"

  当我们从该 URL 请求一个资源时,就不再需要等待 DNS 的解析过程。该技术对使用第三方资源特别有用。

  在 Harry Roberts 的文章中提到:

  通过简单的一行代码就可以告知那些兼容的浏览器进行 DNS 预解析,这意味着当浏览器真正请求该域中的某个资源时,DNS 的解析就已经完成了。

  这似乎是一个非常微小的性能优化,显得也并非那么重要,但事实并非如此 – Chrome 一直都做了类似的优化。当在浏览器的地址栏中输入 URL 的一小段时,Chrome 就自动完成了 DNS 预解析(甚至页面预渲染),从而为每个请求节省了至关重要的时间。

  预连接 Preconnect

  与 DNS 预解析类似,preconnect 不仅完成 DNS 预解析,同时还将进行 TCP 握手和建立传输层协议。可以这样使用:

  1. <link rel="preconnect" href="http://www.aseoe.com/"

  在 Ilya Grigorik 的文章中有更详细的介绍:

  现代浏览器都试着预测网站将来需要哪些连接,然后预先建立 socket 连接,从而消除昂贵的 DNS 查找、TCP 握手和 TLS 往返开销。然而,浏览器还不够聪明,并不能准确预测每个网站的所有预链接目标。好在,在 Firefox 39 和 Chrome 46 中我们可以使用 preconnect 告诉浏览器我们需要进行哪些预连接。

  预获取 Prefetching

  如果我们确定某个资源将来一定会被使用到,我们可以让浏览器预先请求该资源并放入浏览器缓存中。例如,一个图片和脚本或任何可以被浏览器缓存的资源:

  1. <link rel="prefetch" href="image.png"

  与 DNS 预解析不同,预获取真正请求并下载了资源,并储存在缓存中。但预获取还依赖于一些条件,某些预获取可能会被浏览器忽略,例如从一个非常缓慢的网络中获取一个庞大的字体文件。并且,Firefox 只会在浏览器闲置时进行资源预获取。

  在 Bram Stein 的帖子中说到,这对 webfonts 性能提升非常明显。目前,字体文件必须等到 DOM 和 CSS 构建完成之后才开始下载,使用预获取就可以轻松绕过该瓶颈。

  注意:要测试资源的预获取有点困难,但在 Chrome 和 Firefox 的网络面板中都有资源预获取的记录。还需要记住,预获取的资源没有同源策略的限制。

  Subresources

  这是另一个预获取方式,这种方式指定的预获取资源具有最高的优先级,在所有 prefetch项之前进行:

  1. <link rel="subresource" href="styles.css"

  根据 Chrome 文档:

  rel=prefetch 为将来的页面提供了一种低优先级的资源预加载方式,而 rel=subresource 为当前页面提供了一种高优先级的资源预加载。

  所以,如果资源是当前页面必须的,或者资源需要尽快可用,那么最好使用 subresource 而不是 prefetch。

  预渲染 Prerender

  这是一个核武器,因为 prerender 可以预先加载文档的所有资源:

  1. <link rel="prerender" href="http://www.aseoe.com/"

  Steve Souders 在他的一篇文章中写到:

  这类似于在一个隐藏的 tab 页中打开了某个链接 – 将下载所有资源、创建 DOM 结构、完成页面布局、应用 CSS 样式和执行 JavaScript 脚本等。当用户真正访问该链接时,隐藏的页面就切换为可见,使页面看起来就是瞬间加载完成一样。Google 搜索在其即时搜索页面中已经应用该技术多年了,微软也宣称将在 IE11 中支持该特性。

  需要注意的是不要滥用该特性,当你知道用户一定会点击某个链接时才可以进行预渲染,否则浏览器将无条件地下载所有预渲染需要的资源。

  更多相关讨论:

  所有预加载技术都存在一个潜在的风险:对资源预测错误,而预加载的开销(抢占 CPU 资源,消耗电池,浪费带宽等)是高昂的,所以必须谨慎行事。虽然很难确定用户下一步将访问哪些资源,但高可信的场景确实存在:

  如果用户完成一个带有明显结果的搜索,那么结果页面很可能会被加载

  如果用户进入到登陆页面,那么登陆成功的页面很可能会被加载

  如果用户阅读一个多页的文章或访问一个分页的结果集,那么下一页很可能会被加载

  最后,使用 Page Visibility API 可以防止页面真正可见前被执行。

  Preload

  preload 是一个新规范,与 prefetch 不同(可能被忽略)的是,浏览器一定会预加载该资源:

  1. <link rel="preload" href="image.png"

  虽然该规范还没有被所有浏览器兼容,但其背后的思想还是非常有意思的。

  总结

  预测用户下一步将访问哪些资源是困难的,需要进行大量的测试,但是这带来的性能提升是明显的。如果我们愿意尝试这些预获取技术,一定会显著提升用户的体验。

 

以上是关于使用gzip优化页面加载遇到的问题的主要内容,如果未能解决你的问题,请参考以下文章

前端页面加载速度优化---Ngnix之GZIP压缩

如何使用gzip让你的nginx网站加速三倍??

如何使用Gzip压缩独立站大幅提高页面加载速度?

前端性能优化之Gzip

GZIP压缩优化

前端性能优化 – 资源预加载