html 防网页假死,JavaScript-如何防止由于脚本引起的浏览器假死
尊重版权,看人家总结的挺好:优化js脚本设计,防止浏览器假死
第一步,优化你的循环,循环体中包含太多的操作和循环的次数过多都会导致循环执行时间过长,并直接导致锁死浏览器。如果循环之后没有其他操作,每次循环只处理一个数值,而且不依赖于上一次循环的结果则可以对循环进行拆解,看下面的chunk的函数:
function chunk(array, process, context) {
setTimeout(function() {
var item = array.shift();
process.call(context, item);
if (array.length > 0) {
setTimeout(arguments.callee, 100);
}), 100);
}
chunk()函数的用途就是将一个数组分成小块处理,它接受三个参数:要处理的数组,处理函数以及可选的上下文环境。每次函数都会将数组中第一个对象取出交给process函数处理,如果数组中还有对象没有被处理则启动下一个timer,直到数组处理完。这样可保证脚本不会长时间占用处理机,使浏览器出一个高响应的流畅状态。
其实在我看来,借助JS强大的闭包机制任何循环都是可拆分的,下面的版本增加了callback机制,使可再循环处理完毕之后进行其他的操作。
function chunk(array,process,cbfun){
var i=0,len = array.length; //这里要注意在执行过程中数组最好是不变的
setTimeout(function(){
process( array[i] , i++ ); //循环体要做的操作
if( i < len ){
setTimeout(arguments.callee,100)
}else{
cbfun() //循环结束之后要做的操作
}
}
}
第二步,优化你的函数,如果函数体内有太多不相干但又要一起执行的操作则可以进行拆分,考虑下面的函数:
function dosomething(){
dosomething1();
dosomething2();
}
dosomething1和dosomething2互不相干,执行没有先后次序,可用前面提到的chunk函数进行拆分:
function dosomething(){
chunk([dosomething1,dosomething2],function(item){item();})
}
或者直接交给浏览器去调度
function dosome(){
setTimeout(dosomething1,0);
setTimeout(dosomething2,0);
}
第三步,优化递归操作,函数递归虽然简单直接但是过深的递归操作不但影响性能而且稍不注意就会导致浏览器弹出脚本失控对话框,必须小心处理。
看以下斐波那契数列的递归算法:
function fibonacci(n) {
return n < 2 ? n: fibonacci(n - 1) + fibonacci(n - 2);
};
fibonacci(40)这条语句将重复调用自身331160280次,在浏览器中执行必然导致脚本失控,而采用下面的算法则只需要调用40次
fibonacci = function(n){
var memo = {0:0,1:0}; //计算结果缓存
var shell = function(n){
var result = memo[n];
if( typeof result != 'number' ) //如果值没有被计算则进行计算
memo[n] = shell(n-1) + shell(n -2)
return memo[n];
}
return shell(n);
}
这项技术被称为memoization,他的原理很简单就是同样的结果你没必要计算两次。另一种消除递归的办法就是利用迭代,递归和迭代经常会被作为互相弥补的方法。
第四步,减少DOM操作,DOM操作的代价是相当昂贵的,大多数DOM操作都会触发浏览器的回流(reflow)操作。例如添加删除节点,修改元素样式,获取需要经过计算的元素样式等。我们要做的就是尽量少的触发回流操作。
el.style.width = '300px' el.style.height = '300px' el.style.backgroundColor = 'red'
上面的操作会触发浏览器的三次回流操作,再看下面的方式:
el.className = 'newStyle'
通过设置改元素的className一次设置多个样式属性,将样式写再CSS文件中,只触发一次回流,达到了同样是效果而且效率更高。因为浏览器最擅长的就是根据class设置样式。
还有很多可以减少DOM操作的方法,在此就不多说了,但是一个基本的原则就是让浏览器去做它自己擅长的事情,例如通过class来改变元素的属性。
相信经过上面的优化的过程必定可以大大提高用户体验,不会出现浏览器被锁死和弹出脚本失控的对话框,使你的浏览器从繁重的任务中解放出来。需要指出的是上面这些优化并不是必须的,只有当一段脚本的执行时间真的影响到了用户体验才需要进行。虽然它们让用户觉得脚本的执行变快了,但其实完成同一个操作的时间可能被延长了,这些技术只是让浏览器处于一个快速响应的状态,使用户浏览更流畅。
html 防网页假死,JavaScript-如何防止由于脚本引起的浏览器假死相关推荐
- 浏览器真的能“永不假死”?——六款主流浏览器防假死功能测试
作者:一石来源:家用电脑 浏览器是大家上网必备的工具,而浏览器假死也是大家在上网时常常所遇到的问题,让人头疼.最近各款主流浏览器纷纷推出了最新版本,我们可以发现一个相同点就是他们都以"防假死 ...
- 转:优化js脚本设计,防止浏览器假死
原链接打不开了,复制一份保存: 在Web开发的时候经常会遇到浏览器不响应事件进入假死状态,甚至弹出"脚本运行时间过长"的提示框,如果出现这种情况说明你的脚本已经失控了,必须进行优化 ...
- setTimeout 导致的浏览器假死
setTimeout 导致的浏览器假死 问题 前几天,同事遇到一个浏览器假死的问题.就是浏览器在响应一个请求的时候,就突然不响应时间,进入假死状态,Cup也飙升到100%. 但是这个问题只出现在I ...
- 网页中插入javascript的几种方法
网页中插入javascript的方法常见的有两种: 一.直接使用html标记 JavaScript 可以出现在 html的任意地方.使用标记<script>-</script> ...
- 响应式网页设计之JavaScript基础
JavaScript 一.认识JavaScript 1.什么是JavaScript? 2.JavaScript的组成? 3.JavaScript用来做些什么? 2.JavaScript与java有什么 ...
- java 打开网页并运行脚本_各种浏览器开启JavaScript脚本方法
1.单击右上角的齿轮图标.从出现的菜单中选择Internet 选项. 2.单击安全选项卡.单击窗口底部的自定义级别按钮,弹出安全设置对话框. 3.找到脚本目录.单击JAVA 小程序下的启用选项,选择此 ...
- 在HTML网页中书写JavaScript
参考书籍:<JavaScript 权威指南----ECMAScript5+HTML5DOM+HTML5BOM>编著:张亚飞 1.使用<script>元素定义JavaScript ...
- Win7系统只要一打开浏览器就死机 win7打开网页浏览器卡死怎么办
Win7系统只要一打开浏览器就死机 win7打开网页浏览器卡死怎么办 我们在使用电脑的时候,总是会遇到很多的电脑难题.当我们在遇到了win7电脑中的浏览器一打开就卡死,那么我们应该怎么办呢?今天我们就 ...
- 到底死不死我就请了七天假_“你到底死不死啊?我就请了7天假”
原标题:"你到底死不死啊?我就请了7天假" 刘燕舞教授曾在<农村老年人自杀的社会学研究>中,讲过一件事. 一个留守老人病危,临死前,想见儿子一面. 儿子听闻后,请了一周 ...
- python web py入门(33)- 在HTML网页里嵌入JavaScript脚本
在前面已经学习过在浏览器的console运行JS,那么在网页里又是怎么样运行JS的呢?如果不明白这个,就要跟着本节课来学习了,其实还是蛮简单的.对了,前面已经编辑了一个比较小的网页,并保存成文件了.就 ...
最新文章
- 用Spring Security实现后台登录及权限认证功能
- springboot+mybatis+SpringSecurity 实现用户角色数据库管理(一)
- mapreduce 文件可以切分吗_MapReduce的任务流程
- 手机访问同局域网下的PC中Tomcat中的项目
- 【深度学习】陶大程等人编写!最新41页深度学习理论综述
- Android Studio 中快速提取方法
- 2019计算机科学与技术全日制调济,2019年华侨大学计算机科学与技术学院全日制学术型研究生调剂信息(第三批)...
- USB device如何进入suspend模式
- 第十章数据库恢复技术
- SpringMVC 日期类型转换
- 6a标准 api_机油最新最高标准来了!SN不再是最高标准!车主不要加错机油了!...
- 手机上怎么打开md格式的文件_怎么压缩pdf文件?文件过大、传阅困难就用这个办法...
- 2017-2018-1 20155234第三周《信息安全系统设计基础》学习总结
- screw ---- 数据库转文档
- springboot连接redis错误 io.lettuce.core.RedisCommandTimeoutException:
- iOS 添加PCH文件
- nodejs-基础:路由基础
- pwm gpio android,USB转I2C适配器 模块 USB-IIC/GPIO/PWM/ADC 支持Android 安卓 树莓派
- jeecg-boot配置菜单
- Win9X、2000、XP、2003所有注册表设置
热门文章
- nulls first和nulls last
- 星期一到星期日的英文_缩写_读音_巧记方法
- python查火车票_Python实现12306火车票查询系统
- m4s格式转换mp3_高质量音频转换器,如何转换成mp3音频格式
- Mac 使用brew 安装adb
- Adobe国际认证让科技赋能时尚
- Windows服务器无法配置IP
- matlab神经网络应用设计 张德丰,MATLAB神经网络应用设计
- 感恩—父亲节、母亲节由来及日期
- linux sudo命令、不输入密码执行需要root、sudo报错:xxx is not in the sudoers file. This incident will be reported.