Appearance
qiankun 性能优化
性能优化概述
qiankun 微前端架构的性能优化涉及多个层面,包括微应用加载性能、内存管理、资源优化等方面。合理的优化策略可以显著提升用户体验和应用响应速度。
加载性能优化
1. 预加载策略
基础预加载
javascript
// 启用默认预加载
start({
prefetch: true, // 预加载所有微应用
});
智能预加载
javascript
// 自定义预加载策略
start({
prefetch: {
// 关键应用立即预加载
criticalAppList: [
{
name: 'user-center',
entry: '//localhost:3001',
// 自定义预加载逻辑
prefetchMethod: async () => {
// 可以根据用户角色、权限等条件决定是否预加载
return isUserLoggedIn() && hasPermission('user-center');
}
}
],
// 非关键应用空闲时预加载
idleAppList: [
{ name: 'reporting', entry: '//localhost:3002' }
],
}
});
条件预加载
javascript
// 基于用户行为的预加载
let userBehavior = {
visitedPages: [],
timeOnPage: {},
navigationPattern: []
};
// 记录用户行为
function recordUserBehavior(page, time) {
userBehavior.visitedPages.push(page);
userBehavior.timeOnPage[page] = time || Date.now();
// 限制记录数量
if (userBehavior.visitedPages.length > 10) {
userBehavior.visitedPages.shift();
}
}
// 预测用户可能访问的微应用
function predictNextMicroApp() {
const recentPages = userBehavior.visitedPages.slice(-3);
// 简单的预测逻辑
if (recentPages.includes('/order') && recentPages.includes('/product')) {
return 'payment'; // 可能会访问支付页面
}
return null;
}
// 动态调整预加载
function dynamicPrefetch() {
const predictedApp = predictNextMicroApp();
if (predictedApp) {
// 预加载预测的应用
prefetchApp(predictedApp);
}
}
2. 资源优化
代码分割
javascript
// 微应用代码分割配置
// webpack.config.js
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
// 分离公共依赖
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
priority: 10
},
// 分离微应用特定代码
microApp: {
test: /[\\/]src[\\/]/,
name: 'micro-app',
chunks: 'all',
priority: 5
}
}
}
}
};
懒加载资源
javascript
// 微应用中的懒加载实现
export async function mount(props) {
const { container } = props;
// 立即加载关键资源
await loadCriticalResources();
// 延迟加载非关键资源
setTimeout(async () => {
await loadNonCriticalResources();
}, 0);
// 或使用 Intersection Observer 延迟加载
const lazyLoadObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
loadLazyComponent(entry.target);
lazyLoadObserver.unobserve(entry.target);
}
});
});
}
async function loadCriticalResources() {
// 加载关键的 CSS 和 JS
const criticalResources = [
'/css/critical.css',
'/js/vendor.js'
];
await Promise.all(criticalResources.map(loadResource));
}
function loadResource(url) {
return new Promise((resolve, reject) => {
if (url.endsWith('.css')) {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = url;
link.onload = resolve;
link.onerror = reject;
document.head.appendChild(link);
} else if (url.endsWith('.js')) {
const script = document.createElement('script');
script.src = url;
script.onload = resolve;
script.onerror = reject;
document.head.appendChild(script);
}
});
}
3. 缓存策略
应用实例缓存
javascript
// 应用实例缓存管理
class MicroAppCache {
constructor(options = {}) {
this.cache = new Map();
this.maxCacheSize = options.maxCacheSize || 5;
this.ttl = options.ttl || 5 * 60 * 1000; // 5分钟过期时间
}
set(name, instance) {
// 检查缓存大小
if (this.cache.size >= this.maxCacheSize) {
// 移除最久未使用的实例
const firstKey = this.cache.keys().next().value;
this.delete(firstKey);
}
this.cache.set(name, {
instance,
timestamp: Date.now(),
lastAccessed: Date.now()
});
}
get(name) {
const cached = this.cache.get(name);
if (cached) {
// 检查是否过期
if (Date.now() - cached.timestamp > this.ttl) {
this.delete(name);
return null;
}
cached.lastAccessed = Date.now();
return cached.instance;
}
return null;
}
delete(name) {
const cached = this.cache.get(name);
if (cached && cached.instance) {
// 确保正确清理实例
if (typeof cached.instance.unmount === 'function') {
cached.instance.unmount();
}
}
this.cache.delete(name);
}
clear() {
for (const [name] of this.cache) {
this.delete(name);
}
}
// 定期清理过期缓存
startCleanupTimer() {
setInterval(() => {
for (const [name, cached] of this.cache) {
if (Date.now() - cached.timestamp > this.ttl) {
this.delete(name);
}
}
}, 60 * 1000); // 每分钟检查一次
}
}
const appCache = new MicroAppCache({
maxCacheSize: 3,
ttl: 10 * 60 * 1000 // 10分钟过期
});
资源缓存
javascript
// 资源缓存管理
class ResourceCache {
constructor() {
this.cache = new Map();
this.maxSize = 100; // 最大缓存项目数
}
async fetch(url, options = {}) {
if (this.cache.has(url)) {
const cached = this.cache.get(url);
if (Date.now() - cached.timestamp < cached.ttl) {
return cached.data;
} else {
this.cache.delete(url);
}
}
const response = await fetch(url, options);
const data = await response.clone().text();
if (this.cache.size >= this.maxSize) {
// 删除最久未使用的项目
const firstKey = this.cache.keys().next().value;
this.cache.delete(firstKey);
}
this.cache.set(url, {
data,
timestamp: Date.now(),
ttl: options.ttl || 5 * 60 * 1000 // 默认5分钟
});
return data;
}
}
内存管理优化
1. 正确的生命周期管理
完整的资源清理
javascript
// 微应用完整的生命周期实现
let app = null;
let eventListeners = new Set();
let timers = new Set();
let observers = new Set();
let intervals = new Set();
export async function mount(props) {
const { container } = props;
// 创建应用实例
app = new Vue({
router,
store,
render: h => h(App),
}).$mount(container ? container.querySelector('#app') : '#app');
// 添加事件监听器
const handleResize = () => {
// 处理窗口大小变化
};
window.addEventListener('resize', handleResize);
eventListeners.add(() => window.removeEventListener('resize', handleResize));
// 添加定时器
const timer = setTimeout(() => {
// 定时任务
}, 5000);
timers.add(timer);
// 添加间隔定时器
const interval = setInterval(() => {
// 重复任务
}, 1000);
intervals.add(interval);
// 添加观察器
const resizeObserver = new ResizeObserver(entries => {
// 观察元素大小变化
});
resizeObserver.observe(container);
observers.add(() => resizeObserver.disconnect());
}
export async function unmount(props) {
// 清理事件监听器
eventListeners.forEach(cleanup => cleanup());
eventListeners.clear();
// 清理定时器
timers.forEach(timer => clearTimeout(timer));
timers.clear();
// 清理间隔定时器
intervals.forEach(interval => clearInterval(interval));
intervals.clear();
// 清理观察器
observers.forEach(cleanup => cleanup());
observers.clear();
// 销毁应用实例
if (app) {
app.$destroy();
app.$el.innerHTML = '';
app = null;
}
// 清理全局变量
if (window.__MICRO_APP__) {
delete window.__MICRO_APP__;
}
}
2. 内存泄漏防护
内存监控
javascript
// 内存使用监控
class MemoryMonitor {
constructor(options = {}) {
this.checkInterval = options.checkInterval || 30000; // 30秒检查一次
this.warnThreshold = options.warnThreshold || 100 * 1024 * 1024; // 100MB
this.startMonitoring();
}
startMonitoring() {
if (this.intervalId) {
clearInterval(this.intervalId);
}
this.intervalId = setInterval(() => {
this.checkMemoryUsage();
}, this.checkInterval);
}
checkMemoryUsage() {
if (performance.memory) {
const memory = performance.memory;
const usage = memory.usedJSHeapSize;
if (usage > this.warnThreshold) {
console.warn('Memory usage high:', {
used: (usage / 1024 / 1024).toFixed(2) + 'MB',
total: (memory.totalJSHeapSize / 1024 / 1024).toFixed(2) + 'MB',
limit: (memory.jsHeapSizeLimit / 1024 / 1024).toFixed(2) + 'MB'
});
// 可以触发内存清理
this.triggerCleanup();
}
}
}
triggerCleanup() {
// 强制垃圾回收(仅在开发环境)
if (process.env.NODE_ENV === 'development' && window.gc) {
window.gc();
}
}
stopMonitoring() {
if (this.intervalId) {
clearInterval(this.intervalId);
this.intervalId = null;
}
}
}
const memoryMonitor = new MemoryMonitor({
checkInterval: 60000, // 1分钟检查一次
warnThreshold: 150 * 1024 * 1024 // 150MB 警告阈值
});
网络性能优化
1. 请求优化
请求缓存和去重
javascript
// 请求缓存管理
class RequestCache {
constructor() {
this.cache = new Map();
this.pending = new Map(); // 正在进行的请求
}
async request(url, options = {}) {
// 检查是否有相同的请求正在进行
if (this.pending.has(url)) {
return this.pending.get(url);
}
// 检查缓存
if (this.cache.has(url) && !this.isExpired(this.cache.get(url))) {
return this.cache.get(url).data;
}
// 发起新请求
const promise = fetch(url, options).then(response => response.json())
.then(data => {
// 缓存结果
this.cache.set(url, {
data,
timestamp: Date.now(),
ttl: options.ttl || 5 * 60 * 1000 // 5分钟
});
return data;
})
.finally(() => {
this.pending.delete(url);
});
this.pending.set(url, promise);
return promise;
}
isExpired(cached) {
return Date.now() - cached.timestamp > cached.ttl;
}
}
const requestCache = new RequestCache();
2. 资源预加载
智能预加载
javascript
// 智能资源预加载
class SmartPreloader {
constructor() {
this.preloaded = new Set();
this.loading = new Map();
}
async preloadResource(url, priority = 'normal') {
if (this.preloaded.has(url)) {
return Promise.resolve();
}
if (this.loading.has(url)) {
return this.loading.get(url);
}
const loadPromise = this.loadResource(url);
this.loading.set(url, loadPromise);
return loadPromise.finally(() => {
this.loading.delete(url);
});
}
async loadResource(url) {
if (url.endsWith('.js')) {
return this.preloadScript(url);
} else if (url.endsWith('.css')) {
return this.preloadStylesheet(url);
} else if (/\.(png|jpg|jpeg|gif|svg|webp)$/.test(url)) {
return this.preloadImage(url);
}
}
preloadScript(url) {
return new Promise((resolve, reject) => {
const link = document.createElement('link');
link.rel = 'preload';
link.as = 'script';
link.href = url;
link.onload = () => {
this.preloaded.add(url);
resolve();
};
link.onerror = reject;
document.head.appendChild(link);
});
}
preloadStylesheet(url) {
return new Promise((resolve, reject) => {
const link = document.createElement('link');
link.rel = 'preload';
link.as = 'style';
link.href = url;
link.onload = () => {
this.preloaded.add(url);
resolve();
};
link.onerror = reject;
document.head.appendChild(link);
});
}
preloadImage(url) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => {
this.preloaded.add(url);
resolve();
};
img.onerror = reject;
img.src = url;
});
}
}
const smartPreloader = new SmartPreloader();
渲染性能优化
1. 虚拟滚动
长列表优化
javascript
// 虚拟滚动实现(概念示例)
class VirtualList {
constructor(container, options = {}) {
this.container = container;
this.itemHeight = options.itemHeight || 50;
this.visibleCount = options.visibleCount || 10;
this.data = [];
this.renderedItems = new Map();
}
setData(data) {
this.data = data;
this.updateVisibleItems();
}
updateVisibleItems() {
const scrollTop = this.container.scrollTop;
const start = Math.floor(scrollTop / this.itemHeight);
const end = Math.min(start + this.visibleCount, this.data.length);
// 清理不在视口的项目
for (const [index, element] of this.renderedItems) {
if (index < start || index >= end) {
this.container.removeChild(element);
this.renderedItems.delete(index);
}
}
// 添加新的可见项目
for (let i = start; i < end; i++) {
if (!this.renderedItems.has(i)) {
const itemElement = this.createItemElement(this.data[i], i);
itemElement.style.transform = `translateY(${i * this.itemHeight}px)`;
this.container.appendChild(itemElement);
this.renderedItems.set(i, itemElement);
}
}
}
createItemElement(item, index) {
const element = document.createElement('div');
element.className = 'virtual-list-item';
element.innerHTML = item.content;
return element;
}
}
2. 组件懒加载
路由级懒加载
javascript
// 微应用中的路由懒加载
import { createRouter, createWebHistory } from 'vue-router';
function createRouter() {
return createRouter({
history: createWebHistory(),
routes: [
{
path: '/',
component: () => import('./views/Home.vue') // 懒加载
},
{
path: '/profile',
component: () => import('./views/Profile.vue') // 懒加载
},
{
path: '/settings',
component: () => import(
/* webpackChunkName: "settings" */
'./views/Settings.vue'
)
}
]
});
}
主应用优化
1. 应用切换优化
平滑切换
javascript
// 主应用中的平滑切换实现
class AppSwitcher {
constructor() {
this.currentApp = null;
this.transitionDuration = 300; // 300ms 切换动画
}
async switchTo(appName) {
const container = document.getElementById('subapp-container');
// 添加切换动画
container.style.transition = `opacity ${this.transitionDuration}ms ease`;
container.style.opacity = '0';
// 延迟切换以确保动画效果
setTimeout(async () => {
if (this.currentApp) {
// 隐藏当前应用
this.hideCurrentApp();
}
// 显示新应用
await this.showApp(appName);
container.style.opacity = '1';
}, this.transitionDuration / 2);
}
hideCurrentApp() {
if (this.currentApp) {
// 触发当前应用的隐藏逻辑
this.currentApp.style.display = 'none';
}
}
async showApp(appName) {
// 显示新应用
const appContainer = document.getElementById(appName);
if (appContainer) {
appContainer.style.display = 'block';
}
}
}
const appSwitcher = new AppSwitcher();
2. 资源管理
资源预加载管理
javascript
// 主应用资源预加载
class MainAppPreloader {
constructor() {
this.preloadedApps = new Set();
this.preloadQueue = [];
this.isPreloading = false;
}
async preloadApps(appNames) {
if (this.isPreloading) {
// 如果正在预加载,添加到队列
this.preloadQueue.push(...appNames);
return;
}
this.isPreloading = true;
try {
for (const appName of appNames) {
if (!this.preloadedApps.has(appName)) {
await this.preloadApp(appName);
this.preloadedApps.add(appName);
}
}
} finally {
this.isPreloading = false;
// 处理队列中的预加载请求
if (this.preloadQueue.length > 0) {
const nextBatch = this.preloadQueue.splice(0, 3); // 每次处理3个
this.preloadApps(nextBatch);
}
}
}
async preloadApp(appName) {
// 模拟预加载应用
return new Promise(resolve => {
setTimeout(() => {
console.log(`Preloaded app: ${appName}`);
resolve();
}, 100); // 模拟网络请求时间
});
}
}
const mainAppPreloader = new MainAppPreloader();
监控和分析
1. 性能监控
性能指标收集
javascript
// 性能监控工具
class PerformanceMonitor {
constructor() {
this.metrics = {
loadTimes: {},
memoryUsage: [],
renderTimes: {},
errorCounts: {}
};
}
startAppLoad(appName) {
this.metrics.loadTimes[appName] = {
startTime: performance.now()
};
}
endAppLoad(appName) {
if (this.metrics.loadTimes[appName]) {
this.metrics.loadTimes[appName].endTime = performance.now();
this.metrics.loadTimes[appName].duration =
this.metrics.loadTimes[appName].endTime - this.metrics.loadTimes[appName].startTime;
console.log(`App ${appName} loaded in ${this.metrics.loadTimes[appName].duration}ms`);
}
}
recordRenderTime(appName, time) {
if (!this.metrics.renderTimes[appName]) {
this.metrics.renderTimes[appName] = [];
}
this.metrics.renderTimes[appName].push(time);
// 计算平均渲染时间
const avg = this.metrics.renderTimes[appName].reduce((a, b) => a + b) /
this.metrics.renderTimes[appName].length;
console.log(`Avg render time for ${appName}: ${avg}ms`);
}
recordError(appName, errorType) {
if (!this.metrics.errorCounts[appName]) {
this.metrics.errorCounts[appName] = {};
}
if (!this.metrics.errorCounts[appName][errorType]) {
this.metrics.errorCounts[appName][errorType] = 0;
}
this.metrics.errorCounts[appName][errorType]++;
}
getMetrics() {
return this.metrics;
}
}
const perfMonitor = new PerformanceMonitor();
2. 性能分析
Web Vitals 集成
javascript
// Web Vitals 监控
import { getCLS, getFID, getFCP, getLCP, getTTFB } from 'web-vitals';
function sendToAnalytics(metric) {
// 发送性能指标到分析服务
console.log('Performance metric:', metric);
}
// 监控核心 Web Vitals
getCLS(sendToAnalytics);
getFID(sendToAnalytics);
getFCP(sendToAnalytics);
getLCP(sendToAnalytics);
getTTFB(sendToAnalytics);
// 自定义 qiankun 相关指标
function measureMicroAppPerformance() {
// 监控微应用加载时间
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.name.includes('micro-app')) {
console.log('Micro app performance:', entry);
}
}
});
observer.observe({ entryTypes: ['navigation', 'resource'] });
}
measureMicroAppPerformance();
通过以上性能优化策略,可以显著提升 qiankun 微前端应用的性能表现,提供更好的用户体验。