你不能阻止DOM

浏览器数据库景观

对于外行来说,浏览器数据库的世界可能是一个令人困惑的世界。LawnchairPouchDBLocalForageDexieLovefieldLokiJSAlaSQLMakeDriveForerunnerDBYDN-DB -这是一个很大的数据库!

事实证明,情况要比表面上看起来简单得多。事实上,在浏览器中只有三种存储数据的方式:

上面列出的每个“数据库”都使用这三个之一(或者它们在内存中运行)。所以要了解浏览器存储,你只需要了解LocalStorage,WebSQL和IndexedDB 1

LocalStorage是存储键值对的一种轻量级方法。这个API非常简单,但是在许多浏览器中使用限制在5MB。再加上API是同步的,所以我们稍后会看到,它可以阻止DOM。浏览器支持非常好

WebSQL是一个只支持Chrome和Safari(以及Android和iOS扩展)的API 。它为SQLite提供了一个异步的事务接口。自2010年以来,它已被弃用赞成IndexedDB。

IndexedDB是LocalStorage和WebSQL的继承者,旨在将其替换为“一个真正的”浏览器数据库。它暴露了一个异步的API,它可以避免阻止DOM,但是正如我们下面将会看到的那样,它并不一定会被炒作。浏览器的支持是非常多的,只有Chrome和Firefox具有完全可用的实现。

JavaScript是一个单线程编程环境,这意味着同步操作是阻塞的。而且由于DOM是同步的,这意味着当JavaScript阻塞时,DOM也被阻塞。所以如果任何一个操作的时间超过了16ms,就会导致丢帧,用户体验缓慢,“口吃”或“跳跃”。

这就是JavaScript有这么多异步API的原因。想象一下,如果整个页面在每个AJAX请求期间都被冻结了,那么如果这种方式起作用的话,Web将不会是一个糟糕的用户体验!因此,编程结构像回调,承诺,事件监听器等等非常丰富。

localStorage的

在Chrome,Firefox和Edge的全部三种版本中,LocalStorage在写入数据2时完全阻止了DOM 。因为浏览器必须实际刷新到磁盘,所以阻塞比内存更明显。

这几乎是不使用LocalStorage 的横幅原因。即使插入10000条记录后,API只需要几百毫秒的时间,您仍然会注意到DOM在此之后可能会长时间阻塞。我认为这是因为这些浏览器将LocalStorage缓存到内存中,然后对它们的写入操作进行批处理(这是Firefox如何操作),但是在任何情况下,用户界面仍然看起来很笨拙。

在Safari中,情况更糟。不知怎的,DOM不会被阻止在所有期间localStorage的操作,但在另一方面,如果您将太多的数据,你会得到厄运的纺纱沙滩球,页面将被永久冻结。我已经提交这个作为WebKit上的错误

的WebSQL

我们只能在Chrome和Safari中测试这个,但它仍然很有启发性。在Chrome中,WebSQL实际上阻止了DOM,至少对于繁重的操作。而在Safari中,无论WebSQL在做什么,动画都保持顺畅。

当我们开始转向客户端数据库IndexedDB的所谓救世主时,这应该让你感到不安。WebSQL和IndexedDB不是同步的吗?难道他们不与DOM无关吗?他们为什么要阻止DOM渲染呢?

这些结果让我感到非常震惊,尽管过去两年我在这些API上做了大量的工作。但让我们继续前进,看看这个兔子洞有多深...

IndexedDB的

如果您在Chrome或Firefox中尝试使用演示页面,您可能会惊奇地发现,IndexedDB实际上几乎在整个操作过程中 阻止了DOM 3。在Safari中,我根本没有看到这种行为(虽然IndexedDB是痛苦的缓慢),而在边缘我看到偶尔的下降框架。

在Firefox和Chrome中,对于基本的键值插入,IndexedDB比LocalStorage要慢,并且仍然阻止DOM。在Chrome中,它也比WebSQL慢,它阻止了DOM,但几乎没有那么多。只有在Edge和Safari中,IndexedDB才能在不中断UI的情况下在后台运行,而且这两个浏览器只是部分实现了IndexedDB规范。

这是一个非常令人震惊的发现,所以我及时地在ChromeFirefox提交了一个bug 。令人伤心的是我认为这只是Web开发人员不得不忽视的另外一个原因 - 使用恶意浏览器支持和丑陋的API,我们现在可以添加一个事实,即它甚至不履行其承诺击败LocalStorage在DOM性能。

Web工作者FTW

我确实有一些好消息:IndexedDB在网络工作者中运行良好,运行速度大致相同,但没有阻塞DOM。唯一的例外是Safari,它不支持在一个worker中的IndexedDB。

所以这意味着对于Chrome和Firefox,您总是可以将昂贵的IndexedDB操作卸载到一个工作线程,在那里不会阻塞UI线程。在我自己的测试中,使用这种方法时我没有看到一个丢帧。

另外值得一提的是,IndexedDB是Web工作者(或服务工作者)中唯一的存储选项。在我测试的任何浏览器中,WebSQL和LocalStorage都不在工作人员的内部; 在和全局只是不存在。(支持过去曾在Chrome和Safari中存在的WebSQL,但之后已被删除。)localStorageopenDatabase

检测结果

我已经将这些结果汇总到一个统一的表格中,以及通过一个简单的Date.now()比较测量的以毫秒为单位的时间。所有测试都在2013年的MacBook Air上; Edge在Windows 10 VirtualBox中运行。“内存中”是指一个普通的JavaScript对象(演示页面中的“常规对象”)。在每次测试之间,所有的浏览器数据都被清除,页面刷新。

把这些原始数字与盐粒。它们仅占有问题的API成功返回所花费的时间(或者对于IndexedDB和WebSQL,完成该事务),并且它们不保证数据被持久写入或者DOM未被阻止手术完成后。然而,跨浏览器的速度比较有趣,这与我在过去几年从PouchDB工作中看到的一致。

上一篇:jdbc练习增删改语句


下一篇:优化 --cache