Skip to main content
React

Fast Marketing Site for a Software House

A marketing site fast enough to rank for the services it sells

At a glance

Timeline3 months
Team2 developers
StackReact · TypeScript · Tailwind CSS · Node.js · Express · Framer Motion

The problem

A marketing site for a services business has one job: get found for the work it sells, then load fast enough that the visitor stays. Heavy hero animation and unoptimised imagery are the usual reason it fails at both — the visuals arrive late, Core Web Vitals drop, and the pages that should rank never do. The design brief here was animation-heavy and fixed, so cutting the motion was not an available answer.

The approach

Four decisions carried the build. Motion stayed, but every animation was restricted to transform and opacity — the two properties a browser can composite on the GPU without triggering layout or paint — and scroll-linked effects check the OS reduced-motion setting rather than assuming everyone wants them. Per-page title, description, canonical, Open Graph tags and JSON-LD are emitted at build time instead of injected after hydration, so crawlers and AI answer engines read the real content in the initial HTML. Images ship in modern formats with explicit width and height so nothing shifts as they load, with the hero preloaded and everything below the fold lazy. Contact submissions post to a small Express endpoint rather than a third-party form service, which keeps enquiry data on infrastructure the client controls.

The hard part

Keeping the motion was the expensive choice, and it was the right one. Framer Motion is a runtime animation library shipped to every visitor, and on a marketing site the whole argument is about bytes and main-thread time. Hand-rolling the equivalent spring physics in CSS would have shipped less JavaScript — but the spec had staggered reveals, scroll-linked parallax and transitions between routes, and reproducing those by hand would have cost more in subtle bugs than it saved in kilobytes. The compromise was to constrain what the library is allowed to touch. Every animated property is transform or opacity, so the browser composites on the GPU and never runs layout or paint for a frame of motion. Anything that would have animated width, height, top or box-shadow was rebuilt as a transform, and the few effects that could not be expressed that way were cut rather than special-cased. What it costs: the library still sits in the bundle on pages that barely animate, and the honest fix is route-level code splitting so a text-heavy page does not pay for the homepage's hero. Motion also has to be tested twice — once normally and once with reduced motion enabled — because a scroll-linked reveal that silently no-ops leaves the content invisible, which is a broken page rather than an accessible one.

What I'd do differently

The Express endpoint behind the contact form is one more service for someone to keep alive, for what amounts to a handful of requests a day. I would move it to a serverless function now — the same control over where enquiry data goes, with nothing to restart at 2am. I would also split the animation library out of the routes that barely use it, rather than treating the bundle as one decision made once at the start.

Stack

React
TypeScript
Tailwind CSS
Node.js
Express
Framer Motion

Work like this is quoted under web development services, with fixed prices agreed before anything starts.

Related: what a custom web application costs · how to choose a web development company

Built by Muhammad Mubashar Shahzad — React & MERN developer, WebDevStudio.