0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

CodePenに埋め込んだprogramが遅くなるカラクリ

0
Last updated at Posted at 2026-02-08

今更こんな事説明するまでもないかもしれませんがガガ…、その理由らしキモノを書き散らかしやがっておきマス。
CodePenでは書いたprogramがそのまま実行されるわけではありません。いちいち書き換えやがってくれます。
編集したJavaScriptはhttps://cdpn.io/cpe/boomboom/pen.js?key=pen.js-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxのような名前の外部js fileへと生まれ変わり果てます。中身をいやらしい目つきで観察してみましょう。
すると…なんと整形されまくっているではありませんか! というのはどうでもよくて、随所にwindow.CP.shouldStopExecutionwindow.CP.exitedLoopという関数が挿入されています。

用途

infintyな無限の永久的永劫loopによってbrowserが応答不能になるのを防ぐために自動挿入されるお節介機能。
window.CP.shouldStopExecution(id) でloopの監視を開始し、loopが終了した時点で window.CP.exitedLoop(id) を呼び出して終了を通知する。

window.CPの実装

ここ参照。以下のようになっています

"use strict";"object"!=typeof window.CP&&(window.CP={}),window.CP.PenTimer={programNoLongerBeingMonitored:!1,timeOfFirstCallToShouldStopLoop:0,_loopExits:{},_loopTimers:{},START_MONITORING_AFTER:2e3,STOP_ALL_MONITORING_TIMEOUT:5e3,MAX_TIME_IN_LOOP_WO_EXIT:2200,exitedLoop:function(o){this._loopExits[o]=!0},shouldStopLoop:function(o){if(this.programKilledSoStopMonitoring)return!0;if(this.programNoLongerBeingMonitored)return!1;if(this._loopExits[o])return!1;var t=this._getTime();if(0===this.timeOfFirstCallToShouldStopLoop)return this.timeOfFirstCallToShouldStopLoop=t,!1;var i=t-this.timeOfFirstCallToShouldStopLoop;if(i<this.START_MONITORING_AFTER)return!1;if(i>this.STOP_ALL_MONITORING_TIMEOUT)return this.programNoLongerBeingMonitored=!0,!1;try{this._checkOnInfiniteLoop(o,t)}catch(o){return this._sendErrorMessageToEditor(),this.programKilledSoStopMonitoring=!0,!0}return!1},_sendErrorMessageToEditor:function(){try{if(this._shouldPostMessage()){var o={action:"infinite-loop",line:this._findAroundLineNumber()};parent.postMessage(JSON.stringify(o),"*")}else this._throwAnErrorToStopPen()}catch(o){this._throwAnErrorToStopPen()}},_shouldPostMessage:function(){return document.location.href.match(/boomerang/)},_throwAnErrorToStopPen:function(){throw"We found an infinite loop in your Pen. We've stopped the Pen from running. Please correct it or contact support@codepen.io."},_findAroundLineNumber:function(){var o=new Error,t=0;if(o.stack){var i=o.stack.match(/boomerang\S+:(\d+):\d+/);i&&(t=i[1])}return t},_checkOnInfiniteLoop:function(o,t){if(!this._loopTimers[o])return this._loopTimers[o]=t,!1;var i=t-this._loopTimers[o];if(i>this.MAX_TIME_IN_LOOP_WO_EXIT)throw"Infinite Loop found on loop: "+o},_getTime:function(){return+new Date}},window.CP.shouldStopExecution=function(o){var t=window.CP.PenTimer.shouldStopLoop(o);return t===!0&&console.warn("[CodePen]: An infinite loop (or a loop taking too long) was detected, so we stopped its execution. Sorry!"),t},window.CP.exitedLoop=function(o){window.CP.PenTimer.exitedLoop(o)};

改竄例

原作
for(let n=0,A,B=[];n++<9;){
	B.push(Math.random()*222|0);
	A=B.map((a,b)=>b);
	A.sort((a,b)=>{
		let c=a<b?n-b:n-a,d;
		for(;c--&&!(d=B[a++]-B[b++]););return d||b-a
	});
	document.write(A,"<br>")
}
改竄後
for (let n = 0, A, B = []; n++ < 9;) {if (window.CP.shouldStopExecution(0)) break;
  B.push(Math.random() * 222 | 0);
  A = B.map((a, b) => b);
  A.sort((a, b) => {
    let c = a < b ? n - b : n - a,d;
    for (; c-- && !(d = B[a++] - B[b++]);) {if (window.CP.shouldStopExecution(1)) break;;}window.CP.exitedLoop(1);return d || b - a;
  });
  document.write(A, "<br>");
}window.CP.exitedLoop(0);

ご覧のようにloopの冒頭でwindow.CP.shouldStopExecutionが召喚され、loop終了地点でwindow.CP.exitedLoopが召喚されています。ついでに変てこ整形機能も働いています。
こいつらを召喚したくなければ文字列化してeval()で実行すると良いです。もしくはFunction()を利用

eval(`for(let n=0,A,B=[];n++<9;){
	B.push(Math.random()*222|0);
	A=B.map((a,b)=>b);
	A.sort((a,b)=>{
		let c=a<b?n-b:n-a,d;
		for(;c--&&!(d=B[a++]-B[b++]););return d||b-a
	});
	document.write(A,"<br>")
}`)

原型ではなくbase64から復号して実行するという手もあります

eval(atob`Zm9yKGxldCBuPTAsQSxCPVtdO24rKzw5Oyl7CglCLnB1c2goTWF0aC5yYW5kb20oKSoyMjJ8MCk7CglBPUIubWFwKChhLGIpPT5iKTsKCUEuc29ydCgoYSxiKT0+ewoJCWxldCBjPWE8Yj9uLWI6bi1hLGQ7CgkJZm9yKDtjLS0mJiEoZD1CW2ErK10tQltiKytdKTspO3JldHVybiBkfHxiLWEKCX0pOwoJZG9jdW1lbnQud3JpdGUoQSwiPGJyPiIpCn0`)
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?