Javascript workaround for slow scrolling with smooth scrolling in firefox
I do understand that your question basically is how to disable smooth scrolling. however I will answer you a little differently to get this working.
Why different?
Even if you can detect smooth scrolling of users, you cannot force the user to disable it. In other words, you are trying to cover the problem instead of solving it. so lets solve it!
Intro: pixels-to-screen pipeline
On each frame the browser does the following steps to render the page on screen.
JavaScript. Typically JavaScript is used to handle work that will result in visual changes, whether it’s jQuery’s animate function, sorting a data set, or adding DOM elements to the page. It doesn’t have to be JavaScript that triggers a visual change, though: CSS Animations, Transitions, and the Web Animations API are also commonly used.
Style calculations. This is the process of figuring out which CSS rules apply to which elements based on matching selectors, e.g. .headline or .nav > .nav__item. From there, once rules are known, they are applied and the final styles for each element are calculated.
Layout. Once the browser knows which rules apply to an element it can begin to calculate how much space it takes up and where it is on screen. The web’s layout model means that one element can affect others, e.g. the width of the element typically affects its children’s widths and so on all the way up and down the tree, so the process can be quite involved for the browser.
Paint. Painting is the process of filling in pixels. It involves drawing out text, colors, images, borders, and shadows, essentially every visual part of the elements. The drawing is typically done onto multiple surfaces, often called layers.
Compositing. Since the parts of the page were drawn into potentially multiple layers they need to be drawn to the screen in the correct order so that the page renders correctly. This is especially important for elements that overlap another, since a mistake could result in one element appearing over the top of another incorrectly.
details and source: https://developers.google.com/web/fundamentals/performance/rendering/?hl=en
Step 1:
First step is to remove render costly css properties. You might not be able to remove alot, however you can replace rgba(255,255,255,1);
with #fff
which removes the alpha layer.
check this for more details: https://csstriggers.com/
some properties do not need to do a layout
or a paint
and there are less heavy than others.
Step 2:
Check for forced synchronous layout
triggers. These happen when you force the browser to do a layout
while its in the javascript step, then return to javascript, instead of walking smoothly along the pipeline on each frame. to do this, avoid getting layout attributes and setting them directly afterwards in a loop for example.
here is a list of what causes sync layout: https://gist.github.com/paulirish/5d52fb081b3570c81e3a
read more: https://developers.google.com/web/tools/chrome-devtools/profile/rendering-tools/forced-synchronous-layouts?hl=en
Step 3:
Move components on the page that need to be repainted regularly into new layers.
The browser needs to repaint every time you scroll or an animation is playing. to avoid a full page repaint and only repaint the part that is changing, move that part (ex parallax, navigation, animation) to a new layer on the browser (think about it like photoshop layers)
to do so use the will-change
css property to tell the browser to move it to a new layer, and use transform: translateZ(0);
if you want to force the broswer to move it.
Update position of fixed element on scroll is slightly behind in IE and Firefox only
This is a feature introduced in FF 46.
Basically this can also happen in Chrome and other browsers (Although in Chrome it only happens a) sometimes and b) for just one frame out of 1000.)
The scroll
event is not really synced with the real rendering of the scroll. The oldschool scroll event was indeed synced with the visual scroll. But especially for mobile it was hard to have a performant scroll
rendering that is synced with JS including the scroll
event.
The main solution was to decouple the scroll rendering from the main thread. As you know JS is executed in the main thread and therefore this results in the fact that JS (main thread) and visual scrolling (a special composition thread) are out of sync.
You might be able to workaround this by simply fixing
everything and than animating the transform x property. Maybe also hooking into wheel
event might help. (Using wheel
partially destroys the performant async nature of the scroll rendering (this is why passive event listeners, where introduced).
You can read more:
https://developer.mozilla.org/en-US/docs/Mozilla/Performance/Scroll-linked_effects
https://hacks.mozilla.org/2016/02/smoother-scrolling-in-firefox-46-with-apz/
CSS fixed position movement under scrollbar in Firefox
After a bit of fiddling, my solution would be to put the ScrollToTop anchor inside another fixed position div.
HTML
<div id="ScrollToTopHolder"><a href="#Top" id="ScrollToTop">Top</a></div>
CSS
body {
height: 2000px;
background: #990000;
}
#ScrollToTopHolder {
position: fixed;
width:100%;
bottom:0px;
}
#ScrollToTop {
position: absolute;
right: 0px;
bottom: -10px;
width: 50px;
height: 50px;
line-height: 50px;
background: #fff;
color: #000;
text-transform: uppercase;
text-decoration: none;
text-align: center;
font-size: 15px;
font-weight: bold;
z-index: 1000;
border: solid 1px #000;
border-bottom: none;
border-radius: 10px 10px 0 0;
transition: all 0.4s;
}
#ScrollToTop:hover {
bottom: 0px;
}
JSFiddle
It seems to be that Firefox doesn't like it when you move the fixed anchor position, re-aligning it.
Position: fixed Background DIV with images makes scrolling slow: How to make conditional CSS rules for browser-compatibility?
Q1: How to make that line conditional?
For IE older than version 9 there's always a conditional comment override:
<!--[if lt IE 9]>
<style>img#bg { position: absolute; }</style>
<![endif]-->
For Firefox, one way would be to find some hack that distinguishes version 4 from its predecessors, which I can't really think of right now.
Q2: Could anything in my css have triggered the bug except
position: fixed?
That and the fact that it's an image. But mostly the fixed positioning. This also happens if you used a background image with background-attachment: fixed
, and is a well-known performance issue on those browsers.
fixed position element causes distortion when scrolling
Add overflow:auto
to the fixed-position divs.
If it still doesn't work, there's probably not much you can do about it - it's just a bug/deficiency with Firefox's (re)drawing. Fixed elements are often problematic - Opera back around version 8 was incredibly slow when scrolling any page with a fixed element or background.
Getting rid of CSS font-size padding without slowing Firefox scroll speed
Playing around with my own JSFiddle I managed to figure this one out on my own - I simply needed to wrap the image in an extra div and move the font-size: 0
declaration inside it, and as a result the scroll speed remains sane in the actually scrolling parent div. Seems like posting about this ended up being a successful case of rubber duck debugging.
HTML:
<div class="window">
<div class="view">
<div class="wrap">
<img src="http://placekitten.com/300/2000" alt="kitty" />
</div>
</div>
</div>
CSS:
body {
margin: 0;
padding: 0;
}
.window {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow: hidden;
}
.view {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: auto;
text-align: center;
}
.wrap { font-size: 0; }
Related Topics
Bootstrap Thumbnail Grid Not Starting a New Row Correctly
How to Use Both Rel="Preload" and Rel="Stylesheet" for the Same Tag
Which Border Radius Property Will Work in IE9
In Firebug, How to Tell What Is Overriding a Style
How to Load CSS File Dynamically
Force Elements to Be Horizontally Aligned
CSS Calc and Min-Height Can Not Team Up Properly
How to Make CSS Max Width in IE6 and 7
CSS Get Last-Child That Doesn't Have a Class
100% Div Width Is Not Really 100%
Start Div Scrollbar from Bottom with Pure CSS
IE9 Not Applying Linked Style Sheets
Custom Checkboxes Failing on Firefox
Prevent Nginx from Serving CSS Files as Text/Plain
Why Does This Div Shift Down When Content Is Added
Gradients Hidden Using Svg Symbols
Why Do Modern Browsers Still Put Spaces Between Inline Block If There Is Whitespace