files is terrible over HTTP ◦ Limited number of connections per domain ◦ Each connection can only make one request at a time • Solution ◦ Concatenate JavaScript ◦ Concatenate CSS ◦ Concatenate small images into image sprites
files is terrible over HTTP • Doing it in Rails ◦ Concatenate JavaScript ▪ app/assets/javascripts/application.js ◦ Concatenate CSS ▪ app/assets/javascripts/application.css ◦ Concatenate small images into image sprites ▪ Manually or via a gem (sprite-factory ?)
long time to download, especially over mobile networks • Solution ◦ Choose the right format ▪ Does your image consist of geometric shapes? - SVG ▪ Is your image animated? - GIF (not JIF) ▪ Does your image contain transparent space? - PNG ▪ Is your image a photograph? - JPG ▪ Something else? - Experiment
long time to download, especially over mobile networks • Doing it in Rails ◦ Manually ▪ Safest (allows for visual inspection) and easiest to get started ◦ Automatically ▪ Consider ImageOptim-CLI and a git pre-commit hook ◦ Asset Pipeline ▪ config.assets.precompile += %w(*.png *.jpg *.jpeg *.gif *.svg)
long time to download, especially over mobile networks • Solution ◦ Use subsetting to include only the glyphs you need ◦ Use compression ▪ TTF files should be gzipped ▪ WOFF and WOFF2 have built in compression ▪ EOT has optional built in compression or can be gzipped
long time to download, especially over mobile networks • Doing it in Rails ◦ Manually ▪ http://www.fontsquirrel.com/tools/webfont-generator ◦ Asset Pipeline ▪ config.assets.precompile += %w(*.eot *.ttf *.woff *.woff2)
your assets on every page load even though they don’t change • Solution ◦ Allow assets to be cacheable for a least 1 year ◦ Cache-Control:public, max-age=31536000 ◦ config.static_cache_control = "public, max-age=31536000"
cached for a year it's impossible to update them • Solution ◦ Add a fingerprint to each file that changes if its contents change ◦ This is often accomplished by hashing the contents of the file ◦ config.assets.digest = true ◦ Use asset path helpers
and CSS files means they change frequently • Solution ◦ Segment out slow and fast changing assets into different JavaScript or CSS files ◦ An easy way to start is to separate your code from vendor code ◦ config.assets.precompile += %w(vendor.js vendor.css)
visits your site has to pull your assets • Solution ◦ Use a content delivery network ◦ It takes the load off your poor little 1x dyno ◦ It makes copies of your assets all over the globe so clients can fetch them faster ◦ config.action_controller.asset_host = ENV['ASSET_HOST']
per domain • Solution ◦ HTTP/2 allows for multiple concurrent requests over one connection ◦ Ensure your CDN supports HTTP/2 ◦ Host all of your assets (including fonts) on the same domain ◦ Domain sharding is dead
domInteractive ◦ DOM is ready ◦ parser blocking JavaScript has been executed • domContentLoaded ◦ both the DOM and CSSOM are ready ◦ deferred JavaScript has been executed ◦ domReady event is fired • domComplete ◦ the page and all of its subresources are ready ◦ async JavaScript has been executed ◦ the loading spinner has stopped spinning • loadEvent ◦ onload event is fired
construction and blocks DOM construction • Solution ◦ Put JavaScript at the bottom of the page to block as little DOM construction as possible ◦ Consider inlining any render critical JavaScript ◦ Use async script tags to unblock DOM construction ◦ Defer loading scripts until onLoad when possible