Frontend Solutions:

Ours and Populars

Explosion of Frontend Technologies

  • Node.js & npm
  • Componentization: React / Angular / Vue
  • Assets management: Webpack / Parcel
  • Compilers: Babel / Typescript / Kotlin
  • ...
  • We are using: JUIC / SMRF / UI5

Challenges we are facing to

Componentization

Data Binding

Assets Management

Complex Applications

New syntax

Applications for specific business scenario

We want to make UI elements:

  • Reusable
  • Extendable
  • Combinable

Componentization

UI Component = View                    +     Logic

                              (HTML / CSS)            (Javascript)

Componentization

UI Component:

 

Outside: behaves just like an html tag, can dispatch events and may have public methods

 

Inside: has a renderer which define the real html content, and may have nested components

Componentization

JUIC ✔️

UI5 ✔️

React ✔️

Angular ✔️

Vue ✔️

Componentization

Componentization

<section class="main" v-show="todos.length">
  <input class="toggle-all" type="checkbox" v-model="allDone">
  <ul class="todo-list">
    <li class="todo" v-for="todo in filteredTodos"
        :class="{completed: todo.completed, editing: todo == editedTodo}">
      <div class="view">
        <input class="toggle" type="checkbox" v-model="todo.completed">
        <label @dblclick="editTodo(todo)">{{todo.title}}</label>
        <button class="destroy" @click="removeTodo(todo)"></button>
      </div>
      <input class="edit" type="text" v-model="todo.title" v-todo-focus="todo == editedTodo"
        @blur="doneEdit(todo)" @keyup.enter="doneEdit(todo)" @keyup.esc="cancelEdit(todo)">
    </li>
  </ul>
</section>

Vue's template (renderer)

Componentization

app.TodoItem = React.createClass({
  // other method...
  render: function () {
    return (
      <li className={classNames({
        completed: this.props.todo.completed,
        editing: this.props.editing
      })}>
        <div className="view">
          <input className="toggle" type="checkbox" checked={this.props.todo.completed}
            onChange={this.props.onToggle} />
          <label onDoubleClick={this.handleEdit}>
            {this.props.todo.title}
          </label>
          <button className="destroy" onClick={this.props.onDestroy} />
        </div>
        <input ref="editField" className="edit" value={this.state.editText}
          onBlur={this.handleSubmit} onChange={this.handleChange}
          onKeyDown={this.handleKeyDown}/>
      </li>
    );
  }
});

React's render method (using JSX):

Componentization

juic.set(new juic.Component(), {
    // other methods
    renderHtml : function(h) {
        h.push('<input type="checkbox" ',
                'id="', this.id, '" ',
                (this._checked ? "checked " : " "),
                (!this._enabled ? 'disabled="disabled" ' : ''), ' ');
        if (this._name)
            h.push('name="', this._name, '" ');
        if (this._value)
            h.push('value="', this._value, '" ');
        if (this._isRequired) h.push(' aria-required="true" ');
        if (this._ariaLabelledBy)
            h.push(' aria-labelledby="', this._ariaLabelledBy, '" ');
        h.push('onkeydown="' + this.fireCode('_onKeydownHandler') + '" ');
        h.push('onclick="' + this.fireCode('_click') + '"/>');
        if (typeof this._label != "undefined") {
            h.push(' <label');
        if (!this._ariaLabelledBy) {
          h.push(' for="' + this.id + '"');
            }
            h.push('>',
                   '<span id="lbl', this.id, '" class="', !this._enabled ? 'readonly' : '', '">',
                   juic.escapeHTMLIfNeeded(this._label, this._encodeLabels), '</span>',
                   '</label>');
        }
    }
});

JUIC's render

What's the consequent challenge?

Data - View inconsistence:

Variable's change won't trigger UI change

Automatically keep data and view synchronized

Data Binding

Data Binding

<div id="app">
  <p>{{ message }}</p>
  <button v-on:click="reverseMessage">Reverse Message</button>
</div>

<script>
var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!'
  },
  methods: {
    reverseMessage: function () {
      this.message = this.message.split('').reverse().join('')
    }
  }
})
</script>

How the change event is triggered?

What's the scope of updating?

Data Binding

UI5 & React:

Use setter method

How the change event is triggered?

// Example in React
// ...
handleKeyDown: function (event) {
  if (event.which === ESCAPE_KEY) {

    // set the variable by calling this.setState
    this.setState({editText: this.props.todo.title});

    this.props.onCancel(event);
  } else if (event.which === ENTER_KEY) {
    this.handleSubmit(event);
  }
}
// ...

Angular & Vue:

Change observer

How the change event is triggered?

// Example in Vue
// ...
methods: {
  onEnlargeText: function (enlargeAmount) {
    // Update the variable directly
    this.postFontSize += enlargeAmount
  }
}
// ...

Change observer is more elegant & intuitive

But setter method is better on performance & compatibility

How the change event is triggered?

Rerendering is the bottleneck of performance.

How to restrict the range of rerendering?

What's the scope of updating?

Angular & Vue:

Partial update by analyzing the data-UI binding

What's the scope of updating?

<h1 v-if="title">{{ title }}</h1>

<!--
    This div won't be updated if only this.title is changed.
    Because Vue can analyze the binding relationship and this
    div is not related to title.
-->
<div v-if="content">{{ content }}</div>

UI5:

Full update without checking the binding relationship

What's the scope of updating?

React:

Full update on Virtual-DOM

DOM Diff algorithm to find the part that really need to be changed

Partial update on real DOM

What's the scope of updating?

JUIC ❌

UI5 ⚠️

React ✔️

Angular ✔️

Vue ✔️

Data Binding

What an application should have:

  • Communication between components
  • Routing
  • State Management
  • Acessibility / Localization

Developing complex applications

Libraries - focus on component level functionalities

React, Vue, JUIC

 

Frameworks - provide application level functionalities

UI5, Angular

 

Developing complex applications

Enhance libraries:

React: react-router / redux(mobx) / immutable

Vue: vue-router / vuex

JUIC: N/A

 

Developing complex applications

Look and Feel:

SAPUI5: strictly following Fiori Design

React / Vue / Angular: Various design pattern available (not including Fiori)

Developing complex applications

JUIC ❌

UI5 ✔️

React ⚠️

Angular ✔️

Vue ⚠️

Developing complex applications

Consumes some particular API

Satisfies very detailed requirements

Can build large application with few code (ideally)

Application for specific business scenario

Config UI:

A form renderer developed by SF

Customize layout in WYSIWYG

Fiori Elements:

Form renderer and data visualizer developed by SAP

Annotate data with semantic terms

Application for specific business scenario

Alternatives in industry:

N/A

Why?

Application for specific business scenario

More complex

Less adaptable

Application for specific business scenario

Dependency management

Code minifying

Language Compiler

Assets Management

SMRF

Webpack

UI5?

Assets Management

SMRF

  • JAVA Based
  • Bound with build-system
  • Limited extensions
  • Non-standard syntax
  • Manually build
  • Takes 1~2mins to rebuild
  • Lack of documents

Webpack

  • Node.js based
  • Could be independent
  • Much more plugins (various compilers)
  • Standard syntax
  • File watcher and automated build
  • Takes several secs to rebuild
  • Complete documents for Webpack and its plugins

SAPUI5

Runtime dependency loading - may have severe performance problem.

Can be built by Maven, but build process is not very simple.

More simple code

More strict type system

Static syntax validation

New Syntax & New Languages

JSX

ES7

TypeScript

Kotlin

New Syntax & New Languages

SF status:

Still using ES5

New Syntax & New Languages

JUIC + SMRF UI5 React + Redux + Webpack Angular +
TypeScript +
Webpack
Load Speed 😳 😡 😄 😄
Render Speed 😡 😡 😄 😄
Flexibility 😳 😡 😄 😄
Business scenarios support 😳 😄 😡 😡
Maintainable 😡 😳 😄 😄
Community support 😡 😳 😄 ​😄
Built-in components 😳 😄 😡 😡

Compare

Componentization

Modulization

Strict data management (data type, immutable, ...)

Build the code

Convention over configuration

...

Trend in industry

Separate frontend from backend

Performance (load & run)

Heavy coupling in legacy code

Security in JUIC

Lack of docs (API doc & PRD doc)

...

Challenges in SF

Be open to new technologies

Trust on open source community

Make flexible & improvable software

At last...

frontend solutions

By lukeupup

frontend solutions

  • 248