javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > 前端性能优化

从加载到渲染的前端性能优化全攻略指南

作者:天天进步2015

随着Web应用复杂度不断提升,前端性能优化变得尤为重要,本文将系统性地介绍从资源加载到页面渲染的全链路性能优化策略,希望对大家有一定的帮助

前言

随着Web应用复杂度不断提升,前端性能优化变得尤为重要。本文将系统性地介绍从资源加载到页面渲染的全链路性能优化策略,帮助开发者构建高效、流畅的Web应用。

网络请求优化

DNS预解析

<link rel="dns-prefetch" href="//example.com" rel="external nofollow" >

HTTP缓存策略

CDN加速

将静态资源部署到CDN,利用地理位置分布式节点加速资源访问。

HTTP/2和HTTP/3

利用多路复用、服务器推送等特性提升传输效率。

减少HTTP请求

资源加载优化

资源压缩

资源优先级

<link rel="preload" href="critical.css" rel="external nofollow"  as="style">
<link rel="preconnect" href="https://api.example.com" rel="external nofollow" >
<link rel="prefetch" href="next-page.js" rel="external nofollow" >

懒加载

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

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

代码分割

// React中使用React.lazy和Suspense
const LazyComponent = React.lazy(() => import('./LazyComponent'));

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <LazyComponent />
    </Suspense>
  );
}

JavaScript执行优化

避免阻塞渲染

<script async src="async-script.js"></script>
<script defer src="defer-script.js"></script>

Web Workers

将复杂计算移至后台线程,保持主线程流畅。

const worker = new Worker('worker.js');
worker.postMessage({ data: complexData });
worker.onmessage = function(event) {
  const result = event.data;
  updateUI(result);
};

优化事件处理

使用事件委托和节流/防抖。

// 防抖
function debounce(fn, delay) {
  let timer = null;
  return function() {
    const context = this;
    const args = arguments;
    clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(context, args);
    }, delay);
  };
}

// 使用防抖处理搜索输入
const searchInput = document.getElementById('search');
const debouncedSearch = debounce(search, 300);
searchInput.addEventListener('input', debouncedSearch);

渲染优化

优化DOM操作

// 优化前
for (let i = 0; i < 1000; i++) {
  document.body.appendChild(document.createElement('div'));
}

// 优化后
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
  fragment.appendChild(document.createElement('div'));
}
document.body.appendChild(fragment);

CSS优化

虚拟列表

处理大数据量列表时,只渲染可视区域内的元素。

class VirtualList {
  constructor(container, itemHeight, totalItems, renderItem) {
    this.container = container;
    this.itemHeight = itemHeight;
    this.totalItems = totalItems;
    this.renderItem = renderItem;
    
    this.visibleItems = Math.ceil(container.clientHeight / itemHeight) + 5;
    this.scrollTop = 0;
    this.startIndex = 0;
    
    this.init();
  }
  
  init() {
    this.container.style.position = 'relative';
    this.container.style.height = `${this.totalItems * this.itemHeight}px`;
    this.container.style.overflow = 'auto';
    
    this.container.addEventListener('scroll', () => {
      this.onScroll();
    });
    
    this.renderVisible();
  }
  
  onScroll() {
    this.scrollTop = this.container.scrollTop;
    this.startIndex = Math.floor(this.scrollTop / this.itemHeight);
    this.renderVisible();
  }
  
  renderVisible() {
    this.container.innerHTML = '';
    for (let i = this.startIndex; i < this.startIndex + this.visibleItems; i++) {
      if (i >= 0 && i < this.totalItems) {
        const item = this.renderItem(i);
        item.style.position = 'absolute';
        item.style.top = `${i * this.itemHeight}px`;
        this.container.appendChild(item);
      }
    }
  }
}

用户体验优化

骨架屏

在内容加载前显示页面框架,减少用户等待感知。

html

<div class="skeleton">
  <div class="skeleton-header"></div>
  <div class="skeleton-content">
    <div class="skeleton-line"></div>
    <div class="skeleton-line"></div>
    <div class="skeleton-line"></div>
  </div>
</div>

css 

.skeleton {
  padding: 15px;
  background: #fff;
}
.skeleton-header, .skeleton-line {
  background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
  background-size: 200% 100%;
  animation: shimmer 1.5s infinite;
}
.skeleton-header {
  height: 30px;
  margin-bottom: 15px;
  border-radius: 4px;
}
.skeleton-line {
  height: 15px;
  margin-bottom: 10px;
  border-radius: 2px;
}
@keyframes shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

渐进式加载

<style>
  /* 关键CSS内联 */
  .header { /* 样式 */ }
  .hero { /* 样式 */ }
  /* 其他首屏关键样式 */
</style>
<link rel="stylesheet" href="non-critical.css" rel="external nofollow"  media="print" onload="this.media='all'">

优化首屏内容

性能监控与分析

性能指标

性能监控实现

// 监控FCP
new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    console.log(`FCP: ${entry.startTime}`);
    // 上报数据
  }
}).observe({type: 'paint', buffered: true});

// 监控LCP
new PerformanceObserver((entryList) => {
  const entries = entryList.getEntries();
  const lastEntry = entries[entries.length - 1];
  console.log(`LCP: ${lastEntry.startTime}`);
  // 上报数据
}).observe({type: 'largest-contentful-paint', buffered: true});

// 监控CLS
let clsValue = 0;
new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    if (!entry.hadRecentInput) {
      clsValue += entry.value;
      console.log(`CLS: ${clsValue}`);
      // 上报数据
    }
  }
}).observe({type: 'layout-shift', buffered: true});

调试工具

总结

前端性能优化是一个系统工程,涵盖从网络请求、资源加载到页面渲染的全链路过程。本文介绍的优化策略不是孤立的,它们相互配合,共同构建高性能的前端应用。针对不同项目和场景,开发者需要根据实际情况选择合适的优化方案,并通过持续监控和分析,不断优化用户体验。

以上就是从加载到渲染的前端性能优化全攻略指南的详细内容,更多关于前端性能优化的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文