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...
Copy of frontend solutions
By Shawn Shao
Copy of frontend solutions
- 237