JavaScript性能优化实战(14):跨端JavaScript性能优化

发布于:2025-05-22 ⋅ 阅读:(19) ⋅ 点赞:(0)

在当今多端开发的时代,JavaScript已经突破了浏览器的界限,广泛应用于移动应用、桌面应用、小程序等各类环境。然而,不同平台的运行时环境存在差异,为JavaScript性能优化带来了新的挑战和思考维度。

目录

  1. React Native性能优化最佳实践
  2. Electron应用性能优化策略
  3. 混合应用中JavaScript与原生代码的性能平衡
  4. 小程序环境中的性能优化技巧
  5. Flutter与JavaScript性能对比与互补
  6. 多端统一框架中的性能优化方案

React Native性能优化最佳实践

React Native通过将JavaScript代码转换为原生组件,提供了接近原生的用户体验和开发效率。然而,由于其特殊的架构,性能优化需要同时关注JavaScript引擎性能和原生桥接开销。

1. 架构认知与性能模型

React Native的应用性能主要受三个关键线程影响:

┌─────────────────┐      ┌─────────────────┐      ┌─────────────────┐
│   JS线程        │      │   主线程         │      │   UI线程        │
│                 │      │                 │      │                 │
│ • React渲染     │──┬──>│ • 原生模块调用   │──┬──>│ • 渲染UI组件    │
│ • 业务逻辑      │  │   │ • 桥接通信       │  │   │ • 处理触摸事件  │
│ • 事件处理      │<─┘   │ • 布局计算       │<─┘   │                 │
└─────────────────┘      └─────────────────┘      └─────────────────┘

常见性能问题及解决方案:

  1. JS线程瓶颈

    • 现象:应用卡顿、动画掉帧
    • 原因:复杂计算阻塞线程
    • 解决方案:任务拆分、使用InteractionManager
  2. 桥接通信开销

    • 现象:大量数据传输缓慢
    • 原因:JS与原生通信需要序列化/反序列化
    • 解决方案:减少通信频率、使用Turbo Modules
  3. 内存占用过高

    • 现象:应用崩溃、后台被杀
    • 原因:过多的视图渲染、内存泄漏
    • 解决方案:回收不可见组件、使用FlatList

2. 组件渲染优化策略

React Native的渲染性能直接影响用户体验,优化组件渲染是提升性能的关键。

2.1 精细化使用memo与PureComponent
// 不优化的组件
const UserProfile = (props) => {
   
  // 每次父组件渲染都会重新渲染
  return (
    <View>
      <Text>{
   props.name}</Text>
      <Text>{
   props.email}</Text>
    </View>
  );
};

// 优化后的组件
const UserProfile = React.memo((props) => {
   
  // 只有当props发生变化时才会重新渲染
  return (
    <View>
      <Text>{
   props.name}</Text>
      <Text>{
   props.email}</Text>
    </View>
  );
}, (prevProps, nextProps) => {
   
  // 自定义比较逻辑,返回true表示不需要重新渲染
  return prevProps.name === nextProps.name && 
         prevProps.email === nextProps.email;
});
2.2 大列表渲染优化

使用专用组件处理大量数据:

// 低效的列表实现
const UserList = ({
     users }) => (
  <ScrollView>
    {
   users.map(user => (
      <UserItem key={
   user.id} user={
   user} />
    ))}
  </ScrollView>
);

// 优化的列表实现
const UserList = ({
     users }) => (
  <FlatList
    data={
   users}
    renderItem={
   ({
     item }) => <UserItem user={
   item} />}
    keyExtractor={
   item => item.id}
    initialNumToRender={
   10}         // 初始渲染的条数
    maxToRenderPerBatch={
   5}         // 每批次渲染的最大数量
    windowSize={
   5}                  // 可视区域外的缓冲区大小
    removeClippedSubviews={
   true}    // 移除屏幕外的视图
    getItemLayout={
   (data, index) => ({
     // 预先计算item尺寸
      length: 80,
      offset: 80 * index,
      index,
    })}
  />
);
2.3 避免不必要的重新渲染
  • 避免内联函数和对象:它们在每次渲染时都会创建新的引用
// 不好的做法
const Component = () => (
  <Button 
    onPress={
   () => console.log('Pressed')}  // 每次渲染创建新函数
    style={
   {
    padding: 10 }}                 // 每次渲染创建新对象
  />
);

// 良好的做法
const Component = () => {
   
  const handlePress = useCallback(() => {
   
    console.log('Pressed');
  }, []);
  
  const buttonStyle = useMemo(() => ({
    
    padding: 10 
  }), []);
  
  return <Button onPress={
   handlePress} style={
   buttonStyle} />;
};

3. 新架构优化:Fabric与Turbo Modules

React Native的新架构引入了两项关键技术,大幅提升了性能:

3.1 Fabric:新UI管理器

Fabric采用了共享持久化C++对象模型,带来以下优势:

  • 直接在C++中执行布局计算
  • 支持优先级调度和并发渲染
  • 减少JS和原生之间的序列化开销

迁移到Fabric的关键步骤:

// 1. 确保组件使用现代API
import {
    useAnimatedStyle, useSharedValue } from 'react-native-reanimated';

function AnimatedComponent() {
   
  // 共享值在JS和UI线程间高效同步
  const offset = useSharedValue(0);
  
  // 定义动画样式
  const animatedStyles = useAnimatedStyle(() => {
   
    return {
   
      transform: [{
    translateX: offset.value }],
    };
  });
  
  return (
    <Animated.View style={
   animatedStyles}>
      {
   /* 组件内容 */}
    </Animated.View>
  );
}

// 2. 避免直接操作原生视图
// 不推荐 - 直接引用原生视图
const viewRef = useRef();
viewRef.current.measure((x, y, width, height) => {
   
  // 测量逻辑
});

// 推荐 - 使用布局动画
const onLayout = (event) => {
   
  const {
    width, height } = event.nativeEvent.layout;
  // 处理布局变化
};
3.2 Turbo Modules:高性能原生模块

Turbo Modules提供了直接的JavaScript到C++通信通道,取代传统JSI桥接方式:

  • 延迟加载原生模块,减少启动时间
  • 同步API调用,无需等待桥接队列
  • 类型安全的接口定义

性能对比:

操作类型 传统架构 新架构 (Turbo) 性能提升
简单调用 ~4.5ms ~0.04ms ~112x
传输10KB ~12ms ~0.3ms ~40x
传输1MB ~850ms ~25ms ~34x

4. 状态管理与数据流优化

React Native中的状态管理对性能有重大影响,特别是在复杂应用中:

4.1 精细化使用Context API
// 低效的Context使用
const AppContext = React.createContext();

const AppProvider = ({
     children }) => {
   
  const [user, setUser] = useState(null);
  const [theme, setTheme] = useState('light');
  const [notifications, setNotifications] = useState([]);
  
  // 所有状态放在一个Context中
  const value = {
    user, setUser, theme, setTheme, notifications, setNotifications };
  
  return (
    <AppContext.Provider value={
   value}>
      {
   children}
    </AppContext.Provider>
  );
};

// 优化的Context使用:拆分Context
const UserContext = React.createContext();
const ThemeContext = React.createContext();
const NotificationContext = React.createContext();

const AppProvider = ({
     children }) => {
   
  const [user, setUser] = useState(null);
  const [theme, setTheme] = useState('light');
  const [notifications, setNotifications] = useState([]);
  
  return (
    <UserContext.Provider value={
   {
    user, setUser }}>
      <ThemeContext.Provider value={
   {
    theme, setTheme }}>
        <NotificationContext.Provider value={
   {
    notifications, setNotifications }}>
          {
   children}
        </NotificationContext.Provider>
      </ThemeContext.Provider>
    </UserContext.Provider>
  );
};
4.2 Recoil/Jotai等原子化状态管理

使用原子化状态管理可以精细控制组件重新渲染:

// 使用Recoil进行原子化状态管理
import {
    atom, selector, useRecoilState, useRecoilValue } from 'recoil';

// 定义原子状态
const userAtom = atom({
   
  key: 'userState',
  default: null,
});

const cartItemsAtom = atom({
   
  key: 'cartItems',
  default: [],
});

// 派生状态
const cartTotalSelector = selector({
   
  key: 'cartTotal',
  get: ({
    get}) => {
   
    const items = get(cartItemsAtom);
    return items.reduce((sum, item) => sum + item.price * item.quantity, 0);
  },
});

// 在组件中使用
function CartSummary() {
   
  // 只有cartTotal变化时才会重新渲染
  const total = useRecoilValue(cartTotalSelector);
  return <Text>总价: ¥{
   total}</Text>;
}

function CartItem({
     id }) {
   
  // 只有特定item变化时才会重新渲染
  const [items, setItems] = useRecoilState(cartItemsAtom);
  const item = items.find(item => item.id === id);
  
  const updateQuantity = (newQuantity) => {
   
    setItems(items.map(i => 
      i.id === id ? {
   ...i, quantity: newQuantity} : i
    ));
  };
  
  return (/* 商品显示UI */);
}

5. 网络与数据处理优化

React Native应用常需处理大量网络请求和数据,优化这些操作对性能至关重要:

5.1 优化API调用策略
// 缓存与防抖结合的API调用
import {
    useMemo } from 'react';
import {
    useQuery, QueryClient, QueryClientProvider } from 'react-query';
import debounce from 'lodash/debounce';

// 创建查询客户端
const queryClient = new QueryClient({
   
  defaultOptions: {
   
    queries: {
   
      staleTime: 5 * 60 * 1000,  // 数据5分钟内视为新鲜
      cacheTime: 30 * 60 * 1000, // 缓存保留30分钟
      retry: 2,                  // 失败时重试2次
    },
  },
});

// 应用入口组件
function App() {
   
  return (
    <QueryClientProvider client={
   queryClient}>
      <MainApp />
    </QueryClientProvider>
  );
}

// 搜索组件
function SearchScreen() {
   
  const [query, setQuery] = useState('');
  
  // 防抖处理搜索
  const debouncedSearch = useMemo(
    () => debounce(term => setQuery(term), 300),
    []
  );
  
  // 使用react-query进行数据获取和缓存
  const {
    data, isLoading, error } = useQuery(
    ['search', query],
    () => fetchSearchResults(query),
    {
   
      enabled: query.length > 2, // 只在输入3个字符后才执行
      keepPreviousData: true,    // 显示上一次数据直到新数据加载完成
    }
  );
  
  return (/* 搜索界面UI */);
}
5.2 JSON解析优化

大型JSON处理在React Native中可能成为性能瓶颈:

// 传统JSON解析
const handleResponse = async (response) => {
   
  const jsonText = await response.text();
  const data = JSON.parse(jsonText); // 可能阻塞JS线程
  
  processData(data);
};

// 优化方法1: 流式处理大型JSON
import {
    parse } from 'react-native-stream-json';

const handleLargeResponse = async (response) => {
   
  const jsonStream = response.body;
  
  // 流式处理JSON
  parse(jsonStream)
    .on('data', data => {
   
      // 按需处理数据片段
      addDataChunk(data);
    })
    .on('error', error => {
   
      console.error(error);
    })
    .on('end', () => {
   
      // 所有数据处理完成
      finalizeData();
    });
};

// 优化方法2: 使用原生JSON解析
import JSONFromNative from 'react-native-json-from-native';

const handleResponseWithNative = async (response) => {
   
  const jsonText = await response.text();
  
  // 在原生层解析JSON,减轻JS线程负担
  JSONFromNative.parse(jsonText, (error, result) => {
   
    if (error) {
   
      console.error(error);
      return;
    }
    
    processData(result);
  });
};

6. 性能监控与分析工具

持续监控和分析是React Native性能优化的关键环节:

6.1 监控核心指标
// 监控关键性能指标
import {
    PerformanceObserver } from 'react-native-performance';

// 监控JS线程性能
const jsPerformanceObserver = new PerformanceObserver((list) => {
   
  const entries = list.getEntries();
  
  entries.forEach(entry => {
   
    // 记录长任务
    if (entry.duration > 50) {
    // 超过50ms的任务可能导致卡顿
      console.warn(`Long task detected: ${
     entry.name}, duration: ${
     entry.duration}ms`);
      // 上报到性能监控系统
      reportPerformanceIssue({
   
        type: 'long_task',
        name: entry.name,
        duration: entry.duration,
        timestamp: entry.startTime
      });
    }
  });
});

// 开始监控
jsPerformanceObserver.observe({
    entryTypes: ['longtask'] });

// 应用启动时间监控
import {
    InteractionManager } from 'react-native';

const startTime = Date.now();

InteractionManager.runAfterInteractions(() => {
   
  const ttid = Date.now() - startTime; // Time To Interactive Display
  console.log(`应用可交互时间: ${
     ttid}ms`);
  
  // 上报指标
  reportMetric('ttid', ttid);
});
6.2 使用Flipper进行分析
// 在开发环境启用Flipper性能插件
if (__DEV__) {
   
  const {
    connectToDevTools } = require('react-devtools-core');
  
  connectToDevTools({
   
    host: 'localhost',
    port: 8097,
  });
  
  // 自定义性能日志
  global.LOG_PERF = (label, startTime) => {
   
    const duration = Date.now() - startTime;
    console.log(`[性能日志] ${
     label}: ${
     duration}ms`);
  };
}

// 在关键组件中使用
function ComplexComponent() {
   
  useEffect(() => {
   
    const startTime = Date.now();
    
    // 昂贵的操作
    processLargeData();
    
    if (__DEV__) {
   
      global.LOG_PERF('ComplexComponent初始化', startTime);
    }
  }, []);
  
  return (/* 组件UI */);
}

7. 实战案例分析:电商应用优化

某电商React Native应用通过综合优化提升了性能指标:

优化前问题:

  • 首屏加载时间超过3秒
  • 商品列表滚动卡顿
  • 详情页图片加载导致UI冻结
  • 结账流程跳转延迟明显

优化策略与效果:

优化措施 实施方法 性能提升
启动优化 异步初始化、延迟非关键模块加载 启动时间减少40%
列表渲染 使用FlatList、正确配置windowSize和maxToRenderPerBatch 滚动提升60fps
详情页图片 实现图片预加载、渐进式加载 图片阻塞时间减少85%
结账流程 优化表单输入防抖、状态本地化 页面跳转卡顿降低70%

关键代码片段:

// 优化前:加载所有商品
useEffect(() => {
   
  fetchAllProducts().then(setProducts);
}, []);

// 优化后:分页加载+预加载
const [products, setProducts] = useState([]);
const [page, setPage] = useState(1);
const [loading, setLoading] = useState(false);

// 初始加载
useEffect(() => {
   
  loadProducts(1);
}, []);

// 加载指定页
const loadProducts = async (pageNum) => {
   
  setLoading(true);
  try {
   
    const newProducts = await fetchProducts(pageNum, 20);
    
    if (pageNum === 1) {
   
      setProducts(newProducts);
    } else {
   
      setProducts(prev => [...prev, ...newProducts]);
    }
    
    setPage(pageNum);
    
    // 预加载下一页数据
    prefetchNextPage(pageNum + 1);
  } catch (error) {
   
    console.error('Failed to load products', error);
  } finally {
   
    setLoading(false);
  }
};

// 预加载下一页
const prefetchNextPage = (nextPage) => {
   
  InteractionManager.runAfterInteractions(() => {
   
    fetchProducts(nextPage, 20);
  });
};

// 优化的FlatList实现
<FlatList
  data={
   products}
  renderItem={
   renderProduct}
  keyExtractor={
   item => item.id.toString()}
  onEndReached={
   () => loadProducts(page + 1)}
  onEndReachedThreshold={
   0.3}
  initialNumToRender={
   10}
  maxToRenderPerBatch={
   8}
  windowSize={
   7}
  removeClippedSubviews={
   Platform.OS === 'android'}
  ListFooterComponent={
   loading ? <LoadingIndicator /> : null}
  getItemLayout={
   (data, index) => ({
   
    length: ITEM_HEIGHT,
    offset: ITEM_HEIGHT * index,
    index,
  })}
/>

Electron应用性能优化策略

Electron应用将Chromium与Node.js结合,允许开发者使用Web技术构建跨平台桌面应用。然而,这种便利性也带来了性能挑战,尤其是在资源消耗和启动时间方面。

1. Electron架构与性能特性

Electron应用基于多进程架构,包含主进程(Main)和渲染进程(Renderer):

┌─────────────────────────────────────────────────────┐
│                    Electron应用                      │
│                                                     │
│  ┌─────────────┐         ┌─────────────────────┐    │
│  │  主进程      │         │     渲染进程         │    │
│  │ (Main)      │         │    (Renderer)       │    │
│  │             │         │                     │    │
│  │ • Node.js   │<────────│ • Chromium          │    │
│  │ • 系统访问   │   IPC   │ • Web页面           │    │
│  │ • 进程管理   │────────>│ • DOM操作           │    │
│  └─────────────┘         └─────────────────────┘    │
│                                                     │
└─────────────────────────────────────────────────────┘

性能挑战点:

  1. 内存占用高:每个渲染进程都包含一个Chromium实例
  2. 启动时间长:需要初始化Chromium和Node.js环境
  3. IPC通信开销:主进程与渲染进程间通信需要序列化
  4. 包体积大:默认包含完整的Chromium和Node.js

2. 优化Electron应用启动时间

启动时间是用户体验的第一印象,优化启动速度至关重要。

2.1 懒加载与延迟初始化
// main.js

// 不好的做法:启动时加载所有模块
const {
    app, BrowserWindow, Menu, dialog, globalShortcut } = require('electron');
const fs = require('fs');
const path = require('path');
const {
    checkForUpdates } = require('./updater');

// 好的做法:按需加载模块
const {
    app, BrowserWindow } = require('electron');

let mainWindow;

async function createWindow() {
   
  mainWindow = new BrowserWindow({
   
    width: 1200,
    height: 800,
    show: false, // 初始不显示窗口
    webPreferences: {
   
      preload: path.join(__dirname, 'preload.js'),
      nodeIntegration: false,
      contextIsolation: true
    }
  });
  
  // 加载应用
  await mainWindow.loadFile('index.html');
  
  // 显示窗口,减少白屏时间
  mainWindow.show();
  
  // 延迟非关键功能初始化
  setTimeout(() => {
   
    // 仅在需要时加载
    const {
    Menu } = require('electron');
    const menuTemplate = require('./menu');
    Menu.setApplicationMenu(Menu.buildFromTemplate(menuTemplate));
    
    // 注册全局快捷键
    registerShortcuts();
    
    // 检查更新(非阻塞)
    checkForUpdates();
  }, 2000);
}

// 分离快捷键注册逻辑
function registerShortcuts() {
   
  const {
    globalShortcut } = require('electron');
  globalShortcut.register('CommandOrControl+F', () => {
   
    if (mainWindow) mainWindow.webContents.send('toggle-search');
  });
}

// 仅在ready后创建窗口
app.whenReady().then(createWindow);
2.2 预加载脚本优化
// preload.js - 优化预加载脚本

// 不好的做法:在预加载脚本中执行大量同步操作
const {
    ipcRenderer } = require('electron');
const fs = require('fs');
const userDataPath = '...';
const userData = JSON.parse(fs.readFileSync(userDataPath, 'utf8')); // 阻塞操作

// 好的做法:保持预加载脚本简洁
const {
    contextBridge, ipcRenderer } = require('electron');

// 仅暴露必要的API
contextBridge.exposeInMainWorld('electron', {
   
  // 简单、轻量的API桥接
  sendMessage: (channel, data) => {
   
    // 白名单通道
    const validChannels = ['toMain', 'saveData', 'loadData'];
    if (validChannels.includes(channel)) {
   
      ipcRenderer.send(channel, data);
    }
  },
  receive: (channel, func) => {
   
    const validChannels = ['fromMain', 'dataUpdated'];
    if (validChannels.includes(channel)) {
   
      // 删除旧监听器以避免内存泄漏
      ipcRenderer.removeAllListeners(channel);
      // 添加新监听器
      ipcRenderer.on(channel, (_, ...args) => func(...args));
    }
  }
});

// 数据加载放在渲染进程中异步处理,而不是在预加载中同步加载
2.3 窗口创建策略
// 启动优化:使用BrowserWindow构造函数选项
function createOptimizedWindow() {
   
  const win = new BrowserWindow({
   
    width: 1200,
    height: 800,
    show: false,  // 初始隐藏窗口
    backgroundColor: '#2e2c29', // 设置背景色减少白闪
    webPreferences: {
   
      // 优化预加载
      preload: path.join(__dirname, 'preload.js'),
      // 安全设置
      nodeIntegration: false,
      contextIsolation: true,
      // 性能优化
      backgroundThrottling: false, // 防止后台限流
      // 渲染进程优化
      enableRemoteModule: false, // 禁用remote模块减少开销
    }
  });
  
  // 优化窗口加载策略
  win.once('ready-to-show', () => {
   
    win.show();
    // 在UI可见后延迟执行非关键初始化
    setTimeout(() => {
   
      // 初始化插件、扩展功能等
    }, 500);
  });
  
  return win;
}

// 窗口恢复策略(提高二次启动速度)
function restoreWindowState(win) {
   
  try {
   
    const windowStateKeeper = require('electron-window-state');
    const mainWindowState = windowStateKeeper({
   
      defaultWidth: 1200,
      defaultHeight: 800
    });
    
    // 应用保存的窗口状态
    win.setPosition(mainWindowState.x, mainWindowState.y);
    win.setSize(mainWindowState.width, mainWindowState.height);
    if (mainWindowState.isMaximized) win.maximize();
    
    // 监听窗口变化以便保存
    mainWindowState.manage(win);
  } catch (e) {
   
    console.error('恢复窗口状态失败', e);
    // 使用默认窗口设置
  }
}

3. 主进程优化策略

主进程(Main Process)是Electron应用的核心,负责管理窗口、系统API调用和协调渲染进程。

3.1 避免主进程阻塞
// main.js

// 不好的做法:在主进程中执行CPU密集型任务
ipcMain.on('process-data', (event, data) => {
   
  const result = processMassiveData(data); // 阻塞主进程
  event.reply('process-result', result);
});

// 好的做法:使用工作线程处理密集型计算
const {
    Worker } = require('worker_threads');

ipcMain.on('process-data', (event, data) => {
   
  const worker = new Worker('./workers/dataProcessor.js');
  
  worker.on('message', (result) => {
   
    event.reply('process-result', result);
    worker.terminate();
  });
  
  worker.on('error', (err) => {
   
    console.error(err);
    event.reply('process-error', err.message);
    worker.terminate();
  });
  
  worker.postMessage(data);
});

// workers/dataProcessor.js
const {
    parentPort } = require('worker_threads');

parentPort.on('message', (data) => {
   
  // 执行CPU密集型任务
  const result = processMassiveData(data);
  parentPort.postMessage(result);
});

function processMassiveData(data) {
   
  // 复杂计算逻辑...
  return processedData;
}
3.2 优化IPC通信
// IPC通信优化

// 不佳实践:频繁小数据传输
// 渲染进程
for (let i = 0; i < 1000; i++) {
   
  window.electron.sendMessage('update-data', {
    id: i, value: data[i] });
}

// 主进程
ipcMain.on('update-data', (event, item) => {
   
  updateDatabase(item);
});

// 优化实践:批量传输
// 渲染进程
const batchSize = 50;
for (let i = 0; i < data.length; i += batchSize) {
   
  const batch = data.slice(i, i + batchSize);
  window.electron.sendMessage('update-data-batch', batch);
}

// 主进程
ipcMain.on('update-data-batch', (event, items) => {
   
  // 批量处理
  updateDatabaseBatch(items);
});

// 进一步优化:使用共享内存通信大数据
// main.js
const {
    app, BrowserWindow, ipcMain } = require('electron');
const nodeSharedMem = require('node-shared-mem');

const sharedBuffer = nodeSharedMem.create('my-app-data', 1024 * 1024); // 1MB共享内存

ipcMain.on('get-shared-buffer-info', (event) => {
   
  event.returnValue = {
   
    id: 'my-app-data',
    size: sharedBuffer.size,
  };
});

ipcMain.on('shared-buffer-updated', (event, {
     offset, length }) => {
   
  // 从共享内存读取数据
  const data = sharedBuffer.read(offset, length);
  processSharedData(data);
});

// preload.js
const nodeSharedMem = require('node-shared-mem');

contextBridge.exposeInMainWorld('sharedMemory', {
   
  getBufferInfo: () => ipcRenderer.sendSync('get-shared-buffer-info'),
  writeData: (data) => {
   
    const bufferInfo = ipcRenderer.sendSync('get-shared-buffer-info');
    const sharedBuffer = nodeSharedMem.open(bufferInfo.id);
    
    // 将数据写入共享内存
    sharedBuffer.write(0, data);
    
    // 通知主进程数据已更新
    ipcRenderer.send('shared-buffer-updated', {
    offset: 0, length: data.length });
  }
});
3.3 应用打包与减少体积
// electron-builder配置优化 (electron-builder.yml)
appId: "com.example.app"
productName: "My Electron App"
asar: true

# 文件过滤,缩小包体积
files:
  - "!**/*.map"  # 排除源码映射
  - "!**/*.ts"   # 排除TypeScript源文件
  - "!**/node_modules/*/{CHANGELOG.md,README.md,README,readme.md,readme}"
  - "!**/node_modules/*/{test,__tests__,tests,powered-test,example,examples}"
  - "!**/node_modules/*.d.ts"
  - "!**/node_modules/.bin"
  - "!**/*.{iml,o,hprof,orig,pyc,pyo,rbc,swp,csproj,sln,xproj}"
  - "!.editorconfig"
  - "!**/._*"
  - "!**/{.DS_Store,.git,.hg,.svn,CVS,RCS,SCCS,__pycache__,thumbs.db,.gitignore,.gitattributes}"
  - "!**/{__pycache__,*.py[cod],*$py.class}"
  - "!**/{.env,.env.*,.venv,venv,ENV,env,*.log}"

# 按平台拆分依赖,减少不必要的本地模块
electronDist: "node_modules/electron/dist"
nodeGypRebuild: false
npmRebuild: false

# 优化macOS打包
mac:
  target: 
    - dmg
    - zip
  hardenedRuntime: true
  gatekeeperAssess: false
  darkModeSupport: true
  category: "public.app-category.productivity"
  
# 优化Windows打包
win:
  target: 
    - nsis
    - portable
  artifactName: "${productName}-${version}-${arch}.${ext}"

# 使用压缩选项
compression: "maximum"

# 配置可执行文件元数据
extraMetadata:
  main

网站公告

今日签到

点亮在社区的每一天
去签到