Performance

Why page-builder sites often get heavy over time

Why page-builder sites often accumulate runtime weight through generic layout systems, plugins, animations, and third-party dependencies over time.

The slowest part of many business websites is not the server. It is the amount of general-purpose machinery the browser is asked to run. Page builders are designed to support thousands of layouts and editing choices. That flexibility is valuable for teams that need visual editing. It also means the delivered page often contains code for capabilities the page is not using.

We build differently because most of our clients do not need an infinite page editor. They need a finite site that performs a business job.

General-purpose systems pay for general-purpose flexibility

A page builder has to be ready for columns, nested columns, sliders, tabs, accordions, popups, animation presets, responsive overrides, dynamic blocks, widgets, theme integrations, and plugin hooks. A custom page only has to support the components that exist on that site. That changes the baseline.

Instead of loading a generic layout engine and then configuring it into the desired shape, we write the shape directly in React and CSS.

Performance problems compound

One extra script rarely destroys a site by itself. The problem is accumulation. A builder adds its runtime. A theme adds another layer. A form plugin adds scripts and styles. A review widget adds more. An animation plugin adds observers and event listeners. Analytics and advertising tags arrive after that.

Each tool can be defensible in isolation. Together they create a page where the visitor downloads, parses, and executes a substantial application just to read a service description and click a phone number.

Our repos show the opposite pattern

Across our Next.js sites, the bulk of the page is rendered on the server or generated ahead of time. Interactive behavior is kept narrow. A gallery owns its keyboard listeners. A navigation effect owns a small passive scroll listener. A gated resource owns its dialog state. Most copy, image sections, service grids, articles, and location content do not become browser-side application state.

This is why performance work often starts at architecture rather than optimization. We are not asking, "How do we make 500 KB of client code execute faster?" We are asking, "Why are we sending 500 KB of client code at all?"

CSS can do more than people give it credit for

Simple motion, responsive layout, sticky behavior, visual states, and spacing systems often do not need JavaScript. One of our codebases uses CSS media queries to disable reveal animation on touch-first devices because mobile browser chrome resizing caused compositing glitches. The content remains visible and correct. The decorative effect is what gets dropped.

That is the kind of tradeoff we prefer. The page does not owe the animation anything.

Browser-native behavior is usually cheaper

Native links know how to navigate. Native buttons know how to focus. Native details elements can disclose content. CSS can animate many visual properties. The browser has built-in scrolling and responsive layout systems. We use JavaScript when it adds a behavior the platform does not already provide well enough.

The more work we can leave to native browser primitives, the less application code we have to own and the less code the visitor has to execute.

Page builders can still be the right choice

A marketing department that needs daily visual editing by nondevelopers may decide the runtime cost is worth the workflow flexibility. That is a real business decision. Our clients often have a different operating model. They want us to manage the site, improve search, add content, and maintain the implementation.

In that case, shipping an entire visual editor to every visitor so the internal team could theoretically drag a block is hard to justify.

The hidden cost is maintenance too

Generic systems also create dependency chains. A theme update may affect the builder. A builder update may affect an add-on pack. A plugin update may change markup. A performance plugin may cache around all of them. Custom code has dependencies too, but the dependency graph is usually more visible. The site code says what it uses.

When a feature is not needed, we can remove the feature rather than disable a plugin and hope its assets stop loading.

Why our performance advantage can look boring

There is no single trick. It is a collection of unglamorous decisions:

  • static generation where content is stable
  • server-rendered HTML
  • narrow client components
  • responsive images
  • controlled font loading
  • fewer third-party scripts
  • local assets
  • CSS instead of runtime animation where practical
  • no database when the site does not need one
  • no CMS runtime when the publishing workflow does not need one

A site built that way often starts closer to the performance target. That is more durable than chasing a score after the architecture is already heavy.

From explanation to proof

Where this connects to the work

The performance library explains why our technical scores tend to be unusually strong without treating the score itself as the product.