Why page builder sites are slow and what can actually be done
What a page builder actually sends to the browser, why a caching plugin does not fix it, and which steps genuinely help without a rebuild.
Marko Stančić9 minutes
Field note / Performance
A page builder site is slow because every section arrives in the browser as a stack of nested div elements, along with generated per-element CSS, a global stylesheet, an icon font and a jQuery dependency loaded on every page regardless of what is on it. A caching plugin doesn't fix that: caching removes the time PHP spends, not the bytes, the requests or the work the browser has to do on the main thread.
This is not a piece against Elementor. I've shipped builder sites myself, and part of the work in my index is exactly that: a template implemented properly, on schedule, on a budget where bespoke development wasn't an option. But when a client asks why the site is still slow on a phone after the third optimisation plugin, the answer is always in the same place: in what the builder has to output just to work at all.
What a builder actually adds to the page
A builder is two things at once. The editor you see, and the runtime the visitor gets. The editor is the reason you chose it. The runtime is the reason the site is slow.
First, the structure. So that every element can be moved, aligned and tuned per breakpoint, the builder has to wrap it. One heading is not one tag, it is a chain of wrappers, and only at the end of that chain sits the actual content.
// One heading, the way a builder ships it
<div class="elementor-section elementor-top-section">
<div class="elementor-container">
<div class="elementor-column elementor-col-100">
<div class="elementor-widget-wrap">
<div class="elementor-widget elementor-widget-heading">
<div class="elementor-widget-container">
<h2 class="elementor-heading-title">Our services</h2>
// The same heading, written by hand
<h2>Our services</h2>
Multiply that by the number of elements on a long homepage and the DOM is measured in thousands of nodes rather than hundreds. Every node is work: parsing, style calculation, every layout pass, every repaint.
Second, the CSS. The builder cannot know in advance which spacing, colour or shadow you set, so each setting becomes a rule bound to that element's ID, with separate variants for tablet and phone. Those rules go into a generated file per page, on top of a global stylesheet carrying the styles of every widget you might have used.
Third, dependencies that go everywhere. The builder frontend script depends on jQuery, so jQuery and jquery-migrate land on every page, including the ones with no interactive element at all. With them comes an icon font of several hundred glyphs because you used three icons, and a slider library because one section somewhere has a gallery.
Newer versions do offer real relief: assets loaded only for the widgets present on the page, flex containers instead of the old section and column model, leaner HTML output. They're worth turning on, and I come back to them further down. The base runtime is still there, because without it the page doesn't look the way it was drawn.
And here's the part that is hardest to explain: the excess cannot simply be deleted. The layout hangs off that structure. Remove a wrapper and the section falls apart. Remove the global stylesheet and the widgets lose the styles they inherit. The output is not a set of parts you pick from, it is one package taken whole.
Why a caching plugin does not fix it
Page caching does exactly one thing, and it does it well. The first visit runs through PHP and the database, the result is stored as finished HTML, and every visitor after that receives the file. Time to first byte drops, the server stops straining under traffic, and that's a real gain.
What caching does not touch is everything after that. The number of requests is the same. The number of bytes is the same. The CSS the browser parses, the JavaScript it executes and the DOM it computes are all the same. The origin got faster and the browser has exactly as much work as before.
Working principle
Caching changes who does the work, not how much of it there is. Everything the visitor waits for after the first byte is unchanged.
The more serious optimisation plugins do more than caching: they delay JavaScript until the first interaction, strip CSS the page doesn't use, inline critical CSS into the document head. That genuinely helps. You just have to know what's being paid for it.
Removing unused CSS is a heuristic. The tool looks at what's on the page at the moment of analysis, so the first things to break are the ones that appear conditionally: a popup, the contents of a second tab, the mobile menu, a cart message. Delaying JavaScript doesn't remove the work, it moves it to the visitor's first touch, so the lab score rises while the response to that first click stays the same or gets worse. Both tools are useful, and both work on the symptom rather than the cause.
How it shows up in LCP, CLS and INP
The three Core Web Vitals measure three different kinds of pain, and builder output touches each one in its own way. The standard thresholds for a “good” rating are 2.5 seconds for LCP, 0.1 for CLS and 200 milliseconds for INP.
LCP usually suffers because of the main image. In a builder the hero is often a background image set on a nested div, which means it lives in CSS rather than in HTML. The preload scanner doesn't see it until the style is parsed, it cannot be prioritised the way a real image can, and it is often lazy loaded as well. The most important image on the page starts last.
CLS comes from late arrivals. A web font that replaces the system font and shifts a whole block of text. An icon font that lands after the first paint. Entrance animations that move sections while the visitor scrolls. A slider that only gets its height once it initialises and pushes everything below it down.
INP is the most honest of the three, because it measures how long a visitor waits for a response when they actually click something. At that moment the main thread is running jQuery, the builder runtime and the scripts of every widget on the page. Opening the menu, switching a tab or submitting a form queues up behind that work.
Where you measure matters too. On a laptop with a fast connection a builder page can look fine. On a mid-range Android phone the same page shows all three at once, and that phone is what most of your customers are holding.
When a builder is the right call, and when it stops being one
A builder is the right answer more often than developers like to admit. If the client edits content weekly and doesn't want to call someone for a new section, if the layout is ordinary (hero, three columns, call to action, form), if the site is a company presence rather than the channel revenue flows through, and if the budget doesn't cover bespoke templates, then a cleanly implemented builder site beats a custom project that never shipped.
It stops being the right answer at a few recognisable moments. When the site becomes the main sales channel and every second of load time carries a cost. When the content no longer fits the template, so each new page is assembled by hand instead of coming out of a structure. When the plugins patching the builder outnumber the plugins carrying real features. When one design change means walking through every page to repeat it.
That last threshold is really a question of the content model rather than performance. The Innovation Properties Group platform holds four separate content structures, a property search filtered through the URL and a workspace calculator built into the site. A system like that is not assembled out of sections, it is modelled, and at that point a builder is no longer the tool for the job.
What can genuinely be done without a rebuild, in order of payoff
If a rebuild isn't on the table, and usually it isn't, this is the order in which the work pays off. Do one item, measure the same page, then move to the next.
Images, before anything else. Find the LCP candidate and make sure it is not lazy loaded, that it is in a modern format, that its dimensions are close to the size it is displayed at, and that the browser can see it in the HTML. If the widget allows a real image instead of a background, use it.
Fonts. Every weight and style is a separate file. Cut them to what is actually used, serve them from your own domain and set the loading behaviour. If the site uses six icons, the whole glyph library can go and inline SVG can replace it.
The builder's own options. Conditional asset loading per widget, leaner HTML output, element caching in the paid tier. Turn them on one at a time and review the site after each, because on older pages they can change the layout.
Third-party scripts. Chat, pixels, heatmap tools, embedded widgets. Often the single largest main-thread gain, unrelated to the builder, and no risk to the layout.
A plugin audit. Two sliders, two form plugins, a popup nobody uses, a gallery left over from the last redesign. Each injects its own CSS and JS into every page. Deleting a feature is always faster than minifying its code.
Caching, a CDN and decent hosting. This is where caching belongs, now that you know what to expect from it: a lower TTFB and a stable server under traffic, not a repair of what happens in the browser.
The page itself. An overlong homepage is a content problem and a technical one at the same time. What nobody scrolls to does not need to exist.
The fastest optimisation is deleting what is already on the page, not adding one more plugin that hides it.
Where the ceiling is, and when a rebuild pays
All of that has an end. The wrapper structure, the generated CSS and the builder runtime are a floor you can't get under without removing the builder. On desktop, with decent hosting, a cleaned-up builder page can land in the good range. On a mid-range phone the ceiling shows, and that's the moment to tell the client this route has gone as far as it goes.
When the ceiling really is too low, the way out doesn't have to be all or nothing. On almost every site two or three templates carry most of the traffic: the homepage, some listing, and a service or product page. Those are worth writing natively, through custom WordPress development, while the rest of the content stays on the builder until its turn comes. A migration in steps is cheaper and less risky than a large redesign, and the gain lands where it is measured.
A builder site can be fast enough. The mistake is not choosing one, it is expecting it to deliver what a hand-written template delivers, and spending the budget on plugins that promise it will.
The company paperwork, the store pages and the checkout details a Serbian WooCommerce shop needs in place before card payments are approved and go live.
8 min read
Apply the thinking
Let's examine the real constraint
If performance, architecture or maintainability is slowing the product down, bring the evidence. We can define what should change first.
Field note / Performance
A page builder site is slow because every section arrives in the browser as a stack of nested div elements, along with generated per-element CSS, a global stylesheet, an icon font and a jQuery dependency loaded on every page regardless of what is on it. A caching plugin doesn't fix that: caching removes the time PHP spends, not the bytes, the requests or the work the browser has to do on the main thread.
This is not a piece against Elementor. I've shipped builder sites myself, and part of the work in my index is exactly that: a template implemented properly, on schedule, on a budget where bespoke development wasn't an option. But when a client asks why the site is still slow on a phone after the third optimisation plugin, the answer is always in the same place: in what the builder has to output just to work at all.
What a builder actually adds to the page
A builder is two things at once. The editor you see, and the runtime the visitor gets. The editor is the reason you chose it. The runtime is the reason the site is slow.
First, the structure. So that every element can be moved, aligned and tuned per breakpoint, the builder has to wrap it. One heading is not one tag, it is a chain of wrappers, and only at the end of that chain sits the actual content.
Multiply that by the number of elements on a long homepage and the DOM is measured in thousands of nodes rather than hundreds. Every node is work: parsing, style calculation, every layout pass, every repaint.
Second, the CSS. The builder cannot know in advance which spacing, colour or shadow you set, so each setting becomes a rule bound to that element's ID, with separate variants for tablet and phone. Those rules go into a generated file per page, on top of a global stylesheet carrying the styles of every widget you might have used.
Third, dependencies that go everywhere. The builder frontend script depends on jQuery, so jQuery and jquery-migrate land on every page, including the ones with no interactive element at all. With them comes an icon font of several hundred glyphs because you used three icons, and a slider library because one section somewhere has a gallery.
Newer versions do offer real relief: assets loaded only for the widgets present on the page, flex containers instead of the old section and column model, leaner HTML output. They're worth turning on, and I come back to them further down. The base runtime is still there, because without it the page doesn't look the way it was drawn.
And here's the part that is hardest to explain: the excess cannot simply be deleted. The layout hangs off that structure. Remove a wrapper and the section falls apart. Remove the global stylesheet and the widgets lose the styles they inherit. The output is not a set of parts you pick from, it is one package taken whole.
Why a caching plugin does not fix it
Page caching does exactly one thing, and it does it well. The first visit runs through PHP and the database, the result is stored as finished HTML, and every visitor after that receives the file. Time to first byte drops, the server stops straining under traffic, and that's a real gain.
What caching does not touch is everything after that. The number of requests is the same. The number of bytes is the same. The CSS the browser parses, the JavaScript it executes and the DOM it computes are all the same. The origin got faster and the browser has exactly as much work as before.
Caching changes who does the work, not how much of it there is. Everything the visitor waits for after the first byte is unchanged.
The more serious optimisation plugins do more than caching: they delay JavaScript until the first interaction, strip CSS the page doesn't use, inline critical CSS into the document head. That genuinely helps. You just have to know what's being paid for it.
Removing unused CSS is a heuristic. The tool looks at what's on the page at the moment of analysis, so the first things to break are the ones that appear conditionally: a popup, the contents of a second tab, the mobile menu, a cart message. Delaying JavaScript doesn't remove the work, it moves it to the visitor's first touch, so the lab score rises while the response to that first click stays the same or gets worse. Both tools are useful, and both work on the symptom rather than the cause.
How it shows up in LCP, CLS and INP
The three Core Web Vitals measure three different kinds of pain, and builder output touches each one in its own way. The standard thresholds for a “good” rating are 2.5 seconds for LCP, 0.1 for CLS and 200 milliseconds for INP.
LCP usually suffers because of the main image. In a builder the hero is often a background image set on a nested div, which means it lives in CSS rather than in HTML. The preload scanner doesn't see it until the style is parsed, it cannot be prioritised the way a real image can, and it is often lazy loaded as well. The most important image on the page starts last.
CLS comes from late arrivals. A web font that replaces the system font and shifts a whole block of text. An icon font that lands after the first paint. Entrance animations that move sections while the visitor scrolls. A slider that only gets its height once it initialises and pushes everything below it down.
INP is the most honest of the three, because it measures how long a visitor waits for a response when they actually click something. At that moment the main thread is running jQuery, the builder runtime and the scripts of every widget on the page. Opening the menu, switching a tab or submitting a form queues up behind that work.
Where you measure matters too. On a laptop with a fast connection a builder page can look fine. On a mid-range Android phone the same page shows all three at once, and that phone is what most of your customers are holding.
When a builder is the right call, and when it stops being one
A builder is the right answer more often than developers like to admit. If the client edits content weekly and doesn't want to call someone for a new section, if the layout is ordinary (hero, three columns, call to action, form), if the site is a company presence rather than the channel revenue flows through, and if the budget doesn't cover bespoke templates, then a cleanly implemented builder site beats a custom project that never shipped.
It stops being the right answer at a few recognisable moments. When the site becomes the main sales channel and every second of load time carries a cost. When the content no longer fits the template, so each new page is assembled by hand instead of coming out of a structure. When the plugins patching the builder outnumber the plugins carrying real features. When one design change means walking through every page to repeat it.
That last threshold is really a question of the content model rather than performance. The Innovation Properties Group platform holds four separate content structures, a property search filtered through the URL and a workspace calculator built into the site. A system like that is not assembled out of sections, it is modelled, and at that point a builder is no longer the tool for the job.
What can genuinely be done without a rebuild, in order of payoff
If a rebuild isn't on the table, and usually it isn't, this is the order in which the work pays off. Do one item, measure the same page, then move to the next.
Where the ceiling is, and when a rebuild pays
All of that has an end. The wrapper structure, the generated CSS and the builder runtime are a floor you can't get under without removing the builder. On desktop, with decent hosting, a cleaned-up builder page can land in the good range. On a mid-range phone the ceiling shows, and that's the moment to tell the client this route has gone as far as it goes.
When the ceiling really is too low, the way out doesn't have to be all or nothing. On almost every site two or three templates carry most of the traffic: the homepage, some listing, and a service or product page. Those are worth writing natively, through custom WordPress development, while the rest of the content stays on the builder until its turn comes. A migration in steps is cheaper and less risky than a large redesign, and the gain lands where it is measured.
A builder site can be fast enough. The mistake is not choosing one, it is expecting it to deliver what a hand-written template delivers, and spending the budget on plugins that promise it will.