Open rmannibucau opened 5 years ago
You can't drop Opal entirely since Asciidoctor.js depends on it to function. But if what you mean is to split it into to separate JavaScript files, then that would work.
Currently, Asciidoctor.js produces bundles that target different environments. One of them is browser. This file includes the Opal code and is not minified. We could consider producing a minimized version with and without Opal. However, this would bloat the npm package. So perhaps there is better way to publish it, or we could provide a post-install script that produces it after installation.
It's not that hard to output the file. You'd simply cut out all the lines before // UMD Module
, then run it through a minimizer.
We're not comparing ourselves to Markdown. Asciidoctor.js is made the way it is, and that's not going to change until we have a spec and could consider developing an implementation from scratch. So we can do what we can do to minimize, but Asciidoctor.js is going to rely on Opal for the foreseeable future.
The result I get is 734K after removing Opal (which you still have to load, but you can do it separately) and minimizing it with uglify-js. If I use the google-closure-compiler, I can get it down to 434K.
If you drop the extensions API, you can get down to 674K (402K with google-closure-compiler). If you only need to parse, and not convert, you can cut out the HTML5 converter to get down to 600K (359K with google-closure-compiler).
I wasn't able to get google-closure-compiler to run in advanced mode because of 4 errors, but that could likely reduce it further. Got it to run. Result was 301K (without Opal, extensions API, and HTML5 converter).
If I just take out Opal and run the google-closure-compiler in advanced mode, I get get the size down to 367K. (I'm not sure if that runs, but in theory it will). If I leave Opal in (which gives you an idea of total size), it ends up being 632K.
(Some of the changes for 2.0 could further reduce the transpiled size).
You could also try to do tree shaking on Opal/Asciidoctor.js since we do not use everything included in the Opal Runtime: https://webpack.js.org/guides/tree-shaking/
@Mogztter I'm thinking this would be some great information for the docs, at least to start. "How to optimize asciidoctor.js for the browser". Perhaps the project could provide a minimizer tool that would execute what the docs talk about with some presets.
This doesnt help since you still need to include Opal, and renderer at some point so just splitting and minimizing doesn't solve the issue today, this is why I suggested that to solve this issue, dropping opal can be the only way. Automated tools don't reduce it enough on the overall bundle.
Dropping Opal is dropping Asciidoctor.js. What you are suggestion just doesn't make any sense.
@mojavelinux happy to not drop opal but my reflection path is the following one:
Therefore I think it is likely the option with the most chances to work. However I'm fine while the functional bundle size of adoctor.js becomes acceptable, whatever it means technically.
I can get Asciidoctor.js with Opal included down to 175 Ko gzipped using Google Clojure Compiler in ADVANCED mode.
I removed the following modules from Opal:
corelib/math
corelib/complex
corelib/random
corelib/rationale
We should be able to remove corelib/time
(1K lines of code) if we introduce a few methods in Asciidoctor core (but maybe this Ruby module is used by other modules: Logger ?). corelib/numeric
could also be trimmed down.
As mentioned by @mojavelinux, depending on your use case you could also remove unused modules in Asciidoctor.
The code generated by Opal is modular. You can remove a whole Opal.modules["xyz"]
definition and the associated require
to reduce the size of the bundle.
This issue is about ensuring adoc.js is reduced enough - likely ~100k - to be usable in that context. I understand it likely means to drop opal but this is worth it to stay portable (environments).
@rmannibucau 100k gzipped ? If this is the case then we are not very far with a few cleanups.
I was more on 100k not gzipped but I agree a quick win for 100k gzip is likely worth it, but it can't be the final resolution IMHO
We can use the coverage tab on Chrome to find out which functions are used or not.
I'm using serve
(https://www.npmjs.com/package/serve) to run a local HTTP server and then browse to: http://localhost:5000/spec/browser/
To open the coverage tag, open the DevTools (F12), then click on the 3 vertical dots, then "More tools" > "Coverage".
Using the tests suite about 48% of asciidoctor-browser.js
is unused but we do not have 100% tests coverage.
The upload feature on GitHub is currently unavailable but you get the idea :wink:
@mojavelinux I think we can safely remove corelib/math
, corelib/complex
and corelib/rationale
? Asciidoctor is not using any of them right ?
We should probably also remove corelib/random
but I know this module is used in other API (like Array#sample) so it might be used somewhere...
I've created a new repository where I intend to make a distribution of the Opal Runtime specifically designed for Asciidoctor.js (browser edition): https://github.com/mogztter/asciidoctor-opal-runtime
https://github.com/mogztter/opal-node-runtime should remain for general purpose use.
Arguably we could also create a distribution of the Opal Runtime for Asciidoctor.js desktop edition (Node.js, Electron...). In this case the size does not matter that much but the execution should be faster (less code).
I've created #653 and #654 to track concret actions to reduce the runtime size.
Minified asciidoctor.js is > 1Mb which makes it just not usable in browser case. Compared to markdown (I agree it has less feature but it is the main rival) which is 36k it is a dead end, even gzipped.
This issue is about ensuring adoc.js is reduced enough - likely ~100k - to be usable in that context. I understand it likely means to drop opal but this is worth it to stay portable (environments).