Performance Optimization
|
This content was generated with the assistance of AI and should be verified against the official Webflow documentation before being relied on in production. This sub-section’s Webflow bibliography lists the reference material consulted while preparing these pages. |
This page describes Webflow as it was on 2026-10-28, the date on which its facts were checked against the official documentation. Webflow is a hosted service without version numbers, so a setting name or its location can move between two visits; the Product Changes and Deprecations page tracks what changed. Plans are named by tier only. Everything about images, fonts and measuring works on every plan; the async JavaScript option described below needs a paid Site plan or Workspace plan.
Webflow already does a good deal of the work: it serves assets from a content delivery network, generates responsive image variants, lazy-loads new images and compiles its own style sheet and runtime script. What remains is decided by the people who build the site. A designer chooses the image sizes and fonts, a content editor uploads the files, a marketer pastes tracking snippets, and a developer adds scripts and animations. Each choice adds bytes, requests or work for the browser, and the total decides whether a visitor on a phone waits.
The running example is Fernbrook Gardens, a fictitious botanical garden. Its home page has a glasshouse hero photograph, a looping rain film, a bloom reveal animation, a Collection List of featured plants and an analytics snippet. The page is a good test case because every one of those things can make it slow.
What "fast" means: the Core Web Vitals
Browsers and search engines judge speed with three field metrics, called the Core Web Vitals. Their thresholds are published by Google at https://web.dev/articles/vitals, and a page is judged at the 75th percentile of real visits, separately for mobile and desktop.
| Metric | What it measures | Good threshold |
|---|---|---|
Largest Contentful Paint (LCP) |
How long the largest visible element, usually the hero image or a heading, takes to appear |
2.5 seconds or less |
Interaction to Next Paint (INP) |
How quickly the page responds visually after a click, tap or key press |
200 milliseconds or less |
Cumulative Layout Shift (CLS) |
How much the layout jumps while loading |
0.1 or less |
Source: web.dev: Web Vitals
Each metric points to a different part of this page. LCP is mostly about the hero image, the fonts and the weight of the head of the document. INP is mostly about JavaScript: scripts, interactions and embeds. CLS is mostly about images and embeds that have no reserved space. The HTML and CSS side of the same ideas is explained in Runtime Loading Performance.
Images
Images are usually the heaviest part of a page, so they are the biggest opportunity. Four things matter: the pixel size that is uploaded, the format, the variants Webflow generates and when the browser fetches them. The mechanics of each are explained in Images and Assets; this section gives the performance checklist.
Upload the right size
Webflow generates smaller copies of an image for narrow screens, but it cannot make a 6000-pixel photograph light. Resize the original to the largest size the layout will ever show, at most twice the displayed width for high-density screens, before uploading. The Fernbrook hero is displayed at 1440 pixels wide at most, so the upload is 2400 pixels wide, not the 6000 pixels the camera produced.
Convert to AVIF or WebP
The conversion tool in the Assets panel changes JPEG, JPG and PNG assets to AVIF or WebP and updates every use of the asset on the canvas. Webflow’s own University course recommends it as a first step. The tool and its limits (no conversion of GIF and SVG, and no AVIF or WebP for the Open Graph image) are described on the images page.
Lazy and eager loading
The loading attribute of an image tells the browser when to fetch it. Since the update "New images set to lazy load by
default", images added to a site are lazy-loaded unless another setting is chosen. Existing images are not changed. The
rule that follows is simple and has one important exception.
-
Leave images below the fold lazy. The visitor may never scroll to them.
-
Set the first large image of every page to Eager. A lazy hero is fetched late, which delays LCP.
-
Lazy loading does not apply to CSS background images. A hero set as a background is fetched as soon as its rule matches, which is one reason to prefer an Image element with
object-fitover a background image when the picture is content.
The generated markup of the Fernbrook home page shows the pair.
<img src="https://cdn.prod.website-files.com/<site-id>/<file-id>_glasshouse-hero.jpg"
alt="The Fernbrook glasshouse at dawn" width="1920" height="1080"
loading="eager" sizes="100vw" class="image-hero">
<img src="https://cdn.prod.website-files.com/<site-id>/<file-id>_orchid.jpg"
alt="A purple orchid" width="640" height="640"
loading="lazy" class="image-plant-card">
The width and height attributes reserve the space before the file arrives, and that is what keeps CLS low. An image
whose dimensions are unknown pushes the text below it down when it loads.
Collection Lists repeat one image setting
A Collection List repeats a single Image element for every item, so the loading setting is shared. Fernbrook sets the plant-card image to Lazy. The featured-plants list on the home page shows six items, not sixty, because lazy loading saves bandwidth but not the cost of building a long document. See CMS page weight.
Fonts
A font is a file the browser must fetch before it can show text in that face. Three habits keep the cost low.
-
Load only the weights and styles the design uses. Each Google font variant or uploaded file is a separate download. Fernbrook uses Fraunces for headings in two weights and one sans-serif in two weights, and nothing else.
-
Prefer variable fonts or a small set of static files in WOFF2. One variable file can replace four static ones, but a large variable font with many axes can be heavier than the two weights actually needed.
-
Self-host when the privacy rules require it. Webflow’s article on Google Fonts warns that the integration sends the visitor’s IP address to Google, and recommends uploading the files as custom fonts. Self-hosting also removes a request to another origin.
Always keep a system-font fallback in the stack so text is readable while the file loads. Where fonts come from, and how to upload and register them, is covered in Typography and Fonts.
Minification and publishing options
Webflow compiles the HTML, CSS and JavaScript of a site and offers to minify each of them. Minification removes whitespace, comments and block delimiters without changing what the code does. The files get smaller and transfer faster, and the cost is that the published source is harder to read.
The options live in the publishing dropdown of the Designer, and in Site settings > Publishing > Advanced publishing options. They are:
| Option | Effect |
|---|---|
Minify HTML |
Removes whitespace from the generated markup. It can also remove the stray gaps between inline-block elements |
Minify CSS |
Compresses the site’s style sheet |
Minify JS |
Compresses Webflow’s own runtime script. Since the 2017 update "Minified JavaScript by default", this is the normal state of a site |
Async JavaScript |
Loads scripts without blocking rendering. Needs a paid Site plan or Workspace plan, and custom scripts may break with it |
Per page CSS |
Off by default, which produces one site-wide style sheet. When on, the CSS is split into a shared file and one file per page, which can shorten loading |
Secure frame headers |
Restricts where the site may be embedded in a frame. It is a security option, not a speed option |
Three cautions apply.
-
Async JavaScript can break custom code. A script that expects another to have run first may fail when the order is no longer guaranteed. Webflow suggests adding the
deferattribute to external script tags, or wrapping inline code in a handler for the windowloadevent. Test every page after turning the option on. -
Per page CSS can break styling on sites that use custom CSS code or a shared Library, because the rules that were once in one file are now split. Compare the pages before and after.
-
Minification applies to what Webflow generates. The University course states that Webflow does not minify the custom code you add, so a long inline script in an embed stays as long as you wrote it.
Tidying the project helps too. The Selectors panel and the Interactions panel can remove classes and animations that are connected to nothing, and Webflow deletes only items that are not used by any element or page, draft or live. A class or animation that should be kept can be applied to an element on a style guide page. Smaller style sheets and runtime data parse faster.
Custom code weight
Custom code is the part of performance that Webflow cannot do for you. The places where it goes, and their order, are explained in Custom Code in the Head, Footer and Embeds; the performance rules are these.
-
Scope it. Code in the site-wide head loads on every page. A script used only on the Events page belongs in that page’s own custom code, not in the site settings.
-
Place it deliberately. A script in the head blocks rendering unless it carries
deferorasync. A script before the end of the body does not block rendering of the content above it. -
Count the requests. Every external script is a separate connection. The University course advises limiting the number of scripts, and warns that even async scripts compete for bandwidth.
-
Do not trust remote files blindly. A script hosted by someone else can change or disappear, and your page changes with it. Pin a version in the URL, as the Fernbrook examples do, and review the script when the version changes.
-
Keep embeds small. An embed that builds a large DOM or injects its own style sheet costs time on every view.
A head snippet that loads a small library for the Events page only, deferred and pinned:
<script src="https://cdn.jsdelivr.net/npm/flatpickr@4.6.13/dist/flatpickr.min.js" defer></script>
Third-party scripts
Analytics, chat widgets, consent banners, map embeds and tag managers are the usual cause of a site that scores well on a lab test and feels slow in real use. They add network time, they run on the main thread and they often load further scripts of their own.
For each third-party script, the Fernbrook team asks four questions.
-
Is it needed on every page? The booking widget is needed on the Visit page, not on the Journal.
-
Can it wait? A chat widget can load after the page is interactive, for example after the first user input or a short delay, instead of at the start.
-
Does it reserve its space? A widget that appears and pushes content down raises CLS. Give its container a fixed size.
-
Is there a lighter alternative? A static map image with a link may do the work of an embedded map. A YouTube or Vimeo video can be shown as a poster image that loads the player only when clicked.
The last point is a general rule for video. The University course advises hosting large videos on a video platform, embedding them with the Custom element, lazy-loading videos that are off screen and showing a poster frame before the player loads, which also avoids layout shift. The Webflow-specific details of the Video elements are in Lottie, Spline, Rive and Video, and the privacy side of third-party scripts is in Third-Party Libraries and Scripts.
Interaction and animation cost
Animations are a frequent source of poor INP and of janky scrolling. The cost depends on what is animated and how many elements are involved.
-
Animate
transformandopacity. These can usually be handled by the browser’s compositor. Animatingwidth,height,topormarginforces layout on every frame. -
Target few elements. An interaction that applies to a class used on hundreds of elements does hundreds of times the work. Scope the trigger and the target.
-
Avoid animating large blurred or shadowed surfaces. Filters and big shadows are expensive to repaint.
-
Respect reduced motion. Visitors who ask for less motion should get a static version; this is also an accessibility requirement, covered in Accessibility.
-
Know which engine you use. Classic interactions are described in Classic Interactions and the GSAP-based engine in Interactions with GSAP; scroll effects specifically are in Scroll and Page Animations.
Fernbrook’s bloom reveal animates only opacity and a small vertical translation, and it targets the plant cards that are inside the first two screens, not every card on the page. The pinned seasonal timeline is used on one page only, which means the cost is paid only by visitors who go there.
Lottie, Spline, Rive and video
The media elements are the most expensive items a page can contain, because each one needs a file, a runtime or both.
| Element | Cost and the Fernbrook decision |
|---|---|
Lottie |
A JSON file and a player script. Small decorative loops are cheap; large files with many layers are not. The "growing seed" loop stays small and loads lazily |
Spline |
A runtime, a scene file and a WebGL context that renders while visible. The most expensive of the five. Used only on the Visit page, below the fold, with a still image as fallback |
Rive |
A runtime and a small |
Background Video |
A muted looping film that downloads at once. The rain film is short, compressed and has a poster image |
Video embed |
A third-party player. Shown as a poster that loads the player on click |
Lazy loading is the common remedy. For Webflow’s own elements the lazy setting is in the element settings; for a script
that you load yourself, the usual technique is an IntersectionObserver that adds the script when the container
approaches the viewport.
<div id="guide-mascot" style="min-height:240px"></div>
<script>
const target = document.getElementById("guide-mascot");
const observer = new IntersectionObserver((entries) => {
if (entries.some((entry) => entry.isIntersecting)) {
observer.disconnect();
const script = document.createElement("script");
script.src = "https://unpkg.com/@rive-app/canvas@2.26.0";
script.onload = () => { /* create the Rive instance here */ };
document.head.appendChild(script);
}
}, { rootMargin: "200px" });
observer.observe(target);
</script>
The min-height on the container reserves room so the page does not shift when the animation appears.
CMS page weight
The CMS affects speed in a way that is easy to miss: a page built from a collection is only as light as the list it renders.
-
Limit the items in a Collection List. A list shows up to a fixed number of items per list, and a long list creates a large document with many images. Show the first few and link to the full collection page. Pagination or a "load more" pattern spreads the cost, as described in Collection Lists.
-
Nest lists with care. A list inside a list multiplies the number of elements and requests. Fernbrook’s Plants page shows each plant’s companions as names only, without images.
-
Reuse image fields at the right size. A CMS image field is displayed at whatever size the template needs, so upload files sized for the largest use and let the variants do the rest.
-
Keep rich text lean. A long rich-text field with many embedded images behaves like a page full of uploads.
-
Keep limits in view. The limits of collections, items and lists, and what changes at scale, are in CMS Limits and Scaling.
Measuring
Optimising without measuring is guessing. Two kinds of data complement each other.
-
Field data comes from real visits and decides whether the site passes. The Chrome User Experience Report data shown in PageSpeed Insights is field data at the 75th percentile, split by mobile and desktop. It needs enough traffic.
-
Lab data comes from a controlled test, such as a Lighthouse run in PageSpeed Insights or in Chrome DevTools. It is repeatable, and it explains why a page is slow, but it is not the same as the experience of real visitors.
The routine for Fernbrook is the following.
-
Publish the change to the staging domain, so the test runs on the real hosting and not on the Designer canvas.
-
Test the home page, the Plants collection page and one plant page, on mobile first.
-
Read the opportunities and the diagnostics. Note the LCP element: if it is the hero image, check that it is eager, sized and converted.
-
Change one thing at a time and test again. A change that does not move a metric is not worth keeping.
-
After the live site has collected traffic, compare the field data against the thresholds above.
Webflow’s own analytics are described in Analyze and Optimize. Performance also affects search ranking, covered in SEO and AEO.
Source: web.dev: Web Vitals
A checklist for Fernbrook Gardens
| Area | Check |
|---|---|
Images |
Uploaded at no more than twice the displayed width; converted to AVIF or WebP; hero Eager, the rest Lazy; width and height set |
Fonts |
Two families, four files at most, WOFF2, with fallbacks; self-hosted where privacy requires |
Publishing |
HTML, CSS and JS minification on; per page CSS and async JavaScript tested on every page before keeping them |
Custom code |
Scoped to the page that needs it; |
Third parties |
Each justified and loaded as late as possible; containers have reserved size |
Interactions |
|
Media |
Spline and Rive lazy; videos shown as posters; rain film compressed |
CMS |
Few items per list; no heavy nested lists |
Measuring |
Field data against the thresholds; lab tests on staging after each change |