SlideShare a Scribd company logo
Boston PHP, August 2015    
Better PHP­Frontend
Integration With
Tungsten.js
Let's get started!
Who Are We
Andrew Rota
@andrewrota  
Matt DeGennaro
@thedeeg
Wayfair
Wayfair.com is an online destination for all things
home
Selection of more than seven million home items from 7,000+
suppliers
eCommerce company since 2002
Several large websites running a shared codebase
PHP backend for customer­facing pages
2,000,000+ lines of code for custom eCommerce platform
2,000+ JavaScript modules
Divisions in Web Applications
Server Client
...But there are overlaps
Server Client
View Layer
What Comprises
the View Layer
Constants
Markup
Some data stored somewhere
Client­Side
Interaction is
Hard
The "jQuery"
Approach
Manual UI Management
JS is manually crafted to match the HTML
Event listeners modify the DOM as needed
Usually uses jQuery to smooth browser differences
Can be the fastest code
Maintenance nightmare for larger sites
Developers need to worry about low­level
performance
+
­
­
Maintenance Nightmare?
<div>
  <div class="clickable"></div>
</div>
$('.clickable').on('click', function() {
  $(this).parent().addClass('highlighted');
});
Maintenance Nightmare?
<div>
  <div class="fancy‐border">
    <div class="clickable"></div>
  </div>
</div>
$('.clickable').on('click', function() {
  $(this).parent().parent().addClass('highlighted');
});
Maintenance Nightmare?
<div class="highlightable">
  <div class="fancy‐border">
    <div class="clickable"></div>
  </div>
</div>
<div class="highlightable">
  <div class="clickable"></div>
</div>
$('.clickable').on('click', function() {
  $(this).closest('.highlightable').addClass('highlighted');
});
Maintenance Nightmare?
<div class="highlightable" data‐highlight‐class="fancy‐highlighted"
  <div class="fancy‐border">
    <div class="clickable"></div>
  </div>
</div>
<div class="highlightable" data‐highlight‐class="highlighted">
  <div class="clickable"></div>
</div>
$('.clickable').on('click', function() {
  var $highlightable = $(this).closest('.highlightable');
  $highlightable.addClass($highlightable.data('highlightClass'));
});
Markup === Data
The "Backbone"
Approach
Re­render constantly
Data is managed in JS
Template renders to String
Data + Template = innerHTML
Really simple to implement
Repaint/relayout on each render
Touching DOM on every render
+
­
­
DOM is Slow
Hundreds of properties
Hidden side effects
The "Virtual
DOM" Approach
Described Markup
   
Simplified Code
Turns imperative code into declarative code
<div class="{{#clicked}}fancy‐highlighted{{/clicked}}">
  <div class="fancy‐border">
    <div class="clickable"></div>
  </div>
</div>
<div class="{{#clicked}}highlighted{{/clicked}}">
  <div class="clickable"></div>
</div>
Declarative Code
State + Template is a consistent outcome
So by managing State rather than the page...
We can render the page from the server at any state
JS failures can fall back to forms so the server can update state
Markup is owned by one location
No more "where did this class come from" discovery adventure time
Bugs can be reproduced by copying state
Anyone can copy model data and send to Devs for bug reports
Isn't this the
same as
Backbone?
Virtual DOM
"Re­render" constantly, but in­memory
Only touch the DOM when necessary in a precise
manner (think scalpel vs sledgehammer)
Dev's don't worry about DOM interaction
Better PHP-Frontend Integration with Tungsten.js
How does this
work?
Better PHP-Frontend Integration with Tungsten.js
Vanilla DOM node creation Virtual DOM creation
Virtual DOM
document.createElement('div'); new VirtualNode('div');
  counterReset: ""
  cssText: ""
  cursor: ""
  direction: ""
  display: ""
  dominantBaseline: ""
  emptyCells: ""
  enableBackground: ""
  fill: ""
  fillOpacity: ""
  fillRule: ""
tagName: "DIV"
properties: {}
children: []
count: 0
Virtual DOM vs DOM
Lifecycle of a Render ­ Diffing
{
  "tagName": "INPUT",
  "properties": {
    "id": "toggle‐all",
    "className": "js‐toggle‐all",
    "type": "checkbox"
  },
  "children": [],
  "count": 0
}
{
  "tagName": "INPUT",
  "properties": {
    "id": "toggle‐all",
    "className": "js‐toggle‐all",
    "type": "checkbox",
    "checked": true
  },
  "children": [],
  "count": 0
}
Lifecycle of a Render ­ Patching
Diff creates a "Patch" object
Smallest set of operations it could detect to update
the DOM
{
  "0": { // Index of the element to patch
    "type": 4,  // type of patch operation, in this case 'update properti
    "patch": {  // Properties to update, in this case, update 'checked' t
      "checked": true
    }
  }
}
Lifecycle of a Render ­ Applying Changes
Iterate over Virtual Tree and attached DOM node
Vtree avoid iterating on unchanged DOM
When changed node is found, apply changes
DOM­Free View Abstraction
State + Template = View
Can use same abstraction across platforms
Create markup for server­side rendering
Create native UI for app rendering
Wayfair's
Transition
Why were we looking for a new solution?
Our codebase had a hybrid of the jQuery and
Backbone approaches
Debugging was hard
Unnecessary DOM selection / manipulation
Interactive pages could become janky
What we needed
Performance
The driving force
Stack Cohesion
First­class server­side rendering
Our Stack
Mustache Templates
C++ on server, precompiled for client
Server
Custom PHP MVC
Framework
Client
jQuery / AMD
Backbone on Mobile
Looked at Common Frameworks...
   
..But nothing quite fit
Most common stack was:
Server
node.js / io.js
Isomorphic JS
framework
No first­class server­
side rendering
Client
Same isomorphic
JS framework
So...
Required JS on the server
Server­side rendering was either
Much slower than our templates
Fully unsupported
­  , 
Funny story about server rendering: it
wasn't actually designed that way“
Sebastian Markbåge React.js Conf
Why is server­side rendering important?
Perceived time to load
SEO
Browser/User Support
Link previews for social media
Actual time to load
JS is not single point of failure
So What Did We
Do?
We wrote a new framework
Better PHP-Frontend Integration with Tungsten.js
Tungsten.js
JS framework with high­performance rendering
Designed to work with a portable template language
Server agnostic
Attaches to server­rendered HTML and adds
functionality
Application Logic
DOM Manipulation
Templates
Server
Integration
Our Server Framework
Custom MVC framework using Mustache templates
for View rendering
Page load triggers Controller action
Controller uses load Models for data
Models call DAOs as necessary
Data is passed to View layer
Tungsten + PHP Integration ­ Server
View prepares template data and renders HTML
Wraps HTML with a specific ID so we can attach client­side
Serializes data to JSON and adds data to
namespaced JS variable
View has reference to the JS View and Model
Bootstraps view, model, and precompiled template into our
JS loader
Tungsten + PHP Integration ­ Output
<div id="AppView1"><!‐‐ Markup from AppTemplate.mustache ‐‐></div>
<script src="AppView‐AppModel‐AppTemplate.js"></script>
var tungstenData = {
  App1: {
    view: "AppView",
    model: "AppModel",
    elem_id: "AppView1",
    template: "AppTemplate",
    data: {...}
  }
};
Tungsten + PHP Integration ­ Client
JS factory function reads variable and constructs JS
Views over the rendered HTML
Since data comes from the server, rendered HTML
will match
DOM Events are bound, adding interaction
Advantages
Zero DOM manipulation on page load
Centralized Data Store
Easier to reason about data­flow
Serializable state for debugging
Server can render at any state
Multi­page applications can use shared routes
DEMO
Coming Soon
Abstracting template from Mustache to allow more
template languages
Componentization to avoid all­in­one templates
Better client­side data management
Fork us at 
Driven by feature requests, so let us know what you'd
like to see
github.com/wayfair/tungstenjs

More Related Content

PDF
An Exploration of Frameworks – and Why We Built Our Own
PDF
Tungsten.js: Building a Modular Framework
PDF
UI Rendering at Wayfair
PPTX
Polymer and web component
PPTX
Sencha At Xero
PPTX
Google Polymer Introduction
PDF
Building mobile applications with Vaadin TouchKit
PDF
Mobile web apps in pure Java
An Exploration of Frameworks – and Why We Built Our Own
Tungsten.js: Building a Modular Framework
UI Rendering at Wayfair
Polymer and web component
Sencha At Xero
Google Polymer Introduction
Building mobile applications with Vaadin TouchKit
Mobile web apps in pure Java

What's hot (20)

PPT
Introduction to Vaadin
PPTX
Building single page applications
PPTX
How to build a web application with Polymer
PDF
Booting up with polymer
PPTX
Getting Started with J2EE, A Roadmap
PPTX
Pros and Cons of developing a Thick Clientside App
PDF
Coding a SaaS
PPTX
Maurice de Beijer
PDF
Custom Elements with Polymer Web Components #econfpsu16
PDF
Easy HTML5 Data Visualization with Kendo UI DataViz
PDF
Introduction to Web Components
PDF
Putting the A in JAMstack
PPTX
Developing JavaScript Widgets
PDF
«The Grail: React based Isomorph apps framework»​
PPTX
Event sourcing your React-Flux applications
PPTX
Razor into the Razor'verse
PDF
«Разрушаем Вавилонскую Башню WWW с помощью веб-компонент»​
PDF
Google Polymer Framework
PPTX
More object oriented development with Page Type Builder
PPTX
Web Components
Introduction to Vaadin
Building single page applications
How to build a web application with Polymer
Booting up with polymer
Getting Started with J2EE, A Roadmap
Pros and Cons of developing a Thick Clientside App
Coding a SaaS
Maurice de Beijer
Custom Elements with Polymer Web Components #econfpsu16
Easy HTML5 Data Visualization with Kendo UI DataViz
Introduction to Web Components
Putting the A in JAMstack
Developing JavaScript Widgets
«The Grail: React based Isomorph apps framework»​
Event sourcing your React-Flux applications
Razor into the Razor'verse
«Разрушаем Вавилонскую Башню WWW с помощью веб-компонент»​
Google Polymer Framework
More object oriented development with Page Type Builder
Web Components
Ad

Viewers also liked (18)

PDF
Integrating React.js Into a PHP Application
DOCX
PPTX
Μασάι Ελευθέριος
PPT
Mεσαιωνικο καστρο λεμεσου
PDF
Sample ppt new niche interior by mulavira interior systems
PPTX
Κωνσταντίνος Καβάφης
PDF
Wakayama 1 day
PPTX
Islamic economic system
PPTX
ΟΙ ΖΟΥΛΟΥ Παναγιώτα
PPTX
Κωνσταντίνος Καβάφης
PPTX
RENNIE COWAN - GRAPHIC DESIGN
PPT
Alejandra la paradoja de james hunter
ODP
Conventions of short films
PPTX
οικια μέλπως πηλαβάκη
PPTX
Κωνσταντίνος Καβάφης
PPTX
3d printing....science....
PPTX
ΟΔΟΣ ΔΗΜΟΣΘΕΝΗ ΜΙΤΣΗ
PDF
Big data on AWS
Integrating React.js Into a PHP Application
Μασάι Ελευθέριος
Mεσαιωνικο καστρο λεμεσου
Sample ppt new niche interior by mulavira interior systems
Κωνσταντίνος Καβάφης
Wakayama 1 day
Islamic economic system
ΟΙ ΖΟΥΛΟΥ Παναγιώτα
Κωνσταντίνος Καβάφης
RENNIE COWAN - GRAPHIC DESIGN
Alejandra la paradoja de james hunter
Conventions of short films
οικια μέλπως πηλαβάκη
Κωνσταντίνος Καβάφης
3d printing....science....
ΟΔΟΣ ΔΗΜΟΣΘΕΝΗ ΜΙΤΣΗ
Big data on AWS
Ad

More from Andrew Rota (14)

PDF
Integrating React.js Into a PHP Application: Dutch PHP 2019
PDF
Performant APIs with GraphQL and PHP (Dutch PHP 2019)
PDF
Getting Started with GraphQL && PHP
PDF
Tutorial: Building a GraphQL API in PHP
PPTX
Building a GraphQL API in PHP
PDF
Ten practical ways to improve front-end performance
PDF
Component Based UI Architectures for the Web
PDF
Client-Side Performance Monitoring (MobileTea, Rome)
PDF
Effectively Monitoring Client-Side Performance
PDF
Why Static Type Checking is Better
PDF
The Complementarity of React and Web Components
PDF
Web Components + Backbone: a Game-Changing Combination
PDF
Bem methodology
PDF
Web Components and Modular CSS
Integrating React.js Into a PHP Application: Dutch PHP 2019
Performant APIs with GraphQL and PHP (Dutch PHP 2019)
Getting Started with GraphQL && PHP
Tutorial: Building a GraphQL API in PHP
Building a GraphQL API in PHP
Ten practical ways to improve front-end performance
Component Based UI Architectures for the Web
Client-Side Performance Monitoring (MobileTea, Rome)
Effectively Monitoring Client-Side Performance
Why Static Type Checking is Better
The Complementarity of React and Web Components
Web Components + Backbone: a Game-Changing Combination
Bem methodology
Web Components and Modular CSS

Better PHP-Frontend Integration with Tungsten.js