Optimizing Website Performance Using Pure JS and CSS Tricks

Emma GeorgeEmma George
08 Jun, 2025
Optimizing Website Performance Using Pure JS and CSS Tricks

TABLE OF CONTENTS

1 . Why Performance Matters

2 . Measuring Web Performance

3 . Render-Blocking Resources and How to Avoid Them

4 . Optimizing CSS for Speed

5 . JavaScript Techniques to Reduce Lag

6 . Image Optimization with Lazy Loading

7 . Efficient Event Handling

8 . Using requestAnimationFrame Wisely

9 . Optimizing Layout with Flexbox and Grid

10 . Avoiding Reflows and Repaints

11 . Smart Font Loading

12 . Accessibility and Perceived Performance

13 . Final Checklist

Conclusion

Website performance is one of the most critical aspects of modern web development. Users expect fast, smooth, and responsive experiences and search engines like Google now factor performance into ranking. Yet many developers default to frameworks and plugins that, while powerful, often add unnecessary bloat.

This blog explores how to optimize website performance using only vanilla JavaScript and native CSS tricks. No frameworks. No libraries. Just pure, clean code and modern best practices.

We’ll cover render-blocking issues, DOM optimization, efficient animations, CSS layout techniques, lazy loading, code splitting, and more.

1 . Why Performance Matters

  • Performance impacts everything:
  • User satisfaction
  • Conversion rates
  • SEO rankings
  • Accessibility
  • Retention

Studies show that a 1-second delay in page load can reduce conversions by 7%. Fast websites lead to more engaged users and lower bounce rates.

2 . Measuring Web Performance

  • Before optimizing, measure. Use:
  • Google Lighthouse
  • Chrome DevTools (Performance tab)
  • WebPageTest.org
  • PageSpeed Insights
  • Core Web Vitals (LCP, FID, CLS)

Track metrics like:

  • Time to First Byte (TTFB)
  • First Contentful Paint (FCP)
  • Largest Contentful Paint (LCP)
  • Time to Interactive (TTI)
  • Cumulative Layout Shift (CLS)

3 . Render-Blocking Resources and How to Avoid Them

HTML parsing halts when it hits synchronous CSS or JS. These are "render-blocking."

🔥 Solution:

  • Load critical CSS inline (just for above-the-fold content)
  • Use async/defer for scripts:
<script src="main.js" defer></script>
  • Split CSS into critical and non-critical parts
  • Move non-critical CSS to the bottom or load via JavaScript

4 . Optimizing CSS for Speed

Good CSS can dramatically improve rendering speed.

Tips:

✅ Use shorthand properties (e.g., margin: 10px 20px)

✅ Avoid deeply nested selectors

✅ Minify CSS using tools like cssnano

✅ Remove unused CSS with PurgeCSS or manually

✅ Avoid @import and use

✅ Use CSS variables for better caching and reusability

✅ Reduce specificity to avoid long recalculations

5 . JavaScript Techniques to Reduce Lag

Pure JS can be very efficient—if written wisely.

🚀 Tips:

  • Minify and compress JS (via Terser, UglifyJS)
  • Split large scripts into smaller modules
  • Avoid DOM thrashing: batch DOM reads and writes
  • Use event delegation for fewer listeners
  • Debounce or throttle high-frequency events (scroll, resize)

Example: Debounce function

function debounce(fn, delay) {
  let timer;
  return function (...args) {
    clearTimeout(timer);
    timer = setTimeout(() => fn.apply(this, args), delay);
  };
}

6 . Image Optimization with Lazy Loading

Images are one of the biggest causes of bloat.

Solutions:

  • Use modern formats like WebP or AVIF
  • Compress images before upload (TinyPNG, Squoosh)
  • Use responsive images:
<img src="small.jpg" srcset="large.jpg 1024w" alt="Sample" loading="lazy" />
  • Lazy load offscreen images:
<img src="..." loading="lazy" />
  • Set explicit width and height to prevent layout shifts

7 . Efficient Event Handling

Poorly managed event listeners can cause lag and memory leaks.

Tips:

  • Use once: true to auto-remove listeners
  • Use passive: true for scroll/touch events
  • Example:
window.addEventListener('scroll', handleScroll, { passive: true });
  • Remove unused listeners on component unmount

8 . Using requestAnimationFrame Wisely

Animations should sync with the browser's refresh rate.

❌ Avoid setInterval for animations ✅ Use requestAnimationFrame:

function animate() {
  // update position
  requestAnimationFrame(animate);
}
animate();

Only update what changes, don’t repaint the entire screen.

9 . Optimizing Layout with Flexbox and Grid

CSS Flexbox and Grid are GPU-accelerated, layout-efficient systems.

Tips: ✅ Prefer Grid for page layout, Flexbox for UI components ✅ Use display: contents to eliminate unnecessary wrappers ✅ Avoid setting fixed widths for responsive layouts ✅ Let the browser auto-calculate where possible

10 . Avoiding Reflows and Repaints

DOM changes cause expensive recalculations.

Do NOT:

  • Set style multiple times (batch it)
  • Query layout properties after DOM writes (e.g., offsetHeight)
  • Use table layouts for responsiveness

Do:

  • Use class toggling instead of inline styles
  • Use will-change sparingly for animations

11 . Smart Font Loading

Web fonts are a major cause of render delays.

Optimize by:

  • Using font-display: swap
@font-face {
  font-family: 'MyFont';
  src: url('myfont.woff2') format('woff2');
  font-display: swap;
}
  • Preloading fonts with
<link rel="preload">
  • Reducing font weights and variants
  • Using system fonts for ultra-fast rendering

12 . Accessibility and Perceived Performance

Performance isn’t just technical—it’s psychological.

🧠 Tricks:

  • Use skeleton loaders for perceived speed
  • Show progressive enhancement (e.g., show shell UI fast)
  • Keep focus management accessible
  • Use ARIA roles for assistive technologies

13 . Final Checklist

✅ Inline critical CSS ✅ Defer JS ✅ Lazy load images ✅ Compress and modernize assets ✅ Optimize fonts ✅ Minimize reflows ✅ Use passive event listeners ✅ Clean CSS structure ✅ Audit with Lighthouse

Conclusion

You don’t need bulky frameworks or heavy third-party tools to build a fast, responsive website. With smart use of vanilla JavaScript and CSS, you can significantly improve page load time, interactivity, and overall user experience.

By understanding how the browser renders content, how layout engines respond to DOM changes, and how to leverage modern CSS and JS APIs, you gain full control over your performance.

Frameworks are great, but they’re not magic. The magic lies in clean code, thoughtful optimization, and a user-first mindset.

If you're serious about web performance, start at the roots: pure HTML, CSS, and JS.

Optimize small. Win big. 🚀

Emma George

Emma George

Software Engineer

Senior Software Engineer