你不能阻止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.从浏览器菜单 ...
随机推荐
- commonJS 和 ES6 模块化的不同
commonjs 导出 module.exports={ add:function(){ console.log('add测试') } } 导入 var add=require('./add.js') ...
- securecrt远程管理工具连接VM虚拟机
对桥接,net,host_only网络不理解的,请点击:桥接,net,host_only的区别 我这里以net连接为例: 我们使用securecrt实现net的连接,前提是保证虚拟机的ip和虚拟网卡V ...
- linux下find和grep命令详解
在linux下面工作,有些命令能够大大提高效率.本文就向大家介绍find.grep命令,他哥俩可以算是必会的linux命令,我几乎每天都要用到他们.本文结构如下: find命令 find命令的一般形式 ...
- Ubuntu16.10下mysql5.7的安装及远程访问配置
如何安装mysql 1.sudo apt-get update,如果很慢或者失败,需要在软件和更新中选择最佳服务器,勾选所有互联网下载选项及去掉其他软件所有勾选项 2.sudo apt-get upg ...
- 基础数据类型的坑和集合及深浅copy
一.基础数据类型的坑: 元组: 如果一个元组中,只有一个元素,且没有逗号,则该"元组"与里面的数据的类型相同. # 只有一个数据,且没有逗号的情况: print(tu1,type( ...
- RabbitMQ进阶使用-延时队列的配置(Spring Boot)
依赖 MAVEN配置pom.xml <dependency> <groupId>org.springframework.boot</groupId> <art ...
- js评分
js评分 原理:给ele挂载一个自定义属性保存选中的星星数,鼠标经过时,显示所在星数的评价内容,以及给他星星亮起来,鼠标移开时显示的星星数时选择的星星数,没选的话是默认星星数,点击时,将选中的星 ...
- Map中根据条件删除元素
今天在写程序过程中,需要根据判断条件删除一个Map中的相应数据,我自然而然想到可以通过调用Map中的remove(Object key)函数进行删除:代码如下: public Map<Doubl ...
- sqlalchemy 简介
#! /usr/bin/env python3 # -*- coding:utf-8 -*- #use SQLAlchemy #ORM:Object-Relational Mapping ,把关系数据 ...
- PE文件 02 导出表
0x01 导出表结构 导出表是由数据目录表中的第一个成员DataDirectory[0]指出的: typedef struct _IMAGE_DATA_DIRECTORY { DWORD Virt ...