原文鏈接: pako 壓縮lottie動效資源方案
上一篇: typescript-json-schema 和 ajv 檢測數據是否符合指定的ts類型
下一篇: vue3 i18n 國際化支持
基本思想就是把lottie資源全部打成一個json, 然後轉成二進制格式, 下載後解包再還原回去, 基本上可以壓縮到20%大小, lz可能有30%, 畢竟字符串比二進制要大一點點的
壓縮和解壓也可以使用base64和lz-string實現, 畢竟pako包有點大
有個包, 也能做一些壓縮
https://github.com/fancy-lottie/lottie-compress/blob/master/src/main.ts
主要思想, 將json和裏面的資源全部打成一個二進制文件, 然後只需要下載這個二進制文件就行了, 下載後把圖片鏈接替換掉, lottie資源中支持blob鏈接和base64鏈接, u置爲空, 值設置p即可
一個簡單的演示, pako和lz的計算時間差不多, 但是pako壓縮率能高一點, brotli就不用考慮了太大了
import { readFileSync, writeFileSync } from "fs";
import { resolve } from "path";
import lz from "lz-string";
import pako from "pako";
console.log(pako);
const root = "test/lottie/";
const originPath = resolve(root, "./data.json");
const outputPath = resolve(root, "./compress.json");
console.log(originPath, outputPath);
const s = readFileSync(originPath, { encoding: "utf8" });
console.log("originSize", readFileSync(originPath).length, s.length);
const delKeyList = ["nm", "tyName"];
const json = JSON.parse(s);
function removeKeys(obj) {
for (const k of delKeyList) {
if (k in obj && obj.k) delete obj[k];
}
if (Array.isArray(obj)) {
obj.forEach((item) => removeKeys(item));
}
obj.assets && removeKeys(obj.assets);
obj.layers && removeKeys(obj.layers);
}
removeKeys(json);
let st = +new Date();
const outputStr = lz.compress(JSON.stringify(json));
console.log("time", +new Date() - st);
console.log(outputStr.length);
writeFileSync(outputPath, outputStr);
st = +new Date();
const decode = lz.decompress(outputStr);
console.log("time", +new Date() - st);
console.log(decode.length);
st = +new Date();
const s2 = JSON.stringify(json);
let compressed = pako.deflate(s2);
// let compressed = pako.deflate(s2, { to: 'string' });
console.log(compressed);
let ed = +new Date();
console.log("pako", compressed.length, compressed.length / s2.length, ed - st);
st = +new Date();
let raw = pako.inflate(compressed);
// let raw = pako.inflate(compressed, { to: 'string' });
ed = +new Date();
console.log("pako2", raw.length, ed - st, raw);