Insights
Aug 28, 2025
Why Framer's Interactive Transitions Are Over 50% Faster
Framer improves hydration speed by 50-80%, making user interactions faster, and significantly enhances scroll animations and data loading speeds across all devices.

Uploaded by

Translated by
Contents
Table of Contents
How Does Framer's Site Become Interactive?
Websites are primarily built with HTML, and JavaScript is added to enable interactions like button clicks or text input. To ensure fast initial loading, Framer first serves HTML through server-side rendering. This allows users and search engines to immediately view the content.
At the same time, the JavaScript required for the process is loaded this is the process known as hydration. It's the stage where React receives the HTML and attaches event listeners, enabling the site to respond to actions like clicks or scrolls. In other words, it's only at this point that the site can truly be called ‘interactive’.
Some JavaScript based elements require fetching data from the server to become interactive. For example, on the Framer homepage, the user's login status must be fetched from the server for the area highlighted in red.

Other sites may require reviews, the latest blog posts, weather information, and so on. Fetching this data each time takes some time. Particularly, a request to fetch one piece of data can trigger a chain reaction requiring the fetching of other data, and all these actions are processed during hydration.
Now, let's dive into the technical details to show exactly what happens. If you'd like to skip the technical specifics, feel free to jump straight to the final chapter.
React: The Relationship Between Suspense and Hydration
When fetching data during hydration, React's Suspense feature is used. Suspense is a mechanism that tells React, “This component is currently waiting for something.”
Previously, a single Suspense instance was used for this purpose. An example is as follows.
In other words, each time data for ‘blog’ and ‘footer’ is fetched, a single Suspense tag “Suspense boundary” is triggered. (This is also called ‘suspending’.) React starts fetching data for these two components in parallel, but the issue lies in the detailed behavior.
If a component suspends during hydration and then unsuspends after receiving data, React restarts hydration from the Suspense boundary that captured that component.
This means that in the example above, every time data is fetched, React starts rendering again from the single Suspense tag under <App>. For instance, when fetching ‘blog’ data, React re-renders both <Header> and its two <DataFetching> child components. The same happens when fetching ‘footer’ data.
In other words, parts that could be rendered just once are rendered multiple times. Each data fetching component causes its parent component to re-render. Assuming each data fetcher has child components in the example, this results in a total of 12 renders. <Page> and <Header> render 3 times, the blog data fetcher and its child components render 2 times, and the footer data fetcher and its child components render 1 time (= 6 + 4 + 2).
Faster Hydration: Granular Suspense
While the example above might run quickly in a small-scale scenario, it would significantly slow down on a real website with hundreds or thousands of components. Additionally, rendering speed varies depending on the device (especially the CPU). Since device speeds differ per user, ensuring everyone experiences the same fast performance is crucial.
Initially, we tried solving this with memoization (React.memo). But wouldn't React re-render those components if we did this? Unfortunately, this approach isn't very effective because React still schedules re-renders for the children of the Suspense boundary.
To solve this problem, we need to add granular Suspense boundaries around the components fetching data.
Each Suspense boundary can now capture components that have stalled within the tree structure below it. React resumes hydration immediately from the point where a stalled component is captured, eliminating the need to re-render the entire tree. In fact, the Framer homepage expanded its boundaries from a single one to a whopping 151 granular boundaries.
This ensures every component renders only once during hydration, making the hydration process O(n) linear time (depending on the number of nodes in the n-component tree). It becomes a fast, linear process, regardless of how many data fetches exist within the tree.
What this means for Framer sites
Beta testing revealed this change accelerated hydration by 50–80% on many devices. Depending on the data required during hydration, speeds on slower devices improved by up to 200%. Consequently, scroll animations now work faster, and users can interact with the site much sooner.
(Left: Before, Right: After, recorded on an M2 Pro with 6x CPU throttling and 4G speed applied in the latest Chrome profile.)
In conclusion, scroll animations now start faster, enabling users to interact with Framer sites more quickly. Improvements were also seen on pages heavy with SVG elements. Hydration begins simultaneously with SVG loading. Measurements across all Framer sites visited on mobile devices show elements like cookie banners appear on average 42% faster.
This change is noticeable even on fast devices. Testing on an M2 Pro MacBook with a 100Mbit/s network also showed hydration completion happening significantly sooner.
(Left: Before, Right: After. Recorded on an M2 Pro Mac with the latest Chrome profile and a 100 Mbit/s internet connection.)
If you're a Framer user, this change will be applied automatically without any extra work. Simply republish your site to experience these performance improvements immediately. Special thanks to performance engineer Ivan Akulov for investigating the issue and identifying the cause.
If you have any questions or concerns related to performance, please reach out to the Performance Team on the community forums.
This post is adapted from the official Framer blog article ‘Sites now become interactive 50% faster’.




