Violation Long running JavaScript task took xx ms
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 metricsScroll stuff
elem.offsetLeft
,elem.offsetTop
,elem.offsetWidth
,elem.offsetHeight
,elem.offsetParent
elem.clientLeft
,elem.clientTop
,elem.clientWidth
,elem.clientHeight
elem.getClientRects()
,elem.getBoundingClientRect()
Focus
elem.scrollBy()
,elem.scrollTo()
elem.scrollIntoView()
,elem.scrollIntoViewIfNeeded()
elem.scrollWidth
,elem.scrollHeight
elem.scrollLeft
,elem.scrollTop
also, setting themAlso…
elem.focus()
can trigger a double forced layout (source)
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:
- The element is in a shadow tree
- 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
- 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 styleForms
inputElem.focus()
inputElem.select()
,textareaElem.select()
(source)Mouse events
mouseEvt.layerX
,mouseEvt.layerY
,mouseEvt.offsetX
,mouseEvt.offsetY
(source)document
doc.scrollingElement
only forces styleRange
range.getClientRects()
,range.getBoundingClientRect()
SVG
- Quite a lot; haven't made an exhaustive list , but Tony Gentilcore's 2011 Layout Triggering List pointed to a few.
contenteditable
- Lots & lots of stuff, …including copying an image to clipboard (source)
Check more here.
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:
- 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.
- Minimize CSS rules, and remove unused CSS rules.
- If you make complex rendering changes such as animations, do so out of the flow. Use position-absolute or position-fixed to accomplish this.
- Avoid unnecessary complex CSS selectors - descendant selectors in particular - which require more CPU power to do selector matching.
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.
I found the root of this message in my code, which searched and hid or showed nodes (offline). This was my code:
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');
});
The performance tab (profiler) shows the event taking about 60 ms:
Now:
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'));
});
The performance tab (profiler) now shows the event taking about 1 ms:
And I feel that the search works faster now (229 nodes).
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:
- Cut out some/all of that task that may be unnecessary
- Figure out how to do the same task faster
- 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.