Web Components: Angular, Polymer and React

June 09, 2015 in Web Development Articles

Written by Eric Greene


Component-based techniques are emerging as the dominant approach for client-side web development. However, component-based development is not a new concept. Going back to the days of COM, CORBA, and even the server-side components of ASP.NET Web Forms and JavaServer Pages, the quest for self-contained components (UI and otherwise) has existed for a long time. The current incarnation of a UI component architecture is taking shape within the web browser through the use of new design patterns, new HTML elements, and new DOM capabilities. The goal of these efforts is to allow for the development and deployment of components that are reusable, insulated from external styling, and provide an API.

Three popular JavaScript technologies attempting to bring web components to life in current browsers, to varying degrees and using different approaches, are Angular, Polymer, and React.  This article examines how each of these technologies is used to develop web components, and compares and contrasts the overall concept, syntax, styling, lifecycle and data binding among Angular, Polymer, and React.

Angular

Angular’s concept of component-based web development centers on directives. At their core, directives are JavaScript functions that manipulate the DOM. Where and how they manipulate the DOM is determined by markers placed on the DOM, as well as the element and attributes on which the DOM markers are placed. Directives encapsulate the process of selecting DOM elements and manipulating them. Manipulations can include creating/modifying/removing DOM elements and adding event listeners, as well as linking the DOM elements into Angular’s two-way data-binding system through watches and observes.

<div ng-app="MyApp">
  <div ng-controller="MyCtrl">
    <ul>
      <li ng-repeat="color in colors">{{color}}</li>
    </ul>
  </div>
</div>

In the above code sample, the directives ngApp, ngController, and ngRepeat are used to create the view. The directive ngRepeat observes the colors array with a watch function to perform UI updates when the array changes.  The double curly brace syntax is used for one-way data binding of $scope variables (The $scope variable is used to store UI model data and operations). In addition to the Angular built-in directives, developer usually create custom directives which will create UI components specific to their application.  The following HTML and JavaScript code samples demonstrate a Hello World custom directive.

<div ng-app="HelloWorldApp">
  <div hello-world="Bob"></div>
</div>

HTML markup with an attribute Directive DOM marker named hello-world.

angular.module("HelloWorldApp", [])
  .directive("helloWorld", function() {
  
    return {
      link: function(scope, element, attrs) {
        element.html("Hello World " + attrs.helloWorld + "!!!");
      }
    }

  });

JavaScript code for the helloWorld directive.

Properly written custom directives can serve effectively as re-usable, interoperable components. Directives written as components will typically use an isolated scope and use HTML elements as DOM markers.

Polymer

Polymer’s approach to web components is to create custom HTML elements that encapsulate both the user interface template and user interface logic. To accomplish this encapsulation, Polymer leverages polyfills.  Polyfills are units of coding logic that implement a feature not supported within an environment.  Typically in the web development space, polyfills are used give older browsers features similar to modern browsers.  In the case of Polymer, it uses polyfills in modern browsers to give them features that are still on the drawing board and exist in few, if any, web browsers.  Polymer’s syntax is primarily declarative HTML-style markup with imperative JavaScript embedded in the declarative markup of the component.

<hello-world first-name="Bob"></hello-world>

HTML markup for the Polymer element and first name parameter.

<link rel="import" href="http://www.polymer-project.org/1.0/samples/components/polymer/polymer.html">

<dom-module id="hello-world">
  <template>
    <span>Hello World <span>{{firstName}}</span>!!!</span>
  </template>
</dom-module>

<script>
  Polymer({
    is: "hello-world",
    properties: {
      type: "String",
      value: ""
    }
  });
</script>

HTML markup with embedded JavaScript implementing the Polymer element.

Unlike Angular and React, Polymer uses a new technology in web development known as the shadow DOM. The shadow DOM allows for a tree of DOM elements to be isolated from their parent DOM element. This isolation serves many purposes such as isolating the DOM tree from CSS styles applied by the web page. The shadow DOM has some limited developer support in major browsers, therefore, Polymer uses a polyfill to provide pseudo-support as needed in browsers which do not yet support developer use of the shadow DOM.  The support is “pseudo” because it mostly works as expected.  While polyfills aim to achieve 100% of what the future feature will be, many times the polyfill falls a little short, and this can sometimes impact the application.

React

React uses a JavaScript based-component with embedded HTML and HTML strings to create web components. The use of embedded HTML is accomplished with the JavaScript syntax extensions (JSX) library. React uses a virtual DOM and a DOM tree update algorithm named reconciliation. Unlike Angular and Polymer where developers interact with real HTML DOM objects, React provides a virtual DOM interface to ease cross-browser development and improve performance.

Observe the following code sample where a HelloWorld component is defined with JavaScript code. Once defined, the DOM element on which the component will be applied is selected and passed into the React render function.  The render function will output the DOM elements generated by the React component to the  declarative markup of the component.

var HelloWorld = React.createClass({
  displayName: "HelloWorld",
  render: function() {
    return React.createElement("div", null, "Hello World " +
      this.props.firstName + "!!!");
  }
});

React.render(
  React.createElement(HelloWorld, {firstName: "Bob"}),
  document.getElementById("content")
);

Making changes to the DOM is very expensive in terms of overall performance. To address this, React uses a custom tree comparison algorithm to only update the DOM where needed instead of replacing the entire tree for the component. Using some baseline assumptions, React is able to achieve O(n) performance instead of the more typical O(n3) performance for tree structure comparisons.  Big O notation describes the performance of a particular algorithm.  The more “n” is multiplied, the worse performing the code will be for large sets of data. In order to improve performance, React always replaces an entire tree if the component or root HTML element is different. For comparing multiple child nodes, React uses reference ids to match HTML elements which may have been re-ordered.

Additionally, React supports server-side DOM rendering which can be used in both web applications and desktop-based JavaScript applications.

Analysis of Component Concept

While Angular, Polymer, and React can each be used to develop web components, they go about it in very different ways.  In this section, we will examine some unique or controversial techniques each library employs.

Angular uses DOM markers combined with JavaScript code to place and execute a directive. Some developers criticize the use of DOM markers because some of the directives and their corresponding attribute values appear to be embedded JavaScript code and business logic. This view of DOM markers is largely incorrect. In order to add a web component to a page, there must be a method to specify the location of the web component in the DOM.

Using a DOM marker, such as an element or an attribute, allows for developers to easily identify the web component in the declarative HTML syntax. Some attribute values used with Angular are simple JavaScript expressions. Nevertheless, these JavaScript expressions are used within the directive itself as a configuration parameter, not executed as part of the HTML markup in ways similar to PHP and Classic ASP. Additionally, specifying a loop structure (such as ngRepeat), is not business logic, it is UI logic. Many developers fail to recognize that UIs are complex and that they have a logic and data structure of their own that is independent of the business layer of the application.

React takes a different approach to locate the position of the web component; it uses JavaScript to select the DOM element where the component will be inserted. This approach is similar to how jQuery-based applications work. While this approach accomplishes the same goal as a DOM marker, it makes it harder for the developer to visualize how the web component is inserted into the DOM.

Polymer uses custom HTML elements as DOM markers for web components. Polymer’s approach is similar to Angular, except Polymer only uses custom elements as DOM markers instead of attributes, classes, and comments, as Angular does.

Of the three JavaScript libraries, only Polymer utilizes DOM tree encapsulation through the use of the shadow DOM. While it is fully expected that the shadow DOM will become a standardized specification, utilizing it in web browsers today usually requires polyfills and other workarounds, which do not fully achieve the goals of DOM encapsulation. Planning for the future is good, but if solid solutions for today’s major browsers are needed, then building an application around new ideas such as the shadow DOM should be considered carefully. In fact, Polymer’s reliance upon polyfills as a general concept is very interesting, but risky for building production applications today; the very polyfills that Polymer provides today may not reflect the standards of tomorrow, thereby rendering Polymer obsolete.

React claims to use a browser-independent virtual DOM for performance and browser-compatibility reasons. The virtual DOM differs from the actual DOM in several ways. First, it uses camel case notation for referencing element attributes. Second, CSS styles are applied through a JavaScript object instead of a CSS style string. Lastly, the onChange event has been modified with a version that works consistently across all form fields on all browsers.

React’s approach to DOM tree comparison for finding the specific nodes to update is unique. None of the other libraries use such a technique to rapidly update the DOM. In the case of Angular, the developer is left to update the DOM when the model changes through the use of watch functions which contain jQuery DOM selection and manipulation code.

Analysis of Component Syntax

Because web components primarily use HTML and JavaScript to construct their UIs, the approach each technology takes to implement components in these two languages is key to their acceptance and usage by developers.

Polymer takes the approach of embedding JavaScript and CSS within an HTML element structure.

React does the reverse: it embeds HTML within JavaScript using the JSX library.

Angular keeps the HTML and JavaScript separate, placing the DOM marker within the HTML page. The HTML page contains the template (using several methods such as the template/templateUrl option, transclusion, and directive priority). The JavaScript code for the directive is located in a JavaScript file independent of the HTML.

The approaches of Polymer and React help to package the HTML and JavaScript into one code unit. This one unit helps to isolate the component’s view and code from the surrounding application code. Angular keeps the component’s HTML and JavaScript separated in different files.

Analysis of Component Data Binding

Both Angular and Polymer use two-way data binding as part of their core implementations. React leaves decisions about data-binding methodology up to the developer. The developer decides whether to use one-way and two-way data binding, with the default being one-way. While many developers prefer one-way binding, two-way data binding is often accomplished with React-Link.

Angular relies upon a loop mechanism known as the $digest loop that executes within the Angular framework. Polymer uses observes on browsers that support them; otherwise, an observe polyfill is used and is powered by a traditional looping system such as that used by Angular. Where Angular and Polymer differ, is that the $ digest loop in Angular.js is executed synchronously, whereas in Polymer its process is asynchronous.

Two-way data binding is controversial. Many developers consider it to be an anti-pattern and view it as a performance burden especially for large, complex web pages. Other developers love two-way data binding and view it as one of the primary reasons to use a framework like Angular (and others like it). For developers who don’t want to use two-way binding or desire to specifically control how two-way binding is implemented, React is the best option. For developers looking for a complete and integrated solution, Angular is the preferred approach.

Analysis of Component Life Cycle

Each JavaScript web component framework/library has a component life cycle that allows it to become a live and functioning part of the web site. Each framework/library uses a simple process by which it uses JavaScript to manipulate an HTML fragment. This results in HTML DOM elements that display the component and have JavaScript functions as event handlers for some of the component’s DOM elements. The process of each framework/library is similar, but the names and specific actions for each step in the process are different.

Angular uses the compiling and linking process. Once Angular finds the starting DOM element for the Angular application, the Angular compile service traverses the DOM looking for directives. These directives are collected, then their compile functions are executed. The compile functions prepare the directive templates for use. Once the compile process is complete, the linking process then executes and links the data model (the scope object) to the template, producing real DOM elements that register JavaScript event handlers. The linked DOM elements are added to the DOM of the web page, thereby allowing the end-user to interact with the component. The entire Angular compiling and linking process occurs synchronously.

Polymer uses a similar approach except it performs its operations asynchronously. The component life cycle goes through the following states: created, ready, attach, and DOM ready. React uses the steps of mounting and updating.

Analysis Summary

Concept Angular Polymer React
DOM Normal DOM Shadow DOM
(uses polyfill if needed)
Virtual DOM and Tree Comparison for Changes
DOM Updates Watch functions to trigger the update, jQuery to do the update Observe functions that manipulate the DOM Virtual DOM and Tree Comparison for Changes
CSS Page Styles Component Styles isolated from Page Styles Page Styles
Template HTML string, <script> element template or external template file <template> element
(uses polyfill if needed)
HTML embedded in JavaScript with JSX
Content Transclusion <content> element
(uses polyfill if needed)
props.children property
Data Binding Two-Way, One-Way: $watches and synchronous $digest loop; One-Time is also possible Two-Way, One-Way: Object.observe() (uses observe polyfill and asynchronous Platform.flush if needed) One-Way (preferred) or Two-Way (with ReactLink)
Life Cycle Synchronous: Compile and Linking Asynchronous: Created, Ready, Attached, DOM Ready Mounting and Updating

 

Conclusion

Web components are the future of web application development. As components begin to mature, many technologies are emerging that seek to make components easy to work with. As we have seen, Angular, Polymer, and React are three possible methods for using web components, each with its unique approach to encapsulating JavaScript and HTML into a single, interoperable, reusable component.

Angular, supported by Google, is the oldest and comprises an entire framework for components through directives that, in addition, manages data binding, data models, routing, and more.

React is a mature web component implementation created by Facebook and used by many companies today. It is a library, not a framework, and it focuses on solving the web component problem only.

Polymer is really nothing more than idea at this point. Some developers are using it to build real web sites but it is not in the mainstream and serves more as a proof of concept than a complete solution for web components.

For web sites today, Angular and React are the two best options, while tomorrow’s web sites will want to keep a close watch on Polymer.

To find more code samples, please visit Plunker (http://plnkr.co/) – it is a great resource for code sharing and collaboration for Angular, Polymer, React, and more.

To get all of the code examples in this blog post, please go to the following URLs and click on ‘Code’ in the upper right hand corner of the screen to see all the associated files.  You can then click on ‘Preview’ to see what it would look like in the browser.

First Angular Plunker – http://embed.plnkr.co/NYCHVGA1SshSnKybWQBG/index

Hello World Angular Plunker – http://embed.plnkr.co/GFXO3GOnyfbYh0wt6fVv/index

Hello World Polymer Plunker – http://embed.plnkr.co/OVqxjbICKKsTSvhrOuSF/index

Hello World React Plunker – http://embed.plnkr.co/fo6O4E8Z5CJMxw1XF5qe/index


Author: Eric Greene, one of Accelebrate’s instructors.

Accelebrate offers private AngularJS training and JavaScript training for groups and instructor-led online JavaScript classes for individuals.


Written by Eric Greene

Eric Greene

Eric is a professional software developer specializing in HTML, CSS, and JavaScript technologies. He has been developing software and delivering training classes for nearly 19 years. He holds the MCSD Certification for ASP.Net Web Applications, and is a Microsoft Certified Trainer.


Learn faster

Our live, instructor-led lectures are far more effective than pre-recorded classes

Satisfaction guarantee

If your team is not 100% satisfied with your training, we do what's necessary to make it right

Learn online from anywhere

Whether you are at home or in the office, we make learning interactive and engaging

Multiple Payment Options

We accept check, ACH/EFT, major credit cards, and most purchase orders



Recent Training Locations

Alabama

Birmingham

Huntsville

Montgomery

Alaska

Anchorage

Arizona

Phoenix

Tucson

Arkansas

Fayetteville

Little Rock

California

Los Angeles

Oakland

Orange County

Sacramento

San Diego

San Francisco

San Jose

Colorado

Boulder

Colorado Springs

Denver

Connecticut

Hartford

DC

Washington

Florida

Fort Lauderdale

Jacksonville

Miami

Orlando

Tampa

Georgia

Atlanta

Augusta

Savannah

Hawaii

Honolulu

Idaho

Boise

Illinois

Chicago

Indiana

Indianapolis

Iowa

Cedar Rapids

Des Moines

Kansas

Wichita

Kentucky

Lexington

Louisville

Louisiana

New Orleans

Maine

Portland

Maryland

Annapolis

Baltimore

Frederick

Hagerstown

Massachusetts

Boston

Cambridge

Springfield

Michigan

Ann Arbor

Detroit

Grand Rapids

Minnesota

Minneapolis

Saint Paul

Mississippi

Jackson

Missouri

Kansas City

St. Louis

Nebraska

Lincoln

Omaha

Nevada

Las Vegas

Reno

New Jersey

Princeton

New Mexico

Albuquerque

New York

Albany

Buffalo

New York City

White Plains

North Carolina

Charlotte

Durham

Raleigh

Ohio

Akron

Canton

Cincinnati

Cleveland

Columbus

Dayton

Oklahoma

Oklahoma City

Tulsa

Oregon

Portland

Pennsylvania

Philadelphia

Pittsburgh

Rhode Island

Providence

South Carolina

Charleston

Columbia

Greenville

Tennessee

Knoxville

Memphis

Nashville

Texas

Austin

Dallas

El Paso

Houston

San Antonio

Utah

Salt Lake City

Virginia

Alexandria

Arlington

Norfolk

Richmond

Washington

Seattle

Tacoma

West Virginia

Charleston

Wisconsin

Madison

Milwaukee

Alberta

Calgary

Edmonton

British Columbia

Vancouver

Manitoba

Winnipeg

Nova Scotia

Halifax

Ontario

Ottawa

Toronto

Quebec

Montreal

Puerto Rico

San Juan