Violation Long running JavaScript task took xx ms

Violation Long running JavaScript task took xx ms

Recently, I got this kind of warning, and this is my first time getting it:

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

I’m working on a group project and I have no idea where this is coming from. This never happened before. Suddenly, it appeared when someone else got involved in the project. How do I find what file/function causes this warning? I’ve been looking for the answer, but mostly about the solution on how to solve it. I can’t solve it if I can’t even find the source of the problem.
In this case, the warning appears only on Chrome. I tried to use Edge, but I didn’t get any similar warnings, and I haven’t tested it on Firefox yet.
I even get the error from jquery.min.js:

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

Solutions/Answers:

Solution 1:

Update: Chrome 58+ hid these and other debug messages by default. To display them click the arrow next to ‘Info’ and select ‘Verbose’.

Chrome 57 turned on ‘hide violations’ by default. To turn them back on you need to enable filters and uncheck the ‘hide violations’ box.

suddenly it appears when someone else involved in the project

I think it’s more likely you updated to Chrome 56. This warning is a wonderful new feature, in my opinion, please only turn it off if you’re desperate and your assessor will take marks away from you. The underlying problems are there in the other browsers but the browsers just aren’t telling you there’s a problem. The Chromium ticket is here but there isn’t really any interesting discussion on it.

These messages are warnings instead of errors because it’s not really going to cause major problems. It may cause frames to get dropped or otherwise cause a less smooth experience.

They’re worth investigating and fixing to improve the quality of your application however. The way to do this is by paying attention to what circumstances the messages appear, and doing performance testing to narrow down where the issue is occurring. The simplest way to start performance testing is to insert some code like this:

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

    // Do the normal stuff for this function

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

If you want to get more advanced, you could also use Chrome’s profiler, or make use of a benchmarking library like this one.

Related:  HTML5 mobile app running while phone screen is off?

Once you’ve found some code that’s taking a long time (50ms is Chrome’s threshold), you have a couple of options:

  1. Cut out some/all of that task that may be unnecessary
  2. Figure out how to do the same task faster
  3. Divide the code into multiple asynchronous steps

(1) and (2) may be difficult or impossible, but it’s sometimes really easy and should be your first attempts. If needed, it should always be possible to do (3). To do this you will use something like:

setTimeout(functionToRunVerySoonButNotNow);

or

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

You can read more about the asynchronous nature of JavaScript here.

Solution 2:

These are just warnings as everyone mentioned. However, if you’re keen on resolving these (which you should), then you need to identify what is causing the warning first. There’s no one reason due to which you can get force reflow warning.
Someone has created a list for some possible options. You can follow the discussion for more information.
Here’s the gist of the possible reasons:

What forces layout / reflow

All of the below properties or methods, when requested/called in
JavaScript, will trigger the browser to synchronously calculate the
style and layout*. This is also called reflow or layout
thrashing
,
and is common performance bottleneck.

Element

Box metrics

  • elem.offsetLeft, elem.offsetTop, elem.offsetWidth, elem.offsetHeight, elem.offsetParent
  • elem.clientLeft, elem.clientTop, elem.clientWidth, elem.clientHeight
  • elem.getClientRects(), elem.getBoundingClientRect()

Scroll stuff

  • elem.scrollBy(), elem.scrollTo()
  • elem.scrollIntoView(), elem.scrollIntoViewIfNeeded()
  • elem.scrollWidth, elem.scrollHeight
  • elem.scrollLeft, elem.scrollTop also, setting them

Focus

  • elem.focus() can trigger a double forced layout (source)

Also…

  • elem.computedRole, elem.computedName
  • elem.innerText (source)

getComputedStyle

window.getComputedStyle() will typically force style recalc
(source)

window.getComputedStyle() will force layout, as well, if any of the
following is true:

  1. The element is in a shadow tree
  2. There are media queries (viewport-related ones). Specifically, one of the following:
    (source) * min-width, min-height, max-width, max-height, width, height * aspect-ratio, min-aspect-ratio, max-aspect-ratio

    • device-pixel-ratio, resolution, orientation
  3. The property requested is one of the following: (source)
    • height, width * top, right, bottom, left * margin [-top, -right, -bottom, -left, or shorthand] only if the
      margin is fixed. * padding [-top, -right, -bottom, -left,
      or shorthand] only if the padding is fixed. * transform,
      transform-origin, perspective-origin * translate, rotate,
      scale * webkit-filter, backdrop-filter * motion-path,
      motion-offset, motion-rotation * x, y, rx, ry

window

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

Forms

  • inputElem.focus()
  • inputElem.select(), textareaElem.select() (source)

Mouse events

  • mouseEvt.layerX, mouseEvt.layerY, mouseEvt.offsetX, mouseEvt.offsetY
    (source)

document

  • doc.scrollingElement only forces style

Range

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

SVG

contenteditable

  • Lots & lots of stuff, …including copying an image to clipboard (source)

Check more here.

Related:  Clone a js object except for one key

Also, here’s Chromium source code from the original issue and a discussion about a performance API for the warnings.


Edit: There’s also an article on how to minimize layout reflow on PageSpeed Insight by Google. It explains what browser reflow is:

Reflow is the name of the web browser process for re-calculating the
positions and geometries of elements in the document, for the purpose
of re-rendering part or all of the document. Because reflow is a
user-blocking operation in the browser, it is useful for developers to
understand how to improve reflow time and also to understand the
effects of various document properties (DOM depth, CSS rule
efficiency, different types of style changes) on reflow time.
Sometimes reflowing a single element in the document may require
reflowing its parent elements and also any elements which follow it.

In addition, it explains how to minimize it:

  1. Reduce unnecessary DOM depth. Changes at one level in the DOM tree
    can cause changes at every level of the tree – all the way up to the
    root, and all the way down into the children of the modified node.
    This leads to more time being spent performing reflow.
  2. Minimize CSS rules, and remove unused CSS rules.
  3. If you make complex rendering changes such as animations, do so out of the flow. Use position-absolute or position-fixed to accomplish
    this.
  4. Avoid unnecessary complex CSS selectors – descendant selectors in
    particular – which require more CPU power to do selector matching.

Solution 3:

A couple of ideas:

  • Remove half of your code (maybe via commenting it out).

    • Is the problem still there? Great, you’ve narrowed down the possibilities! Repeat.

    • Is the problem not there? Ok, look at the half you commented out!

  • Are you using any version control system (eg, Git)? If so, git checkout some of your more recent commits. When was the problem introduced? Look at the commit to see exactly what code changed when the problem first arrived.

Related:  React inline style - style prop expects a mapping from style properties to values, not a string

Solution 4:

In my case, I have discovered that this was actually caused by a code from an extension. For me, the extension was AdBlock.

In order to identify the source of the problem, run your application, and record it in Chrome’s Performance tab.

There you can check various functions that took a long time to run. In my case, the one that correlated with warnings in console was from a file which was loaded by the AdBlock extension, but this could be something else in your case.

Check these files and try to identify if this is some extension’s code or yours. (If it is yours, then you have found the source of your problem.)

Solution 5:

Look in the Chrome console under the Network tab and find the scripts which take the longest to load.

In my case there were a set of Angular add on scripts that I had included but not yet used in the app :

<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>

These were the only JavaScript files that took longer to load than the time that the “Long Running Task” error specified.

All of these files run on my other websites with no errors generated but I was getting this “Long Running Task” error on a new web app that barely had any functionality. The error stopped immediately upon removing.

My best guess is that these Angular add ons were looking recursively into increasingly deep sections of the DOM for their start tags – finding none, they had to traverse the entire DOM before exiting, which took longer than Chrome expects – thus the warning.

Solution 6:

This was added in the Chrome 56 beta, even though it isn’t on this changelog from the Chromium Blog: Chrome 56 Beta: “Not Secure” warning, Web Bluetooth, and CSS position: sticky

You can hide this in the filter bar of the console with the Hide violations checkbox.