Violation Long running JavaScript task took xx ms

procatmer picture procatmer · Dec 19, 2016 · Viewed 416.3k times · Source

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

Answer

voltrevo picture voltrevo · Feb 21, 2017

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.

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.