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配置:
- 安装依赖:
npm install react-app-rewired --save-dev
- 新建
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; };
- 修改
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
相关产品推荐
相关产品推荐

