Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

react-pdf generation is very slow in combination with umijs

I included react-pdf in a fresh umi project:

  • PDF-Generation 150 Text-components took arround 311.44 ms without umi
  • Using umi: 7179.40 ms

Every single element takes about 10X more in umi projects!

Code example I tried

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>
  );
}

NOTE: The following examples are ant-design-pro projects. BUT the error occurs in all umi-js projects.

  • Fast version: https://codesandbox.io/s/damp-thunder-rybh7
  • Slow version: https://codesandbox.io/s/confident-leaf-hgk7c?file=/src/pages/user/login/index.tsx Instructions slow version codesandbox
  • Slow version (GitHub): https://github.com/mleister97/ant-design-react-pdf-slow
  • (Slow version is a fresh setup of ant-design-pro, just modified the "startup"-page) fast version
  • (Make sure you open the Browser (:8000) Tab as the application is served on this port AND check directly the browser's console, not the codesandbox one)

What is going on behind the scenes when the toBlob is beeing called?

How can I fix this issue?

like image 854
mleister Avatar asked Sep 11 '20 23:09

mleister


2 Answers

I was able to fix it:

  1. npm install assert browserify-zlib buffer process stream-browserify util
  2. modify 'plugin.config.ts' (umijs chainWebpack config)
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'],
  }]);
};
like image 124
8cells Avatar answered Oct 20 '22 09:10

8cells


Actually, this issue comes from performance of browserify process, the CRA is fast for this test-code, because the configuration of Webpack on CRA used the new version of browserify process and it comes from /node_modules/process/browser.js but the umijs used the older version, the node-libs-browser that is DEPRECATED now and it comes from /node_modules/node-libs-browser/process.js.

I found it be adding break-points and track line after line and see when interpreter fall into /node_modules/node-libs-browser/process.js, it stocks for a long time which is not like it on /node_modules/process/browser.js and passes it as fast as can.

The node-libs-browser had a bad performance and the umijs should update its Webpack configuration to the latest versions. They still uses webpack-dev-middleware version 3.5.1, it is now on vesion 4.x.x.

The umijs has a great ability to get new configuration from developer by modifying /config/config.ts but its config docs is in Chinese language and still didn't have translated.

By these description I prefer to remove umijs from project. that is not a good solution but I think it is a wise decision

like image 1
AmerllicA Avatar answered Oct 20 '22 11:10

AmerllicA