结合 umijs 生成 react-pdf 非常慢
react-pdf generation is very slow in combination with umijs
我在一个新的 umi 项目中包含了 react-pdf:
- PDF 生成 150 个文本组件在没有 umi 的情况下花费了 311.44 毫秒
- 使用 umi:7179.40 毫秒
在 umi 项目中,每个元素的占用量大约多 10 倍!
我试过的代码示例
import React from "react";
import "./styles.css";
import { Document, Page, pdf, Text, View } from "@react-pdf/renderer";
export default function App() {
const pdfClickHandler = async () => {
console.time("PDF generation took:");
await pdf(
<Document>
<Page>
<View>
{Array.from(Array(150).keys()).map((key) => (
<Text key={key}>text-element</Text>
))}
</View>
</Page>
</Document>
).toBlob();
console.timeEnd("PDF generation took:");
};
return (
<div className="App">
<button onClick={pdfClickHandler}>
Generate fast PDF (without ant-design-pro)
</button>
</div>
);
}
注意:以下示例是ant-design-pro
个项目。但是错误发生在所有 umi-js
个项目中。
- 快速版本:https://codesandbox.io/s/damp-thunder-rybh7
- 慢速版本:https://codesandbox.io/s/confident-leaf-hgk7c?file=/src/pages/user/login/index.tsx
- 慢速版本(GitHub):https://github.com/mleister97/ant-design-react-pdf-slow
- (慢版是ant-design-pro的全新设置,只是修改了“启动”页面)
- (确保打开浏览器 (:8000) 选项卡,因为应用程序在此端口上提供服务,并直接检查 浏览器的控制台 ,而不是 codesandbox)
调用 toBlob 时幕后发生了什么?
我该如何解决这个问题?
实际上,此问题来自 browserify 进程 的性能,CRA 对于此 test-code 来说速度很快,因为Webpack 在 CRA 上的配置使用了新版本的 browserify process 它来自 /node_modules/process/browser.js
但 umijs 使用旧版本,node-libs-browser
现在 DEPRECATED,它来自 /node_modules/node-libs-browser/process.js
.
我发现它正在添加 break-points 并逐行跟踪并查看解释器何时落入 /node_modules/node-libs-browser/process.js
,它存储了很长时间,这与 /node_modules/process/browser.js
上的不同并且尽快通过它。
node-libs-browser
性能不佳,umijs
应该将其 Webpack 配置更新到最新版本。他们仍然使用 webpack-dev-middleware
版本 3.5.1,现在是版本 4.x.x.
umijs
可以通过修改 /config/config.ts
从开发人员那里获取新配置,但是它的配置文档是中文的,仍然没有翻译。
根据这些描述,我更愿意从项目中删除 umijs
。这不是一个好的解决方案,但我认为这是一个明智的决定
我能够修复它:
npm install assert browserify-zlib buffer process stream-browserify util
- 修改'plugin.config.ts'(umijs chainWebpack配置)
export default (config: any, { webpack }: { webpack: any }) => {
// Set alias
config.resolve.alias.set('process', 'process/browser');
config.resolve.alias.set('stream', 'stream-browserify');
config.resolve.alias.set('zlib', 'browserify-zlib');
// Set plugin
config.plugin('record').use(webpack.ProvidePlugin, [{
process: 'process/browser',
Buffer: ['buffer', 'Buffer'],
}]);
};
我在一个新的 umi 项目中包含了 react-pdf:
- PDF 生成 150 个文本组件在没有 umi 的情况下花费了 311.44 毫秒
- 使用 umi:7179.40 毫秒
在 umi 项目中,每个元素的占用量大约多 10 倍!
我试过的代码示例
import React from "react";
import "./styles.css";
import { Document, Page, pdf, Text, View } from "@react-pdf/renderer";
export default function App() {
const pdfClickHandler = async () => {
console.time("PDF generation took:");
await pdf(
<Document>
<Page>
<View>
{Array.from(Array(150).keys()).map((key) => (
<Text key={key}>text-element</Text>
))}
</View>
</Page>
</Document>
).toBlob();
console.timeEnd("PDF generation took:");
};
return (
<div className="App">
<button onClick={pdfClickHandler}>
Generate fast PDF (without ant-design-pro)
</button>
</div>
);
}
注意:以下示例是ant-design-pro
个项目。但是错误发生在所有 umi-js
个项目中。
- 快速版本:https://codesandbox.io/s/damp-thunder-rybh7
- 慢速版本:https://codesandbox.io/s/confident-leaf-hgk7c?file=/src/pages/user/login/index.tsx
- 慢速版本(GitHub):https://github.com/mleister97/ant-design-react-pdf-slow
- (慢版是ant-design-pro的全新设置,只是修改了“启动”页面)
- (确保打开浏览器 (:8000) 选项卡,因为应用程序在此端口上提供服务,并直接检查 浏览器的控制台 ,而不是 codesandbox)
调用 toBlob 时幕后发生了什么?
我该如何解决这个问题?
实际上,此问题来自 browserify 进程 的性能,CRA 对于此 test-code 来说速度很快,因为Webpack 在 CRA 上的配置使用了新版本的 browserify process 它来自 /node_modules/process/browser.js
但 umijs 使用旧版本,node-libs-browser
现在 DEPRECATED,它来自 /node_modules/node-libs-browser/process.js
.
我发现它正在添加 break-points 并逐行跟踪并查看解释器何时落入 /node_modules/node-libs-browser/process.js
,它存储了很长时间,这与 /node_modules/process/browser.js
上的不同并且尽快通过它。
node-libs-browser
性能不佳,umijs
应该将其 Webpack 配置更新到最新版本。他们仍然使用 webpack-dev-middleware
版本 3.5.1,现在是版本 4.x.x.
umijs
可以通过修改 /config/config.ts
从开发人员那里获取新配置,但是它的配置文档是中文的,仍然没有翻译。
根据这些描述,我更愿意从项目中删除 umijs
。这不是一个好的解决方案,但我认为这是一个明智的决定
我能够修复它:
npm install assert browserify-zlib buffer process stream-browserify util
- 修改'plugin.config.ts'(umijs chainWebpack配置)
export default (config: any, { webpack }: { webpack: any }) => {
// Set alias
config.resolve.alias.set('process', 'process/browser');
config.resolve.alias.set('stream', 'stream-browserify');
config.resolve.alias.set('zlib', 'browserify-zlib');
// Set plugin
config.plugin('record').use(webpack.ProvidePlugin, [{
process: 'process/browser',
Buffer: ['buffer', 'Buffer'],
}]);
};