The Fastest Site in the Tour de France – CSS Wizardry


Written by on CSS Wizardry.

Table of Contents
  1. The Teams and Bikes of the 2025 Tour de France
  2. The Fastest Bike Sites in the 2025 Tour de France
  3. Deeper Analysis
    1. 🥇 Merida
    2. 🥈 Factor
    3. 🥉 Giant
    4. Trek
    5. Orbea
    6. Ridley
  4. Patterns and Insights
  5. The Fastest Team Sites in the 2025 Tour de France
  6. Appendix
    1. Credits and Inspiration
    2. Methodology
    3. WebPageTest URLs and Scripts

Which bike brand raced ahead in the browser as well as the bunch?

Today, the 112th edition of the Tour de
France came to a close. Wout van
Aert won the final stage in Paris,
and Tadej Pogačar,
predictably, won the overall title, making it his fourth time taking the
maillot jaune.

I’m a huge cycling nerd, and the Tour de France is the pinnacle of the sport.
Three weeks of racing—21 stages—covering 3,338.8 kilometers of terrain, it
really is a marathon and not a sprint.

But that isn’t to say that speed isn’t important! Cycling is a sport obsessed
with aerodynamics, weight savings, and marginal gains. Bike manufacturers obsess
over every gram shaved or watt saved. Cycling is the perfect sport for the
performance engineer because things can always be measured, and they can always
be improved.

And while most of the success undoubtedly lies on the shoulders of the athletes,
as a bike manufacturer, having the lightest or fastest bike puts you in a much
stronger position on race day. And indeed, this leads to some fairly outlandish
statements:

Nothing is faster than the Tarmac SL8 […] it’s more than the fastest Tarmac
ever – it’s the world’s fastest race bike.
— Specialized

Or:

Having a leading high-tech wind tunnel on-site, unique for a cycling brand,
enables us to build the fastest bikes in the world.
— Ridley

Bold claims, but how do they stack up in the browser? For an industry utterly
obsessed with speed, how does that translate to its online presence? Every
individual in the peloton wants to be the fastest rider, and every bike
manufacturer that sponsors them claims to have the fastest bike, but who has
the fastest website?

I took a look at the sites of every bike manufacturer that has a presence in
2025’s Tour (all 21 of them) and ran the numbers. My question: does a bike
brand’s focus on web performance predict their performance on race day?

The results are in…

The Teams and Bikes of the 2025 Tour de France

In total, 23 teams are sponsored by 21
different bike brands. All teams that compete in the Tour de France are
WorldTeam status, except for
selected ProTeams (marked below)
who are invited to compete in a similar manner to wild cards in tennis.

See full list…

What I want to work out is, of those teams, which of their bike manufacturers
put as much effort into web performance as they do race-day performance?

The Fastest Bike Sites in the 2025 Tour de France

To rank the bike brands, I used my own proprietary CrRRUX
score (higher is
better). CrRRUX is specifically designed to compare the Core Web
Vitals data of a finite cohort of origins,
placing them proportionally on a 0–1 scale. Given just how close a lot of the
sites seem to land, I had to push CrRRUX to four decimal places.

Core Web Vitals, for folk who haven’t come across them before, are three web
performance metrics that are designed to measure site-speed in a way that
reflects how they actually feel. Human-centric signs of fast or slow:

  • Largest Contentful Paint (LCP): How fast did the page and its content
    load?
  • Interaction to Next Paint (INP): How quickly did the page respond to user
    input?
  • Cumulative Layout Shift (CLS): Did elements jump around the page as it was
    loading?

It is around these three metrics that this meta analysis is conducted.

The headline news is right here. According to their relative CrRRUX score, here
are the bike brands from fastest to slowest:

Rank Brand Sponsors of… CrRRUX Score
🥇 Merida Bahrain Victorious 1.0000
🥈 Factor Israel–Premier Tech (ProTeam) 0.9986
🥉 Giant Jayco–AlUla 0.9985
4 LOOK Cofidis 0.9967
5 Enve Team TotalEnergies (ProTeam) 0.9963
6 Cervélo Team Visma | Lease a Bike 0.9942
7 Van Rysel Decathlon AG2R La Mondiale Team 0.9895
8 Canyon Alpecin–Deceuninck, Movistar Team 0.9879
9 BMC Tudor Pro Cycling Team (ProTeam) 0.9876
10 Pinarello Ineos Grenadiers 0.9855
11 Lapierre Team Picnic PostNL 0.7997
12 Cannondale EF Education–EasyPost 0.7941
13 Specialized Red Bull–BORA–hansgrohe, Soudal Quick-Step 0.7919
14 CUBE Intermarché–Wanty 0.7878
15 Bianchi Arkéa–B&B Hotels 0.7657
16 XDS XDS Astana Team 0.7492
17 Colnago UAE Team Emirates–XRG 0.6023
18 Wilier Groupama–FDJ 0.5961
19 Trek Lidl–Trek 0.4581
20 Orbea Lotto (ProTeam) 0.2292
21 Ridley Uno–X Mobility (ProTeam) 0.0000

Huge congratulations to our podium!

  1. Merida, sponsors of Bahrain Victorious
  2. Factor, sponsors of Israel–Premier Tech
  3. Giant, sponsors of Jayco AlUla

And the Core Web Vitals scores for each brand (at the time of writing):

Brand LCP (ms) INP (ms) CLS
Merida 1,188 77 0.00
Factor 1,248 119 0.00
Giant 1,298 105 0.01
LOOK 1,486 112 0.00
Enve 1,552 85 0.01
Cervélo 1,552 137 0.01
Van Rysel 1,893 131 0.00
Canyon 1,394 145 0.06
BMC 2,069 83 0.00
Pinarello 1,415 83 0.09
Lapierre 2,215 144 0.13
Cannondale 2,704 121 0.07
Specialized 2,078 308 0.05
CUBE 2,179 110 0.19
Bianchi 3,381 109 0.01
XDS 3,651 135 0.01
Colnago 3,410 214 0.08
Wilier 3,150 266 0.10
Trek 2,869 210 0.15
Orbea 5,050 138 0.41
Ridley 4,694 1,121 0.61

When we look at the raw data with some colour coding, a fascinating pattern
emerges: a lot of sites performed incredibly well. The fastest 10 pass all three
Core Web Vitals. The general state of web performance in the cycling industry
seems very healthy!

Spreadsheet ranking 21 major bike brands by web performance metrics, with a focus on CrRRUX Score, a composite metric representing Core Web Vitals quality. The best-performing sites include Merida, Factor, Giant, Look, and Enve, all scoring near-perfect 1.0000 CrRRUX values. In contrast, Ridley and Orbea score lowest, with Ridley’s CrRRUX at 0.0000 and Orbea at 0.2292. The table includes LCP, INP, CLS, weighted and aggregate scores, highlighting significant variation in real-world user experience across brands’ official websites.
A visual comparison using CrRRUX highlights interesting insights.

A clear cliff appears between rows 12 (Lapierre) and 13 (Pinarello) when sites
suddenly move from failing one or all of the Core Web Vitals to overwhelmingly
passing all three. This is measured by the Ordinal score—around which CrRRUX
is heavily
weighted—and
means any site that only passes, say, two Core Web Vitals cannot rank above any
site that passes all three.

The fact we go from high-70s to high-90s in one leap isn’t something one
typically observes in these kinds of comparison. There’s no deep or hidden
meaning there—it’s just a very interesting thing to see.

Deeper Analysis

I decided to look further into what made the top three stand out (and the bottom
three come over the line with the
gruppetto), so I did some
individual analysis of this subset of six bike brands:

Rank Brand Sponsors of… CrRRUX Score
🥇 Merida Bahrain Victorious 1.0000
🥈 Factor Israel–Premier Tech (ProTeam) 0.9986
🥉 Giant Jayco–AlUla 0.9985
19 Trek Lidl–Trek 0.4581
20 Orbea Lotto (ProTeam) 0.2292
21 Ridley Uno–X Mobility (ProTeam) 0.0000

I tested the homepage and the product page for the specific bike the teams are
likely to use in a race. This is because the UCI mandates that all bikes used by
race teams must either be already available for purchase by the general public,
or must be available to them within 12 months of the race:

Equipment shall be of a type that is sold for use by anyone practising cycling
as a sport. Any equipment in development phase and not yet available for sale
(prototype) must be subject of an authorization request to the UCI Equipment
Unit before its use. Authorization will be granted only for equipment which is
in the final stage of development and for which commercialization will take
place no later than 12 months after first use in competition.
Article 1.3.006

Crucially, that means any of the bikes raced and sites tested are subject to use
by real people. This isn’t a theoretical exercise.

What follows is an incredibly high-level look at how each site performs and
suggested areas for improvement. Subscribers will get to see much more
in-depth analysis.

Subscribe Now


🥇 Merida

Merida REACTO TEAM aero road bike with deep-section wheels and team Bahrain Victorious livery, displayed on a white product background with detailed geometry, specs, and download links—ideal for elite racers and enthusiasts.
Merida REACTO TEAM

Founded in 1972, Merida is a Taiwan-based design and manufacture operation.
Interestingly, for the first 16 years of its life, Merida only produced bikes
for other brands, and only launched its own line of cycles in 1988.

Fascinatingly, Merida is fast in spite of its site, not because of it. Some
very quick-fire analysis…

General Findings with Merida

LCP (ms) INP (ms) CLS
1,188 77 0.00

Despite utilising Vue.js 2.1.10 in places, Merida’s site is a pretty
traditional—dare I say old school—MPA. I can’t work out the exact stack too
quickly, but it sticks to ‘classic’ CSS and JS, and age-old advice like
styles at the top; scripts at the bottom. This reminds of the
McMaster–Carr site that did the rounds a few years ago: websites are fast
until developers start messing around with them.

  • They host all of their critical path resources on a third-party
    origin!

    • This adds a lot of network overhead.
  • They don’t have a proper font stack in place (font-family: 'Uni Sans';) so
    they get a FOUT showing Times New Roman.

  • Aggressive cache-control: no-store, no-cache, must-revalidate means 200s
    on every request.

    • They could drop it down to just no-store,
      private

      if they really do want to forgo HTTP
      caching on every single page view,
      or a more liberal no-cache coupled with either Etag or Last-Modified
      if they wanted to ensure freshness but also make use of cache after an
      immediate 304.
  • They cache their static assets for six months but don’t attach revalidation
    headers.

    • Based on Age headers (I saw one at 1990959 seconds!), these files don’t
      change very often at all.
  • Their URLs work both with and without a trailing / but they have no
    rel=canonicals set up.

Merida’s Homepage Highlights

Their LCP image is entry 34. Note the 250ms connection overhead added to the critical path at entry 2—we’d like to avoid this wherever possible.

Issues specific to the homepage:

  • Their LCP is
    a background-image
    which is never great without some additional help from preload.
  • Not only is the image late-discovered, it suffers a large Element Render
    Delay
    while the main thread is busy with heavy Scripting and Rendering tasks.

Merida’s Product Details Page Insights

It might have a .tif extension, but their LCP image is
actually a image/jpeg content-type.

And issues specific to their product details page:

  • Their LCP image comes in at a weighty 379.2KB! That’s pretty large.
    • They don’t employ any form of responsive images, either. This means that
      even on the smallest screens we still fetch a 2,500px image.
  • Their LCP image is fetched with Medium priority; we’d rather that be High.
    • Although because it’s an , it at least hits the network before their
      JS, unlike in the homepage.
  • Again, we see a large Element Render Delay while we wait on the main thread.

Takeaways

Merida is a great example of simply not getting in the way of the browser. Sure,
they have room for improvement, but even then they are still coming in at number
one. By not throwing every npm package in the world at the site—by simply
betting on
boring—they’ve
sustained class-leading performance. That’s more than can be said for most
‘modern’ stacks.

Chapeaux, Merida!

Subscribe
now to see detailed analysis of Merida’s website.


🥈 Factor

Close-up of the Factor OSTRO VAM road bike frame showcasing its aerodynamic design and iridescent branding. Displayed on a clean, minimal product page, ideal for performance-focused cyclists researching high-end race bikes.
Factor OSTRO VAM

Founded in 2007 in Norfolk, England, Factor Bikes began life as an offshoot of
motorsport engineering firm bf1systems. The company’s early projects included
high-performance prototypes before it launched its first commercial bike, the
Factor ONE, in 2013.

General Findings with Factor

LCP (ms) INP (ms) CLS
1,248 119 0.00

Our second fastest site, Factor, is built on Shopify’s headless Hydrogen
storefront and deployed onto their Oxygen.

  • Factor is built as a Single Page App with soft navigations.
  • I’ve never see tags so tiny! Only nine items in the source HTML.
  • Unfortunately, they do have a number of assets on third-party origins.
    Persistently across the site, that is a stylesheet on the unpkg.com CDN.

    • This is easily remedied by pulling the file onto first party infrastructure.
    • I must have said this a million times by now, but please, self-host your
      static assets!
  • No cache-control headers means HTML responses can’t be accurately
    revalidated, always returning a 200 when it could have been a 304.

    • The absence of a cache-control header is not enough to count as a caching
      strategy.
    • However, as everything else is so well cached, including LCP images,
      repeat-view LCP metrics are substantially faster.
  • We’re also missing proprietary Oxygen-Cache-Control headers, meaning we
    can’t get edge cache hits either.
  • LCP images on both pages are both background-images that are
    late-discovered.

    • They also live on yet another third-party origin that is not
      preconnected—Contentful’s images.ctfassets.net.

Factor’s Homepage Highlights

Their LCP (42) is weirdly late-discovered.
  • The homepage compounds the unpkg.com problem by also making requests to the
    first/third-party cdn.shopify.com origin.

    • It would be wise to add Link HTTP response headers to preconnect this
      origin. Cloudflare, who Factor are fronted by, can then upgrade these to
      103 Early Hints for them.
  • The homepage LCP image is very late discovered (entry 42 at 1.7s), and on
    a different origin, as discussed, but it’s also enormous! 1,235.1KB of WebP.

    • There is some synchronous JS visible at around 1.7s on line 1 that must be
      further blocking the discovery of the background-image.
    • To make matters worse, Contentful’s response heavily interleaves image bytes
      with less critical images, returning non-LCP resources (43–47) before our
      key candidate.

Factor’s Product Details Page Insights

It’s refreshing to see such a clean and overwhelmingly first-party
waterfall!

There really isn’t much different between the homepage and product detail pages.
In fact, there are more similarities.

  • Unfortunately, the LCP is a background-image once again.

Takeaways

This site is a remarkable exercise in restraint. No heavy-handed runtime, a very
considerate approach to third parties. A modern stack without any modern
baggage. I’m impressed, Factor!

Subscribe
now to see detailed analysis of Factor’s website.


🥉 Giant

Product page for the Giant Propel Advanced SL 0 RED aero road bike, featuring full carbon frame, deep-section wheels, and SRAM Red components. High-end build targeted at competitive riders seeking top-tier aerodynamics.
Giant Propel Advanced SL 0 (Red)

Established in 1972, Giant is a Taiwanese brand headquartered in Taichung.
Originally a manufacturer for other companies, Giant began producing bikes under
its own name in 1981 and has since grown into the world’s largest bicycle
manufacturer.

General Findings with Giant

LCP (ms) INP (ms) CLS
1,298 105 0.01

Giant took third place on our podium. It looks as though they make use of
Vue.js—or at least Vue Cart—but no obvious signs of a framework such as Nuxt.

  • Giant is built as a Multiple Page App. Or as we used to call them,
    websites.
  • No word of a lie, they have a spacer.gif!
  • Pages open three new connections: two to https://static.giant-bicycles.com
    and one to https://images2.giant-bicycles.com.

    • The static. origins are on the critical path.
  • They make use of old school, JS-based lazy loading.
  • They use unquoted attribute=value pairs like I do—nice.
  • Great restraint shown here—only a small number of resources loaded from the
    .

    • Non-critical CSS files are fetched asynchronously.
  • They’re making good use of font-display.

Giant’s Homepage Highlights

That very last request is their LCP candidate! That’s far too late.
  • They’re lazily loading their homepage LCP!
    • With JS, no less. Super slow. It’s the 84th request.
    • It’s getting requested after Facebook, Google Tag Manager, Google
      Analytics, and Klaviyo have been completely returned.
    • And they’re putting fetchpriority=high on there. Make your mind up!

Giant’s Product Details Page Insights

There’s no point fast-fetching your LCP if you’re going to wait so
long to paint it.
  • The LCP image is preloaded now, meaning the images2. connection is
    negotiated much earlier on PDPs.

    • This is why it’s now the sixth request as opposed to the 84th.
    • The preload needs fetchpriority=high
    • The killer here is the fact that we don’t put the LCP on the glass for
      a very, very long time.
    • In the screenshot above, we see our LCP image is on the device by about
      1.5s, but our LCP event doesn’t fire until approximately 7s (the dashed
      green line).
    • This eyewatering Element Render Delay is down to the fact that Giant move
      to a client-rendered architecture for their image gallery (and Add to
      Cart
      ) on PDPs.
  • Our repeat view has heavily cached assets, but as the LCP event is so runtime
    dependent, we get no customer-facing performance improvements.

Takeaways

With the Giant site, we’re in a place where looking at two pages in isolation
actually look quite bad—there are a couple of egregious decisions that put them
on the back foot. But looking at the site overall, they’re glowing. It would be
interesting to drill down into specific page- and template-types.

Subscribe
now to see detailed analysis of Giant’s website.


Trek

Trek Madone SLR 9 Gen 8 road bike displayed on a premium product page with race-ready features, OCLV carbon frame, aerodynamic shaping, and integrated cockpit. Designed in collaboration with pro riders for optimal speed and handling.
Trek Madone SLR 9 Gen 8

Founded in 1976 in Waterloo, Wisconsin, Trek was created with a mission to build
high-end bikes in the United States. It has since become a major global player,
with a strong focus on innovation and racing pedigree across road and mountain
disciplines.

General Findings with Trek

LCP (ms) INP (ms) CLS
2,869 210 0.15

Trek is a cycling powerhouse! One of the bigger brands in the peloton, how have
they found themselves toward the back of the pack? Trek use fully
client-rendered Vue.js on top of SAP Commerce Cloud, deployed on Azure and
fronted by Cloudflare.

  • Fully client-rendered Vue.js (without Nuxt, etc.).
  • They still force hard navigations, so every page view runs into a high boot-up
    cost—it runs as an MPA.
  • They have a silly redirect whereby their logo links to /us/en_US, but the
    resulting URL is actually /us/en_US/. This adds pure latency onto every
    homepage click.
  • Most pages don’t place-hold client rendered content very well at all,
    explaining their high CLS scores.

Trek’s Homepage Highlights

Client-side rendering spells disaster for this late-rendered LCP
image.
  • I haven’t included the full waterfall for any of the sites so far, but it’s
    worth noting that Trek’s homepage yielded 262 requests!
  • The homepage’s LCP (29) is actually fetched relatively quickly, despite being
    fully client-rendered.

    • And JS-lazy loaded once it arrives—wow!
    • This slow-path request for the LCP image got it onto the device by about
      five seconds, but we don’t display it until approximately 15 seconds!
  • The homepage seems to have its app-shell pretty well place-held as there is no
    CLS penalty.
  • Another very aggressive cache-control: no-cache, no-store, max-age=0,
    must-revalidate
    header means we get 200 responses on every subsequent
    visit.

    • Almost all other directives are redundant in the presence of no-store as
      if there is nothing to store, there is nothing to cache, nothing to expire,
      and nothing to revalidate. Still, it doesn’t do any harm to include them
      all.
  • INP scores are pushed up by a huge Recalculate Style event when opening the
    nav.

    • They’re reading style properties while also attempting to write them.
    • As just 2.9× CPU throttling, this event took an eyewatering 154ms!

Trek’s Product Details Page Insights

The story gets worse as key content is late-fetched via client-side
API calls.
  • Interestingly enough, the video on the PDP isn’t classed as the LCP
    candidate—it’s a piece of text that appears quite a lot earlier.

    • The PDP’s ‘obvious’ LCP candidate is a YouTube video loaded via an iframe.
      Both RUM and synthetic testing cannot detect iframe-originated LCP’s for
      privacy reasons, but CrUX, being part of Chrome, can. The upshot of this is
      that developers might wrongly assume that the site is much faster than it is
      if they are relying on Lighthouse, DevTools, WebPageTest, or anything other
      than CrUX.
  • The rest of the PDP’s LCP story is a bit of a car crash. As content loads on
    the client, the LCP candidate keeps on changing (all while CLS scores keep on
    increasing). Once the browser does settle on its LCP candidate, Trek fade it
    in! Chrome takes the end of the animation as its LCP timestamp, further
    exacerbating the issue.

    • The API response that contains the LCP content is the 148th
      request!
  • Product pages are not sufficiently place-held to safeguard CLS scores: the
    main app shell is empty, and oncoming content is not place-held either.

Takeaways

The Trek site going all in on client-side Vue has left it struggling to hit
decent paint timings. This coupled with particular page types not being
adequately place-held gives us the CSR double whammy of LCP and CLS penalties.
I can only imagine (or hope) Trek might have a rebuild or replatform on the
horizon—seeing fully-client rendered Vue is already something of a relic.

Subscribe
now to see detailed analysis of Trek’s website.


Orbea

Orbea ORCA AERO M10i Replica road bike in Lotto team colours, shown with integrated cockpit and deep rims. Customisable colour and size options highlighted on the page, reflecting Orbea’s focus on personalisation and performance.
Orca Aero M10i Replica

Founded in 1840 in the Basque Country of Spain, Orbea actually started out
making guns. It pivoted to bicycles in the 1930s and is now one of the oldest
bike manufacturers in the world, known for its sleek, performance-oriented
designs.

General Findings with Orbea

LCP (ms) INP (ms) CLS
5,050 138 0.41

Orbea is deployed as an MPA but uses Alpine.js for client-side templating. Other
than that, it’s quite difficult to see what stack they’re on.

  • Orbea is deployed as an MPA.
    • They suffer incredibly high TTFB.
    • And they also have an extremely aggressive no-store, no-cache,
      must-revalidate
      policy.
    • This means every page view is a back end-heavy trip to origin:
      cf-cache-status DYNAMIC.
  • They link to a lot of render-blocking resources, including third-party ones.
  • They use Typekit which contains an
    @import—a
    real killer.

    • It’s particularly harmful for Orbea as the bulk of their JavaScript is
      blocked behind it.
    • They’re attempting to use Typekit.load() but it’s undefined.
  • Their fallback font is very different to their custom font; different enough
    to almost go over 0.1 CLS on the homepage.
  • They seem to have the same rel=canonical issues as Merida.
  • They make sporadic use of font-display.

Orbea’s Homepage Highlights

Orbea’s JS-heavy and lazily-loaded homepage means late LCP for them.
  • They lazy load their LCP on the homepage.
    • The sheer amount of JS that runs beforehand means it’s discovered incredibly
      late—entry 89.
  • However they don’t lazy load images much further down the page.
    • They also omit alt and width and height attributes.
  • They fetched about 11.8MB of images.

Orbea’s Product Details Page Insights

More Element Render Delay issues, but for Trek this time.
  • The PDP introduces two new third party blocking origins.
    • One points at https://unpkg.com/tippy.js@6 which then 302s to
      /tippy.js@6.3.7/dist/tippy-bundle.umd.min.js.
    • This adds a whole round trip of latency to the critical path and is only
      cacheable for one minute.
  • They appear to be attempting a JS-based lazy loading strategy with data-src
    attributes but they also have a non-empty src that points to the mobile
    image anyway.

    • This means desktop will fetch the mobile image and, conditionally, the
      desktop image.
  • The PDP has two near (if not completely) identical carousels on it—more
    additional fetches.

    • JS hides one of the carousels, but not before incurring a severe layout
      shift.
  • You see those two colour swatch images in the screenshot above? The two
    bisected circles? They are both 822KB JPEGs.

Takeaways

It’s first byte times that are crippling Orbea. Setting even a modest max-age
(and allowing Cloudflare to serve cached HTML responses) would take the edge
off. Typekit and the way they’ve placed it cause them sever paint-timing issues.
Blocking on top of blocking on top of blocking. The double-carousel issue on the
PDP accounts almost exactly for their CLS scores. That would be a quick win for
them.

Subscribe
now to see detailed analysis of Orbea’s website.


Ridley

Ridley Noah FAST 3.0 Ultegra Di2 aero road bike product page showing the bike in purple colourway with integrated cables, aggressive aero tubing, and DT Swiss wheels. Aimed at serious road cyclists and racers.
Ridley Noah FAST 3.0

Established in 1997 in Belgium by Jochim Aerts, Ridley has built a reputation
around aerodynamic innovation and cobble-tough endurance bikes. Its roots in
Flemish cycling culture are unmistakable, and its bikes are a regular fixture in
the pro peloton.

General Findings with Ridley

LCP (ms) INP (ms) CLS
4,694 1,121 0.61
  • Ridley is built on Nuxt and is a soft-navigation SPA.
  • They fetch Google Maps in a blocking manner.
  • They also have a blocking tracking script on a separate origin which always
    causes a network request as it’s marked max-age=0.
  • Their LCP candidates live on separate asset domains.
  • The fallback font is so far from the web font that it causes severe layout
    shifts.
  • There are no caching headers whatsoever, which is inadvisable.
    • But as they do have an ETag header, 304s are possible.
  • Nuxt is doing that annoying pattern where it preloads a CSS file then
    immediately requests it with rel=stylesheet right after.

    • It’s not harmful, but it’s not helpful either, and ends up marking blocking
      requests as non-blocking which is misleading.
    • On the subject of preload, they’re preloading Google
      Fonts but also async-injecting it with
      JavaScript. Again, not harmful, but also not much point either.
  • The real killer for Ridley is a near-infinite requestAnimationFrame(). The
    whole time we have a page open, rAF() is in a non-stop repetition.

    • This is how we end up with a 1s+ INP score.
    • You can see this in the waterfalls below. It stops after about 20 seconds.
  • Interestingly, despite being visible much earlier, the actual LCP event in
    WebPageTest didn’t fire until the nonstop rAF() settles down briefly.
  • Thankfully, assets are fingerprinted and cached for
    a year.
  • Their Nuxt JS bundles are defined at the with both async and
    defer. In this scenario, async always
    wins.

    • async is an open invite for race conditions, so I can only assume their
      bundles have been designed to run independently (otherwise, expect lots of
      errors and bugs).

Ridley’s Homepage Highlights

A staggeringly large LCP image on line 23. That much dark purple is
bad news.
  • The LCP image is 1.4MB!
    • On slower connections, this is a killer.
    • It is in the HTML at least—they should stick fetchpriority=high on there.
  • The homepage ‘carousel’ is actually stacked one pane on top of the other
    rather than in a row like a traditional carousel.

    • This means that while the heavy images are downloading, we see loads of
      stacked text nodes which looks very broken.

Ridley’s Product Details Page Insights

Even modern image formats like AVIF can’t do much to help us here.
  • The LCP image is in the initial HTML as an , but missing
    fetchpriority=high.

    • They’re actually attempting to lazy load it! But thankfully also getting it
      wrong: lazy=true.
  • When you switch between different bike sizes, you get huge layout shifts.
  • We have more poorly optimised images.
    • 16MB of the 24MB transferred is image data.
  • The PDP’s HTML payload is gargantuan.
    • Almost 4MB decompressed—almost all of it is Nuxt state (window.__NUXT__).
  • We have an eyewatering 5MB of JS.
    • 12MB of the total 37MB uncompressed page bytes are JavaScript.
    • That’s not a typo.

Takeaways

Before we focus on the bad, Ridley’s new Noah 3.0 won its first ever race. And
at the Tour de France, no less. It also marked the first ever Tour stage win for
Uno-X Mobility, the team that ride Ridley’s bikes. That’s more of a win than any
Core Web Vitals, so congratulations are in order. Let’s take a moment.

But onto the job at hand. Ridley is struggling a lot with all three metrics. LCP
is hampered by already-high first-byte times, leaving only a 500ms budget to get
from TTFB to LCP. The majority of their lost time happens between FCP and
LCP—this is almost all lost to Element Render Delay. This may well be the
phenomenon observed above: the LCP event doesn’t fire until the main thread dies
down.

On the subject of the main thread, the constantly-firing
requestAnimationFrame() is dragging them into the very pits of INP—well over
one second! This isn’t because the main thread is necessarily blocked—rAF() is
relatively noninvasive and each one only lasts a small amount of time—but the
main thread is just kept so busy, it’s hard to sneak any user input in.

Note that while none of the tasks are long, there are thousands of them back-to-back. It literally is thousands in that screenshot.

Finally, because INP is so high, a lot of interactions take over 500ms which
then puts us outside of the 500ms grace period for CLS: hadRecentUserInput:
false
.

I honestly think just sorting out that requestAnimationFrame() would start to
take chunks out of the other metrics, too.

Subscribe
now to see detailed analysis of Ridley’s website.


Patterns and Insights

As a cycling enthusiast, perhaps the most surprising insight for me was that
most of the larger, wealthier, and most prestigious brands tend to appear in the
slower half of the cohort. Is this complacency? An Apple-esque arrogance? Who
knows.

Big brands aren’t always the best performers.

Several of the industry’s most recognisable names fall startlingly low on this
list. Trek, Orbea, and Specialized—brands with global reach and significant
marketing clout—rank 19th, 20th, and 13th
respectively. Their reputations far outpace their web performance.

High-end doesn’t always mean high CrUX scores.

Colnago (17th), Wilier (18th), and Bianchi
(15th) are all brands dripping with prestige and heritage (and the
price tags to match), but in terms of web performance, they’re clustered towards
the bottom of the group. This might suggest that legacy and luxury don’t always
translate into digital excellence—or perhaps that their customer base tolerates
slower experiences in exchange for reputation and perception.

The underdog story is online-first.

Merida and Factor might not be the first names fans think of when naming
top-tier race bikes, but they do top this table with near-perfect CrRRUX scores.
These brands show that operational excellence, modern manufacturing, and
attention to digital experience can co-exist without the century-old heritage.


The Fastest Team Sites in the 2025 Tour de France

As a bit of an added stretch goal, I decided to run the numbers for each of the
team sites to see if any patterns emerged. These are the CrRRUX scores for each
team site that raced the 2025 Tour de France:

  1. Team Picnic PostNL – 0.9999
  2. Bahrain Victorious – 0.9982
  3. Israel–Premier Tech – 0.9978
  4. Ineos Grenadiers – 0.9972
  5. Intermarché–Wanty – 0.9928
  6. Lotto – 0.9919
  7. UAE Team Emirates–XRG – 0.9895
  8. Uno–X Mobility – 0.9893
  9. Groupama–FDJ – 0.9892
  10. EF Education–EasyPost – 0.9888
  11. Arkéa–B&B Hotels – 0.9847
  12. Soudal Quick-Step – 0.9792
  13. Cofidis – 0.9761
  14. Team TotalEnergies – 0.9705
  15. XDS Astana Team – 0.9701
  16. Lidl–Trek – 0.9587
  17. Movistar Team – 0.9585
  18. Team Visma | Lease a Bike – 0.7959
  19. Tudor Pro Cycling Team – 0.7941
  20. Red Bull–BORA–hansgrohe – 0.7445
  21. Decathlon AG2R La Mondiale Team – 0.7175
  22. Alpecin–Deceuninck – 0.5588
  23. Jayco–AlUla – 0.5562
  1. Team Picnic PostNL, sponsored by Lapierre
  2. Bahrain Victorious, sponsored by Merida
  3. Israel–Premier Tech, sponsored by Factor

The fastest bike brand also supports a mid-ranked team.

Merida tops the CrRRUX rankings for manufacturers (1.0000) but sponsors Bahrain
Victorious—only 17th in the final Tour standings. The Bahrain
Victorious team site, however, is the second-fastest overall. It’s a rare
alignment: fast bike site, fast team site, middling result.

Factor and Israel–Premier Tech deliver on both fronts.

Factor comes second in the CrRRUX bike table (0.9986) and Israel–Premier Tech
ranks third among team sites (0.9978). This is one of only two pairings where
both bike and team site land in the top three for performance. Their Tour
placement? 18th. Fast site, slow legs.

Jayco–AlUla ride one of the fastest bike sites but have the slowest team site

Giant ranks third in the bike CrRRUX table (0.9985), but Jayco–AlUla come dead
last for team website performance (0.5562). Their Tour
finish—17th—sits toward the bottom. Perhaps the team should take some
performance tips from Giant’s developers?

Could we conclude that Merida and Factor and Bahrain Victorious and
Israel–Premier Tech care about performance in all aspects of their operations?

Appendix

Credits and Inspiration

My good friend and peer Jake Archibald wrote
a multi-part piece in 2021 asking Who has the fastest F1 website in
2021?
. That should
definitely be seen as the genesis of this post.

Methodology

I took the most up-to-date CrUX
data (blended mobile and
desktop data) for the most recent time period available on the final stage of
the Tour (27 July 2025). CrUX data is based on real users’ experiences.

I pulled that data into Google Sheets where I ran it through my own CrRRUX
algorithm—a metric
designed to objectively and fairly rank a cohort of origins’ Core Web Vitals
data.

For each of the fastest and slowest three sites, I took the homepage and the
product details page for their flagship, high-end road race bike. I then ran
a series of synthetic tests with WebPageTest.
Below are the tests and the relevant scripts.

WebPageTest URLs and Scripts

URLs tested (US-locale homepage and flagship bike page; mobile):

https://www.merida-bikes.com/en/
  https://www.webpagetest.org/result/250804_ZiDcGY_AFS/
https://www.merida-bikes.com/en/bike/4850/reacto-team
  https://www.webpagetest.org/result/250804_ZiDcZS_AFT/
https://factorbikes.com/
  https://www.webpagetest.org/result/250804_ZiDcJ3_AFV/
https://factorbikes.com/bikes/ostro-vam
  https://www.webpagetest.org/result/250804_ZiDc69_AFW/
https://www.giant-bicycles.com/us
  https://www.webpagetest.org/result/250804_ZiDc67_AFX/
https://www.giant-bicycles.com/us/propel-advanced-sl-0-red
  https://www.webpagetest.org/result/250804_ZiDcBC_AFY/
https://www.trekbikes.com/us/en_US/
  https://www.webpagetest.org/result/250804_ZiDcS3_AFZ/
https://www.trekbikes.com/us/en_US/bikes/road-bikes/performance-road-bikes/madone/f/F213/madone-slr-9-gen-8/46707/5320708
  https://www.webpagetest.org/result/250804_ZiDc8W_AG0/
https://www.orbea.com/us-en/
  https://www.webpagetest.org/result/250804_ZiDc6C_AG1/
https://www.orbea.com/us-en/bicycles/road/orca-aero/cat/orca-aero-m10i-replica
  https://www.webpagetest.org/result/250804_ZiDc96_AG2/
https://www.ridley-bikes.com/en_US
  https://www.webpagetest.org/result/250804_ZiDcBP_AG3/
https://www.ridley-bikes.com/en_US/bikes/SBINF3RID082
  https://www.webpagetest.org/result/250804_ZiDcYD_AG4/

Cookie consent script:

setCookie https://www.merida-bikes.com cookie_consent_status=["necessary","statistics","media"]
setCookie https://www.giant-bicycles.com cookieControlPrefs=["essential","marketing","statistics"]
setCookie https://factorbikes.com/ preferredCountry=US
setCookie https://factorbikes.com/ preferredMarket=US
setCookie https://www.trekbikes.com/ CookieConsent={stamp:%27atAx5dV3eelO+NTJEeE2/2hjQP8EfzneY261Azp3e9ayU+Ns0nlBKQ==%27%2Cnecessary:true%2Cpreferences:true%2Cstatistics:true%2Cmarketing:true%2Cmethod:%27explicit%27%2Cver:1%2Cutc:1753619313310%2Cregion:%27gb%27}
setCookie https://www.orbea.com/ CookieConsent={stamp:%27-1%27%2Cnecessary:true%2Cpreferences:true%2Cstatistics:true%2Cmarketing:true%2Cmethod:%27implied%27%2Cver:1%2Cutc:1753619371996%2Cregion:%27GB%27}
setCookie https://www.ridley-bikes.com/ __BCF_CONSENT={"categories":["functional","product_enhancement_content_tracking","personalisation","marketing","social_media"],"level":["functional","product_enhancement_content_tracking","personalisation","marketing","social_media"],"revision":0,"data":null,"rfc_cookie":false,"consent_date":"2025-07-27T12:30:56.243Z","consent_uuid":"d5fbdb16-4793-42ca-b748-c517c6b4f427","last_consent_update":"2025-07-27T12:30:56.243Z"}
setCookie https://www.ridley-bikes.com/ _BCF_CONSENT={"categories":["functional","product_enhancement_content_tracking","personalisation","marketing","social_media"],"level":["functional","product_enhancement_content_tracking","personalisation","marketing","social_media"],"revision":0,"data":null,"rfc_cookie":false,"consent_date":"2025-07-27T12:30:56.243Z","consent_uuid":"d5fbdb16-4793-42ca-b748-c517c6b4f427","last_consent_update":"2025-07-27T12:30:56.243Z"}
navigate %URL%


Share this content:

I am a passionate blogger with extensive experience in web design. As a seasoned YouTube SEO expert, I have helped numerous creators optimize their content for maximum visibility.

Leave a Comment