《高性能JavaScript》笔记
1. UI Thread 和 UI Queue,中文叫 UI 线程和UI 队列,JavaScript 和 UI 更新共享的进程通常被称为浏览器UI进程。
2. 如果用户企图在任务运行时于页面交互,不仅没有即时的UI更新,而且不会有新的UI更新任务被创建和加入队列。
3. 一个单一的Javascript操作应当使用的总时间(最大)是100毫秒。
4. 当下面的例子中的按钮被点击时,它触发UI线程创建两个任务并添加到队列中。第一个任务是按钮的UI它需要改变外观以指示出它被按下了,第二个任务是Javascript运行任务,包含 handleClick()的代码,运行的唯一代码就是这个方法和所有被它调用的方法。假设UI线程空闲,第一个任务被检查并运行以更新按钮外观,然后Javascript被检查和运行。在运行过程中,handleClick() 创建了一个新的<div>元素,并追加在<body>元素上,其效果是引发另一次UI改变。也就是说在Javascript运行过程中(注意不是运行完了以后),一个新的UI更新任务被添加在队列中,当Javascript 运行完成之后,UI还会再更新一次。
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Browser UI Thread Example</title>
</head>
<body>
<button onclick='hanldeClick()'>Click Me</button> <script type='text/javascript'>
function hanldeClick(){
var div = document.createElement('div');
div.innerHTML = 'Clicked!';
document.body.appendChild(div);
}
</script>
</body>
</html>
5. 当脚本执行时,UI不随用户交互而更新。此时Javascript任务作为用户交互的结果被放入队列里面。
如何理解,看下面的代码,当执行 sleep(6000),页面被锁定了6秒,这个时候你点击 "按钮" 2次, 则6秒后 console.log(1) 会被执行2次。
同理,当你点击"百度链接",6秒后页面就会跳转。
但是看不见 "按钮"被按下去的样子。(即 UI 不随用户交互而更新)
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>测试</title>
</head>
<body>
<input type="button" value='按钮' onclick="console.log(1);" />
<a href='https://www.baidu.com/'>百度链接</a> <script type='text/javascript'>
var sleep = function(time){
var d = new Date;
while( new Date - d < time){ }
}
sleep(6000);
</script>
</body>
</html>
6. 假设工作中有一个任务,点击'按钮'发送一次 ajax请求,如何防止在ajax请求回来之前按钮又被点击,即 防止连续发送ajax请求,请看下面的代码。
有人提出问题,如果我非常快速点击按钮2次,有可能发送ajax请求2次吗?答案是:否。
第一次点击,UI队列里有 UI Update 和 handleClick, 第二次快速点击,UI队列里有 UI Update(有可能没有,若这个时候还在执行 handleClick) 和 handleClick,
那么UI 线程里面,先执行 UI Update -> handleClick -> UI Update(有可能没有) -> handleClick
也就是说第二次执行的 handleClick 一定要等第一次执行 handleClick完成之后, 那么 isSend 变量已经变成 true 了。
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Example</title>
</head>
<body>
<button onclick='hanldeClick()'>Ajax Send</button> <script type='text/javascript'>
var isSend = false;
function hanldeClick(){
if(isSend){ return;}
isSend = true;
$.ajax({
url: '',
dataType: 'json'
})
.always(function(){
isSend = false;
});
}
</script>
</body>
</html>
7. setTimeout 和 setInterval 告诉 Javascript 引擎等待一定时间然后将Javascript任务添加到UI队列中。(注意不是 UI 线程中)
考虑下面的代码, 250毫秒从调用 setTimeout()时开始计算,而不是从整个函数运行结束之后开始运算。
如何证明呢,请看例子2,若在整个函数运行结束之后才添加到UI队列,那么 console.log('asleep') 完之后还会过2秒才执行 console.log(1),实际情况确实 asleep 和 1一起输出。即 sleep执行完成之后立刻执行 console.log(1);
例子1:
function hanldeClick(){
oneMethod();
setTimeout(function(){
console.log(1);
}, 250);
anotherMethod();
}
例子2:
var sleep = function(time){
var d = new Date;
while(new Date - d < time){}
console.log('asleep');
}
function hanldeClick(){
setTimeout(function(){
console.log(1);
}, 2000);
sleep(6000);
}
8: 下面的代码当执行完 sleep 以后, 只有一个setInterval会插入到 UI 队列里, 后面的setInterval插入不到UI队列里的。所以最后会输出 asleep, 1。
var interval;
var sleep = function(time){
var d = new Date;
while(new Date - d < time){}
clearInterval(interval);
console.log('asleep');
}
interval = setInterval(function(){
console.log(1);
}, 1000);
sleep(6000);
9: 下面的代码,可以插入2个interval 到队列里面。最后输出 asleep, 1, 2
var interval;
var sleep = function(time){
var d = new Date;
while(new Date - d < time){}
console.log('asleep');
}
setInterval(function(){
console.log(1);
}, 1000);
setInterval(function(){
console.log(2);
}, 1001);
sleep(6000);
10: 下面的代码 setTimeout 是会插入到UI 队列的,所以最后会输出 asleep, 1, 1, 1
var sleep = function(time){
var d = new Date;
while(new Date - d < time){}
console.log('asleep');
}
var loop = function(){
setTimeout(function(){
console.log(1);
}, 1000);
}
loop();
loop();
loop();
sleep(6000);
11: 惊奇发现 clearInterval 和 clearTimeout 可以互相清除定时器。并且 setTimeout 和 setInterval 共享同一组定时器的 number;
clearInterval( setTimeout(function(){ console.log(1);}, 1000) ); // 执行成功
clearTimeout( setInterval(function(){ console.log(1);}, 1000) ); // 执行成功
12: 缓存对象成员,缩短查找的作用域链。
13: 最小化重绘和重排, 使元素脱离文档流 对其应用多重改变 把元素带回文档
1) 设置元素的 display: none, 然后应用操作,然后设回元素的 display: 'block' 或者元素初始display值
2) 创建 document_createDocumentFragment(), 然后对这个值应用各种操作,最后再操作这个值。
3) clone一个元素的备份 cloneNode(true), 然后对这个元素进行各种操作,最后用元素的备份替换它。
《高性能JavaScript》笔记的更多相关文章
- HTML+CSS笔记 CSS笔记集合
HTML+CSS笔记 表格,超链接,图片,表单 涉及内容:表格,超链接,图片,表单 HTML+CSS笔记 CSS入门 涉及内容:简介,优势,语法说明,代码注释,CSS样式位置,不同样式优先级,选择器, ...
- CSS笔记--选择器
CSS笔记--选择器 mate的使用 <meta charset="UTF-8"> <title>Document</title> <me ...
- HTML+CSS笔记 CSS中级 一些小技巧
水平居中 行内元素的水平居中 </a></li> <li><a href="#">2</a></li> &l ...
- HTML+CSS笔记 CSS中级 颜色&长度值
颜色值 在网页中的颜色设置是非常重要,有字体颜色(color).背景颜色(background-color).边框颜色(border)等,设置颜色的方法也有很多种: 1.英文命令颜色 语法: p{co ...
- HTML+CSS笔记 CSS中级 缩写入门
盒子模型代码简写 回忆盒模型时外边距(margin).内边距(padding)和边框(border)设置上下左右四个方向的边距是按照顺时针方向设置的:上右下左. 语法: margin:10px 15p ...
- HTML+CSS笔记 CSS进阶再续
CSS的布局模型 清楚了CSS 盒模型的基本概念. 盒模型类型, 我们就可以深入探讨网页布局的基本模型了.布局模型与盒模型一样都是 CSS 最基本. 最核心的概念. 但布局模型是建立在盒模型基础之上, ...
- HTML+CSS笔记 CSS进阶续集
元素分类 在CSS中,html中的标签元素大体被分为三种不同的类型:块状元素.内联元素(又叫行内元素)和内联块状元素. 常用的块状元素有: <div>.<p>.<h1&g ...
- HTML+CSS笔记 CSS进阶
文字排版 字体 我们可以使用css样式为网页中的文字设置字体.字号.颜色等样式属性. 语法: body{font-family:"宋体";} 这里注意不要设置不常用的字体,因为如果 ...
- HTML+CSS笔记 CSS入门续集
继承 CSS的某些样式是具有继承性的,那么什么是继承呢?继承是一种规则,它允许样式不仅应用于某个特定html标签元素,而且应用于其后代(标签). 语法: p{color:red;} <p> ...
- HTML+CSS笔记 CSS入门
简介: </span>年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的<span>脚本解释程序</span>,作为ABC语言的一种继承. & ...
随机推荐
- Python 基礎 - pyc 是什麼
Python2.7 版中,只要執行 .py 的檔案後,即會馬上產生一個 .pyc 的檔案,而在 Python3 版中,執行 .py 的檔案後,即會產生一個叫 __pycache__ 的目錄,裡面也會有 ...
- 创建一个maven web project
几经周折总算是找到了和高杨学长一样的web project的方法.感谢学长的一语点醒.我之前以为,既是maven又是web project的项目得要是通过dynamic web project转换到 ...
- ZFIR054-现金流量表
*********************************************************************** * Title : ZFIR102 * * Applic ...
- 将war包部署到服务器的详细步骤
第一步: 先将项目打包成war文件,也就是将在项目上单击鼠标右键,选择Export: 选择WAR file,点击下一步: 会出现如下所示,选择你要保存的位置,点击完成: 在你所选择的地方会有个如下所示 ...
- yii使用MongoDB作为数据库服务软件[win7环境下](1)
1.进入http://php.net,在站内搜索栏搜索mongodb,查看相关的安装步骤信息. 2.找到相应的php.ini配置文件,使用wampserver等服务器软件时,千万不要找错了php.in ...
- 在Swift中应用Grand Central Dispatch(上)转载自的goldenfiredo001的博客
尽管Grand Central Dispatch(GCD)已经存在一段时间了,但并非每个人都知道怎么使用它.这是情有可原的,因为并发很棘手,而且GCD本身基于C的API在 Swift世界中很刺眼. 在 ...
- vi编辑器使用相关
一.vi的使用 1.vi一共分为3种模式,分别是一般模式.编辑模式和命令行模式 2.一般模式:以vi打开一个文件就直接进入一般模式(也是默认的模式). 在这个模式下可以使用上下左右移动光标,还可以删除 ...
- OpenMP对于嵌套循环应该添加多少个parallel for 分类: OpenMP C/C++ Linux 2015-04-27 14:48 53人阅读 评论(0) 收藏
一个原则是:应该尽量少的使用parallelfor, 因为parallel for也需要时间开销.即: (1)如果外层循环次数远远小于内层循环次数,内层循环较多时,将parallel for加在内层循 ...
- Spring MVC入门实战(一)
本文主要把一个菜鸟从“只是听说过Spring MVC”到“可以手动创建并运行一个Spring MVC工程”的过程记录下来,供以后复习. 0. 开发环境准备 计算机平台:Windows 7 X64. 需 ...
- 观察者模式及Java实现例子
http://www.cnblogs.com/mengdd/archive/2013/02/07/2908929.html 观察者模式 观察者模式 Observer 观察者模式定义了一种一对多的依赖关 ...