我第一次使用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-4

    今日进步: 1.国庆答题界面和结果界面的连接完成,并能显示GetRankData API返回结果和错误题目的单词信息. 2.天赋: 完成了整个  单词挑战需要碰到的"Storage" ...

  2. redis的多路复用是什么鬼

    有没有人和我一样, 自打知道了redis, 就一直听说什么redis单线程, 使用了多路复用等等. 天真的我以为多路复用是redis实现的技术. 今天才发现, 我被自己骗了, 多路复用是系统来实现的. ...

  3. 实战 | 将Apache Hudi数据集写入阿里云OSS

    1. 引入 云上对象存储的廉价让不少公司将其作为主要的存储方案,而Hudi作为数据湖解决方案,支持对象存储也是必不可少.之前AWS EMR已经内置集成Hudi,也意味着可以在S3上无缝使用Hudi.当 ...

  4. MVC-基础02

    MVC是Model(模型).View(视图)和Controller(控制). 1)最上面的一层,是直接面向最终用户的"视图层"(View).它是提供给用户的操作界面,是程序的外壳. ...

  5. Java多台中成员访问特点

    多态中的成员访问特点: A:成员变量 编译看左边,运行看左边 B:构造方法 创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化 C:成员方法 编译看左边,运行看右边.//因为调用对象时,子 ...

  6. <string>头文件常用成员函数

    之前说过 string和vector一样,也是一种顺序容器,并且它也自带成员函数,用法和vector的成员函数差不多,不过它只能用来存放字符,也就是字符串. 在c++中,<string>基 ...

  7. JS面向对象编程之封装

    来源:https://segmentfault.com/a/1190000015843072 我们所熟知的面向对象语言如 C++.Java 都有类的的概念,类是实例的类型模板,比如Student表示学 ...

  8. css3--:target选择器称为目标选择器

    :target选择器称为目标选择器,用来匹配文档(页面)的url的某个标志符的目标元素.我们先来上个例子,然后再做分析. 示例展示 点击链接显示隐藏的段落. HTML代码: <h2>< ...

  9. OSG加载倾斜摄影数据

    目录 1. 概述 2. 实例 2.1. 代码 2.2. 解析 3. 结果 1. 概述 ContextCapture(Smart3D)生成的倾斜摄影模型数据一般都形如如下组织结构: 在Data目录下包含 ...

  10. rabbitMQ本地安装(Mac版)

    一. 首先测试本机器是否安装wget命令 (可以通过wget www.baidu.com来测试,如果有响应则可直接进入步骤二,如果报错或者提示未安装wget则需要先安装wget) 1http://ft ...