Skip to content
imshengli blog
Go back

前端性能优化:网络、渲染、代码与图片全链路指南

前端性能优化完整指南:网络层、渲染层、代码层、图片优化,以及 Lighthouse 和 Core Web Vitals 度量。

· 7 min

概述

前端性能优化直接影响用户体验和业务转化率。研究表明,页面加载时间每增加 1 秒,转化率下降约 7%。本文从网络、渲染、代码、图片四个维度梳理常用的优化手段,并介绍性能度量工具。

网络层优化

减少 HTTP 请求

每个 HTTP 请求都有建立连接的开销。减少请求数量是最直接的优化方式:

CDN 加速

将静态资源部署到 CDN 节点,利用就近访问原则缩短网络传输距离:

// 将静态资源指向 CDN 域名
const CDN_BASE = 'https://cdn.example.com';

function getAssetUrl(path) {
  return `${CDN_BASE}/${path}?v=${VERSION}`;
}

资源压缩

开启 Gzip/Brotli 压缩,通常能减少 60%-80% 的传输体积:

# Nginx 配置示例
gzip on;
gzip_types text/plain text/css application/json application/javascript;
gzip_min_length 1024;

缓存策略

合理使用 HTTP 缓存减少重复请求:

// Service Worker 缓存示例
self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request).then(cached => {
      return cached || fetch(event.request).then(response => {
        const clone = response.clone();
        caches.open('v1').then(cache => cache.put(event.request, clone));
        return response;
      });
    })
  );
});

渲染层优化

关键渲染路径

浏览器渲染流程:HTML → DOM → CSSOM → Render Tree → Layout → Paint → Composite。优化的目标是让首屏内容尽快完成渲染。

<!-- async: 下载不阻塞,下载完立即执行 -->
<script async src="analytics.js"></script>

<!-- defer: 下载不阻塞,DOM 解析完再执行,保持顺序 -->
<script defer src="app.js"></script>

避免重排与重绘

重排(Reflow)比重绘(Repaint)开销更大。以下操作会触发重排:

// 反面示例:多次触发重排
for (let i = 0; i < 100; i++) {
  element.style.left = element.offsetLeft + 1 + 'px';
}

// 正确做法:批量修改,一次重排
const left = element.offsetLeft;
element.style.left = left + 100 + 'px';

使用 DocumentFragment 批量操作 DOM:

const fragment = document.createDocumentFragment();

for (let i = 0; i < 1000; i++) {
  const li = document.createElement('li');
  li.textContent = `Item ${i}`;
  fragment.appendChild(li);
}

document.getElementById('list').appendChild(fragment);

CSS 加载优化

/* 告知浏览器该元素即将变化,提前创建合成层 */
.animated-element {
  will-change: transform;
}

代码层优化

懒加载

按需加载非首屏资源,减少初始加载体积:

// 路由级懒加载(React 示例)
const Detail = React.lazy(() => import('./pages/Detail'));

// 图片懒加载(Intersection Observer)
const observer = new IntersectionObserver(entries => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const img = entry.target;
      img.src = img.dataset.src;
      observer.unobserve(img);
    }
  });
});

document.querySelectorAll('img[data-src]').forEach(img => {
  observer.observe(img);
});

防抖与节流

高频事件(scroll、resize、input)需要控制回调执行频率:

// 防抖:停止触发后才执行(适合搜索输入)
function debounce(fn, delay) {
  let timer = null;
  return function (...args) {
    clearTimeout(timer);
    timer = setTimeout(() => fn.apply(this, args), delay);
  };
}

// 节流:固定间隔执行一次(适合滚动事件)
function throttle(fn, interval) {
  let lastTime = 0;
  return function (...args) {
    const now = Date.now();
    if (now - lastTime >= interval) {
      lastTime = now;
      fn.apply(this, args);
    }
  };
}

// 使用
window.addEventListener('scroll', throttle(handleScroll, 100));
input.addEventListener('input', debounce(search, 300));

Web Worker

将 CPU 密集型任务移到 Worker 线程,避免阻塞主线程:

// main.js
const worker = new Worker('compute.js');
worker.postMessage({ data: largeArray });
worker.onmessage = event => {
  console.log('计算结果:', event.data);
};

// compute.js
self.onmessage = event => {
  const result = heavyComputation(event.data);
  self.postMessage(result);
};

图片优化

格式选择

格式特点适用场景
JPEG有损压缩,体积小照片、渐变色图片
PNG无损压缩,支持透明图标、需要透明的图片
WebP体积比 JPEG 小 25-30%现代浏览器通用
SVG矢量,无限缩放图标、Logo

响应式图片

根据设备分辨率加载不同尺寸的图片:

<picture>
  <source srcset="image.webp" type="image/webp">
  <source srcset="image-800.jpg" media="(max-width: 800px)">
  <img src="image-1200.jpg" alt="responsive image">
</picture>

图片压缩策略

性能度量

Performance API

浏览器内置的性能测量接口:

// 测量关键指标
const timing = performance.timing;
const metrics = {
  dns: timing.domainLookupEnd - timing.domainLookupStart,
  tcp: timing.connectEnd - timing.connectStart,
  ttfb: timing.responseStart - timing.requestStart,
  domReady: timing.domContentLoadedEventEnd - timing.navigationStart,
  load: timing.loadEventEnd - timing.navigationStart
};

// 使用 Performance Observer 监听 LCP
const observer = new PerformanceObserver(list => {
  const entries = list.getEntries();
  const lcp = entries[entries.length - 1];
  console.log('LCP:', lcp.startTime);
});
observer.observe({ type: 'largest-contentful-paint', buffered: true });

Lighthouse

Google 提供的自动化审计工具,从五个维度评估页面质量:

可以通过 Chrome DevTools、命令行或 CI 集成使用:

# 命令行审计
npx lighthouse https://example.com --output=json --output-path=./report.json

核心 Web 指标

Google 定义的三个关键体验指标:

小结

前端优化不是一次性工作,而是持续的过程。优先处理影响最大的问题:

  1. 先度量,找到瓶颈所在
  2. 网络优化投入产出比最高(缓存、压缩、CDN)
  3. 渲染优化关注关键渲染路径
  4. 代码优化按需进行,避免过早优化

性能优化的核心原则:减少传输量、减少请求数、减少计算量、延迟非关键资源。


Share this post on:

Previous Post
ES6 Class 继承:extends、super 与原型链对比
Next Post
什么是渐进式框架:Angular、React、Vue 设计哲学对比