Best Practices
Modern web development standards based on Lighthouse best practices audits. Covers security, browser compatibility, and code quality patterns.
Security
HTTPS Everywhere
❌ Mixed Content
✅ HTTPS Only
< img src = "http://example.com/image.jpg" >
< script src = "http://cdn.example.com/script.js" ></ script >
HSTS Header:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Content Security Policy (CSP)
# Prevent clickjacking
X-Frame-Options: DENY
# Prevent MIME type sniffing
X-Content-Type-Options: nosniff
# Enable XSS filter (legacy browsers)
X-XSS-Protection: 1; mode=block
# Control referrer information
Referrer-Policy: strict-origin-when-cross-origin
# Permissions policy (formerly Feature-Policy)
Permissions-Policy: geolocation=(), microphone=(), camera=()
No Vulnerable Libraries
# Check for vulnerabilities
npm audit
yarn audit
# Auto-fix when possible
npm audit fix
# Check specific package
npm ls lodash
Keep dependencies updated:
// package.json
{
"scripts" : {
"audit" : "npm audit --audit-level=moderate" ,
"update" : "npm update && npm audit fix"
}
}
Known vulnerable patterns to avoid:
❌ Prototype Pollution
✅ Safer Alternatives
Object . assign ( target , userInput );
_ . merge ( target , userInput );
❌ XSS Vulnerable
✅ Safe Text Content
element . innerHTML = userInput ;
document . write ( userInput );
Secure Cookies
❌ Insecure Cookie
✅ Secure Cookie (Server-Side)
document . cookie = "session=abc123" ;
Browser Compatibility
Doctype Declaration
❌ Missing or Invalid
✅ HTML5 Doctype
< HTML >
<! DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" >
Character Encoding
❌ Missing or Late Charset
✅ Charset as First Element
< html >
< head >
< title > Page </ title >
< meta charset = "UTF-8" >
</ head >
❌ Missing Viewport
✅ Responsive Viewport
< head >
< title > Page </ title >
</ head >
Feature Detection
❌ Browser Detection (Brittle)
✅ Feature Detection
✅ Using @supports in CSS
if ( navigator . userAgent . includes ( 'Chrome' )) {
// Chrome-specific code
}
Polyfills (When Needed)
<!-- Load polyfills conditionally -->
< script >
if ( ! ( 'fetch' in window )) {
document . write ( '<script src="/polyfills/fetch.js">< \/ script>' );
}
</ script >
<!-- Or use polyfill.io -->
< script src = "https://polyfill.io/v3/polyfill.min.js?features=fetch,IntersectionObserver" ></ script >
Deprecated APIs
Avoid These
document.write
Synchronous XHR
Application Cache
// ❌ document.write (blocks parsing)
document . write ( '<script src="..."></script>' );
// ✅ Dynamic script loading
const script = document . createElement ( 'script' );
script . src = '...' ;
document . head . appendChild ( script );
// ❌ Synchronous XHR (blocks main thread)
const xhr = new XMLHttpRequest ();
xhr . open ( 'GET' , url , false ); // false = synchronous
// ✅ Async fetch
const response = await fetch ( url );
<!-- ❌ Application Cache (deprecated) -->
< html manifest = "cache.manifest" >
// ✅ Service Workers
if ( 'serviceWorker' in navigator ) {
navigator . serviceWorker . register ( '/sw.js' );
}
Event Listener Passive
❌ Non-Passive (May Block Scrolling)
✅ Passive Listeners
element . addEventListener ( 'touchstart' , handler );
element . addEventListener ( 'wheel' , handler );
Console & Errors
No Console Errors
❌ Errors in Production
✅ Proper Error Handling
console . log ( 'Debug info' ); // Remove in production
throw new Error ( 'Unhandled' ); // Catch all errors
Error Boundaries (React)
class ErrorBoundary extends React . Component {
state = { hasError: false };
static getDerivedStateFromError ( error ) {
return { hasError: true };
}
componentDidCatch ( error , info ) {
errorTracker . captureException ( error , { extra: info });
}
render () {
if ( this . state . hasError ) {
return < FallbackUI /> ;
}
return this . props . children ;
}
}
// Usage
< ErrorBoundary >
< App />
</ ErrorBoundary >
Global Error Handler
// Catch unhandled errors
window . addEventListener ( 'error' , ( event ) => {
errorTracker . captureException ( event . error );
});
// Catch unhandled promise rejections
window . addEventListener ( 'unhandledrejection' , ( event ) => {
errorTracker . captureException ( event . reason );
});
Source Maps
Production Configuration
❌ Source Maps Exposed
✅ Hidden Source Maps
// webpack.config.js
module . exports = {
devtool: 'source-map' , // Exposes source code
};
Avoid Blocking Patterns
❌ Blocking Script
✅ Deferred Script
< script src = "heavy-library.js" ></ script >
❌ Blocking CSS Import
✅ Link Tags (Parallel Loading)
@import url ( 'other-styles.css' );
Efficient Event Handlers
❌ Handler on Every Element
✅ Event Delegation
items . forEach ( item => {
item . addEventListener ( 'click' , handleClick );
});
Memory Management
❌ Memory Leak
✅ Cleanup When Done
const handler = () => { /* ... */ };
window . addEventListener ( 'resize' , handler );
Code Quality
Valid HTML
❌ Invalid HTML
✅ Valid HTML
< div id = "header" >
< div id = "header" > <!-- Duplicate ID -->
< ul >
< div > Item </ div > <!-- Invalid child -->
</ ul >
< a href = "/" >< button > Click </ button ></ a > <!-- Invalid nesting -->
Semantic HTML
❌ Non-Semantic
✅ Semantic HTML5
< div class = "header" >
< div class = "nav" >
< div class = "nav-item" > Home </ div >
</ div >
</ div >
< div class = "main" >
< div class = "article" >
< div class = "title" > Headline </ div >
</ div >
</ div >
Image Aspect Ratios
❌ Distorted Images
✅ Preserve Aspect Ratio
< img src = "photo.jpg" width = "300" height = "100" >
<!-- If actual ratio is 4:3, this squishes the image -->
Permissions & Privacy
Request Permissions Properly
❌ Request on Page Load (Bad UX)
✅ Request in Context
navigator . geolocation . getCurrentPosition ( success , error );
Permissions Policy
<!-- Restrict powerful features -->
< meta http-equiv = "Permissions-Policy"
content = "geolocation=(), camera=(), microphone=()" >
<!-- Or allow for specific origins -->
< meta http-equiv = "Permissions-Policy"
content = "geolocation=(self 'https://maps.example.com')" >
Audit Checklist
Security (Critical)
Compatibility
Code Quality
| Tool | Purpose |
|------|---------||
| npm audit | Dependency vulnerabilities |
| SecurityHeaders.com | Header analysis |
| W3C Validator | HTML validation |
| Lighthouse | Best practices audit |
| Observatory | Security scan |
External Resources
Web Quality Audit For comprehensive best practices audit as part of overall quality