JBrowse 2 · React App examples

Web worker RPC

Offload data parsing/rendering to a web worker.

By default the embedded app runs all data parsing and rendering on the main thread, which can cause noticeable hitches on large alignments datasets (BAM, CRAM). Switching to the WebWorker RPC moves that work off the main thread and dramatically reduces UI stalls.

Pass a makeWorkerInstance factory to <JBrowse> and select the WebWorkerRpcDriver via configuration. In a Vite/Astro setup you construct the worker from the package’s ?worker entry; in a webpack/CRA setup, import the package’s prebuilt @jbrowse/react-app2/esm/makeWorkerInstance instead:

import RpcWorker from '@jbrowse/react-app2/esm/rpcWorker?worker'
;<JBrowse
  assemblies={assemblies}
  tracks={tracks}
  configuration={{ rpc: { defaultDriver: 'WebWorkerRpcDriver' } }}
  makeWorkerInstance={() => new RpcWorker()}
/>

Bundler notes

  • Webpack — set output.publicPath: 'auto' so the worker resolves its own URL (see the Webpack web-workers guide).
  • Vite and other ESM bundlers — the worker is constructed via new Worker(new URL(...), { type: 'module' }), which Vite handles natively.

The worker is off by default precisely because of these bundler requirements, but we recommend enabling it whenever your toolchain supports it. If you also load plugins, they must be registered in both the main thread and the worker. The rpc config block (driver, worker count, timeouts) is documented in RpcOptions.

View source
import { JBrowse } from '@jbrowse/react-app2'
// Vite/Astro apps construct the RPC worker with Vite's `?worker` suffix. (With
// a webpack/CRA setup you'd instead import the package's prebuilt
// `@jbrowse/react-app2/esm/makeWorkerInstance`.)
import RpcWorker from '@jbrowse/react-app2/esm/rpcWorker?worker'

const assemblies = [
  {
    name: 'volvox',
    sequence: {
      adapter: {
        type: 'TwoBitAdapter',
        uri: 'https://jbrowse.org/genomes/volvox/volvox.2bit',
      },
    },
    refNameAliases: {
      adapter: {
        type: 'FromConfigAdapter',
        adapterId: 'W6DyPGJ0UU',
        features: [
          { refName: 'ctgA', uniqueId: 'alias1', aliases: ['A'] },
          { refName: 'ctgB', uniqueId: 'alias2', aliases: ['B'] },
        ],
      },
    },
  },
]

const tracks = [
  {
    type: 'FeatureTrack',
    trackId: 'volvox_gff3',
    name: 'Volvox genes',
    assemblyNames: ['volvox'],
    adapter: {
      type: 'Gff3TabixAdapter',
      uri: 'https://jbrowse.org/code/jb2/main/test_data/volvox/volvox.sort.gff3.gz',
    },
  },
]

export default function WithWebWorker() {
  return (
    <JBrowse
      assemblies={assemblies}
      tracks={tracks}
      configuration={{ rpc: { defaultDriver: 'WebWorkerRpcDriver' } }}
      makeWorkerInstance={() => new RpcWorker()}
      views={[
        {
          type: 'LinearGenomeView',
          init: {
            assembly: 'volvox',
            loc: 'ctgA:1..50000',
            tracks: ['volvox_gff3'],
          },
        },
      ]}
    />
  )
}