Skip to main content

Stop the Page Jump When Your Site Loads in a Browser

A page that jumps around is not just a bug in the page. This guide shows how to tune the server side, so the page stops moving. We look at fonts, CSS, and how the page is sent.

Cover image for Stop the Page Jump When Your Site Loads in a Browser

Cumulative Layout Shift (CLS) shows if items jump while a page loads. A slow host adds lag before fonts and CSS reach the screen.

When text jumps or boxes shift, users tap the wrong link. Google tests CLS to rank sites. On phones in India, links lag. Small delays turn into big jumps.

You can fix these jumps on a Linux VPS. You do not need heavy code. You need font files on disk. You need tuned TCP sockets. You need fast Nginx headers. This guide shows how to reach zero page jumps.

How lag makes layout shifts.

Web teams often treat CLS as a client bug. They tweak image tags. They fix box heights. But lag at the host causes the worst jumps.

When a phone loads a page, it pulls files from the host. It needs HTML, CSS, and web fonts:

  1. Flash of Unstyled Text (FOUT). The browser paints text with a stock font. Your font lands late. Words grow and wrap. Page content then moves down.
  2. Flash of Invisible Text (FOIT). The browser hides text while it waits for the font. The host stalls. Users see white boxes. Then the text snaps on.
  3. Late style sheet drop. Your main CSS may split across two TCP round trips. The page paints plain text first. The rules load later.
  4. Third-party font host lag. Outside font hosts add DNS lookups. They add TLS handshakes. They add round trips over phone links.
StageFar hostTuned Indian VPSTime saved
Network round trip160 ms18 ms-142 ms
Font link setup140 ms0 ms-140 ms
File download burst110 ms25 ms-85 ms
Total font wait410 ms43 ms-367 ms
Stock CLS score0.24 (Poor)0.01 (Good)-0.23 (95% cut)

A fast host in India cuts the wait. It sends key files in the first burst. Content then stays still from start to finish.

What is a good CLS score for search rank?

Short answer: Under 0.1 is good. From 0.1 to 0.25 needs work. Over 0.25 is poor.

Google tests real phone visits with the Chrome User Experience Report (CrUX). It scores your site on the top 75% of visits. One in four phone hits may jump. If so, your rank drops.

Fast, still pages earn high ranks. Guests read with ease. Guests stay on the page.

AI bots like OAI-SearchBot and PerplexityBot check page shifts. Headless bots scan page blocks to pull facts. Blocks may jump or stall. Bots then miss text or skip to rival sites.

Host fonts on disk with fast local storage.

In short: Self-host WOFF2 fonts on your own VPS. This cuts the lag from far hosts.

Many sites load fonts from far hosts. This creates a big jump risk.

When a phone hits an outside font link, it must stop. The phone opens a new call:

  • It runs one DNS lookup for the outside host.
  • It makes one TCP handshake.
  • It ends one TLS setup step.

On cell towers in India, these steps add lag. They add 150 to 300 ms of lost time. Font bytes land late. By then the browser has drawn the fallback text. This gives a sharp jump.

External font path (High shift risk):
Browser ---> GET HTML (Origin VPS)
Browser ---> DNS Lookup (Font CDN) ---> TCP Handshake ---> TLS Setup ---> GET Font (Lag: 250ms -> FOUT jump)

Local VPS path (Zero shift risk):
Browser ---> GET HTML + Preload Font (Same Origin VPS, open HTTP/2 multiplexed pipe)
Browser ---> Font arrives in first packet burst ---> Clean immediate text paint

Download your web fonts in WOFF2 format. Put them in /var/www/html/assets/fonts/. Serving fonts from the same host uses the open link. That link runs HTTP/2 or HTTP/3.

Nginx rules for fonts and CSS.

Set up Nginx to preload key fonts. Cache assets with a long expiry.

Open your site conf file:

# /etc/nginx/conf.d/webhost24.conf

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com;

    # TLS certificates and protocols
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;

    root /var/www/html;
    index index.html index.php;

    # Send 103 Early Hints to preload main font and layout style
    location / {
        add_header Link "</assets/css/layout.min.css>; rel=preload; as=style" always;
        add_header Link "</assets/fonts/inter-bold.woff2>; rel=preload; as=font; type=font/woff2; crossorigin" always;
        try_files $uri $uri/ /index.php?$args;
    }

    # Cache WOFF2 fonts on disk with immutable flag
    location ~* \.woff2$ {
        expires 365d;
        add_header Cache-Control "public, max-age=31536000, immutable";
        add_header Access-Control-Allow-Origin "*";
        types { font/woff2 woff2; }
        access_log off;
    }

    # Cache CSS styles with long expiration
    location ~* \.css$ {
        expires 30d;
        add_header Cache-Control "public, max-age=2592000, no-transform";
        access_log off;
    }
}

This tag tells the client the font bytes never change. On the next visit, the browser reads the font from disk. It reads from RAM cache with no network call. This stops layout shifts on repeat visits.

Tune the Linux TCP window.

In short: Make the TCP window bigger. Fonts and CSS then arrive in the first flight.

The Linux kernel sets how data leaves the card.

By default, the TCP congestion window (initcwnd) holds 10 segments (RFC 6928). Ten segments equal about 14.6 KB.

If your main CSS and WOFF2 font total 24 KB, the host cannot send them in one go:

  1. The host sends the first 14.6 KB.
  2. The link pauses.
  3. The host waits for a reply pack (ACK) from the phone.
  4. The phone gets the rest of the font 80 ms later. It swaps the text on screen.

That brief pause gives a clear text jump. Raise initcwnd from 10 to 20. Your host then sends 29.2 KB in the first flight. Your CSS and font reach the phone before the first paint.

Check the route.

Run ip route in your shell:

ip route show

The stock route shows no window size:

default via 192.0.2.1 dev eth0 proto dhcp src 192.0.2.10 metric 100

Set initcwnd and initrwnd to 20.

Run this command to set both the send and read side to 20:

sudo ip route change default via 192.0.2.1 dev eth0 initcwnd 20 initrwnd 20

Check the route chart again:

ip route show

It now shows:

default via 192.0.2.1 dev eth0 proto dhcp src 192.0.2.10 metric 100 initcwnd 20 initrwnd 20

Now your host sends both your CSS and font. It does not wait for a round trip.

Tune sysctl socket rules.

Add socket rules to stop packet drops on weak links.

Create a file at /etc/sysctl.d/99-cls-tuning.conf:

# Prevent TCP window size from dropping after idle periods
net.ipv4.tcp_slow_start_after_idle = 0

# Turn on TCP Fast Open for inbound and outbound calls
net.ipv4.tcp_fastopen = 3

# Expand socket memory limits for modern web traffic
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216

# Increase network backlog buffer to absorb traffic spikes
net.core.netdev_max_backlog = 10000
net.core.somaxconn = 8192

Apply the changes now:

sudo sysctl --system

Turning off tcp_slow_start_after_idle keeps your TCP path wide open. When a user opens a second page, the host sends fonts and CSS at full speed. There is no pause.

Step-by-step test guide.

Check your headers with plain shell tools.

1. Test font caching.

Send a head call to your font file:

curl -I https://example.com/assets/fonts/inter-bold.woff2

Check the shell output:

HTTP/2 200
server: nginx
content-type: font/woff2
content-length: 18420
cache-control: public, max-age=31536000, immutable
access-control-allow-origin: *

Check that immutable is set. Check that content-type is font/woff2.

2. Check HTTP 103 Early Hints headers.

Test your root page:

curl -I -X HEAD https://example.com/

Check the Link lines:

HTTP/2 200
server: nginx
link: </assets/css/layout.min.css>; rel=preload; as=style
link: </assets/fonts/inter-bold.woff2>; rel=preload; as=font; type=font/woff2; crossorigin

These head lines tell the client to pull assets early. The page builds at the same time.

3. Check the route settings.

Confirm your route is active:

ip route show | grep initcwnd

The shell will confirm initcwnd 20 initrwnd 20.

Common questions.

Can tuning replace font-display: optional?

In short: No, tuning alone is not enough. Font rules help too.

Use font-display: optional with your web fonts. It gives the font just 100 ms to load. If the host sends the font fast, it paints clean. If the link stalls, the fallback font stays. There is no second text jump.

Does a CDN replace initcwnd tuning?

In short: No, edge nodes often use stock kernel settings.

Many edge proxies reset initcwnd back to 10 segments. Live pages and cache misses hit your host. Tuning your own VPS protects your guests at all times.

How does a host in India cut CLS?

In short: A host near your guests cuts lag below the paint window.

A host in the west adds 150 ms of raw fiber lag. On phone links, that delay pushes the font past the render deadline. In India, a host sends font bytes fast. The wait is under 20 ms, so assets reach the screen before it paints.

Do AI bots check CLS?

In short: Yes. AI bots track page shifts to check the page structure.

AI search systems use headless browsers to read content. A late script or font can shift the text. Then tools misread the headings and body text. Still layouts keep the index clean.

Next steps for your setup.

Zero layout shifts need a fast host. They also need smart asset rules. Pair local WOFF2 fonts with Nginx early hints. Then raise the TCP window. This keeps your site free of jumps.

To tune the rest of your stack, read our guide on LCP tuning. You can cut live code delay with our TTFB tuning guide. Or cut client input lag with INP tuning. Learn how fast local storage stops disk wait.

Ready to run your apps on fast hosts in India? Explore our app hosting plans. We offer month-to-month billing. You get a 30 days money-back guarantee. You get 7-day backup retention. Message our team on WhatsApp. Or visit our contact page to start today.

Written by

Renish Mithani

Hosted in India, written in English

  • 9 min read

Share this post

Need help?

Ask us on WhatsApp

Our team replies during Indian business hours. Ask us anything about hosting, and we will help. We are the people who run the servers, so we can answer the hard ones too.

That is the end of this post. If you want to keep reading, the posts below are the ones we share with it. We write every post ourselves, and each one stands on its own.

We write about hosting, servers, backups, and the day to day work of running a site for a customer. There is no sales pitch in a post, and every post is free to read.

We write them for the people who run a site from India, and we keep the words plain. We do not write for a prize, and we do not sell you anything here. Read the post, take what you need, and ignore the rest.

Related posts

We rank these by the tags they share with the post you came from. Read one to learn more. Every post is free to read.

Cookie Preferences