12 min read
Performance Optimization
Optimize pxlpeak for maximum performance with minimal impact on page load and user experience.
Introduction
Analytics tracking should provide insights without impacting user experience. This guide covers techniques to ensure pxlpeak loads fast, tracks efficiently, and has minimal impact on Core Web Vitals.
Performance Goals
code
Target Performance Metrics:
┌─────────────────────────────────────────────────────────────────────────────┐
│ │
│ Script Loading │
│ ├── Time to first byte (TTFB): < 50ms (CDN) │
│ ├── Script size: < 15KB gzipped │
│ └── Parse time: < 10ms │
│ │
│ Runtime Impact │
│ ├── Main thread blocking: < 5ms per event │
│ ├── Memory footprint: < 2MB │
│ └── Network requests: Batched (1 req per 5 seconds max) │
│ │
│ Core Web Vitals Impact │
│ ├── LCP impact: None (loads after critical path) │
│ ├── FID impact: < 1ms │
│ └── CLS impact: Zero │
│ │
└─────────────────────────────────────────────────────────────────────────────┘Script Loading Optimization
Async Loading (Recommended)
code
<!-- Recommended: Async script loading -->
<head>
<!-- DNS prefetch and preconnect for faster loading -->
<link rel="dns-prefetch" href="https://cdn.pxlpeak.com">
<link rel="preconnect" href="https://api.pxlpeak.com" crossorigin>
<!-- Async script loading - non-blocking -->
<script>
(function(w,d,s,l,i){
// Initialize queue before script loads
w[l]=w[l]||[];
w[l].push({'event':'init','siteId':i,'timestamp':new Date()});
// Load script asynchronously
var f=d.getElementsByTagName(s)[0],
j=d.createElement(s);
j.async=true;
j.src='https://cdn.pxlpeak.com/v1/pxlpeak.min.js';
f.parentNode.insertBefore(j,f);
})(window,document,'script','pxlpeak','YOUR_SITE_ID');
</script>
</head>Deferred Loading (For Non-Critical Pages)
code
// Load pxlpeak only after page is interactive
function loadPxlpeakDeferred() {
// Wait for page to be idle
if ('requestIdleCallback' in window) {
requestIdleCallback(() => loadScript(), { timeout: 3000 });
} else {
// Fallback for Safari
setTimeout(loadScript, 2000);
}
}
function loadScript() {
const script = document.createElement('script');
script.src = 'https://cdn.pxlpeak.com/v1/pxlpeak.min.js';
script.async = true;
script.onload = () => {
pxlpeak.init('YOUR_SITE_ID');
// Process any queued events
processQueue();
};
document.head.appendChild(script);
}
// Queue events before script loads
window.pxlpeakQueue = window.pxlpeakQueue || [];
window.pxlpeak = {
track: (...args) => window.pxlpeakQueue.push(['track', ...args]),
identify: (...args) => window.pxlpeakQueue.push(['identify', ...args])
};
// Process queue after script loads
function processQueue() {
window.pxlpeakQueue.forEach(([method, ...args]) => {
pxlpeak[method](...args);
});
}Conditional Loading
code
// Only load on production
if (process.env.NODE_ENV === 'production') {
loadPxlpeak();
}
// Skip on specific pages
const skipPages = ['/privacy', '/terms', '/admin'];
if (!skipPages.includes(window.location.pathname)) {
loadPxlpeak();
}
// Skip for internal users
if (!document.cookie.includes('internal_user=true')) {
loadPxlpeak();
}
// Load after user consent
function onConsentGranted() {
loadPxlpeak();
}Event Batching
Automatic Batching
code
// pxlpeak batching configuration
const batchConfig = {
// Enable batching (default: true)
enabled: true,
// Maximum events per batch
maxSize: 10,
// Flush interval in milliseconds
flushInterval: 5000,
// Flush on page unload
flushOnUnload: true,
// Priority events that bypass batching
priorityEvents: ['purchase', 'signup', 'error']
};
// Initialize with batching config
pxlpeak.init('YOUR_SITE_ID', {
batching: batchConfig
});Manual Batch Control
code
// Force flush current batch
pxlpeak.flush();
// Disable batching temporarily
pxlpeak.setBatching(false);
// Track high-priority event immediately
pxlpeak.track('purchase', {
order_id: 'ORD-123',
value: 99.99
}, { immediate: true });
// Batch multiple related events
pxlpeak.batch([
{ event: 'funnel_step_1', properties: { step: 1 } },
{ event: 'funnel_step_2', properties: { step: 2 } },
{ event: 'funnel_step_3', properties: { step: 3 } }
]);Page Unload Handling
code
// Ensure events are sent on page unload
// pxlpeak uses sendBeacon API for reliability
// Configuration
pxlpeak.init('YOUR_SITE_ID', {
// Use sendBeacon for unload events (default: true)
useBeacon: true,
// Events to capture on unload
unloadEvents: {
pageLeave: true,
timeOnPage: true,
scrollDepth: true
}
});
// Custom unload handling
window.addEventListener('beforeunload', () => {
// Flush any pending events
pxlpeak.flush();
// Track final page metrics
pxlpeak.track('page_exit', {
time_on_page: getTimeOnPage(),
scroll_depth: getScrollDepth()
}, { immediate: true, useBeacon: true });
});
// Handle visibility change (tab switch)
document.addEventListener('visibilitychange', () => {
if (document.hidden) {
pxlpeak.flush();
}
});Efficient Event Tracking
Throttling High-Frequency Events
code
// Throttle function utility
function throttle<T extends (...args: any[]) => any>(
func: T,
limit: number
): T {
let inThrottle = false;
return function(this: any, ...args: any[]) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
} as T;
}
// Throttled scroll tracking
const trackScroll = throttle(() => {
const scrollDepth = Math.round(
(window.scrollY / (document.body.scrollHeight - window.innerHeight)) * 100
);
pxlpeak.track('scroll', { depth: scrollDepth });
}, 1000); // Max once per second
window.addEventListener('scroll', trackScroll, { passive: true });
// Throttled mouse movement (for heatmaps)
const trackMouse = throttle((e: MouseEvent) => {
pxlpeak.track('mouse_position', {
x: e.clientX,
y: e.clientY
});
}, 500);
// Only enable for heatmap sessions
if (isHeatmapSession) {
document.addEventListener('mousemove', trackMouse, { passive: true });
}Debouncing Input Events
code
// Debounce function utility
function debounce<T extends (...args: any[]) => any>(
func: T,
wait: number
): T {
let timeout: ReturnType<typeof setTimeout>;
return function(this: any, ...args: any[]) {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), wait);
} as T;
}
// Debounced search tracking
const trackSearch = debounce((query: string) => {
pxlpeak.track('search', { query, timestamp: Date.now() });
}, 500); // Wait 500ms after last keystroke
searchInput.addEventListener('input', (e) => {
const target = e.target as HTMLInputElement;
trackSearch(target.value);
});
// Debounced form field interaction
const trackFieldBlur = debounce((fieldName: string) => {
pxlpeak.track('form_field_interacted', { field: fieldName });
}, 300);Passive Event Listeners
code
// Use passive listeners for better scroll performance
window.addEventListener('scroll', handleScroll, { passive: true });
document.addEventListener('touchstart', handleTouch, { passive: true });
document.addEventListener('touchmove', handleTouch, { passive: true });
// IntersectionObserver for visibility tracking (more efficient than scroll)
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
pxlpeak.track('element_viewed', {
element_id: entry.target.id,
viewport_percent: Math.round(entry.intersectionRatio * 100)
});
}
});
}, {
threshold: [0.25, 0.5, 0.75, 1.0]
});
// Observe elements
document.querySelectorAll('[data-track-visibility]').forEach(el => {
observer.observe(el);
});Memory Management
Preventing Memory Leaks
code
// Clean up event listeners on SPA navigation
class TrackingManager {
private listeners: Array<{ element: Element; type: string; handler: EventListener }> = [];
addTrackedListener(element: Element, type: string, handler: EventListener) {
element.addEventListener(type, handler);
this.listeners.push({ element, type, handler });
}
cleanup() {
this.listeners.forEach(({ element, type, handler }) => {
element.removeEventListener(type, handler);
});
this.listeners = [];
}
}
const trackingManager = new TrackingManager();
// On route change (SPA)
router.beforeEach(() => {
trackingManager.cleanup();
});
// On component unmount (React)
useEffect(() => {
const handler = () => pxlpeak.track('button_click');
buttonRef.current?.addEventListener('click', handler);
return () => {
buttonRef.current?.removeEventListener('click', handler);
};
}, []);Limiting Stored Data
code
// Configure local storage limits
pxlpeak.init('YOUR_SITE_ID', {
storage: {
// Maximum events to queue offline
maxQueueSize: 100,
// Maximum age of queued events (24 hours)
maxQueueAge: 24 * 60 * 60 * 1000,
// Maximum user properties to cache
maxUserProperties: 50,
// Clear expired data on init
cleanupOnInit: true
}
});
// Manual cleanup
pxlpeak.clearStorage({
queue: true,
userProperties: false,
sessionData: false
});Network Optimization
Request Compression
code
// Enable request compression (default in modern browsers)
pxlpeak.init('YOUR_SITE_ID', {
network: {
// Use gzip compression for requests
compression: true,
// Request timeout
timeout: 10000,
// Retry configuration
retry: {
maxAttempts: 3,
backoff: 'exponential',
initialDelay: 1000
}
}
});Offline Support
code
// Handle offline scenarios
pxlpeak.init('YOUR_SITE_ID', {
offline: {
// Queue events when offline
enabled: true,
// Storage method
storage: 'localStorage', // or 'indexedDB' for larger capacity
// Sync when back online
syncOnReconnect: true,
// Maximum offline queue size
maxQueueSize: 1000
}
});
// Check online status
window.addEventListener('online', () => {
pxlpeak.sync(); // Sync queued events
});
// Custom offline detection
const isOnline = navigator.onLine &&
await fetch('/api/health', { method: 'HEAD' }).then(() => true).catch(() => false);CDN and Caching
code
// pxlpeak script is served from global CDN with optimal caching
// Cache headers (set by pxlpeak CDN)
// Cache-Control: public, max-age=86400, stale-while-revalidate=604800
// ETag: "abc123"
// Service Worker caching for offline support
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open('pxlpeak-v1').then((cache) => {
return cache.addAll([
'https://cdn.pxlpeak.com/v1/pxlpeak.min.js'
]);
})
);
});
// Serve from cache with network fallback
self.addEventListener('fetch', (event) => {
if (event.request.url.includes('cdn.pxlpeak.com')) {
event.respondWith(
caches.match(event.request).then((response) => {
return response || fetch(event.request);
})
);
}
});Core Web Vitals Impact
Measuring Impact
code
// Measure pxlpeak's impact on Core Web Vitals
import { onLCP, onFID, onCLS, onINP } from 'web-vitals';
// Track before pxlpeak loads
const metricsBeforeLoad: Record<string, number> = {};
onLCP((metric) => {
metricsBeforeLoad.lcp = metric.value;
});
onFID((metric) => {
metricsBeforeLoad.fid = metric.value;
});
onCLS((metric) => {
metricsBeforeLoad.cls = metric.value;
});
onINP((metric) => {
metricsBeforeLoad.inp = metric.value;
});
// Load pxlpeak and measure after
loadPxlpeak().then(() => {
// Compare metrics
// pxlpeak should have zero or minimal impact
});Avoiding CLS (Cumulative Layout Shift)
code
// pxlpeak does NOT inject any visible elements
// No CLS impact by design
// If you're adding custom UI (consent banners, etc.)
// Reserve space in advance:
// Bad - causes layout shift
function showConsentBanner() {
const banner = document.createElement('div');
banner.innerHTML = 'Cookie consent...';
document.body.prepend(banner); // Shifts content down
}
// Good - space reserved
// CSS:
// .consent-placeholder { min-height: 60px; }
function showConsentBanner() {
const placeholder = document.querySelector('.consent-placeholder');
placeholder.innerHTML = 'Cookie consent...';
}Avoiding FID/INP Impact
code
// pxlpeak minimizes main thread work
// Event handling is async and non-blocking
pxlpeak.track('click', { button: 'cta' });
// Returns immediately, processing is async
// Heavy computations are deferred
const trackWithData = (data: LargeDataset) => {
// Use requestIdleCallback for non-critical processing
requestIdleCallback(() => {
const processed = processData(data);
pxlpeak.track('data_processed', processed);
});
};
// Avoid tracking in critical user interactions
button.addEventListener('click', async () => {
// Do the important thing FIRST
await performCriticalAction();
// Track AFTER the critical path
pxlpeak.track('button_clicked');
});Framework-Specific Optimization
React Optimization
code
// React-specific performance patterns
import { useEffect, useCallback, useRef } from 'react';
// Use refs to avoid re-renders
function TrackedComponent() {
const trackingRef = useRef({ hasTracked: false });
useEffect(() => {
// Track only once on mount
if (!trackingRef.current.hasTracked) {
pxlpeak.track('component_mounted');
trackingRef.current.hasTracked = true;
}
}, []);
return <div>...</div>;
}
// Memoize tracking callbacks
function TrackedButton() {
const handleClick = useCallback(() => {
pxlpeak.track('button_clicked');
}, []); // Empty deps - function reference is stable
return <button onClick={handleClick}>Click</button>;
}
// Track in useEffect, not render
function ProductPage({ productId }: { productId: string }) {
useEffect(() => {
pxlpeak.track('product_viewed', { product_id: productId });
}, [productId]); // Only track when productId changes
return <div>...</div>;
}Next.js Optimization
code
// Next.js App Router
// app/providers.tsx
'use client';
import { useEffect } from 'react';
import { usePathname, useSearchParams } from 'next/navigation';
export function AnalyticsProvider({ children }: { children: React.ReactNode }) {
const pathname = usePathname();
const searchParams = useSearchParams();
useEffect(() => {
// Track page views on route change
pxlpeak.track('page_view', {
path: pathname,
search: searchParams.toString()
});
}, [pathname, searchParams]);
return <>{children}</>;
}
// Load script in layout
// app/layout.tsx
import Script from 'next/script';
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
<Script
src="https://cdn.pxlpeak.com/v1/pxlpeak.min.js"
strategy="afterInteractive" // Load after page is interactive
/>
</body>
</html>
);
}Vue Optimization
code
// Vue 3 composable
import { onMounted, onUnmounted, watch } from 'vue';
import { useRoute } from 'vue-router';
export function useAnalytics() {
const route = useRoute();
// Track page views on route change
watch(() => route.fullPath, (path) => {
pxlpeak.track('page_view', { path });
});
return {
track: pxlpeak.track,
identify: pxlpeak.identify
};
}
// Plugin for global tracking
export const analyticsPlugin = {
install(app) {
app.config.globalProperties.$track = pxlpeak.track;
// Track all route changes
app.mixin({
watch: {
'$route'(to) {
pxlpeak.track('page_view', { path: to.path });
}
}
});
}
};Performance Monitoring
Built-in Performance Metrics
code
// Get pxlpeak performance metrics
const metrics = pxlpeak.getPerformanceMetrics();
console.log(metrics);
// {
// scriptLoadTime: 45, // ms to load script
// initTime: 12, // ms to initialize
// eventsTracked: 156, // total events
// eventsSent: 150, // successfully sent
// eventsFailed: 0, // failed events
// avgEventLatency: 23, // ms average API latency
// batchesSent: 15, // batches sent
// avgBatchSize: 10, // events per batch
// queueSize: 6, // currently queued
// memoryUsage: 1.2 // MB estimated
// }Custom Performance Tracking
code
// Track pxlpeak performance
const perfObserver = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.name.includes('pxlpeak')) {
console.log(`${entry.name}: ${entry.duration}ms`);
}
}
});
perfObserver.observe({ entryTypes: ['resource', 'measure'] });
// Manual performance marks
performance.mark('pxlpeak-init-start');
pxlpeak.init('YOUR_SITE_ID');
performance.mark('pxlpeak-init-end');
performance.measure('pxlpeak-init', 'pxlpeak-init-start', 'pxlpeak-init-end');Performance Checklist
code
## pxlpeak Performance Checklist
### Script Loading
- [ ] Using async script loading
- [ ] DNS prefetch/preconnect configured
- [ ] Script loads after critical resources
- [ ] Consider deferred loading for non-critical pages
### Event Tracking
- [ ] High-frequency events are throttled
- [ ] Input events are debounced
- [ ] Passive event listeners used where appropriate
- [ ] Intersection Observer used for visibility tracking
### Batching & Network
- [ ] Event batching enabled
- [ ] Flush on page unload configured
- [ ] Offline support enabled if needed
- [ ] Compression enabled
### Memory
- [ ] Event listeners cleaned up on navigation
- [ ] Storage limits configured
- [ ] No memory leaks in SPA
### Core Web Vitals
- [ ] Zero CLS impact verified
- [ ] Minimal FID/INP impact verified
- [ ] LCP not blocked by analytics
### Monitoring
- [ ] Performance metrics being tracked
- [ ] Alerts set for performance degradationNext Steps
- Audit Current Setup - Check your current loading strategy
- Enable Batching - Reduce network requests
- Monitor Impact - Track Core Web Vitals impact
- Optimize Events - Throttle/debounce high-frequency events
- Test Performance - Use Lighthouse and WebPageTest
Related Guides: