nwjs / nw.js

Call all Node.js modules directly from DOM/WebWorker and enable a new way of writing applications with all Web technologies.
https://nwjs.io
MIT License
40.33k stars 3.88k forks source link

slow startup on packaged windows app #514

Closed zippo445 closed 9 years ago

zippo445 commented 11 years ago

I packaged my node-webkit app for windows as described in https://github.com/rogerwang/node-webkit/wiki/How-to-package-and-distribute-your-apps

the startup is very slow when double-clicking on the resulting app.exe ( ~ 15 secs). On the same platform, when I start my app by dragging the uncompressed nw directory on nw.exe the startup time is quite good ( < than 2 sec). dragging a compressed folder has a slow startup time as well, bringing me to believe the problem is around uncompressing of resources by node-webkit... any way around the compression for a stand-alone app on windows? if not, would it be possible to display some kind of feedback during startup (splash screen, progress)?

tested on win7 running in virtualbox

owenc4a4 commented 11 years ago

What is the size of your app?

wahono77 commented 11 years ago

My app run slowly too at startup, about 25 secs. I test create app with Maqetta (Dojo toolkit), after compressed app and all libraries, the file size (app.nw) is 8,3 MB, after merging with nw.exe the size of app.exe is 42 MB.

I think slow in startup normally because of extracting compressed file. How to add progress display (percentage) while starting app.

Thanks

zippo445 commented 11 years ago

Slow startup is definitely due to extraction of the compressed file. I don't experience the problem on OSX since my resources are not compressed in the app bundle. on windows, I have 14MB of compressed data bundled in the app for a total app size of 47MB...

plrdev commented 11 years ago

I have this happening as well, but I get the delay even when opening my project as a folder, which would imply that it is not necessary due to extraction of the compressed files. I am yet to see any pattern to understand why it happens. It just some times does and sometimes not. Running Win7 64bit if that helps. This is more annoying than anything else, but I think would still be worth looking into.

matthiasg commented 11 years ago

is it really wise and neccesary to unpack it every time ? it might make more sense add a unique identifier (e.g. a version) into package.json and only unpack when that version folder does not exist in the temp area ...

rogerwang commented 11 years ago

@zippo445 there is an alternative way: You can just put files of node-webkit in the same directory with your package.json and then distribute the tree. When nw executable is started it will look for package.json in the same directory.

matthiasg commented 11 years ago

i have done some tests and even a minimal zip file of 385kb it takes a number of seconds to start. i watched with process monitor and it seems the zip is read from the file one byte at a time that could be the issue (~385 k calls in my case) even with buffering this might be the issue

matthiasg commented 11 years ago

@rogerwang actually you cannot really put your files next to it, because parameters passed to your own app are interpreted by nw.exe then which causes nw to show a cannot load error instead of running the index.html.

1) nw.exe should not interpret the command line looking for an app to start when a package.json exists locally (other arguments for webkit are ok of course) 2) nw source should be reviewed as to why it steps through the zip file in 1byte increments which makes the feature basically unusable. startup times of multiple seconds when the bare app starts in less than a second is not acceptable. see my previous comment

matthiasg commented 11 years ago

btw: the zip behaviour as tested and described above was on Windows XP SP3 which is one of our major deployment targets still (being in the enterprise field with mostly xp as target machines still)

matthiasg commented 11 years ago

this is a capture of the zip behavior as seen on my test machine (its a 380k zip standalone) file. the exe is 0.5.1 nw.exe.

zip-behavior

i also tried with appended zip/compressed and uncompressed exe and 0.4.2 which looks similar...

PS: I also saw that nw is using chrome's built in unzip functionality so i wonder whether the problem is a little deeper. (https://github.com/chromium-illumos/src/blob/master/chrome/common/zip.cc)

rogerwang commented 11 years ago

@matthiasg we fixed the argument passing issue. Does it work for you now?

I'll look into the 1-byte-scanning issue at some time.

Codelica commented 10 years ago

This thread seems to have gone cold, but appears to still be an issue in 0.9.2. The unzip performance under Windows is devastating if the application has even moderate resources zipped up. :(

Any new thoughts on the 1-byte-scanning issue or some potential way to avoid zipping for packaged Windows applications?

EDIT: Just to follow-up, we seem to have found some success in leaving the application completely uncompressed (package.json, index.html, nw.exe, etc...) and wrapping it all up (again uncompressed) via Enigma Virtual Box. http://enigmaprotector.com/en/aboutvb.html

kk86bioinfo commented 10 years ago

Hi, just want to share what I did to get it run better in my node-webkit app.

  1. I wrap most of my app codes in a folder "core".
  2. Zip this folder of core scripts to core.zip.
  3. I write the basic index.html as splashscreen.html and get it run as top wrapper in package.json.
  4. Use https://github.com/EvanOxfeld/node-unzip, make sure all your node modules are in same directory with package.json (same level with splashscreen.html)
  5. Example:
  var fs = require('fs'),
  unzip = require('unzip'),
  rootPath = require('path').resolve(process.cwd(), './'),
  corePath = require('path').resolve(process.cwd(), './core.zip');

  var unPacking = fs.createReadStream(corePath)
      .pipe(unzip.Extract({path: rootPath}));
  unPacking.on('close', function(){
      console.log('Unpacking is done...');                
      initApp();
  });
  function initApp(){
      setTimeout(function(){
                // Load native UI library
                var gui = require('nw.gui');
                var win = gui.Window.get();
                win.hide();
                //Open real app screen.
                var appWin = gui.Window.open(
                    "./core/index.html",
                    {
                        position: 'center',
                        width: 800,
                        height: 600,
                        frame: false,
                        toolbar: true,
                        focus: true
                    }
                );
                appWin.focus();
      }, 2000);
  }

Hope it helps.

matthiasg commented 10 years ago

@rogerwang the argument passing seems fixed thank you .. sorry for replying so late i did not see your message until now. The unzip performance is still bad. The workaround from kk_loke86 would work of course but defeat the purpose a little since the performance of unzip i got using node was less than optimal (especially memory consumption was suboptimal). But even when that changes or has changed already (did not try to unzip in some time) it should really not be an issue to begin with and be handled correctly by node-webkit.

On Thu, Aug 1, 2013 at 11:17 PM, Roger Wang notifications@github.com wrote:

@matthiasg https://github.com/matthiasg we fixed the argument passing issue. Does it work for you now?

I'll look into the 1-byte-scanning issue at some time.

— Reply to this email directly or view it on GitHub https://github.com/rogerwang/node-webkit/issues/514#issuecomment-21970419 .

Mithgol commented 10 years ago

I believe https://github.com/Stuk/jszip/ has better performance than node-unzip.

(JSZip is based on https://github.com/nodeca/pako that has impressive benchmark results.)

VoidStatic commented 9 years ago

Any update on this issue?

Codelica commented 9 years ago

If you're willing/able to use Enigma Virtual Box with your project to wrap it into a single .exe you can leave things unzip'd in their container and performance is quite good. We've done this on a couple projects now with good results. From my earlier post if you missed it:

"Just to follow-up, we seem to have found some success in leaving the application completely uncompressed (package.json, index.html, nw.exe, etc...) and wrapping it all up (again uncompressed) via Enigma Virtual Box. http://enigmaprotector.com/en/aboutvb.html

mustapha-wang commented 9 years ago

Yes,don`t packaged into *.zip,use Enigma box you application directory directly. Launching nw_boxed.exe is more faster,about 5 seconds. But,appears 4 process of nw_boxed.exe. 3 of them is busy if I use a cloudTag.(cpu 20%+)

christomitov commented 9 years ago

@mustapha-wang @Codelica I'm sorry I'm trying to use enigma virtual box without packaging anything (just raw directory structure with package.json) . When it's boxed with enigma virtual box I see it in task manager but nothing is running. When I click the nw.exe in the folder the app loads instantly as expected.. so I'm not missing any modules or anything in the virtual boxed exe, any ideas?

Codelica commented 9 years ago

@christomitov Hard to say off hand. We just use nw.exe as the "Input file" and drag all the assets for NW and our application to the "Files" section. Here is a screenshot example (from an older version of NW, but we've used it with the latest also):

enigmavirtualbox_screenshot

matthew-dean commented 9 years ago

Not sure why this is closed. For me, my app starts in a few seconds for Mac, and takes 2-3 MINUTES to open on Windows. I have timing analytics which show that the difference in running the actual app between platforms is only a few seconds, so all the extra time is spent loading node-webkit itself (and I guess extracting the package?).

baconbrad commented 9 years ago

@matthew-dean How massive is your app because it sounds like you might have a bit in it? Mac has an obvious advantage. "The bonus over other platforms is that app.nw does not need to be a zip file, if you want to speed up startup, you can make app.nw your app's directory." Otherwise your application needs to unpack itself every run. You can reduce this load time by moving resources out of your .nw file and into the applications root directory where nw.exe is stored for an example.

matthew-dean commented 9 years ago

@baconface - It's not huge in size, but there a number of node modules included for distribution that have lots of files.

It would be great if the extraction was a one-time event, but I'll probably look for a way to not zip them because even an initial load of 3 minutes is a lot. Enigma Virtual Box looks promising, but looks like you can only build on Windows, not with Wine.

baconbrad commented 9 years ago

@matthew-dean That can cause it. More files is worse than big files. You can put your node_modules folder in the same directory as your nw.exe and it will function like normal.

matthew-dean commented 9 years ago

@baconface Oh interesting. I'm using nw-builder so it just zips them together. I'm thinking I can probably modify the gulp file to exclude node_modules from zip and then copy them to the build folder before packaging. Thanks for the tip!

matthew-dean commented 9 years ago

You can put your node_modules folder in the same directory as your nw.exe and it will function like normal

.... Um, how do you get this to work exactly? You mean the node_modules folder in the same folder as my executable? That doesn't seem to work.

ABeltramo commented 9 years ago

Same problem here! In Windows it's super slow but on other platforms works really fast. Can't understand why this issue is closed.

matthew-dean commented 9 years ago

To follow up, I used the as-of-yet-unmerged pull request here: https://github.com/nwjs/nw-builder/pull/200

This made Windows startup decrease from 2 MINUTES to a few seconds.

soichih commented 8 years ago

+1 I am having the same slowness issue. I am using nw-builder to build the application package. I've tried setting "zip:false" with nw-builder but it didn't make any difference.

proofofvirtue commented 8 years ago

same issue here, it takes over 3 minutes to load in windows, as opposed to 5 seconds in my mac

datnordstrom commented 8 years ago

Same here, are there any solutions yet?

RohitSharma27 commented 8 years ago

Your packaged app is too big and has got too many files, may be? If this is the case then you may try upgrading to nw >= 0.13. As you don't need to zip your files on windows anymore. But this would increase your app's size. Anyways this could be an option.

matthew-dean commented 8 years ago

@RohitSharma27 Wait, how do later versions of NW.js resolve this?

To my knowledge, zip: false should fix this now.

RohitSharma27 commented 8 years ago

@matthew-dean I thought @datnordstrom is doing it manually and not with the "nw-builder". As far as I know, before nw 0.13, we had to zip our file and and name them "app.nw" for windows but now you can put them in a folder(zipping it is not required for windows anymore) named "package.nw" and put it in the same directory as "nw.exe". See this http://docs.nwjs.io/en/latest/For%20Users/Package%20and%20Distribute/

matthew-dean commented 8 years ago

@RohitSharma27 Oh. So why doesn't nw-builder do this?

RohitSharma27 commented 8 years ago

May be because this was the only possibility back with nw <= 0.12 versions. I don't use the zip:false option. But as far as I understand it just put our files with nw binaries, as stated in the quick start way. I will try the zip:false option when I get the bandwidth. In case you try then please share your observation.