Simple steps to reduce the carbon footprint of websites and save energy
Photo: Musab Al Rawahi on Unsplash
Load images only when they're visible to reduce initial bandwidth:
<img src="image.jpg" loading="lazy" alt="..." />Use .webp or .avif for 50-80% smaller files:
<picture>
<source srcset="image.avif" type="image/avif">
<source srcset="image.webp" type="image/webp">
<img src="image.jpg" alt="Example image" />
</picture>Skip web font downloads and use system fonts:
font-family: system-ui, -apple-system, sans-serif;OLED screens use 60% less energy with dark themes:
@media (prefers-color-scheme: dark) {
body { background: #111; color: #eee; }
}Bundle CSS/JS files and use CSS sprites for icons:
/* Inline critical CSS */
<style>/* critical styles */</style>
<link rel="preload" href="main.css" as="style">Tree-shake unused code and defer non-critical scripts:
<script defer src="non-critical.js"></script>
<script type="module">/* modern JS only */</script>Use Gzip/Brotli compression for 70% smaller payloads:
# .htaccess
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/css application/javascript
</IfModule>Set proper cache headers to reduce repeat requests:
Cache-Control: public, max-age=31536000, immutableServe content from locations closer to users:
Embrace simplicity - fewer elements = less energy:
/* Less is more */
.simple { padding: 1rem; background: #f5f5f5; }Use CSS transforms instead of changing layout properties:
/* Efficient */
.element { transform: translateX(100px); }
/* Avoid */
.element { left: 100px; }Use modern codecs and provide fallbacks:
<video preload="none" poster="thumb.jpg">
<source src="video.webm" type="video/webm">
<source src="video.mp4" type="video/mp4">
</video>Optimize queries and use indexes:
-- Add indexes for frequently queried columns
CREATE INDEX idx_user_email ON users(email);
-- Use LIMIT to reduce data transfer
SELECT * FROM posts ORDER BY date DESC LIMIT 10;Each redirect adds latency and server processing:
Build core functionality first, enhance with JavaScript:
<form action="/submit" method="POST">
<!-- Works without JS -->
<button type="submit">Submit</button>
</form>Each external script adds network overhead and CPU load:
Choose providers powered by renewable energy:
Track your site's carbon footprint regularly:
Never send a 2000px photo to a 400px phone screen:
<img src="photo-800.jpg"
srcset="photo-400.jpg 400w,
photo-800.jpg 800w,
photo-1600.jpg 1600w"
sizes="(max-width: 600px) 100vw, 600px"
alt="..." />A single video embed can pull in over 1MB before anyone presses play:
<iframe src="..." loading="lazy" title="..."></iframe>Some visitors explicitly ask for a lighter page. Honour it:
@media (prefers-reduced-data: reduce) {
.hero { background-image: none; }
}Vector marks are usually a few hundred bytes and scale to any screen:
<svg viewBox="0 0 24 24" width="24" height="24">
<path d="M12 2 2 22h20Z" />
</svg>If you must use web fonts, ship only the glyphs you actually need:
<link rel="preload" href="/fonts/subset.woff2" as="font"
type="font/woff2" crossorigin>
@font-face { font-display: swap; }Render HTML once at build time instead of on every single request:
Serve repeat visits from the device instead of the network:
caches.open('v1').then(c => c.addAll(['/', '/main.css']));Every node costs memory, layout and paint work on the client:
Run heavy batch jobs when the grid is at its greenest:
"Dark data" nobody reads still sits on spinning, powered storage:
Autoplay burns bandwidth and battery for content nobody asked for:
<video preload="none" controls poster="thumb.jpg"></video>Skip animation work entirely for users who have opted out:
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation: none !important;
transition: none !important;
}
}