cjfff / issue-blog

博客已经迁移至语雀
https://www.yuque.com/ubdme4/ccc
0 stars 0 forks source link

记一次打包(图片)优化 #3

Open cjfff opened 6 years ago

cjfff commented 6 years ago

起因

某次研发公司的客服系统,在打包的过程中发现css文件特别巨大; 打包 可以明显看出css出现了 webpack的体积庞大预警....

起初我看到这个并没怎么在意

但随着几次打包后,想了想,恩,不对劲!

此项目的重点在交互上,所以js大我是可以谅解的,但css文件过大???此时我的内心~

黑人问号

通过思考,我想起来之前为了解析微信用户发送过来的表情,我引入了别人的一个库。

这个库是用来干嘛的呢?微信内置表情(不包含emoji部分)解析+替换图片。

原理是用微信发送过来的表情,会变成字符在网络上传输,我们接收到字符后,进行替换成特定的图片显示在网页上。

使用他的这个库...里面的图片没有进行过优化,一共有105个2kb左右的小图片 这时候 webpack里面引用的一个插件 url-loader

      {
        test: /\.(gif|png|jpe?g|svg)$/,
        loader: 'url-loader',
        options: {
          limit: 8192,
          name: utils.assetsPath('media/[name].[hash:7].[ext]')
        }
      },

注意看options 里面有一个limit属性,意思小于这个字节数的图片都会被转换成 base64 然后 嵌入到css文件中, base64转码后,大小一般会是原文件大小的 4/3 所以也就造成了css 文件巨大的缘故~

第一个解决办法

将限制改为更低,让图片都不编译成 base64 但这样做的话显然是不合理的,因为每一次不同的表情都会去请求不同的小图标地址, 这需要经过一长串的过程

http请求过程: DNS解析 -> 建立TCP连接 -> 发送请求 -> 等待服务器返回首字节 -> 接收数据 虽然不是每次都会把这个过程重复走一遍

  • 浏览器会缓存DNS信息
  • HTTP 1.1 keep-alive特性,会使HTTP请求去复用已有TCP连接,所以也并不是每个HTTP请求都需要新建TCP连接

第二个解决办法

使用老前辈们创造的 CSS Sprites精灵图 原理是,把多个小图片文件合成一张大图,通过background-position 属性去选择显示某个图片

方案是有了,但是该怎么做呢?总不能打开photoshop 自己一个个粘上去把!

这时候就要用到一些在线工具了。

首先打开这个 网址

把我们的小图标全部选中生成一张大图

效果是这样的 雪碧图 然后先别急,把图片下载下来后再对图片进行压缩, 再把css复制下来改改就能使用了.

这时候我们再用这些刚刚生成的资源文件把项目中正在使用的资源文件替换掉;

这时候我们再来打包一次~

这时候该测试下结果了,重新 npm run build

压缩后

可以看到!我们的css文件从 421kb 下降到 69kb, 然后我们制作的精灵图才32kb, 也就是说我们节省的空间是 421 - 69 - 32 = 320

这只是优化中的一个小点而已...优化还有很多方方面面要做的事情,这只是一次技术尝试!