你不能阻止DOM
浏览器数据库景观
对于外行来说,浏览器数据库的世界可能是一个令人困惑的世界。Lawnchair,PouchDB,LocalForage,Dexie,Lovefield,LokiJS,AlaSQL,MakeDrive,ForerunnerDB,YDN-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规范。
这是一个非常令人震惊的发现,所以我及时地在Chrome和Firefox上提交了一个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的更多相关文章
- Angular4.x Event (DOM事件和自定义事件)
Angular组件和DOM元素通过事件与外部进行通信,两者中的事件绑定语法是相同的-(eventName)="expression": <button (click)=&qu ...
- ios10 safari 的坑!
| 导语 ios10 的safari,又给前端开发者挖坑了..测试验证此问题只出现在ios10 safari中.想早点知道结论的,可以直接看最后一个结论~因为,解决过程不重要! 个人原创,未经允许,禁 ...
- KnockOut绑定
KnockOut绑定之Click绑定 Click绑定对DOM元素添加一个函数,当DOM元素被点击的时候调用.在button,input 或者a标签中常用,但其实他适用于任何可见的DOM元素. exam ...
- AlloyTouch.js 源码 学习笔记及原理说明
alloyTouch这个库其实可以做很多事的, 比较抽象, 需要我们用户好好的思考作者提供的实例属性和一些回调方法(touchStart, change, touchMove, pressMove, ...
- jQuery中的常用内容总结(三)
jQuery中的常用内容总结(三) 转载请注明地址:http://www.cnblogs.com/funnyzpc/p/7571998.html 内容提要 选择器(第一节) 选择器的扩展方法(第一节) ...
- 将CSS放头部,JS放底部,可以提高页面的性能的原因
css不阻止dom的解析 js阻止dom的解析 css js都会阻止dom的渲染 原因: js有可能影响dom的解析,比如在js里面新增dom等这些操作 css不能影响dom的解析 而 dom的渲染 ...
- KnockOut绑定之Click绑定
example(click绑定) Click绑定对DOM元素添加一个函数,当DOM元素被点击的时候调用.在button,input 或者a标签中常用,但其实他适用于任何可见的DOM元素. 每当你点击b ...
- 3.8 Templates -- Actions
一.The {{action}} Helper 你的应用程序通常会需要一种方法来让用户用控件交互改变应用程序状态. 例如,你有一个显示blog post的模板,并支持用额外的信息扩展post. 可以使 ...
- [转]Tips——Chrome DevTools - 25 Tips and Tricks
Chrome DevTools - 25 Tips and Tricks 原文地址:https://www.keycdn.com/blog/chrome-devtools 如何打开? 1.从浏览器菜单 ...
随机推荐
- python列表反转函数
def reverse(ListInput): RevList=[] for i in range (len(ListInput)): RevList.append(ListInput.pop()) ...
- 小程序证书申请FAQ
1. 帮别人开发小程序, 先把你的微信号加到成员里, 并给予开发者权限,体验者权限,登录,数据分析,开发管理,开发设置 2. 需要https, 不能用windows2003,必须2008以上,用IIS ...
- 【Jmeter基础知识】Jmeter的三种参数化方式
JMeter的三种参数化方式包括: 1.用户参数 2.函数助手 3.CSV Data Set Config 一.用户参数 位置:添加-前置处理器-用户参数 操作:可添加多个变量或者参数 二.函数助手 ...
- laravel的firstOrCreate的作用:先查找表,如果有就输出数据,如果没有就插入数据
public function zan(Post $post){ $param=[ 'user_id'=>\Auth::id(), 'post_id'=>$post->id ] Za ...
- 大白菜装机版一键制作启动u盘教程
第一步 下载并且安装好大白菜装机版,打开安装好的大白菜装机版,插入u盘等待软件成功读取到u盘之后,点击“一键制作启动u盘”进入下一步操作.如下图所示 第二步 在弹出的信息提示窗口中,点击“确定”进入下 ...
- java⑾
1.数组: 01.一组 相同数据类型的集合! 02.数组在内存中会 开辟一串连续的空间来保存数据! ***存储30名学生的姓名! 01.姓名 应该用什么数据类型保存??? String02.难道需要创 ...
- vue-router-5-命名路由
创建 Router 实例的时候,在 routes 配置中给某个路由设置名称 const router = new VueRouter({ routes: [ { path: '/user/:userI ...
- tomcat 启动Spring boot 项目
SpringBoot 项目如何在tomcat容器中运行 1.相关连接: https://blog.csdn.net/u010598360/article/details/78789197/ 2.修改打 ...
- centos tar 常用
tar命令详解 -c: 建立压缩档案 -x:解压 -t:查看内容 -r:向压缩归档文件末尾追加文件 -u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用 ...
- 线程安全的集合类、CopyOnWrite机制介绍(转)
看过并发编程的书,这两种机制都有所了解,但不扎实其实.看到别人的博客描述的很精辟,于是转过来,感谢! 原文链接:https://blog.csdn.net/yen_csdn/article/detai ...