indexDB解决过的难题
我第一次使用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解决过的难题的更多相关文章
- 十年磨一剑,王坚自研的MaxCompute如何解决世界级算力难题
摘要: 2009年这项关于大数据的技术长征开始.王坚带队,目标是自研大数据计算平台MaxCompute统一阿里巴巴内部的数据和大数据计算体系. 大数据时代,随着企业数据规模的急剧增长,传统软件已无法承 ...
- 深入super,看Python如何解决钻石继承难题 【转】
原文地址 http://www.cnblogs.com/testview/p/4651198.html 1. Python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通 ...
- 深入super,看Python如何解决钻石继承难题
1. Python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通方法和super方法 假设Base是基类 class Base(object): def __init_ ...
- [干货]Kaggle热门 | 用一个框架解决所有机器学习难题
新智元推荐 来源:LinkedIn 作者:Abhishek Thakur 译者:弗格森 [新智元导读]本文是数据科学家Abhishek Thakur发表的Kaggle热门文章.作者总结了自己参加100 ...
- 使用prolog逻辑语言解决爱因斯坦斑马难题
如果你想获得更好的阅读体验,可以前往我在 github 上的博客进行阅读,http://lcomplete.github.io/blog/2013/06/28/sevenlang-prolog/. 目 ...
- 七周七语言之使用prolog解决爱因斯坦斑马难题
如果你想获得更好的阅读体验,可以前往我在 github 上的博客进行阅读,http://lcomplete.github.io/blog/2013/06/28/sevenlang-prolog/. 目 ...
- (转载)深入super,看Python如何解决钻石继承难题
1. Python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通方法和super方法 假设Base是基类 class Base(object): def __init_ ...
- 解决大数据难题 阿里云MaxCompute获科技大奖
摘要: 据介绍,MaxCompute(大规模分布式的数据计算平台)是国内最早自研的大数据计算平台之一,主要应用于大规模数据处理场景.目前,这项源自浙江.解决世界级难题的成果已拥有EB(百京)级别的数据 ...
- 使用$.when()解决AJAX异步难题之:多个ajax操作进行逻辑与(and)
上一篇文章"JQuery.deferred提供的promise解决方式",提到了javascript异步操作的3个问题,以及javascript Promise入门.如今我们看下怎 ...
随机推荐
- Daily Scrum 1/14/2016
Zhaoyang & Yandong: Still optimizing the speech input interface Dong & Fuchen: Image asynchr ...
- H - Hamiltonian Hypercube Gym - 101170H
规律题 首先我们要知道他的顺序是怎么来的,首先当n等于1时,是0,1 当n=2时,先按照与按顺序在他们前面分别加0,即00,01,在逆序加1,即11,10 构成的顺序为00,01,11,10:往后同理 ...
- mysql datetime类型 按格式在页面输出
mysql datetime类型对应java Date类型 java.util.Date类型会显示时间戳 java.sql.Date 只显示年月日不显示时分秒 只需要重写get方法 就能按格式输出 ...
- redis:String字符串类型(三)
字符串拼接(如果key不存在则创建):append name " applesnt" 获取字符串的长度:strlen name 127.0.0.1:6379> set nam ...
- SpringCloud(二)笔记之Eureka
Eureka包含两个组件:Eureka Server和Eureka Client Eureka Server:提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册 Eureka ...
- Java 多线程实现方式二:实现 Runnable 接口
由于java是单继承,很多时候为了实现多线程 通过继承 Thread 类后,就不能再继承其他类了.为了方便可以通过实现 Runnable 接口来实现,和Tread 类似需要重写run 方法. 下面通过 ...
- windows下部署.netcore+docker系列四 (部署程序,重点就要来了)
前面的都是为这章做准备,加油把骚年们 PS:C# 项目可以按照流程一步步来,java 偶然其他的可以找下其他的网上资源 1.在 VS2019中 添加docker 支持 (其实也就是追加一个Docker ...
- PHP中的11个魔术方法
1.__get.__set 这两个方法是为在类和他们的父类中没有声明的属性而设计的 __get( $property ) 当调用一个未定义的属性时访问此方法__set( $property ...
- linux抓包的实现
工具: wireshark tcpdump 在这里仅仅介绍后者: 在网络问题的调试中,tcpdump应该说是一个必不可少的工具,和大部分linux下优秀工具一样,它的特点就是简单而强大. 默认情况下, ...
- [Inno Setup] 卸载 重启之后 删除文件
某些系统文件,例如驱动,不重启无法删除. 利用windows注册表里的 RunOnce.注意必须在HKLM下,否则可能权限不够. 不能直接填cmd命令,要以cmd的参数形式填写. procedure ...