Ad Hoc Javascript Performance Benchmarking

Jan 15, 2018

At Exago, we are always looking for ways to further improve the application’s user experience. While these advances are most noticeable in major enhancements such as our newly-released dashboard designer and formula code completion, upgrades to client- and server-side performance are just as important. For Exago’s v2017.2 release, I was tasked with speeding up our client-side application and so became familiar with a number of performance improvement tools. Web technologies such as Flexbox, better in-browser performance profiling, and particularly jsPerf.com have helped us reach our usability goals.

JsPerf is a free, open source JavaScript benchmarking tool that encourages collaboration and sharing of performance testing. The website uses Benchmark.js along with an embedded Java applet to record execution times of JavaScript code snippets at a high precision. Benchmarks of many commonly used JS web functions have already been cataloged on jsPerf. Most of these tests show results from different browsers, revisions of the original test, and comments on the results and their validity. Although these publicly searchable benchmarks are unlikely to match your specific need exactly, they’re a great reference tool for comparing the performance of simple functions.

How can jsPerf help with more complex systems?

The first step to leveraging jsPerf for your own use is logging in with a GitHub account, from which you will be taken directly to creating your first test case. For a simple test, the least you have to do is add a title, indicate whether you’d like to post the test case publicly, and copy-and-paste two or more JS snippets with unique titles. You also have the option to add preparation HTML and test setup code that will run outside the timed benchmark.

The array will only run once per test case.

The preparation HTML section is particularly powerful— it allows you to include any online JS libraries or other HTML that may be necessary for running test cases. This feature has been helpful at Exago because the web application has grown structurally complex. One such case (described in Customizing jsPerf for your own company’s needs below) resulted in our improving the performance of an outdated function for finding DOM elements. The function is called in many places and often repeatedly, making it important to optimize but difficult to test. JsPerf allows us to replace our dynamically changing HTML tree with a static representation and to reduce inconsistencies in the JS runtime that may be caused by garbage collection or irrelevant event listeners. It should be noted that because of these differences, jsPerf won’t replicate a live environment identically or accurately portray how your application will perform in production. This is a necessary tradeoff for performance testing, however, as using browser performance debugging tools without a large sample size may give inconsistent and misleading results.

Exago officially supports over 92% of desktop browsers used globally, which means that we have to put considerable effort into ensuring a quality and responsive experience for every supported browser. Considering the necessity to reconcile differences in browser performance with internal product performance goals, there is rarely a conclusive means of determining which case is better. For example, comparing the array prototype’s forEach function to a simple (but less readable) for loop shows that using a for loop is usually significantly more performant than forEach. However, Internet Explorer is overall slowest, and forEach runs faster than for. Should the slowest browser be given preference and forEach be used? Each software application is going to have different requirements and performance goals and therefore different answers to this question!

Metrics are in operations per second, so a higher number means better performance!

I can’t post my private code online!

Mimicking your web application’s environment on jsPerf.com in order to produce the most accurate results may expose more of your source code than you and your employer are comfortable with. JsPerf.com may also not support exactly what your code requires for testing, or you might want a less-than-public space so that you and your colleagues’ test cases aren’t lost in the slew of other users’ tests, revisions, and spam. Whatever the reason, you might prefer to use a local install of jsPerf rather than the web version.

Fortunately, jsPerf is available on GitHub under the “without restriction” MIT License and comes with a simple setup guide. Cloning the repository, installing NPM and mySQL, and setting up the configuration file with GitHub and Browserscope API keys takes under 30 minutes and allows you to start customizing the application for your ad hoc use. With the website installed to an organization-wide accessible location, anyone granted access can create their own test cases and see yours. Limiting the number of people who have access to the website encourages collaboration and sharing because only performance tests relevant to your work will be seen!

 

Customizing jsPerf for your own company’s needs.

One of the first significant improvements to Exago’s JS performance was changing a custom element selector’s string comparison from a regular expression to String.prototype.endsWith(). JsPerf results show close to a 150x speedup under certain conditions. This is just one of the improvements that have allowed us to create super quick and responsive report builders, such as our new v2017.2 dashboard designer.

 

Testing a custom element selector in worst-case scenarios also means embedding a large DOM tree to test it on. jsPerf supports copy-and-pasting a large block of HTML but doesn’t exactly guarantee that it’s formatted in a usable way. To improve its ease of use, I modified the site’s stylesheets to include a “max-height” property on some text and hid other elements that I knew my team wouldn’t use.

Left: jsPerf.com with a looong “Preparation code output” section, Right: Exago’s styled jsPerf

 

While editing a single stylesheet isn’t a huge change, it makes jsPerf much more usable! I’m considering adding a few more changes to our local installation soon:

  • Embedding a Typescript editor & compiler
  • Adding custom buttons to automatically include application relevant preparation code
  • Fixing Browserscope bugs

How would you customize jsPerf?

Thumbnail photo used with permission from Lucas Volle.

Schedule a Demo

Leave a Comment