Skip to content

[BUG] Extremely poor performance with slow readFile and slow writeFile on very small files #1842

Open
@oscarcoding

Description

@oscarcoding

🐛 Bug Report

Many files are extremely slow to read and write, despite being very small, eg less than 100kb. For example a file with 2 sheets, columns A - L, 200 rows.

This occurs when reading/writing on the API side, ie using nodejs

Lib version: 4.3.0. Node v10 on a Docker image.
Was also occurring on exceljs 3.x

Steps To Reproduce

const filePath = path.join(__dirname, 'myfile.xlsx')
let workbook = new Excel.Workbook()
workbook = await workbook.xlsx.readFile(filePath)
// takes 10 seconds
      
const outFilePath = path.join(__dirname, 'myfile_updated.xslx')
await workbook.xlsx.writeFile(outFilePath)
// takes 45 seconds to one minute

Logs output:

[02:30:31 5170]  START readFile .... 
[02:30:41 1680]  ... DONE readFile
[02:30:41 1700]  START writeFile ....
[02:31:24 9620]   ... DONE writeFile
[02:31:24 9630]  Set headers
[02:31:24 9630]  Send file

Also, occasionally it crashes with an out of memory error when writing the file, which indicates that the slow performance is due to excessive memory use. This is a 67kb file. It should not cause an out of memory error.

==== JS stack trace =========================================
 0: ExitFrame [pc: 0x22878ba5bf1d]
 Security context: 0x2c572fb9e6c1 <JSObject>
    1: /* anonymous */ [0x3333573c1149] [/var/www/api/node_modules/exceljs/lib/xlsx/xform/sheet/data-validations-xform.js:~36] [pc=0x22878ba61947](this=0x3cc2c678d461 <JSGlobal Object>,dataValidation=0x0cfda8d0ac19 <Object map = 0x369bde2c94d9>,address=0x168ed0a4c5a1 <String[7]: K486175>)
    2: /* anonymous */ [0x3333573c11c1] [/var/www/api/node_modules/exc...

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory

Hopefully the stacktrace helps to find where this is occurring.

I have tried the patchDefinedNames fix suggested in other issues however it does not work because DefinedNames.prototype is undefined:

(function patchDefinedNames() {
  console.log('START patchDefinedNames', DefinedNames, DefinedNames.prototype)
    try {
      const desc = Object.getOwnPropertyDescriptor(DefinedNames.prototype, "model");
      console.log('START defineProperty', desc)
      if (desc) {
        Object.defineProperty(DefinedNames.prototype, "model", {
          get: desc.get,
          set: noop
        });
      }
      console.log('DONE defineProperty')
    } catch (error) {
      console.log('ERROR in patchDefinedNames', error)
    }
  console.log('DONE patchDefinedNames')
})();

Log output from the fix is:

START patchDefinedNames { default: [Function: DefinedNames] } undefined }
ERROR in patchDefinedNames TypeError: Cannot convert undefined or null to object
    at Object.getOwnPropertyDescriptor (<anonymous>)
    at getOwnPropertyDescriptor (/var/www/api/node_modules/core-js/library/fn/object/get-own-property-descriptor.js:4:18)
    at Timeout.patchDefinedNames [as _onTimeout] (/var/www/api/dist/controllers/approval/index.js:71:18)
    at ontimeout (timers.js:436:11)
    at tryOnTimeout (timers.js:300:5)
    at listOnTimeout (timers.js:263:5)
    at Timer.processTimers (timers.js:223:10)
DONE patchDefinedNames

This error occurs because DefinedNames.prototype is undefined. So this suggested fix does not work as at v4.3.0

Note that there are many other reported issues regarding read/write performance, and it does not look like it is being fixed. Instead it looks like this is a serious and ongoing issue.

#535,
#1494,
#1609,
#1017,
#1597,
#847,
#742,
#566,
#535,
#527,
#282,
#125,

The expected behaviour:

File should be read in sub 1 second time.
File should write in 1 or 2 seconds time. Obviously file operations have some overhead.

If this not fixable then sadly we will have to stop using exceljs

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions