Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve speed for large projects #1

Open
wbyoung opened this issue Jan 14, 2017 · 0 comments
Open

Improve speed for large projects #1

wbyoung opened this issue Jan 14, 2017 · 0 comments

Comments

@wbyoung
Copy link
Owner

wbyoung commented Jan 14, 2017

Performance may be impacted by PostCSS compilation, the client-server setup (including launching a node process for the client on each compiled file). The following are ideas on how to make things faster.

Synchronous Promise Resolution

The client-server model could be removed entirely if the PostCSS compilation was able to be done synchronously (i.e., resolve a promise synchronously).

In order to accomplish this, a bit of native code would need to be written to run the event loop. For reference, node's event loop is basically just a uv_run(env.event_loop(), UV_RUN_ONCE);. A small bit of native code (similar to deasync… or even use deasync) and a bit of JS code to invoke this could be sufficient. The JS would be something like:

let error, result;
let done = false;
const runner = postcss(plugins);

runner.process(source, opts).then(
  (res) => { done = true; result = res; },
  (err) => { done = true; error = err; }
);

while (!done) {
  binding.runLoop();
}

Besides the fact that a bit of native code would be introduced (making things a little harder to maintain), this actually simplifies the code significantly.

Caching PostCSS Compilation

Since the server remains active while the main process continues, it would be beneficial for various situations to cache the results of a compile. It's important to realize that the cache would likely be in memory, so it would only apply when babel & the plugin remain active in memory while the CSS file is encountered multiple times. This would happen for:

  1. Watched builds
  2. Builds that include the same CSS file from multiple different JS files

Re-write the postcss-client in C++ using node-gyp

The client that we launch is written in Node and is as minimal as possible, but launching a minimal Node process is still nearly 30x slower (on my machine) than launching a native executable.

Creating a binding.gyp with the type set to executable seems to work:

{
  "targets": [
    {
      "target_name": "postcss-client",
      "type": "executable",
      "sources": [ "src/postcss-client.cc" ]
    }
  ]
}
node-gyp rebuild

There's overhead in the client-server communication, too, so this may or may not provide significant performance gains. The best way to find out, though, may be to try it and see. The synchronous promise resolution seems to be a much easier option to avoid this, though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant