Usability Engineering 101 Delay User reaction 0 - 100 ms Instant 100 - 300 ms Feels sluggish 300 - 1000 ms Machine is working... 1 s+ Mental context switch 10 s+ I'll come back later... Stay under 250 ms to feel "fast". Stay under 1000 ms to keep users attention. @igrigorik
For many, mobile is the one and only internet device! Country Mobile-only users Egypt 70% India 59% South Africa 57% Indonesia 44% United States 25% onDevice Research @igrigorik
The (short) life of our 1000 ms budget 3G (200 ms RTT) 4G(80 ms RTT) Control plane (200-2500 ms) (50-100 ms) DNS lookup 200 ms 80 ms TCP Connection 200 ms 80 ms TLS handshake (200-400 ms) (80-160 ms) HTTP request 200 ms 80 ms Leftover budget 0-400 ms 500-760 ms Network overhead of one HTTP request! @igrigorik
Latency client Zeit 0 ms 80 ms 160 ms 240 ms 320 ms 10 TCP Segmente (14.600 Bytes) 20 TCP Segmente (29.200 Bytes) 40 TCP Segmente (15.592 Bytes) server SYN ACK ACK GET SYN,ACK ACK ACK
$ rails new shop $ cd shop $ rails g scaffold Category name $ rails g scaffold Product category:references name description price:decimal{8,2} $ rails g scaffold User email first_name last_name password_digest $ rails g scaffold Review user:references product:references rating:integer $ rails db:migrate
app/models/product.rb: class Product < ApplicationRecord belongs_to :category has_many :reviews def number_of_stars if reviews.any? reviews.average(:rating).round else nil end end end
The (short) life of our 1000 ms budget 3G (200 ms RTT) 4G(80 ms RTT) Control plane (200-2500 ms) (50-100 ms) DNS lookup 200 ms 80 ms TCP Connection 200 ms 80 ms TLS handshake (200-400 ms) (80-160 ms) HTTP request 200 ms 80 ms Leftover budget 0-400 ms 500-760 ms Network overhead of one HTTP request! @igrigorik 497ms And we don’t have product images yet.
app/models/product.rb: class Product < ApplicationRecord belongs_to :category has_many :reviews def number_of_stars if reviews.any? reviews.average(:rating).round else nil end end end
Total Views Activerecord Vanilla 497ms 460 ms 34 ms Fragment Cache Row 79 ms 74,6 ms 1 ms Fragment Cache Table 53 ms 49,5 ms 0,6 ms Plus Database Improvents 40 ms 39 ms 0,5 ms Production Env. 35 ms 34 ms 0,5 ms
Warning: Fragment Caching is slower the 1st request! Why? Rails checks if the Fragment Cache exists. When it doesn’t it renders the view and writes the cache which is time consuming.
Set the Etag class ProductsController < ApplicationController # GET /products def index @products = Product.all fresh_when :etag => @products end [...]
> curl -I http://0.0.0.0:3000/products -c cookies.txt HTTP/1.1 200 OK Etag: "4d348810e69400799e2ab684c0ef4777" > curl -I http://0.0.0.0:3000/products -b cookies.txt HTTP/1.1 200 OK Etag: "4d348810e69400799e2ab684c0ef4777" The cookie is needed for the CSRF-Token.
Add caches_page to your controller to save views as static gz files in your public directory: caches_page :index, :show, :gzip => :true Add gem actionpack-page_caching for Rails 5.2
28K * 10,000,000 = 0,26 TB Harddrive space is cheap. By saving the files non-gz and using a data deduplication file system you just need 5-10% of the 0,26 TB. Nginx can gzip the files on the fly.
To setup a complex page_cache system is a lot of work. You have to tackle not only Rails but Nginx too. It does increase the snappiness of your application but might not be worth the effort for small systems.
Heroku is good for a quick start but has never been a good choice for good WebPerformance. Bare Metal is the way to go if you need maximum WebPerformance.
http://www.chromium.org/developers/design-documents/dns-prefetching „Most common names like google.com and yahoo.com are resolved so often that most local ISP's name resolvers can answer in closer to 80-120ms. If the domain name in question is an uncommon name, then a query may have to go through numerous resolvers up and down the hierarchy, and the delay can average closer to 200-300ms.“
http://www.whatwg.org/specs/web-apps/current-work/#link-type-prefetch „The prefetch keyword indicates that preemptively fetching and caching the specified resource is likely to be beneficial, as it is highly likely that the user will require this resource.“ T I P P : " A C C E P T - R A N G E S : B Y T E S “ H E A D E R