当前位置:首页 > 学习笔记 > 正文内容

前端性能优化完全指南:Web应用加速的核心实践

廖万里22小时前学习笔记0
前端性能优化完全指南
"性能是用户体验的核心指标。研究表明,页面加载时间每增加1秒,转化率下降7%。前端性能优化不仅能提升用户体验,还能降低服务器成本、提高搜索引擎排名。"

一、性能指标与测量

Core Web Vitals

Google提出的核心Web指标,用于衡量用户体验: LCP(Largest Contentful Paint):最大内容绘制时间,应小于2.5秒 FID(First Input Delay):首次输入延迟,应小于100毫秒 CLS(Cumulative Layout Shift):累积布局偏移,应小于0.1

性能测量工具

// 使用Performance API测量
const timing = performance.timing;
const metrics = {
    // DNS查询时间
    dns: timing.domainLookupEnd - timing.domainLookupStart,
    // TCP连接时间
    tcp: timing.connectEnd - timing.connectStart,
    // 请求响应时间
    request: timing.responseEnd - timing.requestStart,
    // DOM解析时间
    domParse: timing.domInteractive - timing.responseEnd,
    // 资源加载时间
    resourceLoad: timing.loadEventStart - timing.domContentLoadedEventEnd,
    // 总加载时间
    total: timing.loadEventEnd - timing.navigationStart
};

// 使用PerformanceObserver监听性能指标
const observer = new PerformanceObserver((list) => {
    for (const entry of list.getEntries()) {
        console.log(`${entry.name}: ${entry.duration}ms`);
    }
});

observer.observe({ entryTypes: ['measure', 'resource', 'paint'] });

// 测量LCP
new PerformanceObserver((list) => {
    const entries = list.getEntries();
    const lastEntry = entries[entries.length - 1];
    console.log('LCP:', lastEntry.startTime);
}).observe({ entryTypes: ['largest-contentful-paint'] });

二、加载优化

代码分割与懒加载

// Webpack代码分割
import(/* webpackChunkName: "lodash" */ 'lodash').then(_ => {
    // 使用lodash
});

// React懒加载
const LazyComponent = React.lazy(() => import('./LazyComponent'));

function App() {
    return (
        }>
            
        
    );
}

// 图片懒加载
Lazy loaded image

// IntersectionObserver实现懒加载
const lazyImages = document.querySelectorAll('img[data-src]');

const imageObserver = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            const img = entry.target;
            img.src = img.dataset.src;
            imageObserver.unobserve(img);
        }
    });
});

lazyImages.forEach(img => imageObserver.observe(img));

资源压缩与优化

// Webpack配置
module.exports = {
    optimization: {
        minimize: true,
        minimizer: [
            new TerserPlugin({
                parallel: true,
                terserOptions: {
                    compress: {
                        drop_console: true,  // 移除console
                        drop_debugger: true  // 移除debugger
                    }
                }
            }),
            new CssMinimizerPlugin()
        ],
        splitChunks: {
            chunks: 'all',
            cacheGroups: {
                vendors: {
                    test: /[\\/]node_modules[\\/]/,
                    name: 'vendors',
                    chunks: 'all'
                }
            }
        }
    }
};

// Gzip压缩(Nginx配置)
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml;
gzip_min_length 1000;
gzip_comp_level 6;

预加载与预连接
















三、渲染优化

避免强制同步布局

// 错误示例:强制同步布局(布局抖动)
function resizeAll() {
    const elements = document.querySelectorAll('.box');
    elements.forEach(el => {
        const height = el.offsetHeight;  // 读取布局属性
        el.style.height = height * 2 + 'px';  // 写入布局属性
    });
}

// 正确示例:批量读取后批量写入
function resizeAllOptimized() {
    const elements = document.querySelectorAll('.box');
    const heights = [];
    
    // 批量读取
    elements.forEach(el => {
        heights.push(el.offsetHeight);
    });
    
    // 批量写入
    elements.forEach((el, i) => {
        el.style.height = heights[i] * 2 + 'px';
    });
}

使用requestAnimationFrame

// 动画优化
function animate() {
    // 计算下一帧
    updatePosition();
    
    // 在下一帧重绘
    requestAnimationFrame(animate);
}

requestAnimationFrame(animate);

// 节流滚动事件
let ticking = false;

window.addEventListener('scroll', () => {
    if (!ticking) {
        requestAnimationFrame(() => {
            updateScrollPosition();
            ticking = false;
        });
        ticking = true;
    }
});

虚拟列表

// React虚拟列表实现
function VirtualList({ items, itemHeight, containerHeight }) {
    const [scrollTop, setScrollTop] = useState(0);
    
    const startIndex = Math.floor(scrollTop / itemHeight);
    const endIndex = Math.min(
        startIndex + Math.ceil(containerHeight / itemHeight) + 1,
        items.length
    );
    
    const visibleItems = items.slice(startIndex, endIndex);
    const offsetY = startIndex * itemHeight;
    
    return (
        
setScrollTop(e.currentTarget.scrollTop)} >
{visibleItems.map((item, index) => (
{item.content}
))}
); }

四、网络优化

HTTP缓存策略

// Express设置缓存
app.use(express.static('public', {
    maxAge: '1y',           // 强缓存1年
    etag: true,             // 启用ETag
    lastModified: true      // 启用Last-Modified
}));

// Service Worker缓存
const CACHE_NAME = 'v1';
const urlsToCache = [
    '/',
    '/styles.css',
    '/script.js'
];

self.addEventListener('install', event => {
    event.waitUntil(
        caches.open(CACHE_NAME)
            .then(cache => cache.addAll(urlsToCache))
    );
});

self.addEventListener('fetch', event => {
    event.respondWith(
        caches.match(event.request)
            .then(response => {
                // 缓存优先,网络降级
                return response || fetch(event.request);
            })
    );
});

CDN加速

# Nginx配置CDN回源
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
    expires 1y;
    add_header Cache-Control "public, immutable";
    add_header X-Content-Type-Options "nosniff";
    
    # CDN回源Host
    proxy_set_header Host $host;
    proxy_pass http://backend;
}

减少HTTP请求

/* CSS Sprite */
.icon {
    background-image: url('sprite.png');
    background-repeat: no-repeat;
}

.icon-home {
    width: 24px;
    height: 24px;
    background-position: 0 0;
}

.icon-user {
    width: 24px;
    height: 24px;
    background-position: -24px 0;
}

/* 内联关键CSS */

五、JavaScript优化

避免长任务阻塞

// 将长任务拆分为小任务
async function processLargeArray(array) {
    const CHUNK_SIZE = 100;
    
    for (let i = 0; i < array.length; i += CHUNK_SIZE) {
        const chunk = array.slice(i, i + CHUNK_SIZE);
        
        // 处理当前块
        chunk.forEach(item => processItem(item));
        
        // 让出主线程
        await new Promise(resolve => setTimeout(resolve, 0));
    }
}

// 使用Web Worker处理CPU密集任务
const worker = new Worker('heavy-task.js');

worker.postMessage({ data: largeData });

worker.onmessage = function(e) {
    const result = e.data;
    // 处理结果
};

内存管理

// 避免内存泄漏
class Component {
    constructor() {
        this.intervalId = null;
        this.eventHandler = null;
    }
    
    mount() {
        this.intervalId = setInterval(() => {
            this.update();
        }, 1000);
        
        this.eventHandler = this.handleClick.bind(this);
        document.addEventListener('click', this.eventHandler);
    }
    
    unmount() {
        // 清理定时器
        clearInterval(this.intervalId);
        
        // 移除事件监听
        document.removeEventListener('click', this.eventHandler);
        
        // 清除引用
        this.eventHandler = null;
    }
}

// 使用WeakMap避免强引用
const cache = new WeakMap();

function cacheData(obj, data) {
    cache.set(obj, data);
}

// obj被垃圾回收时,数据自动释放

六、图片优化



    
    
    Fallback



Responsive image

总结

前端性能优化是一个系统工程,需要从加载、渲染、网络、代码等多个维度综合考虑。核心原则: 1. **测量先行**:使用工具量化性能,找出瓶颈 2. **关键路径优化**:优先优化首屏加载 3. **渐进增强**:基础功能快速加载,增强功能按需加载 4. **持续监控**:建立性能监控体系,及时发现回退 性能优化永无止境,建议制定明确的性能预算,在开发和迭代过程中持续关注和优化。

本文链接:https://www.kkkliao.cn/?id=851 转载需授权!

分享到:

版权声明:本文由廖万里的博客发布,如需转载请注明出处。


“前端性能优化完全指南:Web应用加速的核心实践” 的相关文章

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。