Trim buffering, lift Core Web Vitals and slash carbon in under an hour. Follow this lean, six-step checklist and your self-hosted videos will stream fast from any theme – with zero plugin bloat.
Quick‑Start Checklist
- Find your biggest video with DevTools or the simple file‑size command below.
- Compress it to MP4 + WebM (HandBrake or FFmpeg – your choice).
- Upload to a CDN bucket (BunnyCDN or Cloudflare R2).
- Swap in the lean
<video>
snippet and add lazy‑load script. - Retest: aim for 200 ms faster Largest Contentful Paint (LCP) and 50 % fewer bytes.
- Repeat for the next video on your list.
1. Map your current video footprint
Before you optimise, know what you’re dealing with.
Inventory videos in DevTools (easy)
- Open a page, press
F12
, choose Network ▸ Media. - Reload the page; play the video once.
- Click Size to sort – the heaviest files float to the top.
Prefer a list? Right‑click the grid ▸ Save all as HAR and open it in any spreadsheet.
Spot large files via command line (advanced)
# Run in /wp-content/uploads or your video folder
find . -type f -size +10M -print | sort -hr
Anything over 10 MB is worth shrinking.
2. Compress your video to modern formats
The smaller the file, the faster your page loads. Aim to export each video as MP4 (H.264) and optionally WebM for better browser support. Here’s how to do it, no code needed.
Compress with HandBrake (easiest)
You’ll need to install HandBrake – a free, safe app for Mac and Windows. → Download HandBrake
Once installed, follow these steps:
- Open HandBrake, then drag in your video.
- In the right column, choose the preset: Fast 1080p30.
- Click the Video tab. Set Constant Quality to 22 (smaller number = better quality, bigger file).
- Optional: go to the Dimensions tab and check that the width is no more than 1920 px.
- Click Browse to choose where to save the output.
- Click Start Encode. Done!
Compress with FFmpeg (advanced)
If you’re comfortable with the command line, use this one-liner to compress to MP4:
ffmpeg -i input.mov -c:v libx264 -preset slow -crf 28 -movflags +faststart \
-c:a aac -b:a 128k output.mp4
Want to create a WebM too? Run this:
ffmpeg -i input.mov -c:v libvpx-vp9 -crf 32 -b:v 0 -row-mt 1 \
-c:a libopus -b:a 96k output.webm
Need to install FFmpeg? It takes a few steps – follow these beginner-friendly guides:
• Install FFmpeg on Windows (WikiHow)
• Install FFmpeg on macOS (json2video)
Alternative: Use a browser-based tool (no install)
If you don’t want to install anything, try FreeConvert Video Compressor.
- Select MP4 as the format
- Drag in your video
- Choose Compress by Quality, and aim for about 60–70%
- Download and you’re done
⚠️ Heads-up: Free tools may have file size limits or watermarks.
Why care? Re‑encoding alone can cut 70–90 % of a file’s weight.
The Quick Fix for a Slow, Heavy Site
We optimise your site for speed, efficiency and sustainability. No rebuild. No delays. Just better performance and a lighter footprint.
3. Serve videos from a CDN bucket
BunnyCDN or Cloudflare R2 in three clicks
- Create Storage Zone / Bucket near your audience.
- Upload your freshly compressed files.
- Copy the public URL – done!
The defaults are fine. Just tick Enable Edge Rules if you see it; that turns on instant seeking.
Check range requests (skip if the term is new to you)
curl -I https://cdn.example.com/clip.mp4 | grep Accept-Ranges
You should see Accept‑Ranges: bytes
. If not, flip the HTTP Range toggle in your CDN panel.
4. Embed with lean HTML5 markup
Replace bulky Gutenberg blocks with this copy‑and‑paste snippet.
<video
data-src="https://cdn.example.com/videos/demo.mp4"
poster="/images/demo-poster.webp"
width="1280" height="720"
preload="metadata"
playsinline
fetchpriority="low"
controls
loading="lazy">
<track kind="captions" src="/captions/demo.vtt" default>
Sorry, your browser can’t play this video.
</video>
⚠️ IMPORTANT: Replace both the data-src
and poster
values with the full URLs to your own video file and preview image. The ones in the example are just placeholders.
What each attribute does, in plain English:
- preload=”metadata” → download only header info until needed.
- fetchpriority=”low” → tell the browser this isn’t urgent.
- playsinline → stop iOS autoplaying full‑screen.
- loading=”lazy” → don’t fetch bytes off‑screen.
Add width/height to avoid layout jumps (need a refresher? see our guide on How to add width & height attributes).
5. Lazy‑load the smart way (optional but powerful)
If you’re comfortable pasting a tiny script, IntersectionObserver loads the video only when it’s about to scroll into view.
<script>
document.querySelectorAll('video[data-src]').forEach(v => {
const io = new IntersectionObserver(e => {
if (e[0].isIntersecting) {
v.src = v.dataset.src;
io.disconnect();
}
}, { rootMargin: '150px' });
io.observe(v);
});
</script>
Don’t sweat it – browsers that can’t run this still obey loading="lazy"
.
6. Verify the win
Lighthouse & WebPageTest
Look for ‑200 ms or better on LCP and a 50 % drop in transferred bytes.
Carbon snapshot
Head to WebsiteCarbon and compare grams CO₂‑eq before vs after. Typical saving: 0.02–0.06 g per page.
Wrap-up & next action
Pick your heaviest homepage video, run the CRF-28 command, upload to your CDN bucket, paste the lean <video>
snippet and ship. Measure the impact, then rinse and repeat. Faster, greener pages for every visitor in less than an hour.