Skip to content

Commit

Permalink
improve sync performance of js api by ~20x (#1000)
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Jun 28, 2021
1 parent d58db79 commit aa8b9ce
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 14 deletions.
16 changes: 8 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,25 +63,25 @@ jobs:
- name: npm ci
run: cd scripts && npm ci

- name: Register Test
run: node scripts/register-test.js
- name: Register Test (ESBUILD_WORKER_THREADS=0)
run: ESBUILD_WORKER_THREADS=0 node scripts/register-test.js

- name: Register Test (ESBUILD_WORKER_THREADS)
- name: Register Test
if: matrix.os != 'windows-latest'
run: ESBUILD_WORKER_THREADS=1 node scripts/register-test.js
run: node scripts/register-test.js

- name: Verify Source Map
run: node scripts/verify-source-map.js

- name: E2E Tests
run: node scripts/end-to-end-tests.js

- name: JS API Tests
run: node scripts/js-api-tests.js
- name: JS API Tests (ESBUILD_WORKER_THREADS=0)
run: ESBUILD_WORKER_THREADS=0 node scripts/js-api-tests.js

- name: JS API Tests (ESBUILD_WORKER_THREADS)
- name: JS API Tests
if: matrix.os != 'windows-latest'
run: ESBUILD_WORKER_THREADS=1 node scripts/js-api-tests.js
run: node scripts/js-api-tests.js

- name: NodeJS Unref Tests
run: node scripts/node-unref-tests.js
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

## Unreleased

* Enable faster synchronous transforms by default a flag ([#1000](https://github.com/evanw/esbuild/issues/1000))

Currently the synchronous JavaScript API calls `transformSync` and `buildSync` spawn a new child process on every call. This is due to limitations with node's `child_process` API. Doing this means `transformSync` and `buildSync` are much slower than `transform` and `build`, which share the same child process across calls.

This release improves the performance of `transformSync` and `buildSync` by up to 20x. It enables a hack where node's `worker_threads` API and atomics are used to block the main thread while asynchronous communication with a single long-lived child process happens in a worker. Previously this was only enabled when the `ESBUILD_WORKER_THREADS` environment variable was set to `1`. But this experiment has been available for a while (since version 0.9.6) without any reported issues. Now this hack will be enabled by default. It can be disabled by setting `ESBUILD_WORKER_THREADS` to `0`.

* Fix nested output directories with WebAssembly on Windows ([#1399](https://github.com/evanw/esbuild/issues/1399))

Many functions in Go's standard library have a bug where they do not work on Windows when using Go with WebAssembly. This is a long-standing bug and is a fault with the design of the standard library, so it's unlikely to be fixed. Basically Go's standard library is designed to bake "Windows or not" decision into the compiled executable, but WebAssembly is platform-independent which makes "Windows or not" is a run-time decision instead of a compile-time decision. Oops.
Expand Down
7 changes: 1 addition & 6 deletions lib/npm/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,7 @@ declare const WASM: boolean;

let worker_threads: typeof import('worker_threads') | undefined;

// This optimization is opt-in for now because it could break if node has bugs
// with "worker_threads", and node has had such bugs in the past.
//
// TODO: Determine under which conditions this is safe to enable, and then
// replace this check with a check for those conditions.
if (process.env.ESBUILD_WORKER_THREADS) {
if (process.env.ESBUILD_WORKER_THREADS !== '0') {
// Don't crash if the "worker_threads" library isn't present
try {
worker_threads = require('worker_threads');
Expand Down

0 comments on commit aa8b9ce

Please sign in to comment.