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 Facebook 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!