SlideShare a Scribd company logo
Progressive Enhancement
with Rails
@tylerjohnst
My Name is Tyler Johnston
What is Progressive Enhancement?
Traditional development with Rails works
great. Full page refreshes, static content,
all HTML generation.
But clients and customers want
interactivity and performance.
“Sprinkles of Javascript.”
Keep your Rails workflow but add
Javascript where it’s necessary.
Progressive Enhancment with Rails and React
ails 4 it is now a default gem in the generated G
ert your application in to a single page applica
Download all of the Javascript and
Stylesheets once and reuse for multiple
page views.
s. Turbolinks replaces the content of the <body
Turbolinks gracefully falls back to
browser defaults for
POST/PUT/DELETE requests as well as
the absence of Javascript.
While Turbolinks provides lots of benefits
there are a few caveats which caused a lot
of developers to not use it.
Turbolinks causes most requests to not
yield a full page refresh. This means you
must think differently about how you
organize and handle your Javascript.
Your application is now a long living
Javascript application.
You must be wary of memory leaks. This
means ensuring no circular references and
writing your Javascript in a way that allows
for garbage collection when the controller
changes actions.
$(document).on('page:load', function() {
// wire up javascript events for a page load
});
$(document).on('page:before-unload', function() {
// cleanup references from before
});
This means that just about every jQuery
plugin you may find will cause memory
leaks.
Most of these plugins are poorly
designed and
with a fresh page load in mind. They
don’t tend to track references or have a
way to clean them up.
al solutions to these problems that we’ve all tri
if ($('.organization').length > 0) {
$('.organization').each(function(index, element) {
var $el = $(element);
$.getJSON('/meetup/group/' + $el.prop('data-meetup-id'),
function(data) {
$el.find('a.title').prop('href', 'http://meetup.com/'
+ data.meetup_id)
$el.find('a.title h1').html(data.title);
$el.find('span.members').html(data.members_count);
$el.find('img.meetup-logo').html(data.images.group_logo_large);
});
});
}
Now HTML is rendered by Rails and we
have this pyramid of doom to update our
content.
What if we needed logic for different
pieces?
What if the Meetup API starts replying with
varying data based on something in their
state?
What if we want to poll repeatedly for
changes?
We could move HTML rendering to
templates and now we need another
gem to precompile
Handlebars/Jade/Haml Javascript
templates. Even more logic going in to
this single function.
ot a good fit for this style of development. They
Enter React
React is the light-weight functional view layer
from Facebook designed for building UIs with a
focus on immutable data structures.
React is designing your UI around
reusable and self-contained components.
No separation of files with controllers,
views, templates and models. Allows for
ease of maintainability for even the most of
Javascript novices.
React has a wonderfully simple API that
will take 15 minutes to learn.
OrganizationImage
OrganizationEvent
OrganizationName
OrganizationMembers
var Organization = React.createClass({
componentWillMount: function() {
$.getJSON('/meetup/group/' + this.props.meetup_id)
.then(function(json) {
this.setState(json);
}.bind(this));
},
meetupURL: function(path) {
return "http://www.meetup.com/" +
this.props.meetup_id + path;
},
render: function() {
return <div>
<OrganizationImage photos={this.state.group_photo} />
<OrganizationName name={this.state.name}
meetupURL={this.meetupURL} />
<OrganizationEvent event={this.state.next_event}
meetupURL={this.meetupURL} />
<OrganizationMembers members={this.state.members}
meetupURL={this.meetupURL} />
</div>;
}
});
React is designed around a one-way data
flow. Views are considered to be
immutable and state should be kept to
single place.
When state changes the views are
created from scratch and render and all
mutated state/properties are replaced.
var Organization = React.createClass({
componentWillMount: function() {
$.getJSON('/meetup/group/' + this.props.meetup_id).then(function(json) {
this.setState(json);
}.bind(this));
},
meetupURL: function(path) {
return "http://www.meetup.com/" + this.props.meetup_id + path;
},
render: function() {
return <div>
<OrganizationImage photos={this.state.group_photo} />
</div>;
}
});
var OrganizationImage = React.createClass({
render: function() {
return <img src={this.props.photos.highres_link} width="80" height="80"/>;
}
});
data. What about collecting data or doing things
t unidirectional flow. Data goes down and eve
why was the end of Lost so bad?
SearchAutocomplete
var SearchAutocomplete = React.createClass({
handleAutocomplete: function(event) {
var query = event.target.value;
this.setState({ searchQuery: query });
$.getJSON(this.props.autocompleteUrl, { q: query })
.then(function(autocompleteOptions) {
this.setState({ options: autocompleteOptions });
});
},
render: function() {
return <div>
<SearchAutocompleteInput value={this.state.searchQuery}
handleChange={this.handleAutocomplete} />
<SearchAutocompleteResults options={this.state.options} />
</div>;
}
});
AutocompleteSearchInput
AutocompleteSearchResult
s
var SearchAutocomplete = React.createClass({
handleAutocomplete: function(event) {
var query = event.target.value;
this.setState({ searchQuery: query });
$.getJSON(this.props.autocompleteUrl, { q: query })
.then(function(autocompleteOptions) {
this.setState({ options: autocompleteOptions });
});
},
render: function() {
return <div>
<SearchAutocompleteInput value={this.state.searchQuery}
handleChange={this.handleAutocomplete} />
<SearchAutocompleteResults options={this.state.options} />
</div>;
}
});
Progressive Enhancment with Rails and React
Whats with all the Javascript? Isn’t this
about Rails?
gem 'react-rails'
unctionality and dependencies of React while t
Remember the Organization component?
<% @organizations.each do |organization| %>
<%= react_component('Organization',
organization.to_json) %>
<% end %>
Mounts the React component
Sets the properties of the component
from the given hash
Automatically cleans up references and
handles memory management with
Turbolinks callbacks
But what about SEO and search
engine crawling?
<%= react_component('Organization',
organization.to_json, prerender: true) %>
Progressive Enhancment with Rails and React
React knows how to pre-render using
ExecJS so the component will boot
using the existing HTML that is valid
for React.
I’ve come full circle on my thinking of front
end development.
Rails development feels better than every
alternative, no matter how polished. React
and React-Rails allows for a really great
convergence of great and fast front end
tooling with Rails fast development
cycle.
Go forth and try React with Rails!
Questions? Comments?

More Related Content

PDF
Multi screen HTML5
PDF
AtlasCamp 2015: Using add-ons to build add-ons
PDF
Caldera Learn - LoopConf WP API + Angular FTW Workshop
PPTX
SPTechCon Boston 2015 - Overcoming SharePoint Limitations
PDF
Introduction to plugin development
PDF
jQuery Mobile Workshop
KEY
Geotalk presentation
PDF
Hybrid Web Applications
Multi screen HTML5
AtlasCamp 2015: Using add-ons to build add-ons
Caldera Learn - LoopConf WP API + Angular FTW Workshop
SPTechCon Boston 2015 - Overcoming SharePoint Limitations
Introduction to plugin development
jQuery Mobile Workshop
Geotalk presentation
Hybrid Web Applications

What's hot (16)

PDF
Spca2014 hillier 3rd party_javascript_libraries
PDF
Jqeury ajax plugins
PPTX
(Updated) SharePoint & jQuery Guide
PDF
Assumptions: Check yo'self before you wreck yourself
PDF
Introduction to AngularJS For WordPress Developers
PDF
Two Webs! : combining the best of Web 1.0, Web 2.0 and the Semantic Web
PDF
ApacheCon 2005
PDF
Search APIs in Spotlight and Safari
PDF
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014
PDF
Create responsive websites with Django, REST and AngularJS
PPTX
An Overview of Models in Django
PPT
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)
PDF
Putting the Cat in the Catalogue: A Feline-Inspired OPAC Theme For Koha
PDF
Server Side Swift with Swag
PDF
Moving from Django Apps to Services
PPTX
Take Better Care of Library Data and Spreadsheets with Google Visualization A...
Spca2014 hillier 3rd party_javascript_libraries
Jqeury ajax plugins
(Updated) SharePoint & jQuery Guide
Assumptions: Check yo'self before you wreck yourself
Introduction to AngularJS For WordPress Developers
Two Webs! : combining the best of Web 1.0, Web 2.0 and the Semantic Web
ApacheCon 2005
Search APIs in Spotlight and Safari
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014
Create responsive websites with Django, REST and AngularJS
An Overview of Models in Django
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)
Putting the Cat in the Catalogue: A Feline-Inspired OPAC Theme For Koha
Server Side Swift with Swag
Moving from Django Apps to Services
Take Better Care of Library Data and Spreadsheets with Google Visualization A...
Ad

Similar to Progressive Enhancment with Rails and React (20)

PDF
Crossing platforms with JavaScript & React
PDF
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
PPTX
Adding a modern twist to legacy web applications
PDF
A Little Backbone For Your App
PDF
Backbone.js — Introduction to client-side JavaScript MVC
PPTX
Javascript first-class citizenery
PDF
Building Large jQuery Applications
PDF
Understanding backbonejs
PDF
PDF
Cross Domain Web
Mashups with JQuery and Google App Engine
PPT
JS-05-Handlebars.ppt
PPTX
Html5 and web technology update
PDF
After max+phonegap
PDF
混搭移动开发:PhoneGap+JQurey+Dreamweaver
PDF
Dependency Management with RequireJS
KEY
Asynchronous Interfaces
PDF
Styling components with JavaScript
PDF
Integrating React.js Into a PHP Application
PPTX
Big Data for each one of us
PDF
Frontin like-a-backer
Crossing platforms with JavaScript & React
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
Adding a modern twist to legacy web applications
A Little Backbone For Your App
Backbone.js — Introduction to client-side JavaScript MVC
Javascript first-class citizenery
Building Large jQuery Applications
Understanding backbonejs
Cross Domain Web
Mashups with JQuery and Google App Engine
JS-05-Handlebars.ppt
Html5 and web technology update
After max+phonegap
混搭移动开发:PhoneGap+JQurey+Dreamweaver
Dependency Management with RequireJS
Asynchronous Interfaces
Styling components with JavaScript
Integrating React.js Into a PHP Application
Big Data for each one of us
Frontin like-a-backer
Ad

Recently uploaded (20)

PDF
keyrequirementskkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
PDF
Well-logging-methods_new................
PPTX
OOP with Java - Java Introduction (Basics)
PPTX
Infosys Presentation by1.Riyan Bagwan 2.Samadhan Naiknavare 3.Gaurav Shinde 4...
PPTX
Construction Project Organization Group 2.pptx
PDF
Enhancing Cyber Defense Against Zero-Day Attacks using Ensemble Neural Networks
PPTX
Lecture Notes Electrical Wiring System Components
PPT
CRASH COURSE IN ALTERNATIVE PLUMBING CLASS
PPTX
Internet of Things (IOT) - A guide to understanding
PDF
Model Code of Practice - Construction Work - 21102022 .pdf
PDF
PRIZ Academy - 9 Windows Thinking Where to Invest Today to Win Tomorrow.pdf
PDF
Mitigating Risks through Effective Management for Enhancing Organizational Pe...
PDF
Automation-in-Manufacturing-Chapter-Introduction.pdf
PDF
Operating System & Kernel Study Guide-1 - converted.pdf
PPTX
UNIT 4 Total Quality Management .pptx
PPT
Project quality management in manufacturing
PDF
The CXO Playbook 2025 – Future-Ready Strategies for C-Suite Leaders Cerebrai...
PPTX
additive manufacturing of ss316l using mig welding
PPTX
Welding lecture in detail for understanding
DOCX
ASol_English-Language-Literature-Set-1-27-02-2023-converted.docx
keyrequirementskkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
Well-logging-methods_new................
OOP with Java - Java Introduction (Basics)
Infosys Presentation by1.Riyan Bagwan 2.Samadhan Naiknavare 3.Gaurav Shinde 4...
Construction Project Organization Group 2.pptx
Enhancing Cyber Defense Against Zero-Day Attacks using Ensemble Neural Networks
Lecture Notes Electrical Wiring System Components
CRASH COURSE IN ALTERNATIVE PLUMBING CLASS
Internet of Things (IOT) - A guide to understanding
Model Code of Practice - Construction Work - 21102022 .pdf
PRIZ Academy - 9 Windows Thinking Where to Invest Today to Win Tomorrow.pdf
Mitigating Risks through Effective Management for Enhancing Organizational Pe...
Automation-in-Manufacturing-Chapter-Introduction.pdf
Operating System & Kernel Study Guide-1 - converted.pdf
UNIT 4 Total Quality Management .pptx
Project quality management in manufacturing
The CXO Playbook 2025 – Future-Ready Strategies for C-Suite Leaders Cerebrai...
additive manufacturing of ss316l using mig welding
Welding lecture in detail for understanding
ASol_English-Language-Literature-Set-1-27-02-2023-converted.docx

Progressive Enhancment with Rails and React

  • 2. My Name is Tyler Johnston
  • 3. What is Progressive Enhancement?
  • 4. Traditional development with Rails works great. Full page refreshes, static content, all HTML generation.
  • 5. But clients and customers want interactivity and performance.
  • 7. Keep your Rails workflow but add Javascript where it’s necessary.
  • 9. ails 4 it is now a default gem in the generated G
  • 10. ert your application in to a single page applica
  • 11. Download all of the Javascript and Stylesheets once and reuse for multiple page views.
  • 12. s. Turbolinks replaces the content of the <body
  • 13. Turbolinks gracefully falls back to browser defaults for POST/PUT/DELETE requests as well as the absence of Javascript.
  • 14. While Turbolinks provides lots of benefits there are a few caveats which caused a lot of developers to not use it.
  • 15. Turbolinks causes most requests to not yield a full page refresh. This means you must think differently about how you organize and handle your Javascript.
  • 16. Your application is now a long living Javascript application. You must be wary of memory leaks. This means ensuring no circular references and writing your Javascript in a way that allows for garbage collection when the controller changes actions.
  • 17. $(document).on('page:load', function() { // wire up javascript events for a page load }); $(document).on('page:before-unload', function() { // cleanup references from before });
  • 18. This means that just about every jQuery plugin you may find will cause memory leaks. Most of these plugins are poorly designed and with a fresh page load in mind. They don’t tend to track references or have a way to clean them up.
  • 19. al solutions to these problems that we’ve all tri
  • 20. if ($('.organization').length > 0) { $('.organization').each(function(index, element) { var $el = $(element); $.getJSON('/meetup/group/' + $el.prop('data-meetup-id'), function(data) { $el.find('a.title').prop('href', 'http://meetup.com/' + data.meetup_id) $el.find('a.title h1').html(data.title); $el.find('span.members').html(data.members_count); $el.find('img.meetup-logo').html(data.images.group_logo_large); }); }); }
  • 21. Now HTML is rendered by Rails and we have this pyramid of doom to update our content. What if we needed logic for different pieces? What if the Meetup API starts replying with varying data based on something in their state? What if we want to poll repeatedly for changes?
  • 22. We could move HTML rendering to templates and now we need another gem to precompile Handlebars/Jade/Haml Javascript templates. Even more logic going in to this single function.
  • 23. ot a good fit for this style of development. They
  • 24. Enter React React is the light-weight functional view layer from Facebook designed for building UIs with a focus on immutable data structures.
  • 25. React is designing your UI around reusable and self-contained components.
  • 26. No separation of files with controllers, views, templates and models. Allows for ease of maintainability for even the most of Javascript novices. React has a wonderfully simple API that will take 15 minutes to learn.
  • 28. var Organization = React.createClass({ componentWillMount: function() { $.getJSON('/meetup/group/' + this.props.meetup_id) .then(function(json) { this.setState(json); }.bind(this)); }, meetupURL: function(path) { return "http://www.meetup.com/" + this.props.meetup_id + path; }, render: function() { return <div> <OrganizationImage photos={this.state.group_photo} /> <OrganizationName name={this.state.name} meetupURL={this.meetupURL} /> <OrganizationEvent event={this.state.next_event} meetupURL={this.meetupURL} /> <OrganizationMembers members={this.state.members} meetupURL={this.meetupURL} /> </div>; } });
  • 29. React is designed around a one-way data flow. Views are considered to be immutable and state should be kept to single place. When state changes the views are created from scratch and render and all mutated state/properties are replaced.
  • 30. var Organization = React.createClass({ componentWillMount: function() { $.getJSON('/meetup/group/' + this.props.meetup_id).then(function(json) { this.setState(json); }.bind(this)); }, meetupURL: function(path) { return "http://www.meetup.com/" + this.props.meetup_id + path; }, render: function() { return <div> <OrganizationImage photos={this.state.group_photo} /> </div>; } }); var OrganizationImage = React.createClass({ render: function() { return <img src={this.props.photos.highres_link} width="80" height="80"/>; } });
  • 31. data. What about collecting data or doing things
  • 32. t unidirectional flow. Data goes down and eve
  • 33. why was the end of Lost so bad? SearchAutocomplete
  • 34. var SearchAutocomplete = React.createClass({ handleAutocomplete: function(event) { var query = event.target.value; this.setState({ searchQuery: query }); $.getJSON(this.props.autocompleteUrl, { q: query }) .then(function(autocompleteOptions) { this.setState({ options: autocompleteOptions }); }); }, render: function() { return <div> <SearchAutocompleteInput value={this.state.searchQuery} handleChange={this.handleAutocomplete} /> <SearchAutocompleteResults options={this.state.options} /> </div>; } });
  • 36. var SearchAutocomplete = React.createClass({ handleAutocomplete: function(event) { var query = event.target.value; this.setState({ searchQuery: query }); $.getJSON(this.props.autocompleteUrl, { q: query }) .then(function(autocompleteOptions) { this.setState({ options: autocompleteOptions }); }); }, render: function() { return <div> <SearchAutocompleteInput value={this.state.searchQuery} handleChange={this.handleAutocomplete} /> <SearchAutocompleteResults options={this.state.options} /> </div>; } });
  • 38. Whats with all the Javascript? Isn’t this about Rails?
  • 40. unctionality and dependencies of React while t
  • 42. <% @organizations.each do |organization| %> <%= react_component('Organization', organization.to_json) %> <% end %>
  • 43. Mounts the React component Sets the properties of the component from the given hash Automatically cleans up references and handles memory management with Turbolinks callbacks
  • 44. But what about SEO and search engine crawling?
  • 47. React knows how to pre-render using ExecJS so the component will boot using the existing HTML that is valid for React.
  • 48. I’ve come full circle on my thinking of front end development. Rails development feels better than every alternative, no matter how polished. React and React-Rails allows for a really great convergence of great and fast front end tooling with Rails fast development cycle.
  • 49. Go forth and try React with Rails! Questions? Comments?

Editor's Notes

  • #15: A lot of people were not happy with Turbolinks and most people remove it out of frustration.
  • #31: In this example we can see the state is contained to the “Organization” component. That is responsible for creating and passing data to the child views. When it is “mounted” it sends a network request.
  • #35: The child input isn’t even responsible for updating the state of the “value.” It is passed in after the searchQuery value changes.
  • #37: The child input isn’t even responsible for updating the state of the “value.” It is passed in after the searchQuery value changes.
  • #49: Testing works out of the box. Javascript unit testing works out of the box with `jasmine-rails`. JSX compilation with Sprockets works out of the box.