HTML: SEO, Performance & Best Practices
Structured Data (JSON-LD)
JSON-LD is the preferred format for structured data. Google uses it to create rich results in search (review stars, FAQ dropdowns, recipe cards, etc.).
<!-- Article schema -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "How to Use HTML Semantic Elements",
"datePublished": "2024-01-15",
"dateModified": "2024-02-01",
"author": {
"@type": "Person",
"name": "Alice Johnson",
"url": "https://example.com/authors/alice"
},
"publisher": {
"@type": "Organization",
"name": "My Blog",
"logo": {
"@type": "ImageObject",
"url": "https://example.com/logo.png"
}
},
"image": "https://example.com/article-image.jpg",
"description": "A comprehensive guide to semantic HTML elements"
}
</script>
<!-- Breadcrumb schema -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{"@type": "ListItem", "position": 1, "name": "Home", "item": "https://example.com"},
{"@type": "ListItem", "position": 2, "name": "Blog", "item": "https://example.com/blog"},
{"@type": "ListItem", "position": 3, "name": "This Article"}
]
}
</script>Performance — Core Web Vitals
LCP (Largest Contentful Paint): how fast the largest visible element loads. Target < 2.5s. Fix: preload hero image, fast server response (TTFB), no render-blocking resources.
INP (Interaction to Next Paint): responsiveness to clicks/key presses. Target < 200ms. Fix: reduce main thread blocking, defer heavy JavaScript.
CLS (Cumulative Layout Shift): visual stability. Target < 0.1. Fix: always include width/height on images, don't inject content above existing content, use CSS aspect-ratio.
Preventing Layout Shift (CLS)
<!-- Always specify dimensions — browser reserves space before image loads -->
<img src="photo.jpg" alt="..." width="800" height="600" loading="lazy">
<!-- CSS aspect-ratio for responsive images -->
<style>
img {
width: 100%;
height: auto;
aspect-ratio: 4/3; /* maintains ratio even before image loads */
}
</style>
<!-- Font loading — prevent text flash/shift -->
<link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin>
<style>
@font-face {
font-family: 'Inter';
src: url('/fonts/inter.woff2') format('woff2');
font-display: swap; /* show fallback immediately, swap when loaded */
/* optional: avoid swap shift if font loads late */
font-display: optional;
}
</style>Resource Hints & Loading
<!-- Preload: high-priority fetch of critical resources -->
<link rel="preload" href="/hero.webp" as="image" fetchpriority="high">
<link rel="preload" href="/critical.css" as="style">
<link rel="preload" href="/inter.woff2" as="font" crossorigin>
<!-- Preconnect: early connection to third-party origins (saves 100-500ms) -->
<link rel="preconnect" href="https://api.example.com">
<link rel="preconnect" href="https://fonts.googleapis.com">
<!-- DNS-prefetch: cheaper than preconnect, just resolves DNS -->
<link rel="dns-prefetch" href="https://cdn.example.com">
<!-- Prefetch: low-priority fetch for next navigation -->
<link rel="prefetch" href="/next-page.html">
<!-- fetchpriority attribute (Chrome 101+) -->
<img src="hero.jpg" fetchpriority="high" alt="Hero"> <!-- bump priority -->
<img src="below-fold.jpg" fetchpriority="low" alt="Below fold">
<link rel="preload" href="non-critical.js" as="script" fetchpriority="low">Script & Style Optimization
<!-- Scripts: always defer unless critical -->
<script src="app.js" defer></script> <!-- recommended -->
<script src="analytics.js" async></script> <!-- order-independent scripts -->
<!-- Critical CSS inline + load rest async -->
<style>/* inline above-the-fold CSS here */</style>
<link rel="stylesheet" href="full.css" media="print" onload="this.media='all'">
<noscript><link rel="stylesheet" href="full.css"></noscript>
<!-- Module preload -->
<link rel="modulepreload" href="/app.mjs">
<!-- Lazy load iframes -->
<iframe src="..." loading="lazy"></iframe>SEO Best Practices Checklist
Unique <title> per page: primary keyword + brand name, 50-60 characters
Meta description: 120-155 characters, compelling, includes call to action
Canonical URL on every page — prevents duplicate content penalty
One h1 per page, matching the page topic
All images have descriptive alt text (empty alt for decorative images)
hreflang tags for multi-language sites
Sitemap.xml submitted to Google Search Console
robots.txt controlling what search engines can crawl
Structured data (JSON-LD) for articles, products, FAQs, breadcrumbs
HTTPS (Google uses HTTPS as a ranking signal)
Mobile-friendly (viewport meta tag, responsive design) — Google uses mobile-first indexing
Fast LCP: Core Web Vitals are ranking signals
Keep your own version of these notes — editable, searchable, and organised by your stack.
Start free