Fast interfaces feel better.
Fast interfaces feel better. Optimize from the start.
Target metrics:
Split at route level:
// Next.js
import dynamic from 'next/dynamic';
const DashboardWidget = dynamic(() => import('./DashboardWidget'), {
loading: () => <Skeleton />,
});
// React Router
const Dashboard = lazy(() => import('./pages/Dashboard'));
Defer non-critical components:
import { lazy, Suspense } from 'react';
const HeavyChart = lazy(() => import('./HeavyChart'));
function Analytics() {
return (
<Suspense fallback={<Skeleton />}>
<HeavyChart data={data} />
</Suspense>
);
}
// Next.js Image component
import Image from 'next/image';
<Image
src="/image.jpg"
alt="Description"
width={800}
height={600}
loading="lazy"
placeholder="blur"
/>
// Native responsive images
<img
src="image.jpg"
srcSet="image-400.jpg 400w, image-800.jpg 800w"
sizes="(max-width: 640px) 100vw, 50vw"
alt="Description"
loading="lazy"
/>
Animate only transform and opacity:
/* Good - uses GPU */
.element {
transition: transform 0.2s, opacity 0.2s;
}
.element:hover {
transform: scale(1.05);
opacity: 0.8;
}
/* Bad - triggers layout/paint */
.element {
transition: width 0.2s, height 0.2s, top 0.2s;
}
# Analyze bundle
npm run build -- --analyze
# Remove unused code
npm install -D webpack-bundle-analyzer
Techniques:
<!-- Preload critical fonts -->
<link rel="preload" href="/fonts/zen-sans/Zen-Variable.woff2" as="font" type="font/woff2" crossorigin>
<!-- Preconnect to external domains -->
<link rel="preconnect" href="https://api.example.com">
<!-- Prefetch next page -->
<link rel="prefetch" href="/dashboard">