DEV Community

Cover image for How I Cut My Site Load Time From 10s to 2s With 3 Simple Script Changes
chittaranjan nivargi
chittaranjan nivargi

Posted on

How I Cut My Site Load Time From 10s to 2s With 3 Simple Script Changes

The Problem: My Financial Tools Site Was Painfully Slow

I run ToolsForIndia.com - a collection of financial calculators (SIP, PPF, EMI, etc.) for Indian users. Simple static HTML pages. No frameworks. No fancy stuff.

But PageSpeed Insights was giving me a 35/100 score.

Initial load time: 10.2 seconds on 3G.

For users in India (where 3G is still common), this was unusable.


What Was Causing the Slowdown?

I ran Chrome DevTools Performance tab and found the culprits:

  1. Tailwind CDN (blocking): 4.8 seconds
  2. Google Analytics (blocking): 2.1 seconds
  3. Email capture script (blocking): 1.9 seconds
  4. AdSense (already async): 0.8 seconds

Total blocking time: ~9 seconds before any content rendered.
The irony? All three scripts were non-critical for initial page render.


The Fix: Defer Everything That's Not Critical

Fix #1: Defer Tailwind CSS (Biggest Impact)

Before:

<script src="https://cdn.tailwindcss.com"></script>

Enter fullscreen mode Exit fullscreen mode

After:

<script defer src="https://cdn.tailwindcss.com"></script>
Enter fullscreen mode Exit fullscreen mode

What defer does:

  • Script downloads in parallel with HTML parsing
  • Executes after HTML parsing completes
  • Maintains execution order (important for dependencies)

Impact:

  • Load time: 10.2s → 5.4s (saved 4.8 seconds)
  • First Contentful Paint improved by 60%

Fix #2: Defer Google Analytics

Before:

<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXX"></script>
<script>
    window.dataLayer = window.dataLayer || [];
    function gtag(){dataLayer.push(arguments);}
    gtag('js', new Date());
    gtag('config', 'G-XXXXXX');
</script>
Enter fullscreen mode Exit fullscreen mode

After:

<script>
window.addEventListener('load', function() {
    var script = document.createElement('script');
    script.async = true;
    script.src = 'https://www.googletagmanager.com/gtag/js?id=G-XXXXXX';
    document.head.appendChild(script);

    window.dataLayer = window.dataLayer || [];
    function gtag(){dataLayer.push(arguments);}
    gtag('js', new Date());
    gtag('config', 'G-XXXXXX');
});
</script>
Enter fullscreen mode Exit fullscreen mode

Why this approach:

  • Analytics loads after the page fully loads
  • User sees content immediately
  • No impact on tracking (slight delay is acceptable)

Impact:

  • Load time: 5.4s → 3.3s (saved 2.1 seconds)

Fix #3: Defer Email Capture Script

Before:

html<script async src="https://eomail5.com/form/FORM_ID.js" 
        data-form="FORM_ID"></script>
Enter fullscreen mode Exit fullscreen mode

After:

html<script>
window.addEventListener('load', function() {
    var script = document.createElement('script');
    script.async = true;
    script.src = 'https://eomail5.com/form/FORM_ID.js';
    script.setAttribute('data-form', 'FORM_ID');
    document.head.appendChild(script);
});
</script>
Enter fullscreen mode Exit fullscreen mode

Impact:

  • Load time: 3.3s → 2.1s (saved 1.2 seconds)

Final Results

Key Lessons

  1. async vs defer vs Manual Loading
<!-- async: Downloads in parallel, executes ASAP (may block) -->
<script async src="script.js"></script>

<!-- defer: Downloads in parallel, executes after HTML parse -->
<script defer src="script.js"></script>

<!-- Manual: Full control, loads after page ready -->
<script>
window.addEventListener('load', function() {
    // Load script here
});
</script>
Enter fullscreen mode Exit fullscreen mode

When to use what:

  • Critical CSS/JS: Inline or normal blocking
  • UI frameworks (Tailwind, Bootstrap): defer
  • Analytics, ads: Manual load after page ready
  • Third-party widgets: Manual load (lowest priority)
  1. The "Template Header" Approach

Since I have 20+ HTML pages, I don't want to update each one individually.
Solution: Create a reusable header template with all fixes:

<!-- header-template.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <!-- Deferred Tailwind -->
    <script defer src="https://cdn.tailwindcss.com"></script>

    <!-- Deferred Analytics -->
    <script>
    window.addEventListener('load', function() {
        if (localStorage.getItem('analytics-consent') === 'granted') {
            var script = document.createElement('script');
            script.async = true;
            script.src = 'https://www.googletagmanager.com/gtag/js?id=G-XXXXXX';
            document.head.appendChild(script);

            window.dataLayer = window.dataLayer || [];
            function gtag(){dataLayer.push(arguments);}
            gtag('js', new Date());
            gtag('config', 'G-XXXXXX');
        }
    });
    </script>
</head>
Enter fullscreen mode Exit fullscreen mode

Copy-paste this into all pages. One-time fix, massive impact.

  1. Test on Real Devices
    PageSpeed Insights is great, but test on actual 3G/4G connections.
    I used Chrome DevTools:

  2. Open DevTools → Network tab

  3. Throttling dropdown → "Slow 3G"

  4. Hard refresh (Cmd+Shift+R)

This showed me the real user experience.

What I Learned NOT to Do

Don't defer critical CSS

I tried deferring ALL CSS initially. Result: FOUC (Flash of Unstyled Content) that looked terrible.
Rule: If CSS is needed for above-the-fold content, keep it blocking or inline it.

Don't break dependencies

Tailwind needs to load before custom Tailwind classes work. Using async instead of defer caused race conditions.
Rule: Use defer for scripts with dependencies; they execute in order.

Don't over-optimize

I tried code-splitting, tree-shaking Tailwind, etc. Not worth it for a simple site.
Rule: Fix the low-hanging fruit first. 80/20 principle.

The "Good Enough" Philosophy

Before: Chasing 100/100 PageSpeed score with complex build tools.
After: 92/100 with 3 script changes. Good enough.
My site is:

  • Static HTML (no SSR, no frameworks)
  • Uses CDN scripts (no build process)
  • Easy to maintain (no webpack config hell)

And now it's fast.


Your Turn: Quick Audit Checklist

  1. Run PageSpeed Insights on your site
  2. Check "Reduce JavaScript execution time" section
  3. Identify blocking scripts:
    • Analytics? → Defer after page load
    • UI frameworks (Tailwind, Bootstrap)? → Add defer
    • Third-party widgets? → Load last
  4. Test on slow connection (Chrome DevTools throttling)
  5. Re-run PageSpeed → Enjoy your 50+ point improvement

Code Repository

I've open-sourced the before/after versions:
Before (slow):

<!DOCTYPE html>
<html>
<head>
    <script src="https://cdn.tailwindcss.com"></script>
    <script async src="https://www.googletagmanager.com/gtag/js?id=G-XXX"></script>
    <script async src="https://eomail5.com/form/XXX.js"></script>
</head>
<body>
    <!-- Content -->
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

After (fast):

<!DOCTYPE html>
<html>
<head>
    <!-- Defer Tailwind -->
    <script defer src="https://cdn.tailwindcss.com"></script>

    <!-- Defer Analytics -->
    <script>
    window.addEventListener('load', function() {
        var ga = document.createElement('script');
        ga.async = true;
        ga.src = 'https://www.googletagmanager.com/gtag/js?id=G-XXX';
        document.head.appendChild(ga);

        window.dataLayer = window.dataLayer || [];
        function gtag(){dataLayer.push(arguments);}
        gtag('js', new Date());
        gtag('config', 'G-XXX');
    });
    </script>

    <!-- Defer Email Script -->
    <script>
    window.addEventListener('load', function() {
        var email = document.createElement('script');
        email.async = true;
        email.src = 'https://eomail5.com/form/XXX.js';
        email.setAttribute('data-form', 'XXX');
        document.head.appendChild(email);
    });
    </script>
</head>
<body>
    <!-- Content -->
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Conclusion

You don't need:

  • Webpack
  • Build tools
  • Framework migrations
  • Complex optimizations

You just need:

  • Understand defer vs async
  • Defer non-critical scripts
  • Test on real connections

Result: 79% faster load time with 3 changes.


Discussion

What's your biggest site speed bottleneck? Share in the comments!


Building financial tools for 1 billion Indians at ToolsForIndia.com. Follow for more performance tips and dev lessons.

Meet the Creator: Chittaranjan Gopalrao Nivargi
Founder & Creator

Top comments (0)