IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 回归 HTTP 协议本质:前端还能做哪些性能优化? -> 正文阅读

[网络协议]回归 HTTP 协议本质:前端还能做哪些性能优化?

上篇文章聊到:在 HTTP 2.0 时代以后,不需要额外担心由于 TCP 连接数带来的前端性能问题,因此我们不再需要雪碧图等优化手段了。于是前端工程师在 HTTP 协议这层能做的性能优化似乎只有「尽可能地减小资源体积」这一方向。

这篇文章会围绕这个主题,列举现阶段前端能在网络层面做的性能优化。

以图片为例:资源体积压缩

要说减少资源的体积,首当其冲的就是媒体资源了:图片、视频、音频等。

这里就拿图片举例。早在 Web 2.0 时代,那时短视频行业还没有兴起,一个最最最丰富的网站也不过是由文字和图片组成,比如大家经常访问的酒妖、草榴等知名网站。

2e0c961548f000b7a6d6ad4d43fa6cc3.png

比如我们打开酒妖的一个帖子(全是图片的那种da4c7afd28abfc9117d2f49d9c848237.png),浏览器 tab 上的菊花在一直转圈,直到很久才加载完成,为什么呢?因为这个帖子的不仅有很多图片,还都是超清的那种389cf23e374fe8cb5ac8ca63c1e37519.png,于是用来加载它们的时间就很长了。这里说的“加载”,实际上就是资源通过网络连接从服务端传输到浏览器端的过程。

有解决办法吗?当然有:减小资源体积呀。

就拿图片来举例子,tinypng / tinyjpg,全球知名的图片在线压缩工具。只要是对图片质量要求没那么苛刻的网站,用这种压缩图片工具把体积减小个 50%(甚至更多),普通人的肉眼几乎是看不出区别的。

7f9833b7b4316dec422734c67313670e.png

图片压缩前后对比

比如上面这两只国宝,一个是压缩前(60 kb),另一个是压缩后(15 kb),各位能看出来哪个是哪个吗?

efce3e6e6e820d8d6db6e397058cc06c.png

推翻无脑打包:按需加载

还记得上篇文章提到的“减少 HTTP 请求数量”的性能优化方法吗?其中最常用的就是把所有能打包在一起的静态资源都打包成一个文件,比如 JS、CSS 等。

但这样的做法没有问题吗?当然有,不然我也不会 cue 它。

068be5c14458cdff4ec3e3fe9f902b0a.png

打包资源这件事,主要有两个问题:

  1. 自从进入 HTTP/1.1、HTTP/2 以后,TCP 协议层已经做了很大程度的优化。对于前端来说,请求数量再也不是一个迫在眉睫的问题了

  2. 现代前端工程的复杂度今非昔比,复杂的交互逻辑、繁重的第三方依赖,如果再将所有资源文件打包在一起,那打包结果的体积将变得非常大,虽然请求数量得到了减少,但资源的下载速度反而变得很慢,得不偿失

比如下面这个例子,小明只想访问我的博客首页,但服务器把打包之后的 js 文件返回给了他(包含四个页面的 js),于是不仅浪费了网络带宽,还导致浏览器费劲解析了很多没用的 js,很没有必要。

d8d937261efa3671296f6139a578cbb2.png

只访问首页却得到了所有js

最理想的情况,就是下面这张图描绘的场景:当用户访问首页(index)时,只返回首页对应的资源。

97c370e6adff124969baa78f6fac5f86.png

访问首页只得到了首页的资源

拿 Vue 举例,只要在定义路由文件时用 dynamic import 的语法定义页面对应的组件,即可实现基于路由的组件按需加载。

//?...
{
?name:?'Home',
?path:?'/home',
?component:?()?=>?import('@/components/Home.vue'),
}
//?...

Gzip:服务器端资源压缩

前后端一家亲,性能优化这件事情,如果后端的老哥能帮一把,那效果肯定是一加一大于二的。

HTTP 协议本身是支持多种报文压缩算法的,比如 gzip、deflate、br 等,它们有一个共同的名字:HTTP 压缩

我们就拿 gzip 举例子。浏览器向服务器请求资源时,请求头中有一个字段:Accept-Encoding,代表了浏览器支持的 HTTP 压缩算法。服务端在接受到这个信息后,会用浏览器支持的压缩算法对报文进行压缩,同时在响应头中附上两个关键字段:Content-EncodingContent-Length,前者表示当前使用的压缩算法,而后者是当前资源压缩后的大小。一般情况下,gzip 能将文本文件压缩为原来大小的 30%,奇效。

d9bf832be8cfe002297e51099109a945.png

gzip.png

我们来看下服务器端控制 gzip 压缩的关键字段(nginx):

#?ngx_http_gzip_module

#?开启或关闭?gzip?功能
gzip:?on?|?off

#?设置?gzip?压缩文件使用缓存空间的大小
#?默认值:gzip_buffers 32 4k | 16 8k
gzip_buffers:?number?size

#?gzip?压缩力度,取值范围?1~9
#?数值越小,压缩力度越小,压缩得越快;数值越大,压缩力度越大,压缩得越慢
gzip_comp_level:?level

#?匹配浏览器的?UserAgent(支持正则表达式)
#?若命中匹配,则会关闭?gzip
gzip_disable?regex

#?开启?gzip?时最低的?HTTP?版本
zip_http_version:?1.0?|?1.1

#?该指令用来指定资源的字节数
#?只有当资源的大小大于这个值时,才启用?gzip?压缩
gzip_min_length:?length

如何解决服务端压缩的性能问题

目前看起来,服务端 HTTP 压缩是比较完美的优化方案,但,在技术领域是没有银弹的

银弹:Silver Bullet,在软件工程领域指一种能解决问题并且没有任何瑕疵的方法。

到底会有什么问题呢?

b45c808cf6aa9cf0a6d8cc98ecbdc6f8.png

服务器在返回gzip压缩文件之前都做了什么

从图中可以看到服务端在向浏览器传递所需资源时的三个关键步骤。其中有个被虚线框起来的步骤,即“压缩”这一步:服务端在每一次返回资源前,都会都需要压缩资源进行压缩,而每一次压缩都是要消耗服务端的算力的。假设一个极端的情况,你的网站只有一个服务器,而用户却有十万人......慌了吗?

0011bcfd2574065a5beb7c17923d2a4e.png

这个时候,就该伟大的前端工程师们出手了。如果我们能在前端就把资源都压缩好,再把压缩好的资源放在服务器上等待浏览器享用就行了。思路看起来没什么问题,能实现吗?难不成浏览器有这么大的能耐,还能压缩文件?

小了,格局小了。前端可不止浏览器哦,在前端工程化的世界里,“构建”可是一个很关键的步骤。这下各位思路就开阔了吧:没错,可以在构建的时候整些花里胡哨的,比如我们现在正需要的 gzip 压缩。

e6bedb4aa74f9969a6bdc1c8eb870a44.png

前端构建时gzip.png

这里举两个例子,一个是老牌王者 webpack,另一个是闪亮新秀 vite

如何在 webpack 中开启 gzip 压缩

webpack 对于 gzip 的配置还是蛮简单的,只需要一个叫做 compression-webpack-plugin 的插件就行:

const?compressWebpackPlugin?=?require('compression-webpack-plugin');
//?...
configureWebpack:?{
?plugins:?[
??new?compressWebpackPlugin({
???filename:?'[path].gz[query]',
???algorithm:?'gzip',
???test:?/\.(js|css)$/,
???threshold:?1024,
???minRatio:?0.8,
???deleteOriginalAssets:?false,
??}),
?],
}
//?...

如何在 vite 中开启 gzip 压缩

如果说在 webpack 开启 gzip 的难度是 1 + 1,那在 vite 中开启 gzip 的难度就是 1 本身:

import?viteCompression?from?'vite-plugin-compression';
//?...
plugins:?[?viteCompression()?],
//?...

诶,为什么能这么简单呢,因为 vite-plugin-compression?这个插件本身提供的配置是有默认值的,而这些默认值刚好满足我们基本的要求,所以就有了开箱即用的假象(大多数号称“开箱即用”的插件或工具,几乎都是因为默认值比较抗打罢了...)。

最后

至此,我们基于现代前端工程面临的网络协议(HTTP > 1.1),推翻了合并文件、雪碧图等这些既费力不讨好又过时的方案,又介绍了压缩图片、分包加载、资源压缩(gzip)等符合时代发展的性能优化方案。
不过,在性能优化这件事情上,没有所谓的“一招鲜吃遍天”,我们应当在实际工程中思考并产出符合业务要求回归技术本质的优化方案,要讲究因地制宜

?原创精品文章,推荐阅读?

fb82a97d655b00f98c1113e642a015bb.png

d4966876a1965a7fc25458ec1a325d6f.png

811ac14fcc0577df7ff79cb74ef52f3a.png

(点击图片即可阅读)?

关注后星标🌟,成为我的特别读者

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-09-27 14:27:29  更:2021-09-27 14:28:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 1:39:27-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码