Web技術で
ネイティブアプリ開発
Masahiro Tanaka
Asial Corporation
Sep 24, 2017
HTML5 Conference Tokyo
MASA TANAKA
Founder, Asial Corp.
Head of product mgmt, Monaca & Onsen UI
Tokyo, Japan
@massie
masahirotanaka
今日話すこと
- 各種フレームワークやツールの紹介
- とりあえず動かしてみる
- それぞれの特徴を簡単に紹介
選定の基準になれば幸いです
“Web技術” で
“クロスプラットフォーム”
- マークアップ&スタイルでUIを表現
- EcmaScriptやTypeScriptで実装
- Webアプリ開発と違和感のない開発プロセス
- 異なるOS向けのビルド&パッケージング
- ネイティブAPIやデバイス依存機能の隠蔽
- "Write once, run anywhere" と
"Learn once, write anywhere"
こういったツールの課題
- ユーザーインターフェースの構築
- ネイティブAPIへのアクセス方法
- 開発環境とビルド方法
PCアプリ向け開発技術
- ChromiumをWebViewに用いたデスクトップアプリ向けフレームワーク&ツールキット
- macOS, Windows, Linuxに対応
- GitHub社がAtom Editor向けに開発(Atom Shell)
仕組み
Node.js (V8)
Chromium
メインプロセス
レンダラープロセス
IPC
プロセス間通信
HTML5
JavaScript
CSS
- ネイティブUI
(Menu, Tray...) - BrowserWindow
- npmライブラリ
- ネイティブモジュール (node-gyp)
main.js
Node Integration
index.html
サンプル
const {app, BrowserWindow} = require('electron')
let win;
app.on('ready', () => {
win = new BrowserWindow({width: 800, height: 600})
win.loadURL("https://onsenui.github.io/vue-onsenui-kitchensink/main.html")
});
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (win === null) {
createWindow()
}
})
main.js
※ 外部URLをそのままBrowserWindowに表示しています
UIの構築
標準UIデザインへの準拠は大きく求められないため、ほとんどのElectron製アプリは独自デザインを採用
例: VS Code
ダイアログや新しいBrowserWindowの作成が 必要ないUI設計 |
ダイアログ に相当 |
メニューに相当 |
ネイティブUIに準拠したい場合、OS別の切り替えが重要になる
例: React Desktop
NW.js
Electronと比べて:
- 歴史が長い
- 印刷&PDF機能を持つ
- NaCLプラグインに対応
- Chrome APIとChrome Appsに対応
- HTMLをエントリポイントにセットできる
Node Webkit
main.jsをエントリポイントにできない、Nodeモジュールの統合に難がある等の問題は、0.13にて大幅に解決(追いつき)されました
モバイルアプリ向け開発技術
- Cordova
- React Native
- NativeScript
- Weex
モバイルアプリ開発の難しさ
- CPUやGPUの性能がPCより低い
- 厳格に規定されたUIスタイルガイド
- B2BとB2Cで要件が大きく異なる
CPU/GPU性能比較
SunSpider Benchmark
あれ、最近は変わらない?
画面レイアウトの違い
iOS UIKit
Material Design for Android
ハードウェアボタンの有無
キーボードの違い
標準UIのデザイン
B2CとB2Bの違い
B2Cアプリ
B2Bアプリ
安いコストで多OS展開
メンテナンスも出来るだけかけたくない
AppStoreでTop 10を狙う
とにかく最高の性能のアプリを
https://ja.monaca.io/showcase/proroutemarumitsu.htmlより
同じ
「チャット」
機能のアプリ
- 元祖 “ハイブリッドアプリ”
- WebViewを用いたモバイルアプリ向けフレームワーク
- Android, iOS, Windows (Universal Apps)に対応
- Webをそのままネイティブアプリに
仕組み
WebView
ネイティブプラグイン
WebView-Native Bridge
HTML
CSS
JavaScript
GPS
Camera
Filesystem...
iOS / Androidパッケージ
CordovaWebView (CordovaActivity) / CDVViewController
cordova.js
ネイティブ連携
- Cordova PluginとしてNPMにて管理
- Objective-C(iOS)やJava(Android)で記述
- JavaScriptからネイティブへのブリッジ
- cordova.exec()関数を呼ぶと、対応するネイティブコードがコールされる
- iOSではgap://スキーム、Androidではprompt()関数を用いて通知
Cordova CLI
開発環境をセットアップするためのコマンドラインツール
$ npm install -g cordova
$ cordova create cordova-sample && cd cordova-sample
# iOSプラットフォームを追加
$ cordova platform add ios
# エミュレーターで起動
$ cordova run ios --emulator
WebViewの選択肢
iOSとAndroidともにWebViewを選択できる
iOS
Android
- UIWebView
- WKWebView
- System WebView
- Crosswalk Engine
cordova.jsのロードとCSP(Content Security Policy)の追加をお忘れなく
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;">
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
<link rel="stylesheet" type="text/css" href="css/index.css">
</head>
<body>
<div class="app">
<h1>Apache Cordova</h1>
<div id="deviceready" class="blink">
<p class="event listening">Connecting to Device</p>
<p class="event received">Device is Ready</p>
<a href="https://onsenui.github.io/vue-onsenui-kitchensink/main.html?platform=android" target="_self">サンプルアプリ</a>
</div>
</div>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/index.js"></script>
</body>
</html>
サンプルアプリ
ネイティブプラグイン
① Cordova Pluginコマンドで組み込み
$ cordova plugin add cordova-plugin-camera
② cordova.jsが自動的にPolyfillを追加
<script>
var srcType = Camera.PictureSourceType.CAMERA;
var options = setOptions(srcType);
var func = createNewFileEntry;
navigator.camera.getPicture(function cameraSuccess(imageUri) {
// Do something
}, function cameraError(error) {
console.debug("Unable to obtain picture: " + error, "app");
}, options);
</script>
モバイルUIフレームワーク
iOS / Androidのデザイン基準に合わせるためには
UIフレームワークの導入が必要不可欠。
Onsen UI |
Ionic |
jQuery Mobile |
開発環境
Cordova CLIは最小限の機能しか持たない。効率的な開発にはツールの導入が必要。
Monaca |
VS Code |
18万ユーザーが利用する開発環境で、リモートビルド、クラウドIDE、CLI、エンタープライズ向けプラグインなど、多くの付加機能を提供。
無償版もあり、簡単に開発を始めることができる。
Microsoft自体がCordovaのサポーター企業。
VS Codeを使ったデバッグやビルドが簡単に行う事ができる。
リモートビルドには対応していないが、Macユーザーは手軽に利用できる。
- JavaScriptCoreとReactを用いたモバイルアプリ開発フレームワーク
- iOSとAndroid(+Windows Universal)に対応
- WebViewを使わず、独自のUIレイヤーを持つ
仕組み
JavaScriptスレッド
UIスレッド
React
Native
Bridge
JavaScriptCore
iOS / Androidパッケージ
Reactライブラリ
ソースコード
JavaScript + JSX
ネイティブモジュール
<View />
<Text />
ActionSheetIOS
ReactJSとの違い
React Component
(JSX)
ReactJS
+
ReactDOM
Browser DOM
ReactNative
iOS / Android
Native UI
ReactDOMの出力先をNative UIに変更したのがReact Native
はじめ方
Create-React-Native-App
(Expo)方式
React Native CLI方式
# create-react-native-appをインストール
$ yarn global add create-react-native-app
# アプリケーションを作成
$ create-native-app app && cd $_
# 実行
$ yarn start
# react-native-cliをインストール
$ yarn global add react-native-cli
# アプリケーションを作成
$ react-native init reactnative && cd $_
# 実行
$ react-native run-ios
QRコードが表示されるので、Expoアプリをストアからダウンロードして実行
Xcodeビルドが始まり、シミュレーター上でアプリが実行
サンプルコード
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
export default class reactnative extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
AppRegistry.registerComponent('reactnative', () => reactnative);
Native Module
rnpm(React Native Package Manager) がReact Nativeに統合され
ネイティブパッケージが簡単に組み込めるように
例: react-native-maps (AirBnB製)
$ react-native install react-native-maps
開発環境
Facebookが開発するNuclideや
ブラウザー上でも動作するExpoなど
Expo Snack
Nuclide
クロスプラットフォームUI
"Learn once, write anywhere" から
"Write once, run anywhere"へ
NativeBase
iOSとAndroidの両方に対応したコンポーネントにより、OS依存のコードをなるべく吸収できる。
WebView vs. Native UI
パフォーマンスの考察
レンダリングコスト
WebView
Native Component
CSSは装飾性重視で設計されている。DOM計算やレイアウト処理はCPU、描画はCPU/GPUが行う。DOM構造が複雑になったり、スタイル計算が増えてしまうと、スムーズなアニメーションを実現しづらくなる。
パフォーマンス考察 ①
ネイティブのUIコンポーネントはスピード重視で設計されており、RNが持つスタイルも少ない。レイアウトに必要な計算は最小限となり、GPUを効率的に生かせる。
スレッドモデルの違い
Cordova
React Native
WebView
Native
UI Thread
JS Thread
WebView上で動作するJavaScriptがネイティブを呼び出した場合は、同じスレッドで実行される。ネイティブ側でUIスレッドや別スレッドの立ち上げが可能。
UI Thread
WebCore Thread
パフォーマンス考察 ②
JavaScriptCoreから出されたレンダリング指示はすべてUIスレッドにて描画される。
HTML/CSSの高速化
パフォーマンスを改善する仕組みの登場
WebAssembly:
CSS will-change Property:
window.requestIdleCallback()
バイナリ形式のアセンブリを直接ブラウザーが実行することで、ネイティブコードと同等の処理速度を実現する仕組み。iOS 11にも搭載。
WebWorker:
別スレッドに処理を分散することで、マルチコアCPUを効率的に使う技術。window.postMessage()を使ってやりとりを行う。
将来変化するプロパティを伝えることで、ブラウザーが効率的にGPUを使うことを助ける仕組み。Chrome、Mobile Safariともに利用可能。
アイドル時に処理を行うためのコールバック。プリフェッチ等、表示されない領域のDOM更新などを行うのに向いている。Chromeでサポート。
その他の
Native Mobile App
ツール
- Alibabaが開発するネイティブアプリ開発ツール
- iOSにJavaScriptCore、AndroidでV8を使用
- Vue.jsをインテグレーション
- 活発な中国コミュニティ
- iOS、Android、Web向けのビルドに対応
- Progress Software(Telerik)が開発、商用サポート
- Angularを公式サポート。Vue.jsへの対応が進む
- NativeのUIKitやAndroid APIをJavaScriptで直接呼び出せる
選定ガイド
PC向けアプリを作りたい |
Electron NW.js |
Cordova |
ReactNative |
NativeScript |
Weex |
Yes
Webアプリでも展開したい |
Yes
React大好き |
Yes
中国語が読める |
Yes
Electron | Cordova | React Native | Weex | NativeScript | |
---|---|---|---|---|---|
開発元 | GitHub | Adobe, MS | Alibaba | Progress Soft | |
ライセンス | MIT | Apache v2 | BSD + Patent | Apache v2 | Apache v2 |
対象OS | Win32, Mac | iOS, Android, Win Univ. | iOS, Android, Win Univ. | iOS, Android, Web | iOS, Android |
エンジン | Chromium | WebView | JavaScriptCore | JSC, V8 | JSC, V8 |
開発言語 | EcmaScript | EcmaScript | ES + JSX | EcmaScript | ES, TypeScript |
Native連携 | npm | Cordova Plugin | Native Plugin |
比較表
結論
お好きなものを選定しましょう
- PCアプリならElectron
- Web開発の延長線ならCordova
- パフォーマンスを求めるならRNやNativeScript
で、いかがでしょうか。
ありがとうございました
スライド資料
Please try Onsen UI if you're interested in creating Cordova apps!
Web技術でネイティブアプリ開発
By Masa Tanaka
Web技術でネイティブアプリ開発
- 4,374