运行在浏览器中的JavaScript都被分配了一个肯定数量的资源,不一样于桌面应用每每可以随意控制他们要的内存大小和处理时间,Javascript被严格限制了,以防止恶意的Web程序员吧用的计算机搞挂了,其中一个限制是长时间运行脚本的制约,若是代码运行超过特定时长或者特定数量的语句就不让它继续执行,询问是容许其继续执行仍是中止它。全部JavaScript开发人员的目标就是,确保用户永远不会再浏览器中看到这个使人费解的对话框。定时器是绕开此限制的方法之一javascript
脚本运行时间长的2个缘由:css
1.过长的、过深嵌套的函数调用;html
2.进行大量处理的循环;java
这2种后者较为容易的被解决jquery
进行大量处理的循环:程序员
使用这种方式必须知足的要求:bootstrap
1.该处理不是必须同步完成数组
2.数据不是必须按顺序完成浏览器
解决方案:数组分块markdown
function chunk(arr, process, context){ setTimeout(function () { var item = arr.shift() process.call(context, item) if(arr.length > 0){ setTimeout(arguments.callee, 100) } }, 100) }
使用场景建议:
一旦某个函数的执行须要花50ms以上的时间完成,那么最好看看可否将任务分割为一系列可使用定时器的小任务。
1.4.1 节流函数的起源
浏览器中的某些计算和处理要比其余的开销大不少。例如,DOM比起非DOM交互须要更多的内存和CUP时间。连续尝试进行过多的DOM相关操做可能会致使浏览器挂起,有时候甚至奔溃。尤为在IE中使用onresize时处理程序的时候很容易发生,当调整浏览器大小的时候,该事件会连续触发。在onresize事件处理程序内部若是尝试进行DOM操做,其高频率的更改可能会让浏览器奔溃。为了绕开这个问题,可使用定时器对该函数进行节流。
1.4.2 节流函数的原理
某段代码不能在没有间隔的状况下连续重复执行。
第一次调用函数,建立一个定时器,在指定的时间间隔后执行代码,当第二次调用该函数时,他会清除前一次的定时器并设置另外一个定时器。若是前一个定时器已经执行了,这个操做没有任何意义。而后,若是前一个定时器还没有执行,其实就是将其替换为一个新的定时器。目的只有一个:只有在执行函数的请求中止了一段时间以后才执行。
1.4.3 适合节流的场景:周期性执行的代码
1.4.4 节流函数的实现
var processor = { timeoutId: null, performProcessing: function () { //实际执行的代码 }, process: function () { clearTimeout(this.timeoutId) var that = this this.timeoutId = setTimeout(function () { that.performProcessing() }, 100) } }
1.4.5 节流函数实现的简化
function throttle (cb, context) { clearTimeout(cb.ID) cb.ID = setTimeout(function () { cb.call(context) }, 1000) }
给浏览器设置节流和延迟:使出现的效果可以在本身被本身察觉。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> h1 { color: red!important; } </style> <script> function h () { let h1 = document.getElementById('h1') console.log( h1 ) } setTimeout(h, 0) </script> <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.0.0/css/bootstrap.min.css"> </head> <body> <h1 id="h1">这是红色</h1> </body> </html>
结果:在css正在下载时,h1标签被控制太打印出来,可是页面没有文字。
结论:css加载会阻塞DOM树渲染,不会阻塞DOM树的解析。
我的见解:这样子作仍是符合优化的正常逻辑的,css不会阻塞解析;若是不阻塞css渲染,等这个css加载完成后,会触发回流和重绘额外增长性能开销,因此还不如直接等css加载完成后再来渲染。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> h1 { color: red!important; } </style> <script> console.log('before css') var startDate = new Date() </script> <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.0.0/css/bootstrap.min.css"> </head> <body> <h1 id="h1">这是红色</h1> <script> var endData = new Date() console.log('after css') console.log('已通过了' + (endData - startDate)) </script> </body> </html>
结果:在css正在加载时,控制台内容:before css
css加载完成时,控制台内容:
before css after css 已通过了3444
结论:css加载时,会阻塞js的执行。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.slim.min.js"></script> <script> console.log(1111) </script> <style> h1 { color: red!important; } </style> </head> <body> <h1 id="h1">这是红色</h1> </body> </html>
现象:Loading js时,后续js没有执行,后续DOM没有解析。