小程序體積優化(1)--優化大文本

緣起

昨天接手了一個小程序,讓新增一些頁面。頁面寫完,預覽失敗。爲啥?大小超過2M了。雖說小程序目前支持分包的方式讓上限提升到4M,可是考慮到業務的發展,仍是先優化一波。git

去掉無用數據

優化體積,從大文件下手,首先找到的大文件,就是 address.js, 體積頗大,足有 145kb 。咱們看看他。github

// 原始數據, 差很少長這樣

module.exports = [{"code":"110000","region":"北京","regionEntitys":[{"code":"110100","region":"北京市","regionEntitys":[{"code":"110101","region":"東城區"},{"code":"110102","region":"西城區"},{"code":"110105","region":"朝陽區"},{"code":"110106","region":"豐臺區"},{"code":"110107","region":"石景山區"},{"code":"110108","region":"海淀區"},{"code":"110109","region":"門頭溝區"},{"code":"110111","region":"房山區"},{"code":"110112","region":"通州區"},{"code":"110113","region":"順義區"},{"code":"110114","region":"昌平區"},{"code":"110115","region":"大興區"},{"code":"110116","region":"懷柔區"},{"code":"110117","region":"平谷區"},{"code":"110118","region":"密雲區"},{"code":"110119","region":"延慶區"},{"code":"110199","region":"其餘區"}]}]},{"code":"120000","region":"天津","regionEntitys":[{"code":"120100","region":"天津市","regionEntitys":[{"code":"120101","region":"和平區"},{"code":"120102","region":"河東區"},{"code":"120103","region":"河西區"},{"code":"120104","region":"南開區"},{"code":"120105","region":"河北區"},{"code":"120106","region":"紅橋區"},{"code":"120110","region":"東麗區"},{"code":"120111","region":"西青區"},{"code":"120112","region":"津南區"},{"code":"120113","region":"北辰區"},{"code":"120114","region":"武清區"},{"code":"120115","region":"寶坻區"},{"code":"120116","region":"濱海新區"},{"code":"120117","region":"寧河區"},{"code":"120118","region":"靜海區"},{"code":"120119","region":"薊州區"},{"code":"120199","region":"其餘區"}]}]},{"code":"130000","region":"河北省","regionEntitys":[{"code":"130100","region":"石家莊市","regionEntitys":[{"code":"130102","region":"長安區"},{"code":"130104","region":"橋西區"},{"code":"130105","region":"新華區"},{"code":"130107","region":"井陘礦區"},{"code":"130108","region":"裕華區"},{"code":"130109","region":"藁城區"},{"code":"130110","region":"鹿泉區"},{"code":"130111","region":"欒城區"},{"code":"130121","region":"井陘縣"},{"code":"130123","region":"正定縣"},{"code":"130125","region":"行唐縣"},{"code":"130126","region":"靈壽縣"},{"code":"130127","region":"高邑縣"},{"code":"130128","region":"深澤縣"},{"code":"130129","region":"贊皇縣"},{"code":"130130","region":"無極縣"},{"code":"130131","region":"平山縣"},{"code":"130132","region":"元氏縣"},{"code":"130133","region":"趙縣"},{"code":"130183","region":"晉州市"},{"code":"130184","region":"新樂市"},{"code":"130199","region":"其餘區"}]},{"code":"130200","region":"唐山市","regionEntitys":[{"code":"130202","region":"路南區"},{"code":"130203","region":"路北區"},{"code":"130204","region":"古冶區"},{"code":"130205","region":"開平區"},{"code":"130207","region":"豐南區"},{"code":"130208","region":"豐潤區"},{"code":"130209","region":"曹妃甸區"},{"code":"130223","region":"灤縣"},{"code":"130224","region":"灤南縣"},{"code":"130225","region":"樂亭縣"},{"code":"130227","region":"遷西縣"},{"code":"130229","region":"玉田縣"},{"code":"130281","region":"遵化市"},{"code":"130283","region":"遷安市"},{"code":"130299","region":"其餘區"}]},{"code":"130300","region":"秦皇島市","regionEntitys":[{"code":"130302","region":"海港區"},{"code":"130303","region":"山海關區"},{"code":"130304","region":"北戴河區"},{"code":"130306","region":"撫寧區"}, ...], ... ]

經過調用的頁面發現,數據中的 code 字段是沒有被使用的,先全文替換爲空字符串。小程序

let str = JSON.stringify(data)
// 去除code字段
str = str.replace(/"code":"\d{6}",/g, '')

替換後,體積變爲了 90KB, 直接減小了 38% 的體積測試

縮短變量名

去掉code字段以後,體積確實少了不少,可是還須要進一步優化,把長的變量名改短,看看能減小多少體積?優化

// regionEntitys 修改成 E
// region 修改成 R

str = str.replace(/regionEntitys/g, 'E')
str = str.replace(/region/g, 'R')

如今的體積是 68kb,僅僅是經過修改變量名,又減小了 24% 的體積。code

數據字典

到了如今,還能減小嗎?固然能,變量名能夠縮短,漢字字符串能夠提取相同的部分,做爲數據字典。先統計一下那些字出現機率最高:圖片

let hashMap = {};
for(let i = 0, len = str.length; i < len; i++){
  let char = str[i];
  if(['{', '}', '[', ']', ':', ',', '"', 'E', 'R'].indexOf(char) > -1) continue
  if(!hashMap[char]){
    hashMap[char] = 1
  }
  hashMap[char] += 1
}

let sortList = [];
for(var i in hashMap){
  sortList.push([i, hashMap[i]])
}

// sortList 前20個
[ [ '縣', 1503 ],
  [ '區', 1305 ],
  [ '市', 667 ],
  [ '其', 341 ],
  [ '他', 341 ],
  [ '族', 198 ],
  [ '山', 172 ],
  [ '治', 161 ],
  [ '自', 160 ],
  [ '城', 157 ],
  [ '州', 147 ],
  [ '陽', 132 ],
  [ '江', 125 ],
  [ '安', 120 ],
  [ '南', 109 ],
  [ '東', 85 ],
  [ '平', 82 ],
  [ '寧', 80 ],
  [ '河', 78 ],
  [ '西', 74 ] ]

統計完畢以後,作一次全局的文本替換ip

let top20 = sortList.sort((a,b)=>{return b[1] - a[1]}).slice(0, 20).map(i=>i[0])
let keyMap = 'abcdefghijklmnopqrstuvwxyz';

const pat = new RegExp(`(${top20.join('|')})`, 'g')
// 替換字符串
str = str.replace(pat, (hit)=>{
  let index = top20.indexOf(hit);
  return keyMap.charAt(index);
})

壓縮後的文本看起來是這樣的字符串

let region = [{"R":"北京","E":[{"R":"北京c","E":[{"R":"pjb"},{"R":"tjb"},{"R":"朝lb"},{"R":"豐臺b"},{"R":"石景gb"},{"R":"海淀b"},{"R":"門頭溝b"},{"R":"房gb"},{"R":"通kb"},{"R":"順義b"},{"R":"昌qb"},{"R":"大興b"},{"R":"懷柔b"},{"R":"q谷b"},{"R":"密雲b"},{"R":"延慶b"},{"R":"deb"}]}]},{"R":"天津","E":[{"R":"天津c","E":[{"R":"和qb"},{"R":"spb"},{"R":"stb"},{"R":"o開b"},{"R":"s北b"},{"R":"紅橋b"},{"R":"p麗b"}, ...]

替換後的文本是56kb,體積再次減小了 17%。get

文本解析

在進行了字典壓縮文本以後,使用時還須要解析,再次利用提取出的字段:

let pat = new RegExp(`(${Object.keys(top20).join('|')})`, 'g')
function getRegion() {
  let data = null;
  try {
    data = JSON.parse(JSON.stringify(region).replace(pat, (hit)=>{
      return top20[hit];
    }))
  } catch (error) {
    throw new Error(error);
  }
  return data
}

通過測試,解析耗時 5ms左右, 在能夠承受的範圍。

通過不懈努力,終於把這個文件從最初的145kb,減小了到如今的56kb,一共減小了61% 的文件大小。

能夠看出,壓縮雖然有效,可是收益最大的操做仍是去掉無用的字段。順着這個思路,接下來繼續對圖片進行優化。

example

本文demo在這裏 小程序體積優化(1)--優化大文件 demo

相關文章
相關標籤/搜索