You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

npm build后openpgp.generateKey()引发CPU100%卡顿问题求助

问题分析与解决方案

你的问题核心是生产构建后,openpgp.generateKey()作为计算密集型任务阻塞了主线程,导致CPU占用拉满、浏览器卡顿崩溃。开发环境流畅是因为未压缩的代码保留了openpgp内部的异步调度逻辑,而生产构建的压缩优化(比如Terser)可能破坏了这些逻辑,让密钥生成变成同步阻塞操作。

以下是针对性的解决方法:

1. 用Web Worker隔离计算任务(最可靠方案)

把密钥生成逻辑放到Web Worker中,让计算在独立线程执行,完全不阻塞主线程UI。

步骤1:创建Worker文件

新建keyGenerator.worker.js:

import * as openpgp from 'openpgp';

self.onmessage = async (e) => {
  const { name, email, passphrase } = e.data;
  try {
    const { privateKey, publicKey } = await openpgp.generateKey({
      type: 'rsa',
      rsaBits: 4096,
      userIDs: [{ name, email }],
      passphrase
    });
    self.postMessage({ privateKey, publicKey });
  } catch (err) {
    self.postMessage({ error: err.message });
  }
};

步骤2:修改组件调用Worker

更新你的GenKeys组件:

import { useState } from 'react'

function GenKeys () {
    const [name, setName] = useState('')
    const [email, setEmail] = useState('')
    const [passphrase, setPassphrase] = useState('')
    const [privateKey, setPrivateKey] = useState('')
    const [publicKey, setPublicKey] = useState('')
    const [isGenerating, setIsGenerating] = useState(false)

    const genKeyPair = () => {
        if (isGenerating) return;
        setIsGenerating(true);
        
        // 实例化Worker
        const worker = new Worker(new URL('./keyGenerator.worker.js', import.meta.url));
        
        // 传递参数
        worker.postMessage({ name, email, passphrase });
        
        // 接收结果
        worker.onmessage = (e) => {
            setIsGenerating(false);
            if (e.data.error) {
                alert('密钥生成失败:' + e.data.error);
            } else {
                setPrivateKey(e.data.privateKey);
                setPublicKey(e.data.publicKey);
            }
            worker.terminate(); // 用完销毁Worker
        };
        
        // 处理Worker错误
        worker.onerror = (err) => {
            setIsGenerating(false);
            alert('生成出错:' + err.message);
            worker.terminate();
        };
    }

    return <div>
        <input value={name} onChange={e => setName(e.target.value)} placeholder='Name' />    
        <input value={email} onChange={e => setEmail(e.target.value)} placeholder='Email' /> 
        <input value={passphrase} onChange={e => setPassphrase(e.target.value)} type="password" placeholder='Password' />    
        <button onClick={genKeyPair} disabled={isGenerating}>
            {isGenerating ? '生成中...' : 'Gen Keys'}
        </button>
        <div>
            <div>
                Private Key
                <br />
                <textarea value={privateKey} />
            </div>
            <div>
                Public Key
                <br />
                <textarea value={publicKey} />
            </div>
        </div>
    </div>;
}

export default GenKeys;

2. 调整生产构建优化选项(备选)

如果不想用Worker,可以尝试禁用Terser可能破坏openpgp异步逻辑的压缩选项。需要通过react-app-rewired修改CRA配置:

  1. 安装依赖:
npm install react-app-rewired --save-dev
  1. 新建config-overrides.js:
module.exports = function override(config, env) {
  if (env === 'production') {
    config.optimization.minimizer[0].options.terserOptions.compress = {
      ...config.optimization.minimizer[0].options.terserOptions.compress,
      unused: false,
      dead_code: false,
      keep_fnames: true
    };
  }
  return config;
};
  1. 修改package.json的scripts:
{
  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test"
  }
}

3. 升级openpgp版本

检查你当前的openpgp版本,升级到最新版可能修复了生产构建下的兼容性问题:

npm install openpgp@latest

内容的提问来源于stack exchange,提问作者jamezyx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 19:23:22