前端性能优化(2)

TCP请求优化

  • 尽量减少TCP的请求数,也就是减少HTTP的请求数量
  1. 资源合并,对于页面内的图片、css和js进行合并,减少请求量
  2. 使用长链接,使用http1.1,在HTTP的响应头会加上 Connection:keep-alive,当一个网页打开完成之后,连接不会马上关闭,再次访问这个服务时,会继续使用这个长连接。这样就大大减少了TCP的握手次数和释放次数
  3. 使用Websocket进行通信,全程只需要建立一次TCP链接。
HTTP 优化
  • HTTP优化两大方向:(资源的压缩与合并)
    • 减少请求次数
    • 减少单次请求所耗费的时间
  1. 使用内容分发网络(CDN)
  • 使用CDN可以减少网络的请求时延,CDN的域名不要和主站的域名一样,这样会防止访问CDN时还携带主站cookie的问题,对于网络请求,可以使用fetch发送无cookie的请求,减少http包的大小
  1. 使用本地缓存策略,尽量减少对服务器数据的重复获取。
  2. 减少请求
  3. 资源压缩
  • html压缩:在线压缩,webpack
  • css压缩:无效代码删除,语义合并(在线工具
  • js压缩
  1. 文件合并
  • 首屏渲染问题
  • 缓存失效问题:一个变了其他变
渲染过程优化(服务器端渲染)
  • 浏览器渲染过程对于首屏就有较大的损耗,白屏的时间会有所增加。在必要的情况下可以在服务端进行整个html的渲染,从而将整个html直出到我们的浏览器端,而非在浏览器端进行渲染
1. webpack 的性能瓶颈
  • webpack 的构建过程太花时间
  • webpack 打包的结果体积太大
2. webpack 优化方案
  1. 不要让 loader 做太多事情——以 babel-loader 为例:用 include 或 exclude 来帮我们避免不必要的转译
module: { rules: [ { test: /\.js$/, exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'] } } } ] }

  • 这段代码帮我们规避了对庞大的 node_modules 文件夹或者 bower_components 文件夹的处理。
  1. 开启缓存将转译结果缓存至文件系统
loader: 'babel-loader?cacheDirectory=true'

  1. 删除冗余代码
  • 意思是基于 import/export 语法,Tree-Shaking 可以在编译的过程中获悉哪些模块并没有真正被使用,这些没用的代码,在最后打包的时候会被去除。
3. Gzip
  • 前端自己打包压缩的有grunt,gulp,webpack,这些基本能压缩百分之50以上,gzip能在其基础上再压缩
  • 启用gzip需要客户端和服务端的支持,如果客户端支持gzip的解析,那么只要服务端能够返回gzip的文件就可以启用gzip了
  • 浏览器发送一个请求头,告诉服务器接受压缩版本的文件(gzip和deflate是两种压缩算法)Accept-Encoding:gzip,deflate
  • 如果文件压缩了,服务器返回一个头信息:Content-Encoding:gzip
  • 服务器了解到我们这边有一个 Gzip 压缩的需求,它会启动自己的 CPU 去为我们完成这个任务。而压缩文件这个过程本身是需要耗费时间的,大家可以理解为我们以服务器压缩的时间开销和 CPU 开销(以及浏览器解析压缩文件的开销)为代价,省下了一些传输过程中的时间开销。
  • Gzip 压缩背后的原理,是在一个文本文件中找出一些重复出现的字符串、临时替换它们,从而使整个文件变小。根据这个原理,文件中代码的重复率越高,那么压缩的效率就越高,使用 Gzip 的收益也就越大。反之亦然。
  • 一般压缩js,css;图片不要;
图片优化 一个二进制位表示两种颜色(0|1 对应黑|白),如果一种图片格式对应的二进制位数有 n 个,那么它就可以呈现 2^n 种颜色。
不同业务场景下的图片方案选型 1. JPEG/JPG:
  • 有损压缩、体积小、加载快、不支持透明
  • JPG 图片经常作为大的背景图、轮播图或 Banner 图出现。
2. PNG-8 与 PNG-24:
  • 无损压缩、质量高、体积大、支持透明
  • PNG(可移植网络图形格式)是一种无损压缩的高保真的图片格式。8 和 24,这里都是二进制数的位数。按照我们前置知识里提到的对应关系,8 位的 PNG 最多支持 256 种颜色,而 24 位的可以呈现约 1600 万种颜色。
  • png-8体积小
  • logo
3. SVG
  • 文本文件、体积比jpg,png更小、不失真、兼容性好(对像素处理不是基于像素点,而是基于对图像的形状描述)
  • 图片可无限放大而不失真
  • SVG 是文本文件,我们既可以像写代码一样定义 SVG,把它写在 HTML 里、成为 DOM 的一部分,也可以把对图形的描述写入以 .svg 为后缀的独立文件(SVG 文件在使用上与普通图片文件无异)。
4. 雪碧图(CSS Sprites)
  • 一种将小图标和背景图像合并到一张图片上,然后利用 CSS 的背景定位来显示其中的每一部分的技术
  • 相较于一个小图标一个图像文件,单独一张图片所需的 HTTP 请求更少,对内存和带宽更加友好。
5. Base64
  • 和雪碧图一样,Base64 图片的出现,也是为了减少加载网页图片时对服务器的请求次数,从而提升网页性能
  • Base64 是一种用于传输 8Bit 字节码的编码方式,通过对图片进行 Base64 编码,我们可以直接将编码结果写入 HTML 或者写入 CSS,从而减少 HTTP 请求的次数。
  • 图片生成base64可以用一些工具,如在线工具,但在项目中这样一个图片这样生成是挺繁琐。
    特别说下,webpack中的url-loader可以完成这个工作,可以对限制大小的图片进行base64的转换,非常方便。
  • **base64的图片会随着html或者css一起下载到浏览器,减少了请求. **
  • 可避免跨域问题
  • 体积会比原来的图片大一点。
  • css中过多使用base64图片会使得css过大,不利于css的加载。
  • 应用于小的图片几k的,太大的图片会转换后的大小太大,得不偿失。
    用于一些css sprites不利处理的小图片
浏览器缓存 【前端性能优化(2)】浏览器缓存有四个方面,按优先级排序:
  1. Memory Cache
  2. Service Worker Cache
  3. HTTP Cache
  4. Push Cache
HTTP缓存
强缓存
  • 强缓存是利用 http 头中的 Expires 和 Cache-Control 两个字段来控制的。强缓存中,当请求再次发出时,浏览器会根据其中的 expires 和 cache-control 判断目标资源是否“命中”强缓存,若命中则直接从缓存中获取资源,不会再与服务端发生通信。
expires: Wed, 11 Sep 2019 16:12:18 GMT

  • expires:expires 是有问题的,它最大的问题在于对“本地时间”的依赖。如果服务端和客户端的时间设置可能不同,或者我直接手动去把客户端的时间改掉,那么 expires 将无法达到我们的预期。
  • Cache-Control:HTTP1.1新增,在 Cache-Control 中,我们通过 max-age 来控制资源的有效期。max-age 不是一个时间戳,而是一个时间长度。
  • Cache-Control 相对于 expires 更加准确,它的优先级也更高。当 Cache-Control 与 expires 同时出现时,我们以 Cache-Control 为准。
cache-control: max-age=3600, s-maxage=31536000

  • s-maxage 优先级高于 max-age,两者同时出现时,优先考虑 s-maxage。如果 s-maxage 未过期,则向代理服务器请求其缓存内容。
cache-control
  • no-cache:绕开了浏览器:我们为资源设置了 no-cache 后,每一次发起请求都不会再去询问浏览器的缓存情况,而是直接向服务端去确认该资源是否过期(即不要强缓存,直接协商缓存)。
  • no-store 比较绝情,顾名思义就是不使用任何缓存策略。在 no-cache 的基础上,它连服务端的缓存确认也绕开了,只允许你直接向服务端发送请求、并下载完整的响应。
f5 ctrl+f5
  • f5:F5进行页面刷新时会向服务端发送If-Modify-Since请求头到服务端,服务端返回304 Not Modified,浏览器则使用本地缓存;
  • 在调试页面中,可能需要用到CTRL+F5。这样浏览器就不会采用本地缓存了,而是直接从服务端获取。返回HTTP状态码200;原因:Ctrl+F5在发出请求时,会在请求消息头中加入Cache-Control:no-cache,Pragma:no-cache参数,返回200

    推荐阅读