Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rails Frontend: 2016 edition.

Rails Frontend: 2016 edition.

Slides from talk about enhancements in Rails Frontend.

F459742822cf8347e83d5c445378a934?s=128

vipulnsward

June 24, 2016
Tweet

Transcript

  1. None
  2. RAILS FRONTEND: 2016 and That Sprockets Talk

  3. Vipul A M @vipulnsward

  4. None
  5. timezones 1.Mumbai TimeZone (UTC+05:30) 2.Taiwan TimeZone (UTC+08:00) 3.Pacific Time Zone

    (UTC-08:00) 4.Singapore Time Zone (UTC+08:00)
  6. timezones

  7. timezones

  8. timezones +

  9. timezones +=

  10. None
  11. None
  12. None
  13. None
  14. None
  15. None
  16. None
  17. Rails 5

  18. http://blog.bigbinary.com/categories/Rails-5 Rails 5 Blog Series (55+ and counting)

  19. Sprockets: *Spotlight

  20. Sprockets https://speakerdeck.com/rafaelfranca/how-sprockets-works

  21. Sprockets 1. sprockets 2. sprockets-rails 3. sass-rails 4. execjs 5.

    coffee-rails
  22. manifest.js # In Rails configuration
 config.assets.precompile += [“payment.css”, “advertising.css"] <%=

    stylesheet_link_tag "advertising" %> 

  23. manifest.js config.assets.precompile = [“manifest.js”] // app/assets/config/manifest.js //= link_tree ../images
 //=

    link_directory ../stylesheets .css //= link application.css
 //= link advertising.css
 //= link payment.css
 //= link application.js

  24. manifest.js <%= stylesheet_link_tag "advertising" %> .logo {
 background: url(<%= asset_url("logo.png")

    %>)
 }
  25. folders as modules foo/index.js <%= asset_path("foo/index.js") %>
 <%= asset_path("foo.js") %>

  26. folders as modules //= require_tree . foo/jquery-ui.js and foo/jquery.min.js Now:

    //= require foo.js # foo/index.js //= require foo.min.js
 //= require foo-ui.js

  27. sourcemaps.js

  28. sourcemaps.js

  29. sourcemaps.js //# sourceMappingURL= File: public/assets/application.js Map: public/assets/application.js.map //# sourceMappingURL=/assets/application.js.map /*#

    sourceMappingURL=application.css.map */
  30. sourcemaps.js

  31. sourcemaps.js

  32. ES2016!

  33. ES2016! 1. Arrows and Lexical This 2. Classes 3. Enhanced

    Object Literals 4. Template Strings 5. Destructuring 6. Default + Rest + Spread 7. Let + Const 8. Iterators + For..Of 9. Symbols, etc
  34. ES2016!

  35. ES2016!

  36. ES2016!

  37. 12x @schneems https://engineering.heroku.com/blogs/2016-02-18- speeding-up-sprockets/

  38. 1.raw asset 2.processed asset 3.bundled 4.compressed 5.asset fingerprint 6.minified 7.etc

    12x
  39. # https://github.com/rails/sprockets/blob/543a5a27190c26de8f3a1b03e18aed8da0367c63/lib/sprockets/base.rb#L46-L57
 
 def file_digest(path)
 if stat = File.stat(path)
 cache.fetch("file_digest:#{path}:#{stat.mtime.to_i}")

    do
 Digest::SHA256.file(path.to_s).digest
 end
 end
 end 12x
  40. “file_digest:/Users/schneems/my_project/app/assets/javascripts/application.js: 123456” "file_digest:/+Other/path/+my_project/app/assets/javascripts/application.js: 123456" 12x

  41. # https://github.com/rails/sprockets/blob/9ca80fe00971d45ccfacb6414c73d5ffad96275f/lib/sprockets/loader.rb#L55-L58 digest = DigestUtils.digest(resolve_dependencies(paths))
 if uri_from_cache = cache.get(unloaded.digest_key(digest), true)


    asset_from_cache(UnloadedAsset.new(uri_from_cache, self).asset_key)
 end 12x!
  42. <%= javascript_include_tag :application, integrity: true %> 
 <script src="/assets/application.js" integrity=“sha256-

    TvVUHzSfftWg1rcfL6TIJ0XKEGrgLyEq6lEpcmrG9qs="> </script> SRI
  43. *Headers

  44. *Header

  45. ETag

  46. class ItemsController < ApplicationController
 def show
 @item = Item.find(params[:id])
 fresh_when

    @item
 end
 end Etag
  47. $ curl -i http://localhost:3000/items/1
 
 HTTP/1.1 200 OK
 X-Frame-Options: SAMEORIGIN


    X-Xss-Protection: 1; mode=block
 X-Content-Type-Options: nosniff
 Etag: "618bbc92e2d35ea1945008b42799b0e7"
 Last-Modified: Sat, 30 Jan 2016 08:02:12 GMT
 Content-Type: text/html; charset=utf-8
 Cache-Control: max-age=0, private, must-revalidate
 X-Request-Id: 98359119-14ae-4e4e-8174-708abbc3fd4b
 X-Runtime: 0.412232
 Server: WEBrick/1.3.1 (Ruby/2.2.2/2015-04-13)
 Date: Fri, 04 Mar 2016 10:50:38 GMT
 Content-Length: 1014
 Connection: Keep-Alive Etag
  48. $ curl -i -H 'If-None-Match: "618bbc92e2d35ea1945008b42799b0e7"' http:// localhost:3000/items/1
 
 HTTP/1.1

    304 Not Modified
 X-Frame-Options: SAMEORIGIN
 X-Xss-Protection: 1; mode=block
 X-Content-Type-Options: nosniff
 Etag: "618bbc92e2d35ea1945008b42799b0e7"
 Last-Modified: Sat, 30 Jan 2016 08:02:12 GMT
 Cache-Control: max-age=0, private, must-revalidate
 X-Request-Id: e4447f82-b96c-4482-a5ff-4f5003910c18
 X-Runtime: 0.012878
 Server: WEBrick/1.3.1 (Ruby/2.2.2/2015-04-13)
 Date: Fri, 04 Mar 2016 10:51:22 GMT
 Connection: Keep-Alive Etag
  49. Strong Etag: ”543b39c23d8d34c232b457297d38ad99" Weak ETag: W/“543b39c23d8d34c232b457297d38ad99" Etag

  50. # app/controllers/home_controller.rb
 class HomeController < ApplicationController
 def index
 render
 end


    end
 
 # app/views/home/index.html.erb
 <h1>Welcome</h1> http_cache_forever
  51. Processing by HomeController#index as HTML
 Rendered home/index.html.erb within layouts/ application

    (1.3ms)
 Completed 200 OK in 224ms (Views: 212.4ms | ActiveRecord: 0.0ms)
 
 And so on for every request for this action.
 http_cache_forever
  52. # app/controllers/home_controller.rb
 class HomeController < ApplicationController
 def index
 http_cache_forever(public: true)

    {}
 end
 end
 
 # OR
 class HomeController < ApplicationController
 def index
 http_cache_forever(public: true) do
 render
 end
 end
 end
 
 
 # app/views/home/index.html.erb
 <h1>Welcome</h1> http_cache_forever
  53. # When request is made for the first time.
 


    Processing by HomeController#index as HTML
 Rendered home/index.html.erb within layouts/ application (1.3ms)
 Completed 200 OK in 224ms (Views: 212.4ms | ActiveRecord: 0.0ms)
 
 # For consecutive requests for the same page
 
 Processing by HomeController#index as HTML
 Completed 304 Not Modified in 2ms (ActiveRecord: 0.0ms) http_cache_forever
  54. ⛔ Cache-Control: max-age=3155760000 http_cache_forever

  55. Asset Headers

  56. response.headers['X-Tracking-ID'] = '123456' Headers in Simple Responses

  57. # open config/environments/production.rb and add following line
 config.static_cache_control = 'public,

    max-age=1000' Asset Headers
  58. PageSpeed Warnings

  59. Missing Expires header

  60. # production.rb
 
 config.public_file_server.headers = {
 'Cache-Control' => 'public, s-maxage=31536000,

    maxage=15552000',
 'Expires' => "#{1.year.from_now.to_formatted_s(:rfc822)}"
 } Public Asset Header
  61. Result

  62. Caching

  63. 1.Page Caching 2.Action Caching 3.Fragment Caching 4.Russian Doll Caching 5.Low-Level

    Caching 6.SQL Caching http://edgeguides.rubyonrails.org/ caching_with_rails.html Caching
  64. # index.html.erb
 <%= render partial: 'todo', collection: @todos %>
 


    # _todo.html.erb
 <% cache todo do %>
 <%= todo.name %>
 <% end %>
 Partial rendering from cache
  65. # index.html.erb
 <%= render partial: 'todo', collection: @todos, cached: true

    %>
 
 # _todo.html.erb
 <% cache todo do %>
 <%= todo.name %>
 <% end %> multi_fetch_fragments
  66. cached: true => read_multi Rendered collection of todos/_todo.html.erb [100 /

    100 cache hits] (339.5ms) multi_fetch_fragments
  67. 72% read_multi

  68. config.action_mailer.perform_caching = true ActionMailer Fragment Caching

  69. <body>
 
 <% cache 'signup-text' do %>
 <h1>Welcome to <%=

    @company.name %></h1>
 <p>You have successfully signed up to <%= @company.name %>, Your username is:
 <% end %>
 
 <%= @user.login %>.
 <br />
 </p>
 
 <%= render :partial => 'footer' %>
 
 </body> ActionMailer Fragment Caching
  70. Cache digest for app/views/user_mailer/_footer.erb: 7313427d26cc1f701b1e0212498cee38
 Cache digest for app/views/user_mailer/welcome_email.html.erb: 30efff0173fd5f29a88ffe79a9eab617


    Rendered user_mailer/_footer.erb (0.3ms)
 Rendered user_mailer/welcome_email.html.erb (26.1ms)
 Cache digest for app/views/user_mailer/welcome_email.text.erb: 77f41fe6159c5736ab2026a44bc8de55
 Rendered user_mailer/welcome_email.text.erb (0.2ms)
 UserMailer#welcome_email: processed outbound mail in 190.3ms ActionMailer Fragment Caching
  71. ActiveRecord::Relation#cache_key Caching result sets and collection

  72. @users = User.where(city: 'miami') 1.The query statement doesn’t change. If

    we change city name from “Miami” to “Boston” then result might change. 2.No record is deleted. 3.No record is added. Caching result sets and collection
  73. @users = User.where(city: 'Miami')
 @users.cache_key
 => "users/query-67ed32b36805c4b1ec1948b4eef8d58f-3-20160116111659084027" # users.html.erb cache

    @users do 
 #content here
 end Caching result sets and collection
  74. *Layouts and Tags.

  75. async-defer www.growingwiththeweb.com/2014/02/async-vs-defer-attributes.html

  76. simple <script>

  77. <script async>

  78. <script defer>

  79. Defaults

  80. Pagespeed

  81. 1.Placement of JS/CSS imports 2.Font imports 3.Analytics tags 4.Proper viewports

    5.responsive 6.Inlining resources, css/js, etc PageSpeed
  82. <!doctype html>
 <html class="" lang="">
 <head>
 … <title>
 <%= @page_title

    || default_page_title %> | BigBinary
 </title>
 <%= stylesheet_link_tag "application.css", 'data-turbolinks- track' => true %>
 …
 <%= csrf_meta_tags %>
 </head>
 <body>
 <%= yield %>
 <script src="https://use.typekit.net/drp7ohd.js"></script>
 <script>try{Typekit.load({ async: true });}catch(e){}</script>
 
 <%= javascript_include_tag "application.js", media: 'all', 'data-turbolinks-track' => true, async: true, defer: true %>
 
 </body>
 </html>

  83. None
  84. Fin.

  85. Fin.

  86. Images: flickr.com/search/? text=singapore&license=2%2C3%2C4%2C5%2C6%2C9 http://blog.bigbinary.com/categories/Rails%205 https://www.packtpub.com/web-development/reactjs-example-building- modern-web-applications-react http://www.growingwiththeweb.com/2014/02/async-vs-defer- attributes.html https://speakerdeck.com/rafaelfranca/how-sprockets-works https://thenounproject.com/search/?q=sprocket&i=283880

    References