Sustainable Web Development: I Measured My Site's Carbon Footprint. It Was Embarrassing.
#green-web #performance #sustainability

Sustainable Web Development: I Measured My Site's Carbon Footprint. It Was Embarrassing.

The Number That Made Me uncomfortable

I'd been reading about sustainable web development for months — the internet produces roughly 3-4% of global carbon emissions, comparable to the aviation industry, and a meaningful chunk of that is waste from bloated pages. I nodded along every time I read those statistics. The internet is physical. Bytes cost energy. Sure. Obviously.

Then I ran my own site through a carbon calculator and the number was 1.82 grams of CO2 per page view.

That doesn't sound like much until you multiply it. Ten thousand monthly visitors, each viewing three pages on average — that's 54.6 kilograms of CO2 per month. Over a year, my small personal blog was producing more carbon than a round-trip flight from New York to Chicago. For a site that publishes long-form text with a handful of images.

I felt like a fraud. I'd been writing about green technology while running a website that was objectively wasteful. So I decided to fix it — not as an abstract exercise, but as a real engineering project with real numbers.

What I Actually Measured

Before fixing anything, I needed to understand where the waste was. I used three tools: Google Lighthouse for performance metrics, Website Carbon Calculator for emissions estimates, and Chrome DevTools Network tab for raw request analysis.

Here's what I found on my homepage.

Total page weight: 4.2 MB. For a homepage with four article cards and a hero section. The culprit? A hero image I'd grabbed from Unsplash at full resolution — 2.8 MB. I'd slapped a CSS max-width: 100% on it and called it optimized. It was loading the full 4000-pixel-wide image and shrinking it with CSS. Every visitor downloaded a massive image that rendered at a fraction of its size.

Third-party scripts: 14 requests. Google Analytics, a font library (which I wasn't even using — I'd switched to system fonts but never removed the import), a social sharing widget, two tracking pixels, a chat widget I'd disabled but never removed the script for, and a tag manager with six custom tags. Combined, these added about 340 KB of JavaScript and made three separate requests to servers outside my control.

JavaScript bundle: 287 KB. For a site that's 95% static content. The framework overhead was absurd — I was shipping a full React runtime to display blog posts that could have been plain HTML. The actual interactive elements on the page: one dropdown menu and a newsletter signup form. Everything else was server-rendered content that didn't need JavaScript at all.

Fonts: 0 KB. This was the one thing I'd already done right. System font stack, no web font downloads. Every kilobyte of font data not downloaded is energy not consumed.

The total picture: a site that should have been 400 KB was 4.2 MB. Ten times heavier than necessary.

The Fixes That Actually Mattered

I spent a weekend fixing things. Here's what I did, in order of impact.

The hero image. This was the biggest single win. I downloaded the original, resized it to 1200 pixels wide (more than enough for a hero on any screen), compressed it with Squoosh to about 180 KB in WebP format, and served it with a srcset attribute so smaller screens get an even smaller version. Total savings: 2.6 MB per page load. That single change dropped the page weight from 4.2 MB to 1.6 MB.

I also added loading="lazy" to every image below the fold. The hero loads immediately (it's above the fold), but the article card images load only when the user scrolls to them. For a typical visitor who doesn't scroll to the bottom, this means four fewer image downloads.

The third-party scripts. I opened the Network tab and asked myself, for each script: "Does this directly improve the experience for the visitor?" The answer was no for almost everything.

I removed the font import (not using it). Removed the social sharing widget (nobody used it — I checked analytics). Removed the disabled chat widget script. Removed one of the two tracking pixels (the second was redundant). Kept Google Analytics (I need it) and the tag manager (it was managing one tag, but I moved that tag inline and removed the manager).

Total third-party requests went from 14 to 4. Total third-party JavaScript went from 340 KB to 42 KB. The page also loaded faster because it wasn't waiting for fourteen external servers to respond.

The JavaScript bundle. This was the hardest fix. The site was built with a JavaScript framework, and every page shipped the full framework runtime to the browser. Converting to a static-site approach — pre-rendering everything to plain HTML at build time — would have been ideal but would have required a rewrite. Instead, I did the practical version: code-split aggressively, lazy-load the JavaScript that wasn't needed for initial render, and remove every component that wasn't actually interactive.

The dropdown menu stayed (it's interactive). The newsletter form stayed (it needs client-side validation). Everything else was converted to plain HTML where possible. The bundle went from 287 KB to 89 KB. Not perfect, but a 69% reduction without a full rewrite.

Compression and caching. I enabled Brotli compression on my server. Brotli typically beats gzip by 15-25% on text assets. I also set long cache headers for static assets — images, CSS, JavaScript. The hash in the filename means I can cache aggressively without worrying about stale content. Returning visitors now download essentially nothing on repeat visits.

The Results After a Weekend

Here's what changed.

| Metric | Before | After |
|---|---|---|
| Page weight | 4.2 MB | 620 KB |
| CO2 per view | 1.82g | 0.31g |
| Third-party requests | 14 | 4 |
| JavaScript | 287 KB | 89 KB |
| Lighthouse Performance | 62 | 94 |
| Load time (3G) | 8.2s | 2.1s |

The carbon footprint dropped by 83%. The page load time dropped by 75%. The Lighthouse score went from "needs work" to "good." And the site looks identical. Not slightly different — identical. I removed nothing visible. I only removed waste.

The 620 KB is mostly images — the hero and four article card images in WebP format. The HTML is about 12 KB. The CSS is 14 KB. The JavaScript is 89 KB. Everything else is images, and the images are already compressed and properly sized.

What Didn't Work

I tried converting my images to AVIF, the newer format that's about 30% smaller than WebP at the same quality. The results were mixed. AVIF is supported in Chrome and Firefox but not in Safari until very recently. I ended up using AVIF with WebP fallback, which added complexity to my build process for a savings of about 40 KB per image. Not worth it for my site. If you're serving millions of views, maybe. For a small blog, WebP is the sweet spot.

I also tried using a CDN for edge caching. The CDN I tested (I won't name it) actually made things worse for some users because it routed traffic through a data center farther from them than my origin server. CDNs help when you have a global audience and your origin server is in one location. For a site with mostly US traffic and a US-based server, the CDN added latency without meaningful caching benefits.

The other thing that didn't work: measuring carbon per visit as a primary metric. It's a useful number for understanding the big picture, but it's too abstract to drive daily decisions. "Reduce page weight by 50%" is an actionable engineering goal. "Reduce carbon per visit by 50%" is the same goal with extra steps. I track both, but the page weight numbers are what actually guide my work.

The Business Case That's Hiding in Plain Here

I didn't do any of this for SEO. But the SEO benefits were immediate and measurable.

Google's Core Web Vitals — the metrics that directly affect search ranking — are almost perfectly correlated with sustainability metrics. A lighter page loads faster (better Largest Contentful Paint). Fewer third-party scripts mean less main-thread work (better Total Blocking Shift). Optimized images render faster (better Cumulative Layout Shift).

My organic traffic increased about 18% in the month after the changes. Some of that might be coincidence. But the Lighthouse score improvement from 62 to 94 is exactly the kind of change Google's algorithm rewards, and the page load time improvement from 8.2 seconds to 2.1 seconds on simulated 3G directly affects how Googlebot crawls and indexes the site.

The cost savings were real too. My hosting bill dropped about 15% because I'm serving fewer bytes per request. The bandwidth savings scale with traffic — if the site grows, the savings grow with it. And the reduced server load means I can serve more visitors on the same hosting plan.

Performance, sustainability, and cost optimization are the same discipline. Every decision that makes your site greener also makes it faster, cheaper, and better for search ranking. The incentive alignment is almost suspicious.

What I'd Actually Tell You Starting Today

If you're building a website and want it to be both fast and sustainable, here's what matters most and what's a waste of time.

What matters: Image optimization. This is 80% of the problem for most sites. Serve WebP instead of JPEG or PNG. Resize images to the maximum size you actually display them at. Lazy-load everything below the fold. Use srcset for responsive images. This alone will cut your page weight in half or more.

What matters: Removing unused JavaScript and third-party scripts. Open your Network tab, filter by JS, and ask yourself what each script does. If you can't answer, remove it. If the answer is "it tracks users" and you don't need the tracking, remove it. If it's a social widget nobody clicks, remove it.

What matters: Compression and caching. Enable Brotli or gzip. Set proper cache headers. These are configuration changes, not code changes. They take fifteen minutes and save more energy than most optimization projects.

What doesn't matter much: Converting from a JavaScript framework to plain HTML. If your site already works and you're not ready for a rewrite, optimize within the framework. Code-splitting, lazy-loading, and removing unused code get you 80% of the benefit for 20% of the effort.

What doesn't matter much: Carbon calculators as a primary metric. They're useful for understanding the big picture and for communicating with non-technical stakeholders. But they're too abstract to drive engineering decisions. Track page weight and request count instead — the carbon footprint follows automatically.

What's actively misleading:追求 perfect Lighthouse scores. A 100/100 Lighthouse score doesn't mean your site is fast or green — it means you've optimized the specific metrics Lighthouse measures. A site with a 95 score and a 200 KB page weight is better than a site with a 100 score and a 2 MB page weight. Optimize for real outcomes, not scores.

I'm not going to pretend my site is perfectly sustainable. 620 KB per page view is still heavier than it needs to be, and the JavaScript framework overhead is still there. But it's a hell of a lot better than 4.2 MB. And the process of fixing it taught me more about web performance than three years of reading articles about it. The carbon number made it concrete. When you can say "my website produces X kilograms of CO2 per month," the waste stops being abstract and becomes an engineering problem with a clear solution.

The most sustainable web request is the one you never make. The second most sustainable is the one that weighs 180 KB instead of 2.8 MB. Start there.