2、前端性能优化(一):资源压缩与合并

大家好,我是老张。今天咱们聊聊前端性能优化的第一步——资源压缩与合并。说实话,这块内容看起来基础,但很多团队都栽过跟头。我见过不少项目,代码写得挺漂亮,结果上线后加载慢得像蜗牛,一查才发现,光CSS文件就十几个,JS文件更是堆成了山。

为什么会这样?说白了,就是没做好资源的「瘦身」和「打包」。你想想看,浏览器每加载一个文件,就得发起一次HTTP请求。文件越多,请求次数越多,页面加载自然就慢。今天我就把这几招压箱底的经验分享给你。

CSS/JS/HTML压缩:给代码「减减肥」

压缩这事儿,说白了就是去掉代码里那些「没用」的东西。空格、换行、注释,这些在开发时帮了我们大忙,但到了生产环境,它们就成了累赘。

核心思路:开发时写给人看,上线时写给机器看。

我个人的习惯是,在构建流程里直接集成压缩工具。比如用Webpack的话,配置一个terser-webpack-plugin就能搞定JS压缩。CSS压缩更简单,css-minimizer-webpack-plugin一把梭。

给你看个实际例子。这是一段没压缩的CSS:

.container {
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
  /* 这是注释,上线后可以去掉 */
  padding: 20px;
}

压缩之后变成这样:

.container{width:100%;max-width:1200px;margin:0 auto;padding:20px}

你看,体积直接少了将近一半。HTML压缩也是同理,去掉空格和注释,还能把引号优化掉。我在一个项目中试过,光HTML压缩就让首屏加载快了200毫秒。

小技巧:压缩时别把console.log也压缩掉了。我建议用drop_console: true选项,生产环境自动移除所有调试代码。

雪碧图:把零散图片「拼」在一起

雪碧图这名字挺有意思,其实就是把一堆小图标拼到一张大图上。为什么要这么做?因为每张小图标都是一个HTTP请求,拼在一起就只剩一个请求了。

我记得刚入行那会儿,有个项目用了50多个小图标,每个图标单独加载。结果页面加载时,图标是一个一个蹦出来的,用户体验特别差。后来我把它们拼成一张雪碧图,加载速度直接翻倍。

雪碧图的核心逻辑是这样的:

  1. 把所有小图标合并到一张大图上
  2. 用CSS的background-position控制显示哪个图标
  3. 设置background-size适配不同尺寸

举个例子:

.icon-home {
  width: 32px;
  height: 32px;
  background: url('sprite.png') -0px -0px;
}
.icon-user {
  width: 32px;
  height: 32px;
  background: url('sprite.png') -32px -0px;
}

这里要注意一点:雪碧图适合那些「固定尺寸、不常变」的小图标。如果是大图或者需要频繁换肤的场景,雪碧图就不太合适了。

避坑指南:我曾经犯过一个错,把不同尺寸的图标硬塞进一张雪碧图里,结果CSS定位算得我头都大了。建议雪碧图里的图标尺寸保持一致,或者至少是2的倍数,这样计算位置会方便很多。

Base64编码:把图片「写进」代码里

Base64编码,说白了就是把图片转成一串字符,直接嵌到CSS或HTML里。这样就不用额外请求图片文件了。

你可能会问:「那所有图片都用Base64不就好了?」嗯,这里有个坑。Base64编码会让图片体积增大30%左右。所以它只适合小图片,比如图标、loading图这些几KB的玩意儿。

我一般这么用:

.icon-loading {
  background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...');
}

你看,图片直接写在了CSS里。这样做的好处是减少了一次HTTP请求,坏处是CSS文件变大了。所以得权衡一下:

场景 推荐做法 原因
小图标(< 10KB) Base64编码 减少请求,体积增加可接受
中等图标(10-50KB) 雪碧图 合并请求,体积控制好
大图(> 50KB) 单独加载 Base64会导致CSS/HTML过大

我个人习惯是,小于5KB的图片直接Base64,5-30KB的用雪碧图,超过30KB的就单独加载。这个分界线不是绝对的,你可以根据项目实际情况调整。

小技巧:现在很多构建工具都支持自动判断。比如Webpack的url-loader,可以设置一个阈值,小于阈值的自动转Base64,大于阈值的自动生成文件。省心又省力。

知识体系总览

说了这么多,咱们来张图总结一下。这张图展示了资源压缩与合并的核心逻辑:

前端资源压缩与合并知识体系 CSS/JS/HTML压缩 雪碧图 Base64编码 核心目标:减少HTTP请求 具体实现方法 Webpack插件 terser-webpack-plugin css-minimizer-webpack-plugin 构建工具 webpack-spritesmith postcss-sprites 自动转换 url-loader (阈值设置) file-loader 注意事项 ⚠ 压缩时保留必要注释(如版权信息) ⚠ 雪碧图适合小图标,大图单独加载 ⚠ Base64只适合5KB以下的小图片

这张图把咱们今天讲的内容串起来了。你看,三个方法虽然不同,但目标都一样——减少HTTP请求。压缩是去掉冗余,雪碧图是合并同类项,Base64是把小图直接嵌入代码。三者配合使用,效果最好。

好了,今天就聊到这儿。这些方法看着简单,但用好了效果立竿见影。下次咱们接着聊缓存策略,那个更有意思。


专注资料整理