Skip to content

Commit

Permalink
SSR benchmark script
Browse files Browse the repository at this point in the history
  • Loading branch information
wyattades committed Jul 15, 2023
1 parent fb3cce7 commit f933381
Show file tree
Hide file tree
Showing 9 changed files with 270 additions and 70 deletions.
10 changes: 10 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,16 @@ Run `docker-compose build ci` to build the CI container. Run `docker-compose run

Run `docker-compose build tests` to build the tests container. Run `docker-compose run tests` to start all RSpec tests.

### Server-side-rendering performance benchmarking

See a simple example of benchmarking different ExecJS runtimes (NodeJS, [MiniRacer](https://github.com/rubyjs/mini_racer), [Alaska](https://github.com/mavenlink/alaska)) in `spec/dummy/bin/benchmark`.

After setting up the dummy app (`spec/dummy`), run:
```bash
cd spec/dummy
bin/benchmark
```

# Advice for Project Maintainers and Contributors

What do project maintainers do? What sort of work is involved? [sstephenson](https://github.com/sstephenson) wrote in the [turbolinks](https://github.com/turbolinks/turbolinks) repo:
Expand Down
8 changes: 6 additions & 2 deletions Gemfile.development_dependencies
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

gem "shakapacker", "6.5.1"
gem "bootsnap", require: false
gem "rails", "~> 7.0"
gem "rails", "~> 7.0", ">= 7.0.1"
gem "sqlite3"
gem "sass-rails", "~> 6.0"
gem "uglifier"
Expand All @@ -24,7 +24,7 @@ gem "amazing_print"

group :development, :test do
gem "listen"
gem "pry"
gem "pry", ">= 0.14.2"
gem "pry-byebug"
gem "pry-doc"
gem "pry-rails"
Expand All @@ -34,6 +34,10 @@ group :development, :test do
gem "rubocop-rspec", require: false
gem "scss_lint", require: false
gem "spring", "~> 4.0"

# Example ExecJS runtimes
gem "mini_racer", require: false
gem "alaska", require: false
end

group :test do
Expand Down
157 changes: 91 additions & 66 deletions spec/dummy/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -11,67 +11,75 @@ PATH
GEM
remote: https://rubygems.org/
specs:
actioncable (7.0.0)
actionpack (= 7.0.0)
activesupport (= 7.0.0)
actioncable (7.0.6)
actionpack (= 7.0.6)
activesupport (= 7.0.6)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
actionmailbox (7.0.0)
actionpack (= 7.0.0)
activejob (= 7.0.0)
activerecord (= 7.0.0)
activestorage (= 7.0.0)
activesupport (= 7.0.0)
actionmailbox (7.0.6)
actionpack (= 7.0.6)
activejob (= 7.0.6)
activerecord (= 7.0.6)
activestorage (= 7.0.6)
activesupport (= 7.0.6)
mail (>= 2.7.1)
actionmailer (7.0.0)
actionpack (= 7.0.0)
actionview (= 7.0.0)
activejob (= 7.0.0)
activesupport (= 7.0.0)
net-imap
net-pop
net-smtp
actionmailer (7.0.6)
actionpack (= 7.0.6)
actionview (= 7.0.6)
activejob (= 7.0.6)
activesupport (= 7.0.6)
mail (~> 2.5, >= 2.5.4)
net-imap
net-pop
net-smtp
rails-dom-testing (~> 2.0)
actionpack (7.0.0)
actionview (= 7.0.0)
activesupport (= 7.0.0)
rack (~> 2.0, >= 2.2.0)
actionpack (7.0.6)
actionview (= 7.0.6)
activesupport (= 7.0.6)
rack (~> 2.0, >= 2.2.4)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.2.0)
actiontext (7.0.0)
actionpack (= 7.0.0)
activerecord (= 7.0.0)
activestorage (= 7.0.0)
activesupport (= 7.0.0)
actiontext (7.0.6)
actionpack (= 7.0.6)
activerecord (= 7.0.6)
activestorage (= 7.0.6)
activesupport (= 7.0.6)
globalid (>= 0.6.0)
nokogiri (>= 1.8.5)
actionview (7.0.0)
activesupport (= 7.0.0)
actionview (7.0.6)
activesupport (= 7.0.6)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.1, >= 1.2.0)
activejob (7.0.0)
activesupport (= 7.0.0)
activejob (7.0.6)
activesupport (= 7.0.6)
globalid (>= 0.3.6)
activemodel (7.0.0)
activesupport (= 7.0.0)
activerecord (7.0.0)
activemodel (= 7.0.0)
activesupport (= 7.0.0)
activestorage (7.0.0)
actionpack (= 7.0.0)
activejob (= 7.0.0)
activerecord (= 7.0.0)
activesupport (= 7.0.0)
activemodel (7.0.6)
activesupport (= 7.0.6)
activerecord (7.0.6)
activemodel (= 7.0.6)
activesupport (= 7.0.6)
activestorage (7.0.6)
actionpack (= 7.0.6)
activejob (= 7.0.6)
activerecord (= 7.0.6)
activesupport (= 7.0.6)
marcel (~> 1.0)
mini_mime (>= 1.1.0)
activesupport (7.0.0)
activesupport (7.0.6)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
alaska (1.2.2)
execjs (~> 2.7)
amazing_print (1.2.2)
ast (2.4.2)
bootsnap (1.7.2)
Expand Down Expand Up @@ -99,6 +107,7 @@ GEM
thor (>= 0.19.4, < 2.0)
tins (~> 1.6)
crass (1.0.6)
date (3.3.3)
diff-lcs (1.4.4)
docile (1.3.5)
equivalent-xml (0.6.0)
Expand All @@ -109,7 +118,7 @@ GEM
generator_spec (0.9.4)
activesupport (>= 3.0.0)
railties (>= 3.0.0)
globalid (1.0.0)
globalid (1.1.0)
activesupport (>= 5.0)
i18n (1.8.11)
concurrent-ruby (~> 1.0)
Expand All @@ -123,33 +132,46 @@ GEM
json (2.5.1)
launchy (2.5.0)
addressable (~> 2.7)
libv8-node (18.16.0.0-arm64-darwin)
listen (3.4.1)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
loofah (2.13.0)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.7.1)
mail (2.8.1)
mini_mime (>= 0.1.1)
net-imap
net-pop
net-smtp
marcel (1.0.2)
method_source (1.0.0)
mini_mime (1.1.2)
mini_portile2 (2.8.1)
mini_racer (0.8.0)
libv8-node (~> 18.16.0.0)
minitest (5.15.0)
msgpack (1.4.2)
net-imap (0.3.6)
date
net-protocol
net-pop (0.1.2)
net-protocol
net-protocol (0.2.1)
timeout
net-smtp (0.3.3)
net-protocol
nio4r (2.5.8)
nokogiri (1.14.3)
mini_portile2 (~> 2.8.0)
nokogiri (1.14.3-arm64-darwin)
racc (~> 1.4)
parallel (1.20.1)
parser (3.0.1.1)
ast (~> 2.4.1)
pry (0.13.1)
pry (0.14.2)
coderay (~> 1.1)
method_source (~> 1.0)
pry-byebug (3.9.0)
pry-byebug (3.10.1)
byebug (~> 11.0)
pry (~> 0.13.0)
pry (>= 0.13, < 0.15)
pry-doc (1.1.0)
pry (~> 0.11)
yard (~> 0.9.11)
Expand All @@ -162,33 +184,33 @@ GEM
puma (5.2.2)
nio4r (~> 2.0)
racc (1.6.2)
rack (2.2.3)
rack (2.2.7)
rack-proxy (0.7.4)
rack
rack-test (1.1.0)
rack (>= 1.0, < 3)
rails (7.0.0)
actioncable (= 7.0.0)
actionmailbox (= 7.0.0)
actionmailer (= 7.0.0)
actionpack (= 7.0.0)
actiontext (= 7.0.0)
actionview (= 7.0.0)
activejob (= 7.0.0)
activemodel (= 7.0.0)
activerecord (= 7.0.0)
activestorage (= 7.0.0)
activesupport (= 7.0.0)
rails (7.0.6)
actioncable (= 7.0.6)
actionmailbox (= 7.0.6)
actionmailer (= 7.0.6)
actionpack (= 7.0.6)
actiontext (= 7.0.6)
actionview (= 7.0.6)
activejob (= 7.0.6)
activemodel (= 7.0.6)
activerecord (= 7.0.6)
activestorage (= 7.0.6)
activesupport (= 7.0.6)
bundler (>= 1.15.0)
railties (= 7.0.0)
railties (= 7.0.6)
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
rails-html-sanitizer (1.4.2)
loofah (~> 2.3)
railties (7.0.0)
actionpack (= 7.0.0)
activesupport (= 7.0.0)
railties (7.0.6)
actionpack (= 7.0.6)
activesupport (= 7.0.6)
method_source
rake (>= 12.2)
thor (~> 1.0)
Expand Down Expand Up @@ -289,6 +311,7 @@ GEM
tins (~> 1.0)
thor (1.1.0)
tilt (2.0.10)
timeout (0.4.0)
tins (1.28.0)
sync
turbolinks (5.2.1)
Expand All @@ -313,9 +336,10 @@ GEM
zeitwerk (2.5.2)

PLATFORMS
ruby
arm64-darwin-22

DEPENDENCIES
alaska
amazing_print
bootsnap
bundler (= 2.4.9)
Expand All @@ -328,13 +352,14 @@ DEPENDENCIES
jquery-rails
launchy
listen
pry
mini_racer
pry (>= 0.14.2)
pry-byebug
pry-doc
pry-rails
pry-rescue
puma (~> 5.0)
rails (~> 7.0)
rails (~> 7.0, >= 7.0.1)
react_on_rails!
rspec-rails
rspec-retry
Expand Down
80 changes: 80 additions & 0 deletions spec/dummy/bin/benchmark
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#!/usr/bin/env bash

#
# A simple example of how to benchmark the dummy app.
#

set -euo pipefail

shutdown_server() {
if [ -f tmp/pids/server.pid ]; then
kill $(cat tmp/pids/server.pid)
rm -f tmp/pids/server.pid
fi
}

hit_backend() {
local pathname="$1"
curl "http://localhost:3000$pathname" \
--max-time 3 \
--silent \
--no-progress-meter \
--fail \
-w %{time_total} \
-o /dev/null
}

run_benchmarks() {
local runtime="$1"
local pathname="$2"

echo "Benchmarking with $runtime..."

# start dummy app server in background
MANUAL_EXECJS_RUNTIME="$runtime" \
RAILS_ENV=production \
bundle exec rails s -p 3000 &

sleep 3 # wait for server to start

echo "Warmup: $(hit_backend $pathname)"

durations=()
for i in {1..10}; do
dur=$(hit_backend $pathname)
durations+=("$dur")
echo "Request $i: ${dur}s"
done

echo "$runtime average: $(echo "${durations[*]}" | awk '{ total += $1 } END { print total/NR }')s"

shutdown_server
}

# If you modified `node_package` files, first follow the
# instructions in CONTRIBUTING.md to setup `yalc`.

# Build server-rendering assets:
# yarn build:rescript # if needed
rm -rf public/webpack
RAILS_ENV=production NODE_ENV=production bin/webpacker

# kill server on exit
trap shutdown_server EXIT

# kill any existing server
shutdown_server

# remove any existing logs
rm -f log/*.log

echo "Benchmarking server-side rendering..."

# run_benchmarks Node /render_js # FIXME: Node runtime is broken with this setup, it stalls infinitely.
run_benchmarks MiniRacer /render_js
run_benchmarks Alaska /render_js

# FIXME: all others SSR endpoints are broken with this setup
# e.g. Hitting /server_side_hello_world gives error: "ActionView::Template::Error (Shakapacker can't find generated/HelloWorld.js in manifest.json"

echo "Benchmarking complete!"
Loading

0 comments on commit f933381

Please sign in to comment.