diff --git a/bench/fixtures/basic/pages/css.js b/bench/fixtures/basic/pages/css.js
new file mode 100644
index 00000000..ad8b10cf
--- /dev/null
+++ b/bench/fixtures/basic/pages/css.js
@@ -0,0 +1,27 @@
+import React, { Component } from 'react'
+import { StyleSheet, css } from 'next/css'
+
+
+const spans = () => (
+)
+
+export default class CrazyCSS extends Component {
+ spans () {
+ const out = []
+ for (let i = 0; i < 1000; i++) {
+ out.push(This is ${i})
+ }
+ return out
+ }
+
+ render () {
+ return
{this.spans()}
+ }
+}
+
+const spanStyles = {}
+for (let i = 0; i < 1000; i++) {
+ spanStyles[`padding-${i}`] = { padding: i }
+}
+
+const styles = StyleSheet.create(spanStyles)
diff --git a/bench/fixtures/basic/pages/stateless-big.js b/bench/fixtures/basic/pages/stateless-big.js
new file mode 100644
index 00000000..44c37af8
--- /dev/null
+++ b/bench/fixtures/basic/pages/stateless-big.js
@@ -0,0 +1,17 @@
+import React from 'react'
+
+export default () => {
+ return (
+
+ )
+}
+
+const items = () => {
+ var out = new Array(10000)
+ for (let i = 0; i < out.length; i++) {
+ out[i] = This is row {i+1}
+ }
+ return out
+}
diff --git a/bench/fixtures/basic/pages/stateless.js b/bench/fixtures/basic/pages/stateless.js
new file mode 100644
index 00000000..b6796ba8
--- /dev/null
+++ b/bench/fixtures/basic/pages/stateless.js
@@ -0,0 +1,3 @@
+import React from 'react'
+
+export default () => My component!
diff --git a/bench/index.js b/bench/index.js
new file mode 100644
index 00000000..51efc3ef
--- /dev/null
+++ b/bench/index.js
@@ -0,0 +1,32 @@
+
+import { resolve } from 'path'
+import build from '../server/build'
+import { render as _render } from '../server/render'
+import Benchmark from 'benchmark'
+
+const dir = resolve(__dirname, 'fixtures', 'basic')
+const suite = new Benchmark.Suite('Next.js');
+
+suite
+.on('start', async () => build(dir))
+
+.add('Tiny stateless component', async p => {
+ await render('/stateless')
+ p.resolve()
+}, { defer: true })
+
+.add('Big stateless component', async p => {
+ await render('/stateless-big')
+ p.resolve()
+}, { defer: true })
+
+.add('Stateful component with a loooot of css', async p => {
+ await render('/css')
+ p.resolve()
+}, { defer: true })
+
+module.exports = suite
+
+function render (url, ctx) {
+ return _render(url, ctx, { dir, staticMarkup: true })
+}
diff --git a/gulpfile.js b/gulpfile.js
index 3caee0bb..5dd598be 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -3,6 +3,7 @@ const babel = require('gulp-babel')
const cache = require('gulp-cached')
const notify_ = require('gulp-notify')
const ava = require('gulp-ava')
+const benchmark = require('gulp-benchmark')
const sequence = require('run-sequence')
const webpack = require('webpack-stream')
const del = require('del')
@@ -22,7 +23,8 @@ gulp.task('compile', [
'compile-lib',
'compile-server',
'compile-client',
- 'compile-test'
+ 'compile-test',
+ 'compile-bench'
])
gulp.task('compile-bin', () => {
@@ -68,7 +70,20 @@ gulp.task('compile-test', () => {
gulp.task('copy-test-fixtures', () => {
return gulp.src('test/fixtures/**/*')
.pipe(gulp.dest('dist/test/fixtures'))
-});
+})
+
+gulp.task('compile-bench', () => {
+ return gulp.src('bench/*.js')
+ .pipe(cache('bench'))
+ .pipe(babel(babelOptions))
+ .pipe(gulp.dest('dist/bench'))
+ .pipe(notify('Compiled bench files'))
+})
+
+gulp.task('copy-bench-fixtures', () => {
+ return gulp.src('bench/fixtures/**/*')
+ .pipe(gulp.dest('dist/bench/fixtures'))
+})
gulp.task('build', [
'build-dev-client',
@@ -113,6 +128,13 @@ gulp.task('test', ['compile', 'copy-test-fixtures'], () => {
.pipe(ava())
})
+gulp.task('bench', ['compile', 'copy-bench-fixtures'], () => {
+ return gulp.src('dist/bench/*.js', {read: false})
+ .pipe(benchmark({
+ reporters: benchmark.reporters.etalon('RegExp#test')
+ }))
+})
+
gulp.task('watch', [
'watch-bin',
'watch-lib',
diff --git a/package.json b/package.json
index 1121688f..d618327a 100644
--- a/package.json
+++ b/package.json
@@ -29,6 +29,7 @@
"babel-runtime": "6.11.6",
"cross-spawn": "4.0.2",
"glob-promise": "1.0.6",
+ "gulp-benchmark": "^1.1.1",
"htmlescape": "1.1.1",
"minimist": "1.2.0",
"mkdirp-then": "1.2.0",