View on GitHub

PHATDocs

Documentation for https://github.com/chgibb/phat

Home

For 0.8.1

Contents

Previous: Repository Structure

Performance

We strive to provide performance in all our functionality implemented in first-party code. That is, features implemented first-party, but most importantly in our genome visualization. That functionality implemented by third-party code/binaries (such as alignment, QC reports etc) is not a focus of our continual profiling and optimization efforts. Monthly manual stress tests of genome visualization are performed using bacterial genomes with simulated alignments on an Acer C720p Chromebook running Ubuntu 14.04LTS. The primary goal being to keep startup times for application components under 1 second, RAM use (especially when visualising genomes with massive coverage) low and genome resizing and rendering times down. Here, we try to explain individual methods and techniques utilized to try to keep PHAT performant.

V8 Switches

On startup, --expose_gc, --nolazy, --serialize_eager, and --always_compact are applied through Electron.app.commandLine.appendSwitch.

V8 Code Caching

Through Node.jsVM module, we make heavy use of V8’s code caching features in our own code caching module. See some discussion here. PHAT never executes any Javascript directly. All Javascript is compiled into .cdata files. In the case where existing .cdata is rejected due to a change in source (such as through updates), new .cdata is compiled and then run on the user’s machine directly. These files are not shipped in updates in an attempt to keep update downloads as small as possible as well as to prevent issues with different CPUs. V8 will reject cached code compiled on a machine with a different microarchitecture.

Javascript Bundle Optimizations

Over time, the currently employed set of bundle optimizations has evolved. Regular benchmarking has shown these specific optimizations, in the specific order they are listed yields fastest loading code (when combined with code caching, as described above). Performance benchmarking should be a continuous process. These are always subject to change if better performance can be had.

RollupJS

RollupJS is used to pair down first party code to the minimum required at runtime. require statements for third-party modules are localised to the functions which require them in an attempt to eliminate bundling of third-party code into processes which don’t require it.

Bundle Collapsing

bundle collapsing is used to remove paths from require statements and turn them into integers. This has shown to be a non-trivial share of bundle size.

Minification

Uglify-es is used to eliminate whitespace and strip comments, the majority of bundle size. Currently, property names are depended upon heavily at runtime. If we can figure out how to enable aggressive optimizations (such as symbol renaming) without breaking PHAT, there will be far more savings to be had.

IIF/IIFE Optimizations

Optimize-js is applied as a final step. A fantastic explanation and discussion is included at the link.

Circular Visualization Performance

ngPlasmid drives PHAT’s circular visualization. ngPlasmid was born out of an attempt to improve the performance of Angular Plasmid, upon which PHAT’s circular visualization is based. Discussion on techniques employed can be found in its repository.

Contents