87 IE 이슈 (재귀함수, 호출 스텍 크기, 자동취소(?))

source: categories/study/vue-experiance/vue-experiance_9-87.md

87 IE 이슈

에러 내용

SCRIPT28: 스택 공간 부족  
SCRIPT2343: 스택 오버 플로
  1. Vue-input-tag 라이브러리 삭제 - 원인은 Vue.component 메소드로 전역으로 등록되어있어서 어떤 다른 라이브러리 변수명과 충돌하여 발생한 에러로 추측
  2. Vue-input-tag 삭제
  3. Vue.component 사용 못하는 룰 추가 예정
  4. 바벨 규칙 .babelrc 파일로 통일
  5. vue.component 메소드로 등록되어있는 전역 컴포넌트 모두 지역 컴포넌트로 돌릴 예정
  6. 수정 완료

의문점

  • 아니 재귀는 그럼 모든 브라우저에서 발생할텐데 왜 IE11에서만 문제가 된걸까????

0 eslint 규칙 추가 (Vue.component 메소드 사용 금지)



'no-restricted-properties': [
	2,
	{
		object: 'Vue',
		property: 'component',
		message: '전역으로 컴포넌트 등록하지마세요.',
	},
],


1 원인 분석 2009년 글 자바스크립트 스택 오버 플로 오류

너무 많은 재귀적 실행에 의한 스택오버 플로 이슈에 대한 글입니다.
대부분의 브라우저에는 스크립트가 자동으로 취소되기 전에 허용되는 재귀 횟수에 대한 제한이 있습니다.
이것은 스크립트가 장기간 실행되는지 여부를 결정하는 것과는 별개의 제한입니다.
그리고 자바스크립트 호출 스택의 크기만큼 재귀 호출에 대한 제한은 실제로 적습니다.

당연히 브라우저마다 호출 스택 크기가 다릅니다.
또한 호출 스택을 결정하는데 사용하는 방법도 다양합니다.
내가 측정할 수 있는 다양한 호출 스택 크기는 다음과 같았습니다.

  • 인터넷 익스플로러 7: 1,789
  • 파이어폭스 3: 3,000
  • 크롬 1: 21,837
  • 오페라 9.62: 10,000
  • 사파리 3.2: 500

어떤 사람들은 IE와 Opera의 호출 스택 크기가 시스탬의 RAM양과 다소 관련이 있다고 말했지만 나는 확인할 수 없었습니다.
브라우저 테스트를 한 결과 WebKit이 훨씬 더 높은 제한을 갖고 있고 Safari가 자바스크립트 엔진에 더 엄격한 제한을 부과한다는 점도 주목할 가치가 있습니다.

이 제한에 도달할 수 있는 두가지 일반적인 시나리오가 있습니다.
첫 번째는 다음과 같은 단순 재귀입니다.



function recurse() {
    recurse();
}

recurse();


두번째는 특히 다음과 같이 두 함수가 서로 호출하는 대규모 코드 기반에서 더 교활하고 식별하기 어려운 문제입니다.



function doSomething(){
    doSomethingElse();
}

function doSomethingElse(){
    doSomething();
}

doSomething();


각각의 경우에 브라우저는 결국 코드를 중지하고 문제에 대한 메시지를 표시합니다.

  • 인터넷 익스플로러 7: x 라인에서 스택 오버 플로
  • 파이어폭스 3: 재귀가 너무 많습니다.
  • 크롬1: 해당 없음
  • 오페라 9.62: 중단(스택 오버플로 제어)
  • 사파리 3.2: RangeError: 최대 호출 스택 크기를 초과했습니다.

크롬은 문제를 나타내는 메시지를 표시하지 않는 유일한 브라우저입니다.

여튼 이러한 오류 메시지가 표시되면 두 패턴 중 하나가 관련되어 변경해야 함을 의미합니다.
일반적으로 이 오류와 관련된 줄 번호와 파일 이름이 있으므로 디버그하기가 매우 간단합니다.

스택 오버플로 오류의 가장 흥미로운 부분은 일부 브라우저에서 실제 자바스크립트 오류이므로 try-catch 명령문을 사용하여 트래핑할 수 있다는 것입니다.
예외 유형은 사용 중인 브라우저에 따라 다릅니다.
파이어폭스에서는 internalError, 사파리 및 크롬에서는 RangeError이고 인터넷 익스플로러는 일반 Error 유형을 발생시킵니다. (오페라는 오류를 발생시키지 않고 자바스크립트 엔진을 중지할 뿐입니다.)
따라서 다음과 같이 할 수 있습니다.



try {
    recurse();
} catch (ex){
    alert("Too much recursion!");
}


트랩되지 않은채로 두면 이러한 오류는 인터넷 익스플로러를 제외하고 다른 오류와 마찬가지로 버블링됩니다. (파이어폭스에서는 파이어버그 콘솔로, 사파리/크롬에서는 콘솔에 표시됨)
인터넷 익스플로러는 자바스크립트 오류를 표시할 뿐만 아니라 스택오버플로 메시지가 있는 경고처럼 보이는 보기 흉한 대화 상자도 표시합니다.

이제 거의 모든 브라우저에서 이 오류를 트래핑할 수 있다고 해서 반드시 트래핑해야 하는 것은 아닙니다.
스택 오버플로 오류가 발생할 가능성이 있는 경우에도 코드가 프로덕션 단계로 종료되어서는 안 됩니다.
이러한 경우는 잘못된 코드 설계를 나타내며 이 오류를 방지하려면 재평가 및/또는 재설계해야 합니다.
이 게시물을 이 문제를 트랩하고 위장하기 위한 라이선스가 아니라 디버깅하는 데 도움이 되는 것으로 간주하십시오.

호출 스택 크기 테스트 코드

  • 다음 코드를 html 파일에 넣어 실행
  • 보통 브라우저는 어느정도 호출스택이 쌓이면 자동으로 취소한다고함
  • 하지만 그 호출스택 크기 제한


var i = 0;
function inc() {
  i++;
  inc();
}
    
try {
  inc();
}
catch(e) {
  // The StackOverflow sandbox adds one frame that is not being counted by this code
  // Incrementing once manually
  i++;
  console.log('Maximum stack size is', i, 'in your current browser');
}


  • 크롬 : Maximum stack size is 13954 in your current browser (언제나 13900정도)
  • Edge : Maximum stack size is 13955 in your current browser (언제나 13900정도)
  • 파이어폭스 : Maximum stack size is 26216 in your current browser (30000대가 한번 나왔었고 그 후론 계속 26000정도)
  • IE11 : Maximum stack size is 8169 in your current browser (언제나 최초 처음엔 6~7000, 그 후로 쭉 8174)
Note

스택오버플로 에러는 페이지 최초 진입시 발생하는 에러
즉 크롬 13900과 IE11 6~7000 정도는 대량 7~8000 정도의 호출 스택 크기 차이가 남
이러한 이유 때문에 IE11에선 스택오버 플로 에러가 발생했고 크롬에선 발생하지 않았던 듯

크롬에선 13900번 이상 호출되기 전에 자동으로 스크립트를 종료
IE11은 그러지 못하는듯

의문점 2.

  1. 그런데 자동으로 자바스크립트 호출스택을 취소하는 기능이 있나? 브라우저 엔전에 있는걸 뜻하는걸까?
    • 음 이건 검색해도 안나온다.
    • 자동 취소하는 기능이.. 있는거같진 않은데. 그런 글, 말 듣도보도못한듯..?
  2. 아니면 해당 코드 안에 조건이 걸려있는걸까? 10000번 호출되면 알아서 재귀를 끊게하는 조건식이 들어있다던가..
    • 뭐지?
    • 여튼 호출 스택 크기의 차이점은 알겠음
    • 그 때문에 브라우저마다 에러 발생하고 안하고가 차이나는 건 맞는거같음.