
前端性能优化是面试中的热点话题,尤其在大型互联网公司中,对前端性能的极致追求是衡量开发者能力的重要标准。本文基于最新的前端性能优化热搜词,结合实际应用场景,提供一系列可参考的优化方案。
1. CDN缓存策略配置
CDN缓存配置直接影响资源加载速度。以下是一个典型的CDN缓存配置示例:
{
"Cache-Control": "max-age=86400, public",
"Expires": "Wed, 21 Oct 2023 07:28:00 GMT",
"Pragma": "cache"
}
关键点解释:max-age设置为86400秒(24小时),public表示资源可被任何中间节点缓存。这种配置适用于静态资源如JS、CSS文件,能有效减少源站压力。
2. Service Worker缓存策略
Service Worker缓存可以显著提升重复访问速度。以下是一个缓存策略示例:
self.addEventListener('install', event => {
event.waitUntil(
caches.open('my-cache').then(cache => {
return cache.addAll([
'/',
'/index.',
'/styles/main.css',
'/scripts/app.js'
]);
})
);
});
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(response => {
return response || fetch(event.request);
})
);
});
关键点:在install事件中预缓存核心资源,在fetch事件中优先返回缓存资源,未命中时才请求网络。这种策略适用于需要离线功能的应用。
3. 图片懒加载实现
懒加载是提升首屏加载速度的有效手段。以下是一个基于Intersection Observer的懒加载实现:
document.addEventListener("DOMContentLoaded", function() {
const images = document.querySelectorAll('img[data-src]');
const imgObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
img.removeAttribute('data-src');
observer.unobserve(img);
}
});
});
images.forEach(img => {
imgObserver.observe(img);
});
});
关键点:Intersection Observer API能精确监测元素是否进入视口,相比传统滚动事件监听更高效。适用于长列表或瀑布流页面。
4. Webpack性能优化配置
优化Webpack配置可以显著减少构建体积。以下是一个关键配置示例:
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
minSize: 20000,
maxSize: 250000,
automaticNameDelimiter: '-'
},
minimize: true,
minimizer: [new TerserPlugin({...})],
runtimeChunk: 'single'
},
module: {
rules: [
{
test: /.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader',
options: {
plugins: [
require('postcss-preset-env')({
stage: 1
})
]
}
}
]
}
]
}
};
关键点:splitChunks按需分割代码块,minimizer启用代码压缩,runtimeChunk优化运行时代码。这些配置能显著减小打包体积。
5. 请求合并策略
合并请求可以减少HTTP连接开销。以下是一个基于fetch的请求合并实现:
async function loadResources() {
const urls = [
'/api/config',
'/api/user',
'/api/products',
'/api/settings'
];
try {
const response = await Promise.allSettled(
urls.map(url => fetch(url).then(res => res.json()))
);
// 处理响应结果
response.forEach((result, index) => {
if (result.status === 'fulfilled') {
console.log(`[${urls[index]}]`, result.value);
} else {
console.error(`[${urls[index]}]`, result.reason);
}
});
} catch (error) {
console.error('请求合并失败', error);
}
}
loadResources();
关键点:Promise.allSettled处理异步请求结果,避免一个请求失败影响其他请求。适用于需要同时获取多个API数据场景。
6. 预加载关键资源
预加载可以提前加载关键资源。以下是一个预加载配置示例:
<link rel="preload" href="/scripts/main.js" as="script" type="module">
<link rel="preload" href="/styles/main.css" as="style">
<link rel="preload" href="/images/logo.png" as="image">
关键点:preload优先级高于正常加载资源,适合关键JS/CSS/图片资源。as属性指定资源类型,type属性指定资源格式。
7. 动态导入实现代码分割
动态导入实现代码分割,以下是一个基于Webpack的示例:
import('path/to/module').then(module => {
// 使用模块
console.log('模块加载完成', module);
}).catch(error => {
console.error('模块加载失败', error);
});
// 或者使用async/await语法
async function loadModule() {
const module = await import('path/to/module');
console.log('模块加载完成', module);
}
关键点:动态导入会返回Promise,Webpack自动进行代码分割。适用于非首屏必要的功能模块。
8. 性能监控实现
性能监控是性能优化的闭环。以下是一个简单的性能监控实现:
window.addEventListener('load', () => {
if (window.performance && window.performance.navigation.type === 1) {
const performanceData = window.performance.getEntriesByType('measure');
performanceData.forEach(entry => {
console.log(`${entry.name}: ${entry.duration}ms`);
});
}
});
// Web Vitals监控
new PerformanceObserver((list) => {
list.getEntries().forEach(entry => {
if (entry.name === 'Largest Contentful Paint') {
console.log('LCP:', entry.duration);
} else if (entry.name === 'First Input Delay') {
console.log('FID:', entry.duration);
}
});
}).observe({ type: 'largest-contentful-paint', buffered: true });
关键点:使用Performance API收集性能数据,Web Vitals提供关键用户体验指标。这些数据可用于持续优化。
9. SVG优化策略
SVG是轻量级图形解决方案。以下是一个SVG优化示例:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14M22 4L12 14.01l-4-4M5 12h14" />
</svg>
关键点:使用viewBox属性控制显示区域,避免冗余像素。SVG文件通常比PNG/JPG更小,且可缩放。适用于图标和简单图形。
10. Web Workers实现后台处理
Web Workers可用于复杂计算,以下是一个简单实现:
// main.js
if (window.Worker) {
const myWorker = new Worker('worker.js');
myWorker.postMessage([1, 2, 3, 4, 5]);
myWorker.onmessage = function(e) {
console.log('从worker获得消息:', e.data);
};
}
// worker.js
self.onmessage = function(e) {
const result = e.data.reduce((sum, num) => sum + num, 0);
self.postMessage(result);
};
关键点:Web Workers运行在独立线程,不阻塞主线程。适用于数据处理、计算密集型任务。