(拿走不谢)vue项目性能优化6,优化:H5图片缓存,公开图片缓存工具

基于webpack 3、vue 2和vue-cli 2的性能优化。

如果图片还没缓存,先把图片下载,转换成base64字符串,保存到本地。
如果图片已经缓存,直接拿出来,显示到UI上,不用再请求网络。
如果图片改变,重新下载,更新本地缓存。
有两种方案选择:
1、web storage存储。window.localStorage大小限制是5MB左右。
2、IndexedDB存储。没有大小限制,或者说存储的大小更加大。类似SQLite数据库,参考IndexedDBUtils.js文件。推荐使用。

附带IndexedDBUtils工具类:
/**

  • IndexedDB存储
  • 主要解决图片缓存。
  • 官网资料:https://www.w3.org/TR/IndexedDB/
    */

export default {
/**

  • 创建默认数据库

  • @returns {*|Promise}
    /
    createDefaultDB() {
    return this.createOrUpdateDB(‘H5’, 1);
    },
    /
    *

  • 创建或升级数据库

  • 该方法的回调,可以创建表。

  • @param dbName 数据库

  • @param version 版本号

  • @returns {Promise}
    /
    createOrUpdateDB(dbName, version) {
    return new Promise((resolve, reject) => {
    let db;
    let request = indexedDB.open(dbName, version);
    //如果数据库不存在,会调用onupgradeneeded和onsuccess。
    //如果数据库升级版本,也会调用onupgradeneeded和onsuccess。
    request.onupgradeneeded = function () {
    db = request.result;
    /
    *
    * 注意,只有onupgradeneeded可以调用db.createObjectStore()方法。
    * 在onsuccess方法调用db.createObjectStore()方法会报错。
    */
    //一个Promise执行2次resolve(),那么第二次,是不会执行的。因此,需要拆开成2个方法。
    resolve(db);
    };

    /request.onsuccess = function (e) {
    //db = request.result;
    db = e.target.result;
    let data = {db: db, createObjectStore: false};
    resolve(data);
    };
    /

    request.onerror = function (e) {
    reject(e);
    };
    });
    },
    //打开默认数据库
    openDefaultDB() {
    return this.openDB(‘H5’, 1);
    },
    /**

  • 打开数据库

  • 该方法的回调,不能创建表。会报错。

  • @param dbName 数据库名称

  • @param version 版本号(数字)

  • @returns {Promise}
    */
    openDB(dbName, version) {
    return new Promise((resolve, reject) => {
    let db;
    let request = indexedDB.open(dbName, version);

    request.onsuccess = function (e) {
    //db = request.result;
    db = e.target.result;
    resolve(db);
    };

    request.onerror = function (e) {
    reject(e);
    };
    });
    },
    //判断默认表名是否存在
    existDefaultTableName(db) {
    //缓存图片
    return this.existTableName(db, ‘CacheImage’);
    },
    //判断表名是否存在
    existTableName(db, tableName) {
    return db.objectStoreNames.contains(tableName);
    },
    //创建默认的表
    createDefaultTable(db) {
    let exist = this.existDefaultTableName(db);
    //不存在,就创建
    if(!exist) {
    let objectStore = db.createObjectStore(‘CacheImage’, {
    keyPath: ‘id’,
    autoIncrement: true
    });
    objectStore.createIndex(‘code_index’, ‘code’, {unique: true});
    }
    return true;
    },
    saveCacheImage(db, data) {
    return this.saveOrUpdate(db, ‘CacheImage’, data);
    },
    /**

  • 新增或更新数据

  • 如果数据不存在,就新增。

  • 如果数据已存在,则更新。

  • 如果是更新数据,那么,该条数据必须指定主键的值,否则报错。

  • @param tableName 表名

  • @param data json对象的数据,例如:{name: ‘test’, age: 10}
    /
    saveOrUpdate(db, tableName, data) {
    return new Promise((resolve, reject) => {
    let tx = db.transaction(tableName, ‘readwrite’);
    let store = tx.objectStore(tableName);
    let request = store.put(data);
    request.onsuccess = function () {
    resolve();
    };
    request.onerror = function (e) {
    reject(e);
    };
    });
    },
    findCacheImageByIndex(db, code) {
    return this.findByIndex(db, ‘CacheImage’, ‘code_index’, code);
    },
    /
    *

  • 通过唯一索引,查询数据

  • @param db 数据库

  • @param tableName 表名

  • @param indexName 唯一索引(该字段的数据不会重复)

  • @param searchContent 搜索内容

  • @returns {Promise}
    /
    findByIndex(db, tableName, indexName, searchContent) {
    return new Promise((resolve, reject) => {
    let tx = db.transaction(tableName, ‘readonly’);
    let store = tx.objectStore(tableName);
    let index = store.index(indexName);
    let request = index.get(searchContent);
    request.onsuccess = function () {
    let data = request.result;
    if(data !== undefined) {
    resolve(data);
    } else {
    resolve(null);
    }
    };
    });
    },
    //异步加载图片,转换成base64字符串
    loadImage(url) {
    return new Promise((resolve, reject) => {
    let xhr = new XMLHttpRequest();
    xhr.open(‘GET’, url, true);
    //超时时间,单位是毫秒
    xhr.timeout = 60000;
    xhr.responseType = ‘blob’;
    xhr.ontimeout = (e) => {
    reject(e);
    };
    xhr.onload = () => {
    if(xhr.status === 200) {
    let blob = xhr.response;
    let fileReader = new FileReader();
    //转换成base64
    fileReader.onload = (e) => {
    let base64 = e.target.result;
    resolve(base64);
    };
    fileReader.readAsDataURL(blob);
    }
    };
    xhr.send();
    });
    },
    /
    *

  • 异步加载图片,并缓存起来

  • @param code 编码

  • @param imageUrl 图片链接

  • @returns {Promise} 图片的base64字符串,用于显示在元素的src上
    */
    loadCacheImage(code, imageUrl) {
    return new Promise((resolve, reject) => {
    this.createDefaultDB().then((db) => {
    this.createDefaultTable(db);
    });

    this.openDefaultDB().then((db) => {
    this.findCacheImageByIndex(db, code).then((data) => {
    if(!data) {
    this.loadImage(imageUrl).then((base64) => {
    resolve(base64);
    this.saveCacheImage(db, {
    code: code,
    url: imageUrl,
    base64: base64});
    });
    } else {
    //链接改变,重新下载图片
    if(data.url !== imageUrl) {
    this.loadImage(imageUrl).then((base64) => {
    resolve(base64);
    this.saveCacheImage(db, {
    id: data.id,
    code: code,
    url: imageUrl,
    base64: base64});
    });
    } else {
    resolve(data.base64);
    }
    }
    });
    });
    });
    }
    };

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值