Web Technology Hot Issues
TechX 2015/03/04 @ Samsung SDS
나현익 (L4)
SDK 개발그룹, S-Core
Contents
Web-App Now and Future
Technical Issues
Object.observe
Web Components
- Custom Elements
- HTML Templates
- Shadow DOM
- HTML Imports
Service Workers
App Manifests
Picture Elements & srcset Attribute
Web-App Now and Future
Now - Broadening Area
- You already use many Web-apps
- Gmail, Naver map, online malls, online banking
- Office-ware
- Photo editor
- Rich media
Web-App Now and Future
Now - Broadening Area
- 3D Graphics with WebGL
- Games
- Development
- Webida IDE, Cloud9, Codenvy
Web-App Now and Future
Future - Bright Side
- Pros of Web-apps
- No install
- Always up-to-date
- Compatible with every CPU and OS
- Accessible from anywhere if online
- Easy sharing: single copy on the server
- Free from some technical problems (e.g. desktop crash, data backups)
- Centralized security management
Web-App Now and Future
Future - Hurdles
- Cons of Web-apps
- Unavailable when offline
- Poor access to local resources (files, printers, scanners, etc)
- Poor performance
- But, (I think) the real problems are
- Premature apps and inertia
- Poor development environment
Technical Issues
Object.observe
Web Components
- Custom Elements
- HTML Templates
- Shadow DOM
- HTML Imports
Service Workers
App Manifests
Picture Elements & srcset Attribute
Object.observe
Basic Concept
-
Declares a callback to observe changes of an object
var model = {};
Object.observe(model, function (changes) {
changes.forEach(function (c) {
alert('\n name: ' + c.name +
'\n type: ' + c.type +
'\n old value: ' + c.oldValue +
'\n cur value: ' + c.object[c.name]);
});
});Ex-1. Observing an object with Object.observe
Synthetic notification and observing arrays
Spec: ECMAScript 7
Supports: Chrome 36+, Node harmony
Object.observe
Without O.o
- Floods of MVC frameworks.
- Mostly, they are based on
- Container object (e.g. Ember.js): incompatible objects, or
- Dirty-checking (e.g. AngularJS): bad algorithmic behavior
Object.observe
Without O.o - Ember
var person= Ember.Object.create({
firstName: "Gildong",
lastName: "Hong",
fullName: function () {
return this.get("firstName") + this.get("lastName");
}.property("firstName", "lastName")
});
perseon.get("fullName"); // person.fullName
perseon.set("lastName", "Go"); // person.lastName = "Go"Ex-3. An object in Ember
Object.observe
Without O.o - AngularJS
Algorithmic behavior of dirty-checking (HTML5 Rocks)
Object.observe
With O.o
Algorithmic behavior of O.o (HTML5 Rocks)
Technical Issues
Object.observe
Web Components
- Custom Elements
- HTML Templates
- Shadow DOM
- HTML Imports
Service Workers
App Manifests
Picture Elements & srcset Attribute
Web Components
Why
- Limited vocabulary of HTML elements
- <div>, <p>, <input>, <a>, <img>, <h1>, <h2>, ...
- Chaotic mixture of contents and presentation in DOM trees (next page)
An example of a chaotic DOM tree
Web Components
What if ...?
<fs-node-dir> tech-day
<fs-node-dir> examples
<fs-node-file> ex1.html </fs-node-file>
<fs-node-file> ex2.html </fs-node-file>
</fs-node-dir>
<fs-node-dir git="repo"> slides
<fs-node-dir> .git </fs-node-dir>
<fs-node-dir git="unmodified"> css </fs-node-dir>
<fs-node-dir git="unmodified"> images
<fs-node-file git="unmodified"> dirty-checking.png </fs-node-file>
<fs-node-file git="unmodified"> dom-tree.png </fs-node-file>
<fs-node-file git="unmodified"> observe.png </fs-node-file>
</fs-node-dir>
<fs-node-dir git="unmodified"> js </fs-node-dir>
<fs-node-dir git="unmodified"> lib </fs-node-dir>
<fs-node-dir git="unmodified"> plugin </fs-node-dir>
<fs-node-dir git="unmodified"> text </fs-node-dir>
<fs-node-file git="unmodified"> .gitignore </fs-node-file>
<fs-node-file git="unmodified"> .travis.yml </fs-node-file>
<fs-node-file git="unmodified"> Gruntfile.js </fs-node-file>
...
</fs-node-dir>
</fs-node-dir>Ex-4. Only the semantic contents, without presentation details
Web Components
Basic Concept
- Define reusable custom HTML elements (widgets)
- Presentation details are hidden at their use sites
- Base of Polymer
- Four pillars
- Custom Elements: Register new HTML element names to the browser
- HTML Templates: Define presentation layers of the elements with "holes"
- Shadow DOM: Glue templates to the elements with encapsulation
- HTML Imports: Single definition and multiple uses
Spec: WHATWG, W3C
Supports: Chrome 36+, Opera 25+, Android 37+, Chrome for Android 38+
(ref.
Can-I-Use)
Custom Elements @ Web Components
Basic Concept
- Register a new HTML element name (tag name) to a browser using document.registerElement()
var NameTag = document.registerElement('name-tag');
document.body.appendChild(new NameTag());Ex-5. Registering a new element name
- document.registerElement(...) returns the constructor of the new element
- Element names must have a dash for forward compatibility
Custom Elements @ Web Components
Extending Another Element
- Can extend other element (default: HTMLElement)
document.registerElement('extended-button', {
prototype: Object.create(HTMLButtonElement.prototype)
});Ex-6. Extending another element
Custom Elements @ Web Components
Lifecycle Callbacks
- createdCallback, attachedCallback, detachedCallback,
attributeChangedCallback(attrName, oldVal, newVal)
- createdCallback is good to fill the contents of custom elements
<div>
<label>Name: </label> <name-tag> </name-tag>
<script>
var proto = Object.create(HTMLElement.prototype);
proto.createdCallback = function () {
this.innerHTML = '<span> Gildong Hong </span>';
}
document.registerElement('name-taq', { prototype: proto });
</script>
</div>Ex-7. Filling the content of a custom element
HTML Templates @ Web Components
Basic Concept
HTML Templates @ Web Components
How to Use
- Clone its content (tmpl.content, a DocumentFragment object)
and add the clone to the DOM
var tmpl = document.querySelector('#mytemplate');
var clone = document.importNode(tmpl.content, true); // true: deep clone
document.body.appendChild(clone);Ex-9. Using template
Shadow DOM @ Web Components
Basic Concept
- Provides encapsulation for Web components
- Presentation details are kept in Shadow DOM and hidden at use sites
- Avoids name collision: IDs, class names, styling rules, etc
<button>Hello, world!</button>
<script>
var host = document.querySelector('button');
var root = host.createShadowRoot();
root.textContent = '안녕, 세상아!';
</script>Ex-10. Hello world of Shadow DOM
- Instead of shadow host's content, shadow root's content is rendered
Shadow DOM @ Web Components
Separating Presentation and Contents
- Task: Creating a name tag
Shadow DOM @ Web Components
Separating Presentation and Contents
<style>
.outer {
border: 2px solid brown;
border-radius: 1em;
background: red;
font-size: 20pt;
width: 12em;
height: 7em;
text-align: center;
}
.boilerplate {
color: white;
font-family: sans-serif;
padding: 0.5em;
}
.name {
color: black;
background: white;
font-family: "Marker Felt", cursive;
font-size: 45pt;
padding-top: 0.2em;
}
</style>
<div class="outer">
<div class="boilerplate">
Hi! My name is
</div>
<div class="name">
Bob
</div>
</div>Ex-11. Original code - Mixture of contents and presentation
Shadow DOM @ Web Components
Separating Presentation and Contents
- Concentrate on true contents of name tags
- It is a name tag
- The name is 'Bob'
Shadow DOM @ Web Components
Separating Presentation and Contents
<!-- true contents -->
<div id="nameTag">Bob</div>
<!-- presentation details -->
<template id="nameTagTemplate">
<style>
...
</style>
<div class="outer">
...
<div class="name">
Bob <!-- !!! -->
</div>
</div>
</template>Ex-10. Step 1: Extract true contents
Shadow DOM @ Web Components
Separating Presentation and Contents
<!-- true contents -->
<div id="nameTag">Bob</div>
<!-- presentation details -->
<template id="nameTagTemplate">
...
</template>
<script>
var shadow = document.querySelector('#nameTag').createShadowRoot();
var template = document.querySelector('#nameTagTemplate');
var clone = document.importNode(template.content, true);
shadow.appendChild(clone);
</script>Ex-13. Step 2: Populate the presentation layer using Shadow DOM
Shadow DOM @ Web Components
Separating Presentation and Contents
<template id="nameTagTemplate">
<style>
...
</style>
<div class="outer">
...
<div class="name">
<content></content> <!-- !!! -->
</div>
</div>
</template>Ex-14. Step 3: Using <content> to complete the separation
- <content> is a 'hole' in the presentation layer
- Host's content is prejected into the hole
Web Components
Putting Them Together
<template id="nameTagTemplate">
… same as Ex-14 …
</template>
<script>
var proto = Object.create(HTMLElement.prototype);
proto.createdCallback = function () {
var shadow = this.createShadowRoot();
var template = document.querySelector('#nameTagTemplate');
var clone = document.importNode(template.content, true);
shadow.appendChild(clone);
};
document.registerElement('name-tag', { prototype: poroto });
</script>Ex-15. Defining <name-tag> with Custom Element, HTML Template and Shadow DOM
HTML Imports @ Web Components
Single Definition and Multiple Uses
<link rel="import" href="name-tag.html">
...
<name-tag> Bob </name-tag>
<name-tag> Mary </name-tag>
<name-tag> 홍길동 </name-tag>Ex-16. Importing the definition of <name-tag> in another file
Technical Issues
Object.observe
Web Components
- Custom Elements
- HTML Templates
- Shadow DOM
- HTML Imports
Service Workers
App Manifests
Picture Elements & srcset Attribute
Service Workers
- Hooking HTTP Requests + Controllable Cache
- Hooks requests with URLs that match one of predefined URL prefixes
- Acts as a client side proxy, especially for offline usage
- Background processing while browser UI doesn't run
- e.g. handling server push messages and system alarms
- But, looks far from completion for this purpose
- Spec: W3C
- No browsers support yet
App Manifests
- JSON file providing information about a Web-app
- Name, author, icon, description, etc: To create a desktop icon
- Start URL, display, orientation, etc: To indicate how to launch
- The list of WebAPIs the app uses
for browsers incorporating Web runtime
- For more familiar UX and native-like Web-apps
- Launching by double-clicking icons, not by bookmarks
- Accessing security-critical local resources:
files, telephony, contacts, camera, power management, WiFi, Bluetooth, etc
- Spec: W3C
- Supports: Chrome 38+
App Manifests
{
"name": "My App",
"description": "My elevator pitch goes here",
"launch_path": "/index.html",
"icons": {
"512": "/img/icon-512.png",
"128": "/img/icon-128.png"
},
"developer": {
"name": "My Name",
"url": "http://my-homepage.org"
},
"default_locale": "en"
}Ex-17. manifest.json (an example)
... <link rel="manifest" href="manifest.json"> ...Ex-18. index.html
Picture Elements & srcset Attribute
Browser Support for Responsive Images
An example
<picture>
<source media="(min-width: 650px)" srcset="images/kitten-stretching.png">
<source media="(min-width: 465px)" srcset="images/kitten-sitting.png">
<img src="images/kitten-curled.png" alt="a cute kitten">
</picture>Ex-19. <picture> element in the above example
Picture Elements & srcset Attribute
Browser Support for Responsive Images
- Selects an image out of candidates based on ...
- Dimension
- Device pixel ratio
- Viewport proportion
- Image format
- Improves image loading performance
- Fetches only a matching or fall-back image
- Spec: WHATWG
- Supports: Chrome 38+, Opera 25+, Chrome for Android 38+
And Much More
- WebRTC
- WebGL
- Polymer
- Push API
- ...