小程序体积优化(2)--优化图片

通过对大体积文本的优化,总的体积减少了不到100KB,可以说是杯水车薪,看来还是要从大户图片上面下手,分三个方向去处理:

  1. 清理未使用的图片
  2. 压缩图片
  3. 修改部分设计

清理未使用的图片

因为小程序的css文件内不允许使用本地图片,所以只需要查找html里面的引入的图片地址,再加上tab中定义的图标。以 wepy 构建的项目为例,首先,获取页面上使用了哪些图片:

/**
 * 读取pages目录下面的页面文件
 *
 * @returns {Promise} 读取到的.wpy文件
 */
function getPages() {
  return new Promise((resolve, reject)=>{
    fs.readdir(path.resolve('../src/pages/'), (err, files)=>{
      if(err){
        reject(err)
      }
      resolve(files)
    })
  })
}

/**
 * 从页面字符串中提取图片
 *
 * @param {string} fileName 页面文件名字
 * @returns {Promise} 页面提取出的图片 src 数组
 */
function getImagesFormPages(fileName) {

  return new Promise((resolve, reject)=>{
    fs.readFile(path.join('../src/pages/', fileName), (err, data)=>{
      if(err){
        reject(err)
      }
      let fileData = data.toString();
      let imgReg = /<image.*?(?:>|\/>)/gim;
      var srcReg = /src=[\'\"]?([^\'\"]*)[\'\"]?/i;
      let images = fileData.match(imgReg)
      let imagePathArray = null;
      if(images){
        imagePathArray = images.map(item=>{
          var src = item.match(srcReg);
          return src[1]
        })
      }
      resolve({
        fileName: fileName,
        fileData: imagePathArray
      })
    })
  })
}


/**
 * 从页面中获取图片
 *
 * @returns
 */
async function getUsedImages () {
  let pages = await getPages();

  let data = await Promise.all(pages.map(page=>{
    return getImagesFormPages(page)
  }))

  return data
}

再加上tab中定义的图标

const tabImages = [
  '../images/icon_st_nor@2x.png',
  '../images/icon_st_sel@2x.png',
  '../images/icon_tk_nor@2x.png',
  '../images/icon_tk_sel@2x.png',
  '../images/icon_wd_nor@2x.png',
  '../images/icon_wd_sel@2x.png',
];

再获取资源文件夹下面的全部图片

/**
 * 获取资源文件夹下面的图片
 *
 * @returns
 */
function getAssets(){
  return new Promise((resolve, reject)=>{
    glob("../src/images/**/*.{png,jpg}", {}, function (err, files) {
      if(err){
        reject(err)
      }
      resolve(files);
    })
  })
}

再进行一个比对,把在资源目录,而不在html和tab中使用的图片,移动到外部文件夹里面去

const fs = require('fs')
const path = require('path')
const glob = require("glob")

let find = async ()=>{
  // 查找资源目录下的图片
  let allImages = await getAssets();

  // 查找模板中引用的图片
  let usedImages = await getUsedImages();

  usedImages = usedImages
  .filter(i=>i.fileData) // 提取图片数组
  .reduce((a,b)=>a = a.concat(b.fileData), []) // 转化为一维数组
  .filter(i=>i.charAt(0)!=='{') // 删除无效图片
  .map(i=>path.resolve('../src/pages/', i)) // 处理图片路径

  return allImages.filter(image=>{
    return usedImages.indexOf(path.resolve('', image)) === -1
  })
}

find().then(data=>{
  // 找到未使用的图片,移动到外部文件夹,避免再次打包
  if(!fs.existsSync('../un-use-images')){
    fs.mkdirSync('../un-use-images', 0777);
  }

  data.forEach(file=>{
    let name = file.split('/').pop();
    fs.writeFileSync('../un-use-images/'+name, fs.readFileSync(file));
    fs.unlinkSync(file);
  })

})

压缩图片

可以通过 imagemin 库或者软件对图片文件进行批量压缩,我测验的结果是从1.08MB图片压缩到了648KB,效果非常的显著。

修改设计

从设计层面也可以减少不少图片的使用,比如等级从lv1-lv9, 如果设计为反色镂空,用背景色来区分等级,那么最多可以节约8张图片。

尾声

其实图片文件通过手动的方式清理和压缩非常的不方便,但是小程序本身和wepy都没有提供按引入文件打包的功能,接下来我会尝试用 mpvue 重构代码,看能不能做到自动化。

posted on 2018-06-21 14:38  smallcoder  阅读(458)  评论(0编辑  收藏  举报

导航