tinyify icon indicating copy to clipboard operation
tinyify copied to clipboard

Applying tinyify to plotly.js crashes Node

Open m90 opened this issue 7 years ago • 8 comments

I'm trying to optimize a bundle that contains the (rather hefty) plotly.js library.

When I pass -p tinyify to my bundling command it will hang for quite a while and then crash, printing the following:

<--- Last few GCs --->

[9631:0x36f27f0]    56924 ms: Mark-sweep 1345.1 (1440.5) -> 1344.3 (1456.5) MB, 1270.8 / 0.0 ms  (average mu = 0.103, current mu = 0.006) allocation failure scavenge might not succeed
[9631:0x36f27f0]    58143 ms: Mark-sweep 1344.3 (1456.5) -> 1344.3 (1456.5) MB, 1218.0 / 0.0 ms  (average mu = 0.053, current mu = 0.000) allocation failure GC in old space requested


<--- JS stacktrace --->

==== JS stack trace =========================================

    0: ExitFrame [pc: 0x292a09adc01d]
Security context: 0x37fbe811e549 <JSObject>
    1: addHelpers [0x1401217d54e9] [/home/frederik/projects/tinyify-crash/node_modules/transform-ast/index.js:~87] [pc=0x292a0a5a7f5a](this=0x2f3e1e21aa09 <JSGlobal Object>,node=0x071fba8d11c1 <Node map $
 0x213b1d12dc9>)
    2: enter [0x208cdc2350f9] [/home/frederik/projects/tinyify-crash/node_modules/transform-ast/index.js:~33] [pc=0x292a09e5713a](this=0x2f...

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
 1: 0x8c02c0 node::Abort() [node]
 2: 0x8c030c  [node]
 3: 0xad15de v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [node]
 4: 0xad1814 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [node]
 5: 0xebe752  [node]
 6: 0xebe858 v8::internal::Heap::CheckIneffectiveMarkCompact(unsigned long, double) [node]
 7: 0xeca982 v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [node]
 8: 0xecb2b4 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [node]
 9: 0xecdf21 v8::internal::Heap::AllocateRawWithRetryOrFail(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [node]
10: 0xe96236  [node]
11: 0xea8a87 v8::internal::Factory::NewLoadHandler(int) [node]
12: 0xf2828e v8::internal::LoadHandler::LoadFullChain(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Map>, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Smi>) 
[node]
13: 0xf3663d v8::internal::LoadIC::UpdateCaches(v8::internal::LookupIterator*) [node]
14: 0xf36b6c v8::internal::LoadIC::Load(v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Name>) [node]
15: 0xf3b4a5 v8::internal::Runtime_LoadIC_Miss(int, v8::internal::Object**, v8::internal::Isolate*) [node]
16: 0x292a09adc01d 
Aborted (core dumped) 

When I omit the plugin, I can bundle things just fine. I also can pipe the bundle through uglifyjs --mangle just fine.

I created a repo with an example case here: https://github.com/m90/tinyify-crash

As for Node internals, I am running the following on Ubuntu 16:

➜  ~ node -v
v10.9.0
➜  ~ npm -v
6.4.0

m90 avatar Aug 21 '18 14:08 m90

I'm wondering if this is related to the fact that the module that plotly exports is already a browserified bundle (thus somehow ending up in an infinite loop causing the overflow), which was kind of complicated to get to work in the first place, see:

  • https://github.com/plotly/plotly.js/issues/2902
  • https://github.com/plotly/plotly.js/pull/2905

m90 avatar Aug 21 '18 14:08 m90

Scrap the comment above, it also happens when applied to the non-prebundled version of plotly.

m90 avatar Aug 21 '18 15:08 m90

Getting the same over here. Probably because my bundle is quite substantial. I narrowed the problem to this part of the plugin (browser-pack-flat/plugin and bundle-collapser/plugin):

  if (!b._options.fullPaths) {
    if (opts.flat) {
      // Output a flat bundle, without function wrappers for each module.
      b.plugin(packFlat)
    } else {
      // Replace file paths in require() calls with module IDs.
      b.plugin(collapser)
    }
  }

Commenting the above or using browserify fullPaths bundles successfully. Not ideal at all as I don't really want the fullPaths in my bundle.

dmnsgn avatar Dec 05 '18 11:12 dmnsgn

Ack. you can use --no-flat in the CLI or flat: false in the API to disable browser-pack-flat, does it still crash then? bundle-collapser is significanly less complex than browser-pack-flat.

goto-bus-stop avatar Dec 05 '18 11:12 goto-bus-stop

Getting the following error with flat: false using bundle-collapser: SyntaxError: Unexpected token coming from acorn.js. The error isn't descriptive at all but I guess it has to do with acorn and not bundle-collapser.

dmnsgn avatar Dec 05 '18 11:12 dmnsgn

ow, it's possible that bundle-collapser doesn't support some new syntax. in case you're using async functions or something. it should be updated.

goto-bus-stop avatar Dec 05 '18 11:12 goto-bus-stop

I am using some async/await indeed. I'd say it is coming from https://github.com/browserify/browser-unpack/:

  └─┬ [email protected]
    ├─┬ [email protected]
    │ └─┬ [email protected]
    │   └── [email protected]  deduped
    ├─┬ [email protected]
    │ └─┬ @goto-bus-stop/[email protected]
    │   └── [email protected]  deduped
    └─┬ [email protected]
      ├── [email protected]  deduped
      └─┬ [email protected]
        └── [email protected]

Latest acorn is 6.0.4

dmnsgn avatar Dec 05 '18 12:12 dmnsgn

This works now when using today's versions of Node, plotly, tinyify and browserify.

m90 avatar Aug 31 '20 19:08 m90