小强哥博客

小强哥,小强哥博客,技术大咖

博客网页导致电脑CPU飙升的问题解决记录

已经有好几个访客朋友匿名反馈只要打开我的博客电脑的CPU就狂转:

image

因为忙一直也没当一回事,一是我自己的MacbookAir打开并没有异常,二是因为我近期都没进行过折腾改造,不应该有问题才对。

直到今天空下来才想到这个问题还没去验证一番,于是让几个朋友试了下,都反馈确实有问题!Windows下CPU狂转,MAC下风扇呼呼响(奇怪的是我的MAC没问题),看来确实有必要解决下了。

我对于网页导致CPU飙升,也没听过说过有什么解决套路,问了几个前端朋友也说不好定位,只能骑驴找马试试看了。

首先,我看了下是否因为的CSS大括号写成全角带来的问题,结果并未发现异常,然后,在火狐、谷歌查看了下开发者模式,发现也没有明显报错,又陷入了僵局,最后,实在没招了。。。

按照我个人经验,这种导致CPU爆卡的肯定是有什么死循环之类的js定时任务导致的。于是按下F12瞄了下有没有异常代码,结果一眼就瞄到了很久之前加入的防止镜像的img+js代码

image

几乎本能的确定就是这个代码导致的,这段代码的防镜像原理是指定img为错误的src地址,然后触发onerror错误事件来进行域名判断的,这个过程应该是个死循环,也就是不断的产生onerror事件和域名判断,从而带来了CPU飙升问题。

于是注释了这段代码,让朋友试下,结果一切恢复正常了,果然这就是真凶!

目前没时间研究这段代码的兼容性问题,只好先注释了。理论上应该只需要给这个事件逻辑加上一个延时机制,比如延时个1s以上,应该就可以解决了,也就是和while true不加sleep一样的道理!感兴趣的同学可以去研究研究。 好了,这个问题就记录到这,用到这段代码的朋友也可以看看是否存在相同的问题。

解决onerror事件导致死循环的方法

当图片加载失败的时候,我们可以利用onerror事件赋予它默认图片,但是问题来了,假如默认图片又不存在呢,即加载失败,这个时候就会陷入死循环。 为了避免死循环的情况,我们可以在执行完onerror事件后,置于onerror=null 来清除onerror事件,参考代码如下:

<img src="http://127.0.0.1:8088/images/avatar_50x50.gif" onerror="this.onerror=null;this.src='http://127.0.0.1:8088/images/noavatar_small.gif'" />

果然,还是和我猜的那样存在死循环问题,本来想着循环判断也挺好的,所以只需要加一个延时,应该就可以解决高负载的问题。不过onerror既然可以清空,那我还是使用清空方案吧!

修改后的防镜像代码如下:

<img style="display:none" src=" " onerror='this.onerror=null;var currentDomain="zhang" + "ge." + "net"; var str1=currentDomain; str2="docu"+"ment.loca"+"tion.host"; str3=eval(str2) ;if( str1!=str3 ){ do_action = "loca" + "tion." + "href = loca" + "tion.href" + ".rep" + "lace(docu" +"ment"+".loca"+"tion.ho"+"st," + "currentDomain" + ")"; eval(do_action) }'/>

原代码中新增this.onerror=null;来置空onerror事件即可。 看来还是认知不够用,只想到了死循环可以加延时来解决,却忘记了搜索引擎找下【onerror死循环】相关问题解决方法,失策失策。 无聊继续看了下, 发现我前面想的延时方案也已经有前人分享过了,这里继续拓展延伸一下:

img加载图片偶尔会出错,利用onerror可以加载一个缺省图片,也可以重载同一张图片。 但是都要考虑,重载的图片仍然错误,就会陷入死循环。 下面给出一个带重试次数,并且延迟加载的实现,超过重试次数仍不能正常显示的,显示缺省图片。


<html>  
<head>  
<script>  
/**  
 * 图片出错处理,可以重加载指定的图片。超过重试次数仍不能正常显示的,显示缺省图片。  
 * 示例<img onerror="showImgDelay(this,'1.jpg',2)" src="1.jpg">  
 *  
 * imgObj:img节点对象  
 * imgSrc:出错时加载的图片地址  
 * maxErrorNum:最大出错次数,防止出现死循环  
 */  
function showImgDelay(imgObj,imgSrc,maxErrorNum){  
    showSpan.innerHTML += "--" + maxErrorNum;  
    if(maxErrorNum>0){  
        imgObj.onerror=function(){  
            showImgDelay(imgObj,imgSrc,maxErrorNum-1);  
        };  
        setTimeout(function(){  
            imgObj.src=imgSrc;  
        },500);  
    }else{  
        imgObj.onerror=null;  
        imgObj.src="images/default.jpg";  
    }  
}
</script>  
</head>  
<body>  
<img onerror="showImgDelay(this,'1a.jpg',2);" src="1a.jpg" width="200" height="200"/>  
<span id="showSpan"></span>  
</body>  
</html>


原文链接:https://zhangge.net/5128.html