在“流量贵如油”的今天,作为一名自己买服务器、撸代码的站长,如何给服务器“减负”是每天都要思考的必修课。

痛点:博客网站的流量杀手

我有一个运行多年的个人博客。在分析服务器日志时发现,最大的流量开销并不是文字,而是文章里那些高清的图片。

虽然 JPG 和 PNG 已经很普及,但随着屏幕分辨率越来越高,原图动辄几 MB,对于按带宽付费或者流量计费的服务器来说,这都是白花花的银子。

方案:Webp 格式的“降维打击”

现在主流浏览器(Chrome, Safari, Edge 等)已经全面支持 Webp 格式。相比于传统的 JPG 和 PNG,Webp 可以在保证肉眼看不出画质损失的前提下,将文件体积压缩 30% 到 70%。这是一个非常惊人的数据。这意味着原本 100GB 的图床流量,换成 Webp 后可能只需要 30GB。

为了方便处理博客素材,我决定把这个需求也集成到“豆子工具”里。

图片格式转换

实现:基于 Google 官方工具链

图片转换的实现原理与我之前的“音频转换”方案异曲同工,主打一个稳定与高效

  1. 核心引擎:在服务端安装了 Google 官方出品的 webp 命令行工具链(cwebp)。
  2. 后端调度:依然由 Go 语言担任“指挥官”,接收小程序上传的 PNG/JPG 原图,调用外部 cwebp 进程进行压缩。
  3. 参数优化:在后端我预设了平衡性最好的质量参数,确保图片在压缩后的清晰度依然能够满足博客展示的需求。
  4. 闭环应用:现在我写每一篇博客前,都会先用小程序把配图过一遍,转成 Webp 后再上传。

下面是核心代码片段的注解,这是小程序端:

<page-meta root-font-size="system" />
<view class="page">
  <view class="page__hd">
    <view class="page__title">图片格式转换</view>
    <view class="page__desc">可将图片转换为WebP格式,用于Web项目。</view>
  </view>
  <view class="page__bd">
    <view class="weui-cells  weui-cells_radio">
      <view class="weui-cell weui-cell_uploader">
        <view class="weui-cell__bd">
          <view class="weui-uploader">
            <view class="weui-uploader__hd">
              <view aria-role="option" class="weui-uploader__overview">
                <view class="weui-uploader__title">图片信息</view>
              </view>
              <view class="weui-uploader__tips">
                请选取5M内的图片,目前仅支持一张
              </view>
            </view>
            <view class="weui-uploader__bd">
              <view class="weui-uploader__files" id="uploaderFiles">
                <block wx:for="{{files}}" wx:key="*this">
                  <view class="weui-uploader__file" bindtap="previewImage" id="{{item}}">
                    <image class="weui-uploader__img" src="{{item}}" mode="aspectFill" />
                  </view>
                </block>
              </view>
              <view class="weui-uploader__input-box">
                <view aria-role="button" aria-label="选择图片" class="weui-uploader__input" bindtap="chooseImage"></view>
              </view>
            </view>
          </view>
        </view>
      </view>
      <view class="weui-cell">
        <view wx:if="{{headImageExist}}">
          <image style="width: 200px; height: 200px; background-color: #eeeeee;" mode="aspectFit" src="{{headImage}}" bindtap="previewMakeImage"></image>
        </view>
        <view wx:else><text>转换完成的图片会展示在这里</text></view>
      </view>
      <view class="weui-cell">
        <view class="button-sp-area">
          <view class="weui-btn  weui-btn_primary weui-wa-hotarea" aria-role="button" bindtap="imageConvert">开始转换</view>
          <view class="weui-btn  weui-btn_warn weui-wa-hotarea" aria-role="button" bindtap="saveToPhotosAlbum">保存到相册</view>
        </view>
      </view>
    </view>
  </view>
</view>

上面是界面骨架,现在说下它的灵魂。首先通过小程序的上传文件API,wx.uploadfile将图片文件上传到服务器,然后使用Go调用cwebp进行格式转换,转换成功后,下载文件到小程序本地,然后删除服务器端的文件。

// ImageConvert 图片格式转换 微信上传的图片
func (srv *Service) ImageConvert(src string, imgType string) (string, error) {
	srcImage := global.UploadCachePath + "/" + src
	srcType := utils.GetFileExt(srcImage)
	convertFileName := utils.GetFileNameByFileType(src, imgType)
	destImage := global.UploadCachePath + "/" + convertFileName
	// 使用命令行实现
	switch imgType {
	// cwebp -o picture.webp -- ---picture.png
	case ".webp":
		hasSupport := strings.Index(".png,.jpeg,.jpg", srcType)
		if hasSupport != -1 {
			_, err := exec.Command("cwebp", "-o", destImage, "--", srcImage).Output()
			if err != nil {
				return "", err
			}
		} else {
			return "", ErrTypeNotSupport
		}

	case ".png":
		if srcType == ".webp" {
			// dwebp -o output.png -- ---picture.webp
			_, err := exec.Command("dwebp", "-o", destImage, "--", srcImage).Output()
			if err != nil {
				return "", err
			}
		} else {
			return "", ErrTypeNotSupport
		}
	default:
		return "", ErrTypeNotSupport
	}
	return convertFileName, nil
}

这段代码是核心,调用cwebp命令进行转换。需要注意的是需要安装google webp命令,还有权限问题,运行服务的用户要拥有执行webp命令的权限。

成果:全站 Webp 化

目前,我的博客已经全面实现了图片 Webp 化。这不仅显著提升了网页的加载速度(SEO 评分都变高了),更重要的是,它帮我省下了实打实的流量费用。

如果你也面临服务器带宽压力,或者想让自己的网站加载得飞快,建议尽早加入 Webp 的阵营。

在我实际的使用当中,我发现手机每次转换之后,通过微信文件助手传递又转成了jpg格式,所以我推荐直接在PC端使用小程序。