Debugging and Troubleshooting Polyfills

1. Browser DevTools for Polyfill Debugging

Tool/Feature Browser Use Case Key Features
Sources Panel All modern browsers Inspect polyfill code Breakpoints, step through
Console All browsers Test features, log errors Command line, logging
Network Tab All browsers Monitor polyfill loading Timing, size, caching
Performance Profiler Chrome, Edge, Firefox Analyze polyfill overhead Flame charts, call trees
Memory Profiler Chrome, Edge Detect memory leaks Heap snapshots, allocation
Coverage Tool Chrome, Edge Find unused polyfills Code coverage, optimization

Example: DevTools debugging utilities

// devtools-helpers.js
var PolyfillDebugger = {
    // Check if polyfill is loaded
    isPolyfillLoaded: function(featureName) {
        var polyfillMarkers = {
            'Promise': function() {
                return window.Promise && Promise.toString().indexOf('[native code]') === -1;
            },
            'fetch': function() {
                return window.fetch && fetch.polyfill === true;
            },
            'IntersectionObserver': function() {
                return window.IntersectionObserver && 
                       IntersectionObserver.toString().indexOf('[native code]') === -1;
            }
        };
        
        var checker = polyfillMarkers[featureName];
        return checker ? checker() : false;
    },
    
    // List all loaded polyfills
    listLoadedPolyfills: function() {
        var polyfills = [];
        var features = [
            'Promise', 'fetch', 'Map', 'Set', 'WeakMap', 'WeakSet',
            'Symbol', 'Array.from', 'Object.assign', 'IntersectionObserver',
            'ResizeObserver', 'requestAnimationFrame', 'CustomEvent'
        ];
        
        features.forEach(function(feature) {
            if (this.isPolyfillLoaded(feature)) {
                polyfills.push(feature);
            }
        }.bind(this));
        
        console.table(polyfills.map(function(name) {
            return { Feature: name, Polyfilled: '✓' };
        }));
        
        return polyfills;
    },
    
    // Set breakpoint on polyfill
    breakOnPolyfill: function(methodName) {
        var original = window[methodName];
        
        if (!original) {
            console.error('Method not found:', methodName);
            return;
        }
        
        window[methodName] = function() {
            debugger; // Breakpoint here
            return original.apply(this, arguments);
        };
        
        console.log('Breakpoint set on:', methodName);
    },
    
    // Trace polyfill calls
    tracePolyfill: function(obj, methodName) {
        var original = obj[methodName];
        
        if (!original) {
            console.error('Method not found:', methodName);
            return;
        }
        
        obj[methodName] = function() {
            console.group('Polyfill Call: ' + methodName);
            console.log('Arguments:', arguments);
            console.trace('Call Stack');
            
            var result = original.apply(this, arguments);
            
            console.log('Return Value:', result);
            console.groupEnd();
            
            return result;
        };
        
        console.log('Tracing enabled for:', methodName);
    },
    
    // Inspect polyfill source
    inspectPolyfill: function(featureName) {
        var feature = window[featureName];
        
        if (!feature) {
            console.error('Feature not found:', featureName);
            return;
        }
        
        console.group('Polyfill Inspection: ' + featureName);
        console.log('Type:', typeof feature);
        console.log('Source:', feature.toString());
        console.log('Properties:', Object.getOwnPropertyNames(feature));
        
        // Check if native or polyfilled
        var isNative = feature.toString().indexOf('[native code]') !== -1;
        console.log('Native:', isNative);
        console.log('Polyfilled:', !isNative);
        
        console.groupEnd();
    },
    
    // Monitor polyfill performance
    monitorPerformance: function(obj, methodName, iterations) {
        iterations = iterations || 1000;
        
        var original = obj[methodName];
        if (!original) {
            console.error('Method not found:', methodName);
            return;
        }
        
        console.log('Benchmarking ' + methodName + ' (' + iterations + ' iterations)...');
        
        var start = performance.now();
        for (var i = 0; i < iterations; i++) {
            original.call(obj);
        }
        var end = performance.now();
        
        var duration = end - start;
        var avgTime = duration / iterations;
        
        console.log('Total Time: ' + duration.toFixed(2) + 'ms');
        console.log('Average Time: ' + avgTime.toFixed(4) + 'ms');
        console.log('Ops/Second: ' + (1000 / avgTime).toFixed(0));
    },
    
    // Check code coverage for polyfills
    checkCoverage: function() {
        console.log('Run this in Chrome DevTools:');
        console.log('1. Open Coverage tab (Cmd+Shift+P > "Show Coverage")');
        console.log('2. Click record button');
        console.log('3. Interact with your app');
        console.log('4. Click stop to see unused polyfills');
        console.log('5. Filter by "polyfill" to see polyfill coverage');
    },
    
    // Debug feature detection
    debugFeatureDetection: function() {
        var features = {
            'Promise': typeof Promise !== 'undefined',
            'fetch': typeof fetch !== 'undefined',
            'Map': typeof Map !== 'undefined',
            'Set': typeof Set !== 'undefined',
            'Symbol': typeof Symbol !== 'undefined',
            'Proxy': typeof Proxy !== 'undefined',
            'WeakMap': typeof WeakMap !== 'undefined',
            'IntersectionObserver': typeof IntersectionObserver !== 'undefined',
            'ResizeObserver': typeof ResizeObserver !== 'undefined',
            'CustomElements': typeof customElements !== 'undefined',
            'ShadowDOM': 'attachShadow' in Element.prototype,
            'ES6 Classes': (function() {
                try {
                    eval('class Test {}');
                    return true;
                } catch (e) {
                    return false;
                }
            })()
        };
        
        console.table(features);
        return features;
    }
};

// Console helpers - add to global scope for easy access
window.polyfillDebug = PolyfillDebugger;

// Usage examples:
// polyfillDebug.listLoadedPolyfills();
// polyfillDebug.breakOnPolyfill('fetch');
// polyfillDebug.tracePolyfill(Array.prototype, 'find');
// polyfillDebug.inspectPolyfill('Promise');
// polyfillDebug.monitorPerformance(Array.prototype, 'map', 10000);
// polyfillDebug.debugFeatureDetection();
Note: Use Chrome DevTools Coverage to identify unused polyfills. Filter by "polyfill" and remove unused code to reduce bundle size.

2. Common Polyfill Issues and Solutions

Issue Symptoms Root Cause Solution
Polyfill Not Loading Feature undefined, errors Missing import, CSP block Check network, CSP headers
Order of Execution Race conditions, undefined refs Async loading conflicts Load polyfills synchronously
Polyfill Conflicts Incorrect behavior, overrides Multiple polyfills clash Consolidate, check order
Performance Degradation Slow page load, jank Heavy polyfills, poor impl Profile, optimize, lazy load
Memory Leaks Growing heap, crashes Retained references Use WeakMap, cleanup
CSP Violations Blocked execution unsafe-eval in polyfill Use CSP-safe alternatives
Build Tool Issues Missing polyfills in prod Incorrect transpilation Configure Babel properly

Example: Common issue detection and fixes

// polyfill-troubleshooter.js
var PolyfillTroubleshooter = {
    // Diagnose polyfill issues
    diagnose: function() {
        var issues = [];
        
        // Check 1: Are polyfills loading?
        if (!this.checkPolyfillsLoaded()) {
            issues.push({
                severity: 'error',
                issue: 'Polyfills not loading',
                solution: 'Check network tab for failed requests'
            });
        }
        
        // Check 2: Are there conflicts?
        var conflicts = this.detectConflicts();
        if (conflicts.length > 0) {
            issues.push({
                severity: 'warning',
                issue: 'Polyfill conflicts detected',
                conflicts: conflicts,
                solution: 'Remove duplicate polyfills or adjust load order'
            });
        }
        
        // Check 3: Performance issues?
        var perfIssues = this.checkPerformance();
        if (perfIssues.length > 0) {
            issues.push({
                severity: 'warning',
                issue: 'Performance issues detected',
                details: perfIssues,
                solution: 'Consider lazy loading or optimizing polyfills'
            });
        }
        
        // Check 4: Memory leaks?
        this.checkMemoryLeaks().then(function(hasLeaks) {
            if (hasLeaks) {
                issues.push({
                    severity: 'error',
                    issue: 'Potential memory leak detected',
                    solution: 'Use Chrome DevTools Memory profiler'
                });
            }
        });
        
        // Check 5: CSP violations?
        if (this.checkCSPViolations()) {
            issues.push({
                severity: 'error',
                issue: 'CSP violations detected',
                solution: 'Use CSP-safe polyfills or adjust CSP headers'
            });
        }
        
        this.reportIssues(issues);
        return issues;
    },
    
    // Check if polyfills are loaded
    checkPolyfillsLoaded: function() {
        var scripts = document.querySelectorAll('script[src*="polyfill"]');
        
        if (scripts.length === 0) {
            console.warn('No polyfill scripts found');
            return false;
        }
        
        var allLoaded = true;
        scripts.forEach(function(script) {
            if (!script.complete || script.readyState === 'loading') {
                console.error('Polyfill not loaded:', script.src);
                allLoaded = false;
            }
        });
        
        return allLoaded;
    },
    
    // Detect polyfill conflicts
    detectConflicts: function() {
        var conflicts = [];
        
        // Check for duplicate polyfills
        var methods = [
            { obj: Array.prototype, name: 'find' },
            { obj: Array.prototype, name: 'includes' },
            { obj: Object, name: 'assign' },
            { obj: String.prototype, name: 'includes' }
        ];
        
        methods.forEach(function(method) {
            var descriptor = Object.getOwnPropertyDescriptor(method.obj, method.name);
            
            if (descriptor && descriptor.configurable === false) {
                // Check if it was polyfilled after being native
                var source = method.obj[method.name].toString();
                var isNative = source.indexOf('[native code]') !== -1;
                
                if (!isNative && !descriptor.configurable) {
                    conflicts.push({
                        method: method.name,
                        issue: 'Non-configurable polyfill override',
                        recommendation: 'Check polyfill load order'
                    });
                }
            }
        });
        
        return conflicts;
    },
    
    // Check performance issues
    checkPerformance: function() {
        var issues = [];
        
        // Check load time
        var resources = performance.getEntriesByType('resource');
        resources.forEach(function(resource) {
            if (resource.name.indexOf('polyfill') !== -1) {
                if (resource.duration > 500) {
                    issues.push({
                        file: resource.name,
                        issue: 'Slow loading (>500ms)',
                        duration: resource.duration.toFixed(2) + 'ms'
                    });
                }
                
                if (resource.transferSize > 100 * 1024) {
                    issues.push({
                        file: resource.name,
                        issue: 'Large file size (>100KB)',
                        size: (resource.transferSize / 1024).toFixed(2) + 'KB'
                    });
                }
            }
        });
        
        return issues;
    },
    
    // Check for memory leaks
    checkMemoryLeaks: function() {
        if (!performance.memory) {
            console.warn('performance.memory not available');
            return Promise.resolve(false);
        }
        
        var initialHeap = performance.memory.usedJSHeapSize;
        
        return new Promise(function(resolve) {
            setTimeout(function() {
                var currentHeap = performance.memory.usedJSHeapSize;
                var growth = currentHeap - initialHeap;
                var growthMB = growth / 1024 / 1024;
                
                if (growthMB > 10) {
                    console.warn('Significant memory growth detected: ' + 
                               growthMB.toFixed(2) + 'MB');
                    resolve(true);
                } else {
                    resolve(false);
                }
            }, 5000);
        });
    },
    
    // Check for CSP violations
    checkCSPViolations: function() {
        var hasViolations = false;
        
        // Listen for CSP violations
        document.addEventListener('securitypolicyviolation', function(e) {
            console.error('CSP Violation:', e.violatedDirective);
            hasViolations = true;
        });
        
        return hasViolations;
    },
    
    // Report all issues
    reportIssues: function(issues) {
        if (issues.length === 0) {
            console.log('✓ No polyfill issues detected');
            return;
        }
        
        console.group('Polyfill Issues Detected (' + issues.length + ')');
        
        issues.forEach(function(issue, index) {
            var icon = issue.severity === 'error' ? '❌' : '⚠️';
            console.group(icon + ' Issue ' + (index + 1) + ': ' + issue.issue);
            console.log('Severity:', issue.severity);
            console.log('Solution:', issue.solution);
            
            if (issue.conflicts) {
                console.log('Conflicts:', issue.conflicts);
            }
            if (issue.details) {
                console.table(issue.details);
            }
            
            console.groupEnd();
        });
        
        console.groupEnd();
    },
    
    // Fix common issues automatically
    autoFix: function() {
        console.log('Attempting automatic fixes...');
        
        // Fix 1: Remove duplicate polyfills
        this.removeDuplicatePolyfills();
        
        // Fix 2: Optimize polyfill loading
        this.optimizeLoading();
        
        console.log('Auto-fix complete. Run diagnose() to verify.');
    },
    
    // Remove duplicate polyfills
    removeDuplicatePolyfills: function() {
        var scripts = document.querySelectorAll('script[src*="polyfill"]');
        var seen = {};
        
        scripts.forEach(function(script) {
            var src = script.src;
            if (seen[src]) {
                console.log('Removing duplicate polyfill:', src);
                script.remove();
            } else {
                seen[src] = true;
            }
        });
    },
    
    // Optimize polyfill loading
    optimizeLoading: function() {
        // Add async/defer to non-critical polyfills
        var scripts = document.querySelectorAll('script[src*="polyfill"]');
        
        scripts.forEach(function(script) {
            if (!script.async && !script.defer) {
                // Check if polyfill is critical
                var isCritical = script.src.includes('critical') || 
                                script.src.includes('core');
                
                if (!isCritical) {
                    script.defer = true;
                    console.log('Added defer to:', script.src);
                }
            }
        });
    }
};

// Quick diagnostic command
window.polyfillCheck = function() {
    return PolyfillTroubleshooter.diagnose();
};

// Usage:
// polyfillCheck(); // Run diagnostics
// PolyfillTroubleshooter.autoFix(); // Attempt automatic fixes
Warning: Load polyfills before app code. Async loading can cause race conditions where app code tries to use polyfilled features before they're available.

3. Performance Profiling with Polyfills

Metric Tool Target Action
Parse Time DevTools Performance <50 ms Minify, compress
Execution Time Performance API <100 ms Lazy load
Method Overhead Benchmarks <2x native Optimize implementation
Bundle Size webpack-bundle-analyzer <100 KB Tree shake, split
FCP Impact Lighthouse <100 ms delay Defer non-critical
TTI Impact WebPageTest <200 ms delay Code splitting

Example: Performance profiling suite

// performance-profiler.js
var PolyfillProfiler = {
    profiles: [],
    
    // Profile polyfill loading
    profileLoading: function(polyfillName, loadFn) {
        var startMark = 'polyfill-load-start-' + polyfillName;
        var endMark = 'polyfill-load-end-' + polyfillName;
        var measureName = 'polyfill-load-' + polyfillName;
        
        performance.mark(startMark);
        
        return Promise.resolve(loadFn()).then(function() {
            performance.mark(endMark);
            performance.measure(measureName, startMark, endMark);
            
            var measure = performance.getEntriesByName(measureName)[0];
            
            var profile = {
                name: polyfillName,
                type: 'loading',
                duration: measure.duration,
                timestamp: Date.now()
            };
            
            this.profiles.push(profile);
            
            console.log('Polyfill ' + polyfillName + ' loaded in ' + 
                       measure.duration.toFixed(2) + 'ms');
            
            return profile;
        }.bind(this));
    },
    
    // Profile method execution
    profileMethod: function(obj, methodName, iterations) {
        iterations = iterations || 10000;
        
        var method = obj[methodName];
        if (!method) {
            console.error('Method not found:', methodName);
            return;
        }
        
        // Warm up
        for (var i = 0; i < 100; i++) {
            method.call(obj, i);
        }
        
        // Profile
        var start = performance.now();
        
        for (var i = 0; i < iterations; i++) {
            method.call(obj, i);
        }
        
        var end = performance.now();
        var duration = end - start;
        var avgTime = duration / iterations;
        
        var profile = {
            name: methodName,
            type: 'execution',
            totalTime: duration,
            avgTime: avgTime,
            iterations: iterations,
            opsPerSecond: Math.round(1000 / avgTime)
        };
        
        this.profiles.push(profile);
        
        console.log('Method: ' + methodName);
        console.log('  Total: ' + duration.toFixed(2) + 'ms');
        console.log('  Average: ' + avgTime.toFixed(4) + 'ms');
        console.log('  Ops/sec: ' + profile.opsPerSecond.toLocaleString());
        
        return profile;
    },
    
    // Compare native vs polyfill performance
    comparePerformance: function(nativeFn, polyfillFn, testName, iterations) {
        iterations = iterations || 10000;
        
        console.group('Performance Comparison: ' + testName);
        
        // Profile native
        var nativeStart = performance.now();
        for (var i = 0; i < iterations; i++) {
            nativeFn();
        }
        var nativeDuration = performance.now() - nativeStart;
        
        // Profile polyfill
        var polyfillStart = performance.now();
        for (var i = 0; i < iterations; i++) {
            polyfillFn();
        }
        var polyfillDuration = performance.now() - polyfillStart;
        
        var slowdown = polyfillDuration / nativeDuration;
        var acceptable = slowdown < 2;
        
        console.log('Native: ' + nativeDuration.toFixed(2) + 'ms');
        console.log('Polyfill: ' + polyfillDuration.toFixed(2) + 'ms');
        console.log('Slowdown: ' + slowdown.toFixed(2) + 'x');
        console.log('Acceptable: ' + (acceptable ? '✓' : '✗'));
        
        console.groupEnd();
        
        return {
            test: testName,
            native: nativeDuration,
            polyfill: polyfillDuration,
            slowdown: slowdown,
            acceptable: acceptable
        };
    },
    
    // Profile FCP impact
    profileFCPImpact: function() {
        if (!PerformanceObserver) {
            console.warn('PerformanceObserver not available');
            return;
        }
        
        var observer = new PerformanceObserver(function(list) {
            list.getEntries().forEach(function(entry) {
                if (entry.name === 'first-contentful-paint') {
                    var fcp = entry.startTime;
                    
                    // Calculate polyfill impact
                    var polyfillMarks = performance.getEntriesByType('mark')
                        .filter(function(m) { return m.name.includes('polyfill'); });
                    
                    var polyfillTime = 0;
                    polyfillMarks.forEach(function(mark) {
                        var measure = performance.getEntriesByName(mark.name)[0];
                        if (measure && measure.startTime < fcp) {
                            polyfillTime += measure.duration || 0;
                        }
                    });
                    
                    var impact = (polyfillTime / fcp) * 100;
                    
                    console.log('FCP: ' + fcp.toFixed(2) + 'ms');
                    console.log('Polyfill Time: ' + polyfillTime.toFixed(2) + 'ms');
                    console.log('Impact: ' + impact.toFixed(1) + '%');
                    
                    this.profiles.push({
                        type: 'fcp-impact',
                        fcp: fcp,
                        polyfillTime: polyfillTime,
                        impact: impact
                    });
                }
            }.bind(this));
        }.bind(this));
        
        observer.observe({ entryTypes: ['paint'] });
    },
    
    // Generate comprehensive report
    generateReport: function() {
        console.group('📊 Polyfill Performance Report');
        
        // Group by type
        var byType = {};
        this.profiles.forEach(function(profile) {
            if (!byType[profile.type]) {
                byType[profile.type] = [];
            }
            byType[profile.type].push(profile);
        });
        
        // Loading performance
        if (byType.loading) {
            console.group('Loading Performance');
            var totalLoadTime = byType.loading.reduce(function(sum, p) {
                return sum + p.duration;
            }, 0);
            
            console.log('Total Load Time: ' + totalLoadTime.toFixed(2) + 'ms');
            console.table(byType.loading);
            console.groupEnd();
        }
        
        // Execution performance
        if (byType.execution) {
            console.group('Execution Performance');
            console.table(byType.execution.map(function(p) {
                return {
                    Method: p.name,
                    'Avg Time': p.avgTime.toFixed(4) + 'ms',
                    'Ops/sec': p.opsPerSecond.toLocaleString()
                };
            }));
            console.groupEnd();
        }
        
        // FCP impact
        if (byType['fcp-impact']) {
            console.group('FCP Impact');
            byType['fcp-impact'].forEach(function(p) {
                console.log('FCP: ' + p.fcp.toFixed(2) + 'ms');
                console.log('Polyfill Impact: ' + p.impact.toFixed(1) + '%');
            });
            console.groupEnd();
        }
        
        // Recommendations
        console.group('Recommendations');
        var recommendations = this.generateRecommendations(byType);
        recommendations.forEach(function(rec) {
            console.log(rec.icon + ' ' + rec.message);
        });
        console.groupEnd();
        
        console.groupEnd();
        
        return {
            profiles: this.profiles,
            summary: byType,
            recommendations: recommendations
        };
    },
    
    // Generate recommendations
    generateRecommendations: function(byType) {
        var recommendations = [];
        
        // Check loading time
        if (byType.loading) {
            var totalLoadTime = byType.loading.reduce(function(sum, p) {
                return sum + p.duration;
            }, 0);
            
            if (totalLoadTime > 100) {
                recommendations.push({
                    icon: '⚠️',
                    message: 'Total polyfill load time exceeds 100ms (' + 
                            totalLoadTime.toFixed(2) + 'ms). Consider lazy loading.'
                });
            }
        }
        
        // Check execution performance
        if (byType.execution) {
            byType.execution.forEach(function(profile) {
                if (profile.avgTime > 1) {
                    recommendations.push({
                        icon: '⚠️',
                        message: profile.name + ' is slow (>1ms). Optimize implementation.'
                    });
                }
            });
        }
        
        // Check FCP impact
        if (byType['fcp-impact']) {
            byType['fcp-impact'].forEach(function(profile) {
                if (profile.impact > 20) {
                    recommendations.push({
                        icon: '❌',
                        message: 'Polyfills delay FCP by ' + profile.impact.toFixed(1) + 
                                '%. Use differential serving.'
                    });
                }
            });
        }
        
        if (recommendations.length === 0) {
            recommendations.push({
                icon: '✓',
                message: 'All metrics within acceptable ranges'
            });
        }
        
        return recommendations;
    }
};

// Usage examples:
// Profile polyfill loading
PolyfillProfiler.profileLoading('Promise', function() {
    return import('es6-promise/auto');
});

// Profile method execution
PolyfillProfiler.profileMethod(Array.prototype, 'find', 10000);

// Compare native vs polyfill
if (Array.prototype.map) {
    var nativeMap = Array.prototype.map;
    var polyfillMap = function() { /* polyfill implementation */ };
    
    PolyfillProfiler.comparePerformance(
        function() { [1,2,3].map(function(x) { return x * 2; }); },
        function() { [1,2,3].map(function(x) { return x * 2; }); },
        'Array.map',
        10000
    );
}

// Monitor FCP impact
PolyfillProfiler.profileFCPImpact();

// Generate report after page load
window.addEventListener('load', function() {
    setTimeout(function() {
        PolyfillProfiler.generateReport();
    }, 2000);
});
Note: Profile polyfills in target browsers (especially legacy ones). Modern browser performance doesn't reflect real-world usage.

4. Feature Detection Debugging Techniques

Technique Use Case Example Gotcha
typeof Check Check if feature exists typeof Promise !== 'undefined' May exist but be broken
in Operator Check method existence 'includes' in Array.prototype Doesn't verify correctness
try-catch Test Test feature behavior Try executing, catch errors Can hide other errors
Native Code Check Verify if native fn.toString() includes '[native code]' Can be spoofed
Behavior Test Test actual functionality Execute and verify result Can be slow
CSS.supports() CSS feature detection CSS.supports('display', 'grid') Limited browser support

Example: Advanced feature detection utilities

// feature-detection-debugger.js
var FeatureDetector = {
    // Comprehensive feature check
    detectFeature: function(featureName) {
        var detectors = {
            'Promise': this.detectPromise.bind(this),
            'fetch': this.detectFetch.bind(this),
            'Map': this.detectMap.bind(this),
            'Set': this.detectSet.bind(this),
            'Symbol': this.detectSymbol.bind(this),
            'Proxy': this.detectProxy.bind(this),
            'IntersectionObserver': this.detectIntersectionObserver.bind(this),
            'CustomElements': this.detectCustomElements.bind(this)
        };
        
        var detector = detectors[featureName];
        
        if (!detector) {
            console.error('No detector for feature:', featureName);
            return null;
        }
        
        var result = detector();
        
        console.group('Feature Detection: ' + featureName);
        console.log('Exists:', result.exists);
        console.log('Native:', result.isNative);
        console.log('Working:', result.isWorking);
        console.log('Details:', result.details);
        console.groupEnd();
        
        return result;
    },
    
    // Detect Promise support
    detectPromise: function() {
        var exists = typeof Promise !== 'undefined';
        var isNative = exists && Promise.toString().indexOf('[native code]') !== -1;
        var isWorking = false;
        var details = {};
        
        if (exists) {
            try {
                var promise = new Promise(function(resolve) {
                    resolve('test');
                });
                
                isWorking = promise instanceof Promise;
                
                // Test Promise.all
                details.hasAll = typeof Promise.all === 'function';
                details.hasRace = typeof Promise.race === 'function';
                details.hasAllSettled = typeof Promise.allSettled === 'function';
                details.hasAny = typeof Promise.any === 'function';
            } catch (e) {
                details.error = e.message;
            }
        }
        
        return { exists: exists, isNative: isNative, isWorking: isWorking, details: details };
    },
    
    // Detect fetch support
    detectFetch: function() {
        var exists = typeof fetch !== 'undefined';
        var isNative = exists && fetch.toString().indexOf('[native code]') !== -1;
        var isWorking = false;
        var details = {};
        
        if (exists) {
            try {
                // Check if fetch returns a Promise
                var result = fetch('data:text/plain,test');
                isWorking = result instanceof Promise;
                result.catch(function() {}); // Prevent unhandled rejection
                
                details.hasAbortController = typeof AbortController !== 'undefined';
                details.hasHeaders = typeof Headers !== 'undefined';
                details.hasRequest = typeof Request !== 'undefined';
                details.hasResponse = typeof Response !== 'undefined';
            } catch (e) {
                details.error = e.message;
            }
        }
        
        return { exists: exists, isNative: isNative, isWorking: isWorking, details: details };
    },
    
    // Detect Map support
    detectMap: function() {
        var exists = typeof Map !== 'undefined';
        var isNative = exists && Map.toString().indexOf('[native code]') !== -1;
        var isWorking = false;
        var details = {};
        
        if (exists) {
            try {
                var map = new Map();
                map.set('key', 'value');
                
                isWorking = map.get('key') === 'value' && map.size === 1;
                
                // Test iterator
                details.hasIterator = typeof map[Symbol.iterator] === 'function';
                details.hasForEach = typeof map.forEach === 'function';
            } catch (e) {
                details.error = e.message;
            }
        }
        
        return { exists: exists, isNative: isNative, isWorking: isWorking, details: details };
    },
    
    // Detect Set support
    detectSet: function() {
        var exists = typeof Set !== 'undefined';
        var isNative = exists && Set.toString().indexOf('[native code]') !== -1;
        var isWorking = false;
        var details = {};
        
        if (exists) {
            try {
                var set = new Set();
                set.add('value');
                
                isWorking = set.has('value') && set.size === 1;
                
                details.hasIterator = typeof set[Symbol.iterator] === 'function';
                details.hasForEach = typeof set.forEach === 'function';
            } catch (e) {
                details.error = e.message;
            }
        }
        
        return { exists: exists, isNative: isNative, isWorking: isWorking, details: details };
    },
    
    // Detect Symbol support
    detectSymbol: function() {
        var exists = typeof Symbol !== 'undefined';
        var isNative = exists && Symbol.toString().indexOf('[native code]') !== -1;
        var isWorking = false;
        var details = {};
        
        if (exists) {
            try {
                var sym = Symbol('test');
                isWorking = typeof sym === 'symbol';
                
                details.hasFor = typeof Symbol.for === 'function';
                details.hasKeyFor = typeof Symbol.keyFor === 'function';
                details.hasIterator = typeof Symbol.iterator !== 'undefined';
            } catch (e) {
                details.error = e.message;
            }
        }
        
        return { exists: exists, isNative: isNative, isWorking: isWorking, details: details };
    },
    
    // Detect Proxy support
    detectProxy: function() {
        var exists = typeof Proxy !== 'undefined';
        var isNative = exists && Proxy.toString().indexOf('[native code]') !== -1;
        var isWorking = false;
        var details = {};
        
        if (exists) {
            try {
                var target = {};
                var handler = {
                    get: function(obj, prop) {
                        return prop in obj ? obj[prop] : 'proxy';
                    }
                };
                
                var proxy = new Proxy(target, handler);
                isWorking = proxy.test === 'proxy';
                
                details.hasRevocable = typeof Proxy.revocable === 'function';
            } catch (e) {
                details.error = e.message;
            }
        }
        
        return { exists: exists, isNative: isNative, isWorking: isWorking, details: details };
    },
    
    // Detect IntersectionObserver support
    detectIntersectionObserver: function() {
        var exists = typeof IntersectionObserver !== 'undefined';
        var isNative = exists && IntersectionObserver.toString().indexOf('[native code]') !== -1;
        var isWorking = false;
        var details = {};
        
        if (exists) {
            try {
                var observer = new IntersectionObserver(function() {});
                isWorking = typeof observer.observe === 'function';
                observer.disconnect();
            } catch (e) {
                details.error = e.message;
            }
        }
        
        return { exists: exists, isNative: isNative, isWorking: isWorking, details: details };
    },
    
    // Detect Custom Elements support
    detectCustomElements: function() {
        var exists = typeof customElements !== 'undefined';
        var isNative = exists && customElements.define.toString().indexOf('[native code]') !== -1;
        var isWorking = false;
        var details = {};
        
        if (exists) {
            try {
                isWorking = typeof customElements.define === 'function';
                details.hasGet = typeof customElements.get === 'function';
                details.hasWhenDefined = typeof customElements.whenDefined === 'function';
            } catch (e) {
                details.error = e.message;
            }
        }
        
        return { exists: exists, isNative: isNative, isWorking: isWorking, details: details };
    },
    
    // Batch detection
    detectAll: function() {
        var features = [
            'Promise', 'fetch', 'Map', 'Set', 'Symbol', 'Proxy',
            'IntersectionObserver', 'CustomElements'
        ];
        
        var results = {};
        
        features.forEach(function(feature) {
            results[feature] = this.detectFeature(feature);
        }.bind(this));
        
        console.table(Object.keys(results).map(function(name) {
            var result = results[name];
            return {
                Feature: name,
                Exists: result.exists ? '✓' : '✗',
                Native: result.isNative ? '✓' : '✗',
                Working: result.isWorking ? '✓' : '✗'
            };
        }));
        
        return results;
    },
    
    // Debug why feature detection fails
    debugDetection: function(featureName, detectionCode) {
        console.group('Debugging Feature Detection: ' + featureName);
        
        try {
            var result = detectionCode();
            console.log('Detection Result:', result);
            console.log('Type:', typeof result);
            console.log('Truthy:', !!result);
        } catch (e) {
            console.error('Detection Error:', e);
            console.log('Stack:', e.stack);
        }
        
        console.groupEnd();
    }
};

// Global helper
window.detectFeature = FeatureDetector.detectFeature.bind(FeatureDetector);
window.detectAllFeatures = FeatureDetector.detectAll.bind(FeatureDetector);

// Usage:
// detectFeature('Promise');
// detectAllFeatures();
// FeatureDetector.debugDetection('CustomElements', function() {
//     return typeof customElements !== 'undefined';
// });
Warning: Feature detection can give false positives. Always test behavior, not just existence. Some browsers partially implement features.

5. Polyfill Conflict Resolution Strategies

Conflict Type Cause Detection Resolution
Duplicate Polyfills Multiple libraries include same polyfill Check for multiple implementations Deduplicate, use single source
Version Conflicts Different polyfill versions Compare implementations Use latest compatible version
Override Conflicts Polyfill overrides native incorrectly Check for native code Guard with feature detection
Load Order Issues Polyfills loaded in wrong order Check dependencies Correct load order
Namespace Collisions Global variable conflicts Check window object Use modules, avoid globals
Prototype Pollution Unsafe prototype extensions Check prototype chain Use Object.defineProperty

Example: Conflict detection and resolution

// conflict-resolver.js
var PolyfillConflictResolver = {
    conflicts: [],
    
    // Detect all conflicts
    detectConflicts: function() {
        this.conflicts = [];
        
        // Check for duplicate polyfills
        this.checkDuplicates();
        
        // Check for override conflicts
        this.checkOverrides();
        
        // Check for namespace collisions
        this.checkNamespaceCollisions();
        
        // Report conflicts
        this.reportConflicts();
        
        return this.conflicts;
    },
    
    // Check for duplicate polyfills
    checkDuplicates: function() {
        var methods = [
            { obj: Array.prototype, name: 'find', feature: 'Array.find' },
            { obj: Array.prototype, name: 'includes', feature: 'Array.includes' },
            { obj: Object, name: 'assign', feature: 'Object.assign' },
            { obj: String.prototype, name: 'includes', feature: 'String.includes' },
            { obj: window, name: 'Promise', feature: 'Promise' },
            { obj: window, name: 'fetch', feature: 'fetch' }
        ];
        
        methods.forEach(function(method) {
            var fn = method.obj[method.name];
            
            if (!fn) return;
            
            // Check if method has been polyfilled multiple times
            var descriptor = Object.getOwnPropertyDescriptor(method.obj, method.name);
            
            if (descriptor && descriptor.writable === false && descriptor.configurable === false) {
                // Check if there are multiple definitions
                var source = fn.toString();
                
                if (source.includes('polyfill') && source.length > 1000) {
                    this.conflicts.push({
                        type: 'duplicate',
                        feature: method.feature,
                        severity: 'warning',
                        message: 'Possible duplicate polyfill detected'
                    });
                }
            }
        }.bind(this));
    },
    
    // Check for override conflicts
    checkOverrides: function() {
        var methods = [
            { obj: Array.prototype, name: 'map' },
            { obj: Array.prototype, name: 'filter' },
            { obj: Array.prototype, name: 'reduce' },
            { obj: Object, name: 'keys' },
            { obj: Object, name: 'values' }
        ];
        
        methods.forEach(function(method) {
            var fn = method.obj[method.name];
            
            if (!fn) return;
            
            var source = fn.toString();
            var isNative = source.indexOf('[native code]') !== -1;
            
            // Check if a polyfill overrode a native method
            var descriptor = Object.getOwnPropertyDescriptor(method.obj, method.name);
            
            if (!isNative && descriptor && !descriptor.configurable) {
                this.conflicts.push({
                    type: 'override',
                    feature: method.obj.constructor.name + '.' + method.name,
                    severity: 'error',
                    message: 'Polyfill incorrectly overrides native method'
                });
            }
        }.bind(this));
    },
    
    // Check for namespace collisions
    checkNamespaceCollisions: function() {
        var globalVars = ['Promise', 'Map', 'Set', 'Symbol', 'Proxy', 'Reflect'];
        
        globalVars.forEach(function(varName) {
            var value = window[varName];
            
            if (!value) return;
            
            // Check if variable is defined multiple times
            var descriptor = Object.getOwnPropertyDescriptor(window, varName);
            
            if (descriptor && descriptor.configurable === false) {
                var source = value.toString();
                
                if (source.includes('polyfill')) {
                    this.conflicts.push({
                        type: 'namespace',
                        feature: varName,
                        severity: 'warning',
                        message: 'Global namespace collision detected'
                    });
                }
            }
        }.bind(this));
    },
    
    // Report all conflicts
    reportConflicts: function() {
        if (this.conflicts.length === 0) {
            console.log('✓ No polyfill conflicts detected');
            return;
        }
        
        console.group('⚠️  Polyfill Conflicts (' + this.conflicts.length + ')');
        
        this.conflicts.forEach(function(conflict, index) {
            var icon = conflict.severity === 'error' ? '❌' : '⚠️';
            
            console.group(icon + ' Conflict ' + (index + 1) + ': ' + conflict.type);
            console.log('Feature:', conflict.feature);
            console.log('Severity:', conflict.severity);
            console.log('Message:', conflict.message);
            console.groupEnd();
        });
        
        console.groupEnd();
    },
    
    // Resolve conflicts automatically
    resolveConflicts: function() {
        console.log('Attempting to resolve conflicts...');
        
        this.conflicts.forEach(function(conflict) {
            switch (conflict.type) {
                case 'duplicate':
                    this.resolveDuplicate(conflict);
                    break;
                case 'override':
                    this.resolveOverride(conflict);
                    break;
                case 'namespace':
                    this.resolveNamespace(conflict);
                    break;
            }
        }.bind(this));
        
        console.log('Conflict resolution complete');
    },
    
    // Resolve duplicate polyfills
    resolveDuplicate: function(conflict) {
        console.log('Resolving duplicate:', conflict.feature);
        
        // Remove duplicate script tags
        var scripts = document.querySelectorAll('script[src*="' + conflict.feature.toLowerCase() + '"]');
        
        if (scripts.length > 1) {
            for (var i = 1; i < scripts.length; i++) {
                console.log('Removing duplicate script:', scripts[i].src);
                scripts[i].remove();
            }
        }
    },
    
    // Resolve override conflicts
    resolveOverride: function(conflict) {
        console.error('Cannot auto-resolve override conflict:', conflict.feature);
        console.log('Manual intervention required:');
        console.log('1. Check if native implementation exists');
        console.log('2. Remove polyfill if native is available');
        console.log('3. Or guard polyfill with feature detection');
    },
    
    // Resolve namespace collisions
    resolveNamespace: function(conflict) {
        console.log('Resolving namespace collision:', conflict.feature);
        console.log('Consider using ES modules instead of global variables');
    },
    
    // Prevent future conflicts
    preventConflicts: function() {
        // Freeze native methods to prevent override
        var methods = [
            { obj: Array.prototype, names: ['map', 'filter', 'reduce', 'forEach'] },
            { obj: Object, names: ['keys', 'values', 'entries', 'assign'] }
        ];
        
        methods.forEach(function(group) {
            group.names.forEach(function(name) {
                if (group.obj[name]) {
                    var descriptor = Object.getOwnPropertyDescriptor(group.obj, name);
                    
                    if (descriptor && descriptor.configurable) {
                        Object.defineProperty(group.obj, name, {
                            value: group.obj[name],
                            writable: false,
                            configurable: false,
                            enumerable: false
                        });
                        
                        console.log('Protected:', group.obj.constructor.name + '.' + name);
                    }
                }
            });
        });
    }
};

// Global helper
window.checkPolyfillConflicts = function() {
    return PolyfillConflictResolver.detectConflicts();
};

window.resolvePolyfillConflicts = function() {
    PolyfillConflictResolver.resolveConflicts();
};

// Usage:
// checkPolyfillConflicts();
// resolvePolyfillConflicts();
// PolyfillConflictResolver.preventConflicts();

Key Takeaways - Debugging & Troubleshooting

  • DevTools: Use Sources, Console, Network, Performance, and Coverage tabs
  • Common Issues: Load order, conflicts, CSP violations, performance
  • Profiling: Measure parse, execution, FCP impact, target <2x native
  • Detection: Test behavior not just existence, check for native code
  • Conflicts: Deduplicate, correct load order, use feature detection guards