DEV Community 👩‍💻👨‍💻

Cover image for Benchmarking web dev tools on the Mac mini M1
Matt Kane
Matt Kane

Posted on

Benchmarking web dev tools on the Mac mini M1

In the weeks after the new Apple Silicon Macs were launched there were plenty of reviews with benchmarks for tasks like video encoding, 3D rendering and so on. However I couldn't find anything testing the web development tools that I use every day, such as Node, Babel and TypeScript. A lot of the M1's speed comes from specialised cores, so there was a risk that it would not be as fast for web development. In the end I decided to risk it and order one and run some benchmarks myself.

I'd been looking for something to use as a headless compilation machine for a while. I'm an engineer on the Gatsby open source team, and have to compile the massive monorepo many times a day. We do a lot of a pair programming over Zoom, and that's particularly difficult when compiling. VS Code remote development is very slick, so when the M1 Macs were released, a Mac mini seemed just the job. I needn't have worried: the Mac mini M1 comfortably beats my Macbook Pro in every task I threw at it. This includes benchmarks, but also real world development tasks.

Test setup

I ordered the entry level Mac mini with 8GB of RAM, and my comparisons are with my work machine: a Late 2019 16" Macbook Pro 2.3GHz core i9 with 16GB of RAM. For my initial tests I used the V8 Web Tooling Benchmark. This uses Node to run several realistic tasks, using the sort of tools web developers use every day: Babel transpilation, and various other parsers, TypeScript, PostCSS, Prettier, ESLint and more. The benchmark itself is three years old, and uses old versions of these tools. It can run on the latest Node though, and should still be representative of the relative speeds.

To run the tests, I first installed Node 15.4.0 using Homebrew on the mini and using nvm on the MBP. I made sure that it was running natively by using the Node REPL to check process.arch. It will be arch64 if it's a native build, and x64 if running the Intel version using Rosetta2. I ran the benchmarks according to the instructions: npm install, npm build then node dist/cli.js. I ran the benchmarks several times to be sure they weren't outliers.

Results

V8 Web Tooling Benchmark. Higher scores are better

Mac mini M1

Running Web Tooling Benchmark v0.5.3…
-------------------------------------
         acorn: 21.29 runs/s
         babel: 14.64 runs/s
  babel-minify: 20.82 runs/s
       babylon: 21.11 runs/s
         buble: 10.25 runs/s
          chai: 27.62 runs/s
  coffeescript: 14.24 runs/s
        espree:  4.07 runs/s
       esprima: 15.86 runs/s
        jshint: 18.65 runs/s
         lebab: 18.26 runs/s
       postcss: 10.97 runs/s
       prepack: 15.17 runs/s
      prettier: 11.85 runs/s
    source-map: 16.93 runs/s
        terser: 35.89 runs/s
    typescript: 17.13 runs/s
     uglify-js: 11.56 runs/s
-------------------------------------
Geometric mean: 15.57 runs/s
Enter fullscreen mode Exit fullscreen mode

2019 Macbook Pro 2.3GHz core i9

Running Web Tooling Benchmark v0.5.3…
------------------------------------------
         acorn:  9.80 runs/s
         babel:  9.04 runs/s
  babel-minify: 12.95 runs/s
       babylon: 12.37 runs/s
         buble:  6.21 runs/s
          chai: 18.01 runs/s
  coffeescript:  9.25 runs/s
        espree:  4.32 runs/s
       esprima: 10.14 runs/s
        jshint: 12.10 runs/s
         lebab: 13.86 runs/s
       postcss:  8.55 runs/s
       prepack:  9.06 runs/s
      prettier:  8.69 runs/s
    source-map: 11.68 runs/s
        terser: 20.48 runs/s
    typescript: 10.34 runs/s
     uglify-js:  6.61 runs/s
------------------------------------------
Geometric mean: 10.10 runs/s
Enter fullscreen mode Exit fullscreen mode

The Mac mini M1 is consistently around 50% faster than the Macbook Pro in the Web Tooling Benchmark.

These are native speeds, with an arm64 build of Node. However neither Node.js nor Homebrew offically support Apple Silicon yet, and many native npm packages need to compile from source. There are many cases where you may need to run x64 tools using Rosetta2. This is inevitably going to be slower than native, but the good news is that it's still faster than the Macbook Pro.

Mac mini M1, via Rosetta2

Running Web Tooling Benchmark v0.5.3…
------------------------------------------
         acorn: 15.34 runs/s
         babel: 11.84 runs/s
  babel-minify: 15.46 runs/s
       babylon: 14.56 runs/s
         buble:  7.93 runs/s
          chai: 22.66 runs/s
  coffeescript: 11.60 runs/s
        espree:  5.51 runs/s
       esprima: 14.44 runs/s
        jshint: 15.92 runs/s
         lebab: 15.15 runs/s
       postcss: 10.44 runs/s
       prepack: 12.23 runs/s
      prettier:  9.76 runs/s
    source-map: 16.78 runs/s
        terser: 24.10 runs/s
    typescript: 10.36 runs/s
     uglify-js:  7.94 runs/s
------------------------------------------
Geometric mean: 12.64 runs/s
Enter fullscreen mode Exit fullscreen mode

Even via Rosetta the Mac mini is around 25% faster than the Macbook Pro.

Real-world tests

While the benchmark seems to be representative of real-world web development tasks, I still needed to compare with my day-to-day tasks. If anything, the lead is even more there.

Running lerna bootstrap in a clean gatsby monorepo. This runs yarn install in the root of the monorepo, then yarn install across all 112 packages, and then yarn prepare which builds each of them and prepares it for publishing. Most packages are compiled with Babel, but some are compiled with the TypeScript compiler, and some of the Babel ones have TypeScript types generated. Some packages are bundled with microbundle or rollup. There's even a Gatsby site in there (the gatsby-admin app). It's a generally tough but representative sample. Lower times are obviously better!

  • Macbook Pro: 4 mins, 33 seconds
  • Mac mini M1: 2 mins, 45 seconds

This was run simultaneously on both machines (using iTerm input broadcasting), with both on the same network.

One thing I noticed while running it was that the yarn install was noticably faster on the mini, which I put down to faster disk IO. To see the other side of disk IO that most web developers need to do, I checked this by running rm -rf node_modules!

screenshot of running rm-rf node_modules packages/*/node_modules

I tried several other tasks, such as running the gatsby-dev-cli which publishes all gatsby packages to a local npm server, and then installs those in a site for testing. Each of them was considerably faster with the Mac mini.

Conclusion

As I'm using mine as a remote compilation machine I haven't run tests on other apps, but there are plenty of other reviews that have. Based on my tests, the M1 Macs are incredibly fast for web development, and are an absolute bargain too. This was a bottom of the range Mac mini comfortably beating a top of the range Macbook Pro that's just a year old and cost four times as much.

Top comments (6)

Collapse
wmhilton profile image
William Hilton • Edited on

Yes! These are the benchmarks I've been waiting for! (a webpack benchmark would be nice as well, as waiting on webpack-dev-server to compile is really my bottleneck these days.)

I thought I'd contribute my benchmark results as well. Interestingly, despite being a 2.9GHz core i9, it fares a tad worse than your 2.3GHz core i9, I guess because it's from 2018 instead of 2019.

hardware:
MacBook Pro (15-inch, 2018)
2.9 GHz 6-Core Intel Core i9
32 GB 2400 MHz DDR4

node version:
Using node 15.4.0 installed via nvm.

3 consecutive runs:

> node dist/cli.js
Running Web Tooling Benchmark v0.5.3…
-------------------------------------
         acorn: 10.01 runs/s
         babel:  9.16 runs/s
  babel-minify: 12.74 runs/s
       babylon: 12.35 runs/s
         buble:  6.31 runs/s
          chai: 18.19 runs/s
  coffeescript:  8.07 runs/s
        espree:  4.22 runs/s
       esprima:  9.34 runs/s
        jshint: 10.72 runs/s
         lebab: 12.92 runs/s
       postcss:  7.27 runs/s
       prepack:  8.74 runs/s
      prettier:  8.44 runs/s
    source-map: 11.47 runs/s
        terser: 21.34 runs/s
    typescript: 10.83 runs/s
     uglify-js:  6.45 runs/s
-------------------------------------
Geometric mean:  9.78 runs/s

> node dist/cli.js
Running Web Tooling Benchmark v0.5.3…
------------------------------------------
         acorn:  9.75 runs/s
         babel:  9.10 runs/s
  babel-minify: 12.61 runs/s
       babylon: 12.85 runs/s
         buble:  5.94 runs/s
          chai: 18.28 runs/s
  coffeescript:  8.54 runs/s
        espree:  4.32 runs/s
       esprima:  9.93 runs/s
        jshint: 11.05 runs/s
         lebab: 13.70 runs/s
       postcss:  7.45 runs/s
       prepack:  9.21 runs/s
      prettier:  8.43 runs/s
    source-map: 11.19 runs/s
        terser: 20.17 runs/s
    typescript: 10.58 runs/s
     uglify-js:  6.47 runs/s
------------------------------------------
Geometric mean:  9.86 runs/s

> node dist/cli.js
Running Web Tooling Benchmark v0.5.3…
------------------------------------------
         acorn: 10.29 runs/s
         babel:  9.23 runs/s
  babel-minify: 12.84 runs/s
       babylon: 12.88 runs/s
         buble:  6.11 runs/s
          chai: 18.12 runs/s
  coffeescript:  8.74 runs/s
        espree:  4.37 runs/s
       esprima:  9.57 runs/s
        jshint: 11.31 runs/s
         lebab: 14.61 runs/s
       postcss:  7.01 runs/s
       prepack:  8.48 runs/s
      prettier:  8.09 runs/s
    source-map: 10.42 runs/s
        terser: 20.41 runs/s
    typescript: 10.67 runs/s
     uglify-js:  6.75 runs/s
------------------------------------------
Geometric mean:  9.86 runs/s
Enter fullscreen mode Exit fullscreen mode

Sadly, I can't use a Mac Mini as my main development box, because going from 32GB of RAM to 8GB would probably undo the core speed improvements. (With Webpack, Docker, Chrome, Iterm2, and VSCode all running, I easily eat up 20GB of RAM just spinning up my work website. 27GB if I run FF and Jest as well.)

Now, if they made a Mac Mini Pro with 32GB of RAM... that would probably be perfect!

Collapse
chrischen profile image
chrischen

If you look at the current 2020 macbook pro 16” offerings you’ll see that the 2.3ghz build is more expensive than the 2.6ghx. This is because this is the base speed that all cores sustain. The 8-core can sustain a lower frequency but there are more cores. However if not all cores are needed the boost speed is up to 4.8.

Your 2018 intel processor probably is a 6-core, so it has higher base frequencies but fewer cores, but likely can only sustain lower frequencies for the same amount of cores when compared to the 2019 2.3ghz.

I also did some benchmark using webpack and my node stack against a 64gb ram 2.3ghz i9 macbook (2019) and the M1 macbook was on par or faster. Node was compiled natively for darwin arm.

Both machines were from the same time machine restore, and to simulate a normal environment I had safari with about 30 tabs, VS Code, and a mongodb instance running in both.

Also as a bonus Safari loads up about 5+ seconds slower on the 64gb ram macbook 16”.

I believe the way the M1 works means memory usage will work differently too. I wouldn’t go so far as to assume you would need 32gb to maintain any performance advantages... certainly doesn’t help the 16” here.

Collapse
bmansfie profile image
Brandon • Edited on

I installed the latest LTS. I didn't use brew to install it though, I built my own binary via nvm. This is on a Mac-Mini 16GB. Built with xcode command line tools 12.3.

Welcome to Node.js v14.15.4.
Type ".help" for more information.
> process.arch
'arm64'

web-tooling-benchmark % node dist/cli.js
Running Web Tooling Benchmark v0.5.3…
-------------------------------------
         acorn: 28.02 runs/s
         babel: 21.91 runs/s
  babel-minify: 29.47 runs/s
       babylon: 26.94 runs/s
         buble: 12.27 runs/s
          chai: 39.77 runs/s
  coffeescript: 17.94 runs/s
        espree:  7.80 runs/s
       esprima: 19.86 runs/s
        jshint: 28.37 runs/s
         lebab: 28.23 runs/s
       postcss: 16.27 runs/s
       prepack: 20.50 runs/s
      prettier: 16.50 runs/s
    source-map: 19.90 runs/s
        terser: 52.40 runs/s
    typescript: 23.32 runs/s
     uglify-js: 14.84 runs/s
-------------------------------------
Geometric mean: 21.60 runs/s
Enter fullscreen mode Exit fullscreen mode
Collapse
anulaibar profile image
Olle Hellgren

Which processor is that?

Collapse
phil_lgr profile image
Phil Léger

Amazing! The next M chip is going to pulverize intel even more

Collapse
7rulnik profile image
Valentin Semirulnik

Seems that it should be yarn run bootstrap according to gatsbyjs.com/contributing/setting-..., not lerna bootstrap

🌚 Friends don't let friends browse without dark mode.

Sorry, it's true.