我第一次使用indexDB是1年前(2018年10月),运用这个黑科技,解决过3个异常棘手的问题(如果不是indexDB 几乎找不到其他解决方案)所以我经常强调,前端一定要学indexDB!

难题一:本地超大json数据的读取和解析

当时我是负责一个办案app的研发(老项目维护),这是个政府项目,app的使用是在离线环境下进行的,主要运行在特定平板上。
打开app,先进行身份验证,验证通过后会读取并展示本地案件数据。这些数据都是通过文件形式存储的,是用户从电脑上拷贝下来的,主要是很多图片,以及这些图片的ocr识别结果的json文件,对图片进行编目产生的json文件等。读取完毕后,就可以对图片做很多操作了,比如添加批注,标注瑕疵等!

我们遇到的关键的难题是,数据量太大!通常一个案件的材料有200张图片(当然几十张的也有,600张以上的也有,但90%都是200张),下面讨论的都是200张的情况。
读取完一个案件平均用时是5.8s,这太漫长了(当然200张,一本书的厚度呢)。经过排查定位到读取ocr json数据就占5.0s。 ocr的json文件结构相当复杂,有25M左右。读取完json文件中的文本,还要将其转换成js对象!不管怎样,读取25M的数据并转换,花了5.0s,这个平板的性能不咋地呀!

瓶颈在读取数据上,那就采用缓存!
显然indexDB是首选——localStorage等容量太小,而且indexDB可以直接存储js对象,读取数据后不用额外转换了!所以我们的方案是读取ocr数据后,先对其进行裁剪(去掉冗余字段,以及永远用不到的字段),然后放入indexDB。后续每次直接从indexDB读取js对象。经过这一步优化,后续打开一个案件,加载过程大幅加快!
这个项目采用的是vue开发,ocr数据不会展示在页面上,也不会改变,所以又采用了Object.freeze()【参考】加强性能!
然后加载过程变成了1.2s!(由5.8s 变成了 1.2s!)感觉已经是极限了,用户也表示完全能接受,再提速只能从硬件上着手了!

另一个问题:后续加载提升了,首次加载怎么办?首次加载还是要读取文件,转换数据,还要写入indexDB,肯定大于5.8s,怎么办?
用户打开app,需要先做身份校验等系列操作——这个过程很长,可以利用这段时间,在用户无感的情况下,完成首次加载的初始化。使用web worker技术,完美解决首次加载的问题。

难题二:编辑任务的步骤缓存

曾经为配音人员处理配音任务 编写了一个配音编辑器,它可以缓存每一步操作的状态,以便能够随时撤销操作;关闭浏览器,下次打开时可以接着编辑。这个数据一样很大,大约300步 缓存就达到了5M,所以只考虑数据大小的话,就应该用indexDB。
不过,缓存步骤并不能简单的把各个步骤放到任务对应的数组中,这还不够,还要有一个对当前缓存的描述:如当前缓存了多少步?撤销了多少步?下次产生新步骤时怎么放入缓存?哪些步骤是无效了的?—— 可以说描述信息很关键,它决定了接下来该怎样操作缓存。步骤的缓存,以及对步骤的描述信息,这两者是强同步的,当修改缓存时,要保证描述信息被同步修改!

这原本是相当难的,用户可以随时关掉浏览器,你甚至没法保证任何同步的事情—— 幸亏indexDB是事务性的,运用事务,一切都迎刃而解。

用户还可以开启多个页面,处理同一个任务!这会引起缓存混乱,但是我们已经有了一个步骤的描述信息,每次写缓存前对传入的信息做个校验,可以很容易识别出混乱!

难题三:大文件断点续传的任务队列

断点续传:首先将大文件拆成多个文件分片,不断上传分片;浏览器关闭后,下次打开 能够接着上传!这又是一个在浏览器上进行的骚操作,indexDB 可以直接缓存文件,所以这个需求还是比较轻松就搞定了的。
在设计时需要注意,任务信息和对应的上传文件要分开存放。因为我们需要显示所有的任务以便能够对其进行操作(如删除任务,重启已失败任务,暂停任务,立即开始任务),但浏览器一个标签页能使用的内存有限(1G左右),所以文件不能常驻内存!分开存放可以很轻松的解决这个问题。
这两个objectStore(存放文件的,存放任务信息的)一样是具有事务性的!

此外,用户可能打开多个窗口或标签页,如何保证多个窗口处理任务时不会冲突?用户还可能随时关掉页面再打开,或者随时刷新页面。
对于第一个问题,需保证最多只有一个窗口处理任务。运用  ‘storage’ 事件 就可以实现控制!【参考
第二个问题在indexDB面前完全不是问题!

到现在(2020年5月8日17:01:38),使用indexDB在实际运用中,解决的主要难题就是上面这些了吧!希望能引起你学习indexDB的兴趣,我也期待自己在今后能用indexDB创造更多精彩!

indexDB解决过的难题的更多相关文章

  1. 十年磨一剑,王坚自研的MaxCompute如何解决世界级算力难题

    摘要: 2009年这项关于大数据的技术长征开始.王坚带队,目标是自研大数据计算平台MaxCompute统一阿里巴巴内部的数据和大数据计算体系. 大数据时代,随着企业数据规模的急剧增长,传统软件已无法承 ...

  2. 深入super,看Python如何解决钻石继承难题 【转】

    原文地址 http://www.cnblogs.com/testview/p/4651198.html 1.   Python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通 ...

  3. 深入super,看Python如何解决钻石继承难题

    1.   Python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通方法和super方法 假设Base是基类 class Base(object): def __init_ ...

  4. [干货]Kaggle热门 | 用一个框架解决所有机器学习难题

    新智元推荐 来源:LinkedIn 作者:Abhishek Thakur 译者:弗格森 [新智元导读]本文是数据科学家Abhishek Thakur发表的Kaggle热门文章.作者总结了自己参加100 ...

  5. 使用prolog逻辑语言解决爱因斯坦斑马难题

    如果你想获得更好的阅读体验,可以前往我在 github 上的博客进行阅读,http://lcomplete.github.io/blog/2013/06/28/sevenlang-prolog/. 目 ...

  6. 七周七语言之使用prolog解决爱因斯坦斑马难题

    如果你想获得更好的阅读体验,可以前往我在 github 上的博客进行阅读,http://lcomplete.github.io/blog/2013/06/28/sevenlang-prolog/. 目 ...

  7. (转载)深入super,看Python如何解决钻石继承难题

    1.   Python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通方法和super方法 假设Base是基类 class Base(object): def __init_ ...

  8. 解决大数据难题 阿里云MaxCompute获科技大奖

    摘要: 据介绍,MaxCompute(大规模分布式的数据计算平台)是国内最早自研的大数据计算平台之一,主要应用于大规模数据处理场景.目前,这项源自浙江.解决世界级难题的成果已拥有EB(百京)级别的数据 ...

  9. 使用$.when()解决AJAX异步难题之:多个ajax操作进行逻辑与(and)

    上一篇文章"JQuery.deferred提供的promise解决方式",提到了javascript异步操作的3个问题,以及javascript Promise入门.如今我们看下怎 ...

随机推荐

  1. stand up meeting 12-8

    根据计划今天项目组成员和travis老师毕然同学进行了最后一次关于design和feature的确认meeting. 项目design和UI的改动较大,feature改动较小,需对UI进行重新整合,对 ...

  2. stand up meeting for beta release plan 12/16/2015

    今天我们开会讨论一下beta版需要的feature,其中待定的feature是可选做的,如果有时间.其他都是必须实现的. 因为做插件的计划失败了,所以我们现在是pdf阅读器和取词查词加入生词本这两部分 ...

  3. U - Obtain a Permutation CodeForces - 1294E 思维

    题解: 注意每一列与每一列之间互不影响,所以贪心地求出没一列的最小操作值,然后累加起来. 怎么求没一列的最小值呢?维护一个数组same表示其中same[i]=j表示将该序列向上翻滚i次有j个元素归位, ...

  4. string 中的getline

    1 getline 读入string库中的字符串 string a; getline(cin,a);  这样的读入要比任何一种读入字符串都有要快 2 char a[N]; cin.getline(a, ...

  5. tensorflow-参数、超参数、卷积核权值共享

    根据网上查询到的说法,参数就是在卷积神经网络中可以被训练的参数,比如卷积核的权值和偏移等等,而超参数是一些预先设定好并且无法改变的,比如说是卷积核的个数等. 另外还有一个最最基础的概念,就是卷积核的权 ...

  6. 常用ElasticSearch 查询语句

    为了演示不同类型的 ElasticSearch 的查询,我们将使用书文档信息的集合(有以下字段:title(标题), authors(作者), summary(摘要), publish_date(发布 ...

  7. 牛客网 - vivo2020届春季

    牛客网 - vivo2020届春季 1.[编程题]手机屏幕解锁模式 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M 现有一个 3x3 规格的 Android ...

  8. LDA概率主题模型

    目录 LDA 主题模型 几个重要分布 模型 Unigram model Mixture of unigrams model PLSA模型 LDA 怎么确定LDA的topic个数? 如何用主题模型解决推 ...

  9. 在java 8 stream表达式中实现if/else逻辑

    目录 简介 传统写法 使用filter 总结 简介 在Stream处理中,我们通常会遇到if/else的判断情况,对于这样的问题我们怎么处理呢? 还记得我们在上一篇文章lambda最佳实践中提到,la ...

  10. Libra教程之:Libra testnet使用指南

    文章目录 Libra testnet网络 下载和安装Libra 编译Libra client并连接到Testnet网络 创建两个A和B的两个账号 检查libra cli Client是否运行 创建A的 ...