kiwix-js icon indicating copy to clipboard operation
kiwix-js copied to clipboard

Electron vs NWJS notes

Open Jaifroid opened this issue 4 years ago • 5 comments

Having spent some time playing and building with both frameworks (ElectronJS and NWJS), I thought I should summarize my findings before I forget, as they could influence which one Kiwix JS should adopt (if any). Here are pros and cons:

Electron pros:

  • It is by far the most popular framework, so there are many more packages and up-to-date build scripts;
  • Zipped Kiwix Packages built with latest Electron are about 20MB smaller than those built with latest NWJS (136,957KB vs 159,302KB, including the wikipedia-en-100 ZIM);
  • Scrolling is smoother inside the Electron app.

Electron cons:

  • There is no version compatible with Windows XP;
  • It is more complicated to set up (requires extra scripts main.js and preload.js);
  • URLs internally are file:///, so browser-provided caching does not work in SW mode (but SW does work);
  • For the same reason, cookies do not work and we need to patch cookies.js to use localStorage instead (though it's a very small patch).

NWJS pros:

  • A legacy version is available which allows building a specific binary to support Windows XP 32bit;
  • The app runs internally in the context of a Chrome extension, so it has chrome-extension:// URLs and caching works in SW mode (producing noticeable speedup of page reloads in SW mode);
  • Cookies and Service Worker work "out of the box" in recent builds (SW mode does not of course work in the WinXP build);
  • Requires less patching of code: only a four-line script needs to be added to index.html, and a small change to util.js (to enable reading of files with the node API);
  • Runs with no proprietary menus, so has a cleaner look.

NWJS cons:

  • Scrolling "framerate" is slow / noticeable in the latest version (may be a transitory issue: need to try a LTS version perhaps);
  • Larger footprint;
  • Less well supported by dev community (but as it's easy to set up, maybe this doesn't matter).

Both frameworks would need extra code added to Kiwix JS in order to auto-load a packaged ZIM or a ZIM previously picked by the user. We should be able to adapt the existing Firefox OS code to do this.

Jaifroid avatar Aug 10 '19 16:08 Jaifroid

Wouah, that's cool. Thanks for all these tests. Based on your pros and cons, I'd say NWJS is more suited IF the framerate issue can be solved.

mossroy avatar Aug 17 '19 15:08 mossroy

You can try the NWJS package for Win7/8/10 to see if it is smooth enough:

https://github.com/kiwix/kiwix-js-windows/releases/tag/v0.9.9.93-IA32

When running on battery, I notice the scroll-rate issue, but not when my machine is plugged in. Maybe I'm exaggerating. Possibly the scrolling issue wouldn't exist on Kiwix JS, because I use a setTimeout onscroll script (just one) to monitor various things in the Windows version.

The XP version (jQuery only) is here:

https://github.com/kiwix/kiwix-js-windows/releases/tag/v0.9.9.93-XP

(The XP one will run on more recent machines, but can't render properly the landing page due to age of Chromium build.)

I'd be happy to provide the necessary bits of code and instructions to build this with Kiwix JS.

Jaifroid avatar Aug 17 '19 15:08 Jaifroid

PS If running both the XP and the IA32 versions, I once got an error about the Chromium profile on XP being incompatible because I'd used a later version of Chromium. I had to delete the Chromium profile on my machine to be able to run the XP versions. JFYI.

Jaifroid avatar Aug 17 '19 15:08 Jaifroid

Some of the glitches I had experienced with Electron on Kiwix JS Windows appear to have been ironed out in the latest release I tested (v9.0.5): it is now possible to print from the iframe document (using window.print()) without crashing the app and Service Worker mode seems stable (before it would randomly hang, mostly due to CORS issues). It can be tested with the WikiMed Electron packaged app.

I still prefer the NWJS approach of simulating a chrome extension. Electron in default mode runs from file:// protocol and patches it to allow Service Worker to work. However, the patching isn't complete: Cache API isn't patched to allow the protocol.

Jaifroid avatar Jul 07 '20 06:07 Jaifroid

As promised in #727, some further notes on NWJS vs Electron, from my experience with both.

  • NWJS:
    • As I say above, I still prefer how NWJS do things, running the code as a Chromium extension. Things just work. For example, no fiddling is required to get Service Worker mode to work (with the one excpetion that Cache API is not supported in Chromium extensions, but we have workarounds for that in our code already).
    • NWJS fully supports the File System Access API. While this is not needed for NWJS or Electron because they have the Node API for filesystem access (fs), it is great to be able to use a standard API, integrating well with PWA code. NWJS hacks the File System Access API so that the user does not need to provide permsiison, therefore it works as well as the underlying Node fs.
    • The big drawback of NWJS is lack of developer support. Both of its recommended packaging solutions, NWJS Builder and NWJS Builder Phoenix, are "archived" on GitHub and NPM, and receive no further updates. They were never finished either, so don't support Linux and many other modern features, like modern installers and code-signing. So, all you can really build are Zipped portable versions.
  • Electron:
    • Electron runs local code from the file:// protocol, but hacks it so that the browser sees it as privileged. The hacking is not always complete, when new features come out, and this leads to difficulty supporting Service Worker running from local code. It's currently working, but I have to evaluate each new release of Electron, as things break easily. The API has just changed again, and has extra security features that require a rewrite and testing. The way in which Node modules are exposed to the main app window has changed yet again. Yes, it's very secure, but difficult for developers to keep up. Hence I am using a release that is a few cycles behind the latest, for stability.
    • As a result of the above, the File System Access API is not fully supported in Electron (yet). There is an open issue on this. Because they have their own API, they don't see it as a priority. So I fall back to using Node fs in a "raw" manner, and it's fine, providing all the functionality that users would expect of an installed app (no file picking required on relaunch of app, etc.).
    • Electron's big, big advantage is the fantastic Electron Builder, which makes it almost ridiculously easy to build portable and installable, code-signed packages for all major OS's (except you need a Mac to build for macOS). They provide a docker container with everything required to build on Linux and Windows, though you can also build for both platforms from the Windows commandline and leveraging Windows Subsystem for Linux. MacOS requires a Mac, however.
    • Electron Builder provides a self-update module which allows the app to check the release server (which can be GitHub) for a new package and inform users that one is waiting, provide an Update button, and update, all within the app. I haven't implemented it yet, but it looks relatively easy and I've experienced it with other Electron apps.
    • Electron is much better known in the developer community, and has lots of mainstream support, lots of NPM packages and modules that extend functionality.

Reluctantly (because I think the main NWJS developer is doing an amazing job), I feel I would now have to recommend Electron for Kiwix JS due to the building options and the wide developer support. However, if Kiwix JS only wants to build minimal portable Zipped packages, then the recommenation would be less firm.

Jaifroid avatar May 29 '21 09:05 Jaifroid

Only relevant to KJSWL now.

Jaifroid avatar Nov 06 '22 13:11 Jaifroid