source

위반 장시간 실행 JavaScript 태스크에 xxms가 소요되었습니다.

goodcode 2022. 10. 6. 21:43
반응형

위반 장시간 실행 JavaScript 태스크에 xxms가 소요되었습니다.

최근에 이런 경고를 받았는데, 이번이 처음입니다.

[Violation] Long running JavaScript task took 234ms
[Violation] Forced reflow while executing JavaScript took 45ms

그룹 과제를 하고 있는데 이게 어디서 나온 건지 모르겠어요.전에는 이런 일이 없었어요.갑자기 다른 사람이 프로젝트에 참여했을 때 나타났다.이 경고의 원인이 되는 파일/함수를 찾으려면 어떻게 해야 합니까?저는 답을 찾고 있었지만, 주로 해결 방법에 대한 해결책에 관한 것입니다.문제의 근원을 찾지 못하면 해결할 수 없다.

이 경우 주의는 Chrome에서만 나타납니다.Edge를 사용하려고 했지만 비슷한 경고는 받지 않았고 Firefox에서도 테스트하지 않았습니다.

요.jquery.min.js:

[Violation] Handler took 231ms of runtime (50ms allowed)            jquery.min.js:2

업데이트: Chrome 58+는 이러한 디버깅메시지 및 기타 디버깅메시지를 기본적으로 숨겼습니다.이 정보를 표시하려면 '정보' 옆에 있는 화살표를 클릭하고 '자세히'를 선택합니다.

크롬57은 기본적으로 '은폐 위반'을 설정했다.필터를 다시 켜려면 필터를 활성화하고 '위반 숨기기' 상자의 선택을 취소해야 합니다.

다른 누군가가 프로젝트에 관여했을 때 갑자기 나타난다

Chrome 56으로 업데이트 했을 가능성이 높다고 생각합니다.이 경고는 훌륭한 신기능입니다.제 생각에는 절박하고 평가관이 당신에게서 점수를 빼앗아 갈 경우에만 꺼주세요.근본적인 문제는 다른 브라우저에도 있지만 브라우저는 문제가 있다는 것을 알려주지 않습니다.크롬 티켓은 여기 있지만 그것에 대한 흥미로운 논의는 없다.

이러한 메시지는 큰 문제를 일으키지 않기 때문에 오류가 아닌 경고입니다.프레임의 드롭이나, 그 외의 조작이 원활하지 않은 경우가 있습니다.

다만, 애플리케이션의 품질을 향상시키기 위해서 조사해 수정할 필요가 있습니다.이를 수행하려면 메시지가 표시되는 상황에 주의하여 성능 테스트를 수행하여 문제가 발생하는 위치를 좁힙니다.퍼포먼스 테스트를 시작하는 가장 간단한 방법은 다음과 같은 코드를 삽입하는 것입니다.

function someMethodIThinkMightBeSlow() {
    const startTime = performance.now();

    // Do the normal stuff for this function

    const duration = performance.now() - startTime;
    console.log(`someMethodIThinkMightBeSlow took ${duration}ms`);
}

고급화를 원한다면 Chrome의 프로파일러를 사용하거나 이와 같은 벤치마킹 라이브러리를 사용할 수도 있습니다.

시간이 오래 걸리는 코드(Chrome 임계값 50ms)를 찾으면 몇 가지 옵션을 사용할 수 있습니다.

  1. 불필요할 수 있는 작업의 일부/전부를 삭제한다.
  2. 동일한 작업을 신속하게 수행하는 방법 파악
  3. 코드를 여러 비동기 단계로 분할합니다.

(1)과 (2)는 어렵거나 불가능할 수 있지만 때로는 매우 쉬우며 첫 번째 시도여야 합니다.필요한 경우 항상 (3)을 수행할 수 있어야 합니다.이를 위해 다음과 같은 방법을 사용합니다.

setTimeout(functionToRunVerySoonButNotNow);

또는

// This one is not available natively in IE, but there are polyfills available.
Promise.resolve().then(functionToRunVerySoonButNotNow);

JavaScript의 비동기 특성에 대한 자세한 내용은 여기를 참조하십시오.

이것은 모두가 언급했듯이 경고일 뿐이다.그러나 이러한 문제를 해결하려면 먼저 경고의 원인을 파악해야 합니다.강제 리플로우 경고를 받을 수 있는 유일한 이유는 없습니다.다른 사용자가 사용 가능한 옵션에 대한 목록을 만들었습니다.자세한 내용은 토론을 참조하십시오.
할 수 있는과 같습니다.

레이아웃/리플로우를 강제하는 이유

아래 속성 또는 메서드는 모두 JavaScript에서 요청/호출되면 브라우저가 스타일과 레이아웃을 동기화하여 계산하도록 트리거됩니다*.이는 리플로우 또는 레이아웃 스레싱이라고도 하며 일반적인 성능 병목 현상입니다.

요소

박스 메트릭
  • elem.offsetLeft,elem.offsetTop,elem.offsetWidth,elem.offsetHeight,elem.offsetParent
  • elem.clientLeft,elem.clientTop,elem.clientWidth,elem.clientHeight
  • elem.getClientRects(),elem.getBoundingClientRect()
스크롤 내용
  • elem.scrollBy(),elem.scrollTo()
  • elem.scrollIntoView(),elem.scrollIntoViewIfNeeded()
  • elem.scrollWidth,elem.scrollHeight
  • elem.scrollLeft,elem.scrollTop(Seting)
초점
  • elem.focus()이중 강제 레이아웃을 트리거할 수 있습니다(소스).
★★★★★★★★★★★★。
  • elem.computedRole,elem.computedName
  • elem.innerText(소스)

getComputedStyle

window.getComputedStyle()일반적으로 스타일을 강제로 재계산합니다(소스).

window.getComputedStyle() 하나에 적용합니다.

  1. 요소가 그림자 트리에 있습니다.
  2. 미디어 쿼리(뷰포트 관련 쿼리)가 있습니다.구체적으로는, (소스)* 중 하나입니다.min-width,min-height,max-width,max-height,width,height*aspect-ratio,min-aspect-ratio,max-aspect-ratio
    • device-pixel-ratio,resolution,orientation
  3. 요청된 속성은 다음 중 하나입니다(소스).
    • height,width*top,right,bottom,left*margin-top,-right,-bottom,-left여백이 고정된 경우에만, 또는 속기]를 선택합니다.*padding-top,-right,-bottom,-left패딩이 고정되어 있는 경우에만, 또는 속기]를 선택합니다.*transform,transform-origin,perspective-origin*translate,rotate,scale*webkit-filter,backdrop-filter*motion-path,motion-offset,motion-rotation*x,y,rx,ry

윈도

  • window.scrollX,window.scrollY
  • window.innerHeight,window.innerWidth
  • window.getMatchedCSSRules() force style only force 'style only'

  • inputElem.focus()
  • inputElem.select(),textareaElem.select()(소스)

마우스 이벤트

  • mouseEvt.layerX,mouseEvt.layerY,mouseEvt.offsetX,mouseEvt.offsetY(소스)

문서

  • doc.scrollingElement force style only force 'style only'

범위

  • range.getClientRects(),range.getBoundingClientRect()

SVG

만족할 만한

  • 이미지를 클립보드에 복사하는 등 매우 많은 것(소스)

자세한 것은 이쪽을 봐 주세요.

또한, 원호의 크롬 소스 코드와 경고에 대한 성능 API에 대한 설명입니다.


편집: PageSpeed Insight by Google의 레이아웃 리플로우를 최소화하는 방법에 대한 기사도 있습니다.브라우저 리플로우가 무엇인지 설명합니다.

Reflow는 문서의 일부 또는 전체를 재렌더하기 위해 문서 내 요소의 위치와 형상을 재계산하는 웹 브라우저 프로세스의 이름입니다.reflow는 브라우저의 사용자 차단 작업이기 때문에 개발자는 리플로우 시간을 개선하는 방법을 이해하고 다양한 문서 속성(DOM 깊이, CSS 규칙 효율성, 다양한 유형의 스타일 변경)이 리플로우 시간에 미치는 영향을 이해하는 데 유용합니다.문서의 단일 요소를 다시 표시하기 위해 상위 요소 및 그 뒤에 이어지는 요소를 다시 표시해야 할 수 있습니다.

또한 이를 최소화하는 방법에 대해서도 설명합니다.

  1. 불필요한 DOM 깊이를 줄입니다.DOM 트리의 한 수준에서 변경하면 트리의 모든 수준(루트까지, 수정된 노드의 자식까지)에서 변경이 발생할 수 있습니다.이로 인해 리플로우를 수행하는 데 더 많은 시간이 소요됩니다.
  2. CSS 규칙을 최소화하고 사용하지 않는 CSS 규칙을 삭제합니다.
  3. 애니메이션과 같은 복잡한 렌더링을 변경할 경우 흐름에서 변경하십시오.이를 수행하려면 position-absolute 또는 position-fixed를 사용합니다.
  4. 셀렉터 매칭을 실시하기 위해 CPU의 파워가 더 필요한 불필요한 복잡한 CSS 셀렉터(특히 하위 셀렉터)는 피하십시오.

몇 가지 아이디어:

  • 코드의 반을 삭제합니다(코멘트 아웃으로 할 수도 있습니다.

    • 아직도 문제가 있나요?좋아, 가능성을 좁혔군!따라하다.

    • 문제는 거기에 없나요?좋아, 네가 말한 반쪽을 봐!

  • it전git등을ggggggg등gg))?그렇다면,git checkout했습니까?제제문 ?제 ?? ????커밋을 보고 문제가 처음 발생했을 때 어떤 코드가 변경되었는지 확인합니다.

이 메시지의 루트를 검색 및 숨김 또는 노드(오프라인)를 표시하는 코드에서 찾았습니다.제 암호는 이렇습니다.

search.addEventListener('keyup', function() {
    for (const node of nodes)
        if (node.innerText.toLowerCase().includes(this.value.toLowerCase()))
            node.classList.remove('hidden');
        else
            node.classList.add('hidden');
});

[ 에는 약 60밀리초 걸리는 이벤트가 표시됩니다.[ Performance ]([Performance ]([Performance ])([Performance ]([Performance])([Performance])([Performance])([Performance]))는, [60]는 [Performance](Performance](Per)](Per)의)의)크롬 성능 프로파일러 레이아웃 재계산 리플로우

지금:

search.addEventListener('keyup', function() {
    const nodesToHide = [];
    const nodesToShow = [];
    for (const node of nodes)
        if (node.innerText.toLowerCase().includes(this.value.toLowerCase()))
            nodesToShow.push(node);
        else
            nodesToHide.push(node);

    nodesToHide.forEach(node => node.classList.add('hidden'));
    nodesToShow.forEach(node => node.classList.remove('hidden'));
});

[ ]약 1밀리초됩니다.[ Performance ](「Performance ])(「Performance 」(「Performance 」)는 1밀리초 걸립니다.크롬 프로파일러 다크

검색 속도가 빨라진 것 같습니다(229 노드).

문제의 원인을 식별하려면 응용 프로그램을 실행하고 Chrome의 성능 탭에 기록합니다.

실행 시간이 오래 걸린 다양한 기능을 확인할 수 있습니다.내 경우 콘솔의 경고와 관련된 것은 AdBlock 확장자에 의해 로드된 파일이지만, 이 경우 다른 것일 수 있습니다.

이 파일들을 체크하고 이것이 내선번호인지 내선번호인지 내선번호인지 확인해 보십시오.(내선번호라면 문제의 원인을 찾은 것입니다.)

Chrome 콘솔의 [네트워크]탭에서 로드하는 데 가장 오래 걸리는 스크립트를 찾습니다.

내 경우 앱에서 아직 사용하지 않은 Angular add on 스크립트 세트가 있었다.

<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.8/angular-ui-router.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-utils/0.1.1/angular-ui-utils.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular-animate.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular-aria.min.js"></script>

이 파일들만이 "Long Running Task" 오류가 지정한 시간보다 로드하는 데 더 오래 걸렸습니다.

이 모든 파일은 다른 웹 사이트에서 오류 없이 실행되지만, 기능이 거의 없는 새로운 웹 앱에서 이 "Long Running Task" 오류가 발생했습니다.삭제 즉시 에러가 정지.

이러한 Angular 애드온은 시작 태그를 위해 DOM의 점점 더 깊은 부분을 재귀적으로 들여다보고 있었던 것으로 추측됩니다.-아무것도 찾지 못한 채 종료하기 전에 DOM 전체를 통과해야 했습니다.이것은 Chrome의 예상보다 오래 걸렸습니다.그 때문에 경고가 표시됩니다.

아파치 코르도바 소스코드에서 해결책을 찾았어요실장은 다음과 같습니다.

var resolvedPromise = typeof Promise == 'undefined' ? null : Promise.resolve();
var nextTick = resolvedPromise ? function(fn) { resolvedPromise.then(fn); } : function(fn) { setTimeout(fn); };

심플한 실장, 스마트한 방법.

에서는 Android 4.4를 합니다.Promise 브라우저의 " " 를 setTimeout()


사용방법:

nextTick(function() {
  // your code
});

이 트릭 코드를 삽입하면 모든 경고 메시지가 사라집니다.

이 스레드에 제 통찰력을 더하면 이 주제에 대한 스택오버플로우 질문으로 이동합니다.

Material-UI 앱(초기)에서 문제가 발생하였습니다.

  • 커스텀 테마 프로바이더의 배치가 원인입니다.

페이지의 렌더링을 강제적으로 실행했을 때(한 컴포넌트, 「결과 표시」는, 다른 컴포넌트, 「입력 섹션」에 설정되어 있는 것에 의해서 다릅니다.

결과 컴포넌트를 강제로 다시 렌더링하는 "상태"를 업데이트하기 전까지는 모든 것이 정상이었습니다.여기서 가장 큰 문제는 동일한 렌더러(App.js/return)에 material-ui 테마(https://material-ui.com/customization/theming/#a-note-on-performance)가 있다는 것입니다.결과 컴포넌트로서 Summary AppBarPure를 사용합니다.

해결책은 ThemeProvider를 한 단계 위로 들어 올리고(Index.js), 앱 컴포넌트를 여기에 랩하는 것입니다.따라서 ThemeProvider는 재계산 및 레이아웃/리플로우를 강요하지 않습니다.

전에

App.js:

  return (
    <>
      <MyThemeProvider>
      <Container className={classes.appMaxWidth}>

        <SummaryAppBarPure
//...

index.displaces에 있습니다.

ReactDOM.render(
  <React.StrictMode>
      <App />
//...

끝나고

App.js:

return (
    <>
      {/* move theme to index. made reflow problem go away */}
      {/* <MyThemeProvider> */}
      <Container className={classes.appMaxWidth}>

        <SummaryAppBarPure
//...

index.displaces에 있습니다.

ReactDOM.render(
  <React.StrictMode>
    <MyThemeProvider>
      <App />
//...

이것은 Chromium 블로그의 Changelog에는 없지만 Chrome 56 베타판에 추가되었습니다.Chrome 56 베타판: "Not Secure" 경고, 웹 블루투스 및 CSS

[ Hide violations ]체크박스를 사용하여 콘솔의 필터바에서 숨길 수 있습니다.

Chrome Canary(또는 베타)를 사용하는 경우 'Hide Violations(위반 숨기기)' 옵션을 선택하십시오.

Chrome 56 콘솔에서 위반 확인란 숨기기

이것은 구글 크롬으로부터의 위반 에러입니다.이 에러는, 다음의 경우에 표시됩니다.Verbose로깅 레벨이 네이블입니다.

오류 메시지의 예:

경고 스크린샷

설명:

Reflow는 문서의 일부 또는 전체를 재렌더하기 위해 문서 내 요소의 위치와 형상을 재계산하는 웹 브라우저 프로세스의 이름입니다.reflow는 브라우저의 사용자 차단 작업이기 때문에 개발자는 리플로우 시간을 개선하는 방법을 이해하고 다양한 문서 속성(DOM 깊이, CSS 규칙 효율성, 다양한 유형의 스타일 변경)이 리플로우 시간에 미치는 영향을 이해하는 데 유용합니다.문서의 단일 요소를 다시 표시하기 위해 상위 요소 및 그 뒤에 이어지는 요소를 다시 표시해야 할 수 있습니다.

원본 기사:UX 개발자인 Lindsey Simon이 developers.google.com에 게시한 브라우저 리플로우를 최소화합니다.

경고에 대한 자세한 내용은 Google Chrome이 성능 프로파일러의 레이아웃 프로파일(마우브 영역)에 제공하는 링크입니다.

중요한 건, 여기 제가 만난 2달러가 있습니다.

[Violation] Forced reflow while executing JavaScript took <N>ms

경고합니다.문제의 페이지는 유저 컨텐츠로부터 생성되고 있기 때문에, 저는 DOM 의 사이즈에 큰 영향을 주지 않습니다.제 경우, 문제는 두 개의 컬럼으로 이루어진 표로 수백, 심지어 수천 개의 행이 있을 수 있다는 것입니다.(아직 주문형 행 로딩이 구현되지 않았습니다. 죄송합니다.)

페이지에서 jQuery를 사용하여 행 세트를 선택하고 표시 여부를 전환합니다.그 세트로 사용하는 것이 명시적으로 사용하는 것보다 더 쉽게 경고를 트리거한다는 것을 알게 되었습니다.

이 퍼포먼스 시나리오의 상세한 것에 대하여는, 이 문서도 참조해 주세요.

강제 리플로우는 실행 종료 전에 여러 번 호출된 함수가 있을 때 자주 발생합니다.

예를 들어 스마트폰에서는 문제가 발생하지만 기존 브라우저에서는 문제가 발생하지 않을 수 있습니다.

저는 를사 a a a a a a a a a를 사용하는 것이 .setTimeout문제를 해결합니다.

이것은 그다지 중요하지 않습니다만, 반복하지만 함수가 50밀리초 이상 걸릴 때가 아니라 함수를 여러 번 호출할 때 문제가 발생합니다.내 생각에 네가 틀린 것 같아.

  1. 1 바이 1 의 콜을 끄고, 코드를 새로고침 해, 에러가 아직 발생하고 있는지를 확인합니다.
  2. 가 발생한 를 사용합니다.setTimeOut위반 기간을 기준으로 합니다.

이것은 에러가 아니라 단순한 메시지입니다.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> (카메라에)
로로 합니다.
<!DOCTYPE html>되어 있습니다 (Firefox " " )

Google Chrome 74 오페라 60 0으로 하다
접근법

언급URL : https://stackoverflow.com/questions/41218507/violation-long-running-javascript-task-took-xx-ms

반응형