Closed Mohsen-Khakbiz closed 7 years ago
Thanks for asking Mohsen.
I’m not aware of any performance issues with ScrollReveal; in fact, the only issue I can recall was related to layout reflow, and it was improved significantly in ScrollReveal 4 (beta).
Other improvements include caching all element dimensions and position, further lightening the burden on event handlers. Even though it’s in beta (for only a few more weeks), version 4 is the most stable and robust version to date—I strongly recommend upgrading.
<script src="https://cdn.jsdelivr.net/npm/scrollreveal@beta"></script>
See What’s New in 4.0.
It’s important to know that Intersection Observer will include CSS Transforms in its logic—which actually complicates using them for reveal on scroll libraries, particularly ScrollReveal. Let’s go through an example to explain why.
I know
IntersectionObserver
doesn’t return coordinates, but the idea behind this example still applies. Please bear with me.
Imagine we have an Element at coordinates (2, 1) on our page:
ScrollReveal (and I presume other reveal on scroll libraries) will use CSS Transform to create animations. Let’s say we’ve added some translateX
to our Element because we’re planning to reveal it from the right side of the window.
What would we expect/want the coordinates of our Element to be?
This is where we see the critical difference between using offsetLeft
and offsetTop
to determine element visibility (the technique used by ScrollReveal), and using modern browser APIs such as IntersectionObserver
or getBoundingClientRect
.
If we use the newer APIs, they will include the CSS Transform and we’d get (9, 1):
Whereas, if we use offset values, we’ll still get the original coordinates (2, 1):
Well, is the Element (9, 1) within the window's range of {8, 5}?
No. It’s not within the window (which is easily seen in the figure). In fact, this element would never be considered "visible" (without some form of horizontal scrolling), but herein lies the problem.
We don’t really care where the element is in its pre-reveal state... rather, we want to know "if we revealed this element now, would it be visible after the animation completes?"
It sounds like a good thing that modern APIs include our CSS Transform, and indeed for many use cases I’m sure it is... but by obscuring the element’s original/post-reveal position, it actually makes it significantly more difficult to determine whether our Element should be revealed.
I actually tried to use
getBoundingClientRect
at one point, and elements would constantly bounce in and out of view because the position coordinates were constantly changing during animation.
Now, IntersectionObserver
uses percentages (something called Intersection Ratios), not coordinates, but the problem is the same: The position reported by IntersectionObserver
is influenced by CSS Transform.
Well, because offset values ignore CSS transforms, we can trust that when we check an element’s position, we will be checking the "post-reveal" position we care about... not the rendered position of the element.
I’m sure a clever developer could build a reveal on scroll library from scratch that leverages getBoundingClientRect
or IntersectionObserver
, but ScrollReveal has a pretty substantial feature base with very wide browser support—and relying on offset values works quite well.
I wouldn’t recommend trying to replace the element visibility logic with IntersectionObserver
(or getBoundingClientRect
for that matter). If you’re concerned about performance, consider upgrading to ScrollReveal 4 (beta).
is there anyway to use intersection observer api for this plugin? you know for better performance. as there's a polyfill for IO there's no concern about browser compatibility in my case. or if you could guide me how to achieve it, it'll be much appreciated.
Regards, Mohsen