浏览器数据库景观

对于外行来说,浏览器数据库的世界可能是一个令人困惑的世界。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工作中看到的一致。

你不能阻止DOM的更多相关文章

  1. Angular4.x Event (DOM事件和自定义事件)

    Angular组件和DOM元素通过事件与外部进行通信,两者中的事件绑定语法是相同的-(eventName)="expression": <button (click)=&qu ...

  2. ios10 safari 的坑!

    | 导语 ios10 的safari,又给前端开发者挖坑了..测试验证此问题只出现在ios10 safari中.想早点知道结论的,可以直接看最后一个结论~因为,解决过程不重要! 个人原创,未经允许,禁 ...

  3. KnockOut绑定

    KnockOut绑定之Click绑定 Click绑定对DOM元素添加一个函数,当DOM元素被点击的时候调用.在button,input 或者a标签中常用,但其实他适用于任何可见的DOM元素. exam ...

  4. AlloyTouch.js 源码 学习笔记及原理说明

    alloyTouch这个库其实可以做很多事的, 比较抽象, 需要我们用户好好的思考作者提供的实例属性和一些回调方法(touchStart, change, touchMove, pressMove, ...

  5. jQuery中的常用内容总结(三)

    jQuery中的常用内容总结(三) 转载请注明地址:http://www.cnblogs.com/funnyzpc/p/7571998.html 内容提要 选择器(第一节) 选择器的扩展方法(第一节) ...

  6. 将CSS放头部,JS放底部,可以提高页面的性能的原因

    css不阻止dom的解析 js阻止dom的解析 css js都会阻止dom的渲染 原因: js有可能影响dom的解析,比如在js里面新增dom等这些操作 css不能影响dom的解析 而 dom的渲染 ...

  7. KnockOut绑定之Click绑定

    example(click绑定) Click绑定对DOM元素添加一个函数,当DOM元素被点击的时候调用.在button,input 或者a标签中常用,但其实他适用于任何可见的DOM元素. 每当你点击b ...

  8. 3.8 Templates -- Actions

    一.The {{action}} Helper 你的应用程序通常会需要一种方法来让用户用控件交互改变应用程序状态. 例如,你有一个显示blog post的模板,并支持用额外的信息扩展post. 可以使 ...

  9. [转]Tips——Chrome DevTools - 25 Tips and Tricks

    Chrome DevTools - 25 Tips and Tricks 原文地址:https://www.keycdn.com/blog/chrome-devtools 如何打开? 1.从浏览器菜单 ...

随机推荐

  1. python 数字格式化

    第二种办法比较常用:   %02d print '%02d' % 11

  2. 把旧系统迁移到.Net Core 2.0 日记(6) MapRoute/Area/ViewPath

    我想实现 http://localhost:5000/{moduleName}/{controller}/{action}/{id?} 这样的url. 有2个方法 方法1: 在路由里设置多个modul ...

  3. 码云git使用一(上传本地项目到码云git服务器上)

    主要讲下如果将项目部署到码云git服务器上,然后使用studio导入git项目,修改本地代码后,并同步到码云git上面. 首先:我们在码云上注册账号并登陆.官网(https://git.oschina ...

  4. axios API速查表

    原来jq自带ajax方法,但是近期项目用vue,在vue项目中发送ajax请求原来用vue resource,现在更推荐使用axios,因为axios和vue更配! GET 请求 // Make a ...

  5. webpack+typescript

    1. npm install --save typescript 2. npm install --save ts-loader webpack.config.js module.exports = ...

  6. NIO完成网络通信(一)

    NIO:即非阻塞式IO 视频教程:  https://chuanke.baidu.com/v1982732-211322-1316084.html 使用步骤: 1.创建 ServerSocketCha ...

  7. jps -- process information unavailable

    在之前停止java进程时,使用了 kill -9,结果进程未正常退出. 之后每次执行 jps 命令时都会打印出 -- process information unavailable 在ls /tmp/ ...

  8. (C/C++学习笔记) 七. 类型转换

    七. 类型转换 ● 隐式类型转换 隐式类型转换 implicit type conversions #include<iostream> using namespace std; void ...

  9. 6.2 C++ string类型字符串的连接

    参考:http://www.weixueyuan.net/view/6391.html 总结: 对于string类型变量,我们可以直接用“+”或者“+=”进行字符串的连接,操作符非常方便. 用“+”风 ...

  10. 1.6socket服务器传送文件--gui窗口

    socket服务器代码 import sys,os,time,_thread from socket import * class Server(object): def __init__(self) ...