Building for Performance Without Sacrificing Beauty
Journal/Engineering

Building for Performance Without Sacrificing Beauty

Maksym Bondarenko
Maksym BondarenkoCTO & Co-Founder
29 May 20269 min read

The false choice between fast and beautiful is one of the most persistent myths in web development. Here is how we engineer experiences that are both.

When clients come to Obsidian Fern, they often arrive with a belief rooted in painful past experience: that beautiful, animation-rich interfaces are necessarily slow. That choosing craft means accepting compromise on Core Web Vitals. After years of proving the opposite, I want to share the architectural decisions that allow us to build interfaces that score 95+ on Lighthouse while delivering the kind of motion and depth that makes users stop and look twice.

Start with the Rendering Budget

Every animation, every gradient, every blur filter has a cost. The mistake most teams make is not thinking about the rendering budget until they have already spent it. We start every project by defining a performance contract: target LCP, CLS, and INP numbers agreed upon before a single component is built. This changes how we make decisions. When a designer proposes a backdrop-filter blur on a card that appears in a list of 50 items, we can immediately model the cost and find alternatives.

Performance is a design decision. It should be made by designers and engineers together, at the beginning, not retrofitted by engineers at the end.

The CSS-First Approach to Motion

The majority of our animations run on CSS transforms and opacity — properties that trigger compositing rather than layout or paint. We reach for JavaScript animation libraries only when we need physics-based motion or gesture-driven interactions that CSS simply cannot express. This discipline alone eliminates the most common performance bottlenecks we see in client codebases.

  • Animate only transform and opacity properties whenever possible
  • Use will-change sparingly and only on elements actively animating
  • Prefer CSS @keyframes over JS for scroll-independent animations
  • Lazy-load heavy visual components below the fold
  • Implement intersection-observer driven reveals instead of blanket animations
  • Audit your third-party scripts — they are often the silent killers

The most important shift is cultural. At Obsidian Fern, performance is not an engineering constraint imposed on design — it is a shared value. When our designers propose a motion concept, they are already thinking about frame rates. When our engineers review a component, they are measuring rendering cost. That shared language is what allows us to ship things that are genuinely both.