37
WebView 뛰어 넘기 부제: 고성능 WebView 만들기 박창현

125 고성능 web view-deview 2013 발표 자료_공유용

  • Upload
    naver-d2

  • View
    10.116

  • Download
    3

Embed Size (px)

Citation preview

Page 1: 125 고성능 web view-deview 2013 발표 자료_공유용

WebView 뛰어 넘기부제: 고성능 WebView 만들기

박창현

Page 2: 125 고성능 web view-deview 2013 발표 자료_공유용

About Us

http://www.skplanet.comhttp://readme.skplanet.com

Page 3: 125 고성능 web view-deview 2013 발표 자료_공유용

About Me

단말 플랫폼 개발 Specialist웹 플랫폼 개발 SpecialistAndroid 보안 시스템 개발 SpecialistAndroid/HTML5/Hybrid App Framework/...현) SK planet / Mobile SW 개발 1팀 / 팀장

•••••

Page 4: 125 고성능 web view-deview 2013 발표 자료_공유용

Why High-performance WebView?Basic Tech. Idea for High-performance

WebViewDemoLessons Learned

••

••

Contents

Page 5: 125 고성능 web view-deview 2013 발표 자료_공유용

Why High-performance WebView?

Page 6: 125 고성능 web view-deview 2013 발표 자료_공유용

Hybrid Apps. Become More Popular

Page 7: 125 고성능 web view-deview 2013 발표 자료_공유용

What is Hybrid Application?

Native Web

WebView

Frag

mentat

ion

Page 8: 125 고성능 web view-deview 2013 발표 자료_공유용

WebView Is ...

A Part of AndroidFrameworkDifferent from Web

Browser (Chrome)Less Powerful Than Web

Browser (Chrome...)Web Standard

CompatibilityDepend On Android OS

Version

-

A Part of iOSDifferent from Web

Browser (Safari)Less Powerful Than Web

Browser (Safari)Web Standard

CompatibilityDepend On iOS Version

••

-

Frag

mentat

ion

Page 9: 125 고성능 web view-deview 2013 발표 자료_공유용

Frag

mentat

ion

Web Standard Compatibility forWebView

CanvasAudio/Vi

deo

WebWorker

s

WebSockets

WebAudio

WebNotificat

ionWebGL

GB O △ X X X X X

ICS O △ X X X X X

JB O △ △ X X X X

Page 10: 125 고성능 web view-deview 2013 발표 자료_공유용

Web Standard Compatibility forWebView

CanvasAudio/Vi

deo

WebWorker

s

WebSockets

WebAudio

WebNotificat

ionWebGL

5.0 O △ O △ X X X

6.0 O △ O O O X X

7.0 O △ O O O X X

Page 11: 125 고성능 web view-deview 2013 발표 자료_공유용

Hybrid App’s Problems Are ...

“We have to make several versions of in-appweb contents for each android/iOS version.”

“We need Web Worker feature for ourcontents. But because only iOS can support

Web Worker spec at this time, we can’ssupport android devices.”

Fragmentation

Performance

Page 12: 125 고성능 web view-deview 2013 발표 자료_공유용

We Need To Have SpecialWebView

Provide The Same Web StandardsIndependent of OS version and Manufacturers

Should Be Faster Than Native

Page 13: 125 고성능 web view-deview 2013 발표 자료_공유용

Basic Technical Ingredient

Page 14: 125 고성능 web view-deview 2013 발표 자료_공유용

We Need To Know ...

How To Call JavaScript FunctionFrom Native

How To Call Native Function FromJavaScript

Page 15: 125 고성능 web view-deview 2013 발표 자료_공유용

AndroidonPageFinished + bookmarklet•

webview.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { // evaluate your javascript code here! view.loadUrl(“javascript:.... “); }});

Page 16: 125 고성능 web view-deview 2013 발표 자료_공유용

AndroidaddJavascriptInterface•

//Define Bridge Classclass MyBridgeClass { public void foo(final String args) { // do something }}

webview.addJavascriptInterface(new MyBridgeClass(), “MyBridge”);

// In javascript codewindow.MyBride.foo(“hello world”);

Page 17: 125 고성능 web view-deview 2013 발표 자료_공유용

iOSwebViewDidFinishLoad +

stringByEvaluatingJavaScriptFromString•

//Insert my own javascript codes like this:- (void)webViewDidFinishLoad:(UIWebView *)webView{ outputString = [webViewstringByEvaluatingJavaScriptFromString:@"whatever js code I wantto evaluate"]; }

Page 18: 125 고성능 web view-deview 2013 발표 자료_공유용

iOSshouldStartLoadWithRequest•

//Insert my own javascript codes like this:- (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType: UIWebViewNavigationType)navigationType { if ([[[request URL] absoluteString] hasPrefix:@"skp:"]) { // do my job return NO; } return YES;}

//Javascript codevar iframe = document.createElement("IFRAME");iframe.setAttribute("src", "skp:myBridgeFunction";document.documentElement.appendChild(iframe);iframe.parentNode.removeChild(iframe);iframe = null;

Page 19: 125 고성능 web view-deview 2013 발표 자료_공유용

Add & Replace

Page 20: 125 고성능 web view-deview 2013 발표 자료_공유용

Web Sockets and Canvas 2D

Web SocketsAndroid WebView Does Not SupportAdd Web Sockets Features Into WebView

•--

Canvas 2DAndroid WebView’s Canvas 2D Is Extremely SlowReplace Canvas 2D Features With My Own

Implementation (with SurfaceView)

•--

Page 21: 125 고성능 web view-deview 2013 발표 자료_공유용

Add Web Socket (Android)

WebSocket_shim.js

NativeWebSocket

NativeWebSocketImplNativeWebSocketImpl...

WebSocket WebSocket ...

NativeWebSocket

WebView

Page 22: 125 고성능 web view-deview 2013 발표 자료_공유용

Add Web Socket (Android)

// websocket_shim.js(function() { var store = {}; // Websocket constructor var WebSocket = window.WebSocket = function(url) { // Initialize web socket this.socketId = nativewebsocket.getInstance(url); WebSocket.store[this.socketId] = this; } // declare prototype method WebSocket.prototype.send = function(data) { // bind to native nativewebsocket.send(data, this.socketId); } ... // event dispatcher WebSocket.onopen = function(evt) { // dispatch event to proper instance WebSocket.store[evt.id].onopen(evt); }...})();

Define Web Socket (JavaScript)•

Page 23: 125 고성능 web view-deview 2013 발표 자료_공유용

Add Web Socket (Android)

// Define Bridge Interfaceclass NativeWebSocket { class NativeWebSocketImpl { public String id; public void send(String data) { } public void onOpen(...) { webview.post(new Runnable() { @override public void run() { webview.loadUrl(“javascript:WebSocket.onopen({targetId:“ + id + “,data:” + “data + “});”); } }); } }; ... public void send(String data, String id) { } public String getInstance(String url) { hash.put(getId(), newNativeWebSocketImpl(url, id)); }}...// Register NativeWebSocketwebview.addJavascriptInterface(new NativeWebSocket(), “nativewebsocket”);

Define Web Socket / Register /Callback(Java)

Page 24: 125 고성능 web view-deview 2013 발표 자료_공유용

Add Web Socket (Android)Install WebSocket_shim.js!•

webview.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { // evaluate your javascript code here! view.loadUrl(“javascript:“ + <WebSocket_shim.js 파일 내용>); }});

Page 25: 125 고성능 web view-deview 2013 발표 자료_공유용

Replace Canvas 2D (Android)

WebKit

Original Canvas(JavaScript)

Canvas Canvas ...

CanvasRenderingContext2DCanvasRenderingContext2D...

Image Image ...

WebView

NativeCanvas2DContext

canvas_shim.js(JavaScript)

Canvas Canvas ...

CanvasRenderingContext2DCanvasRenderingContext2D...

Image Image ...

SurfaceView

Bitmap

SurfaceView

Bitmap

...

...

WebKit

NativeCanvas2DContext

WebView

Page 26: 125 고성능 web view-deview 2013 발표 자료_공유용

Replace Canvas 2D (Android)

HTML

WebView

SurfaceView

Canvas

Page 27: 125 고성능 web view-deview 2013 발표 자료_공유용

Replace Canvas 2D (Android)

// canvas2d_shim.js

// Replace built-in function prototype with your ownHTMLCanvasElement.prototype.getContext = function(getCtxOld) { return function (val) { var ctx; ctx = getCtxOld.apply(this, arguments); if (val == ‘2d’) { // make Native Canvas NativeCanvas2DContext.createNativeCanvas(...); // Object Instance Mixin } return ctx; };}(HTMLCanvasElement.prototype.getContext);

Override Canvas.getContext(“2d”)•

Page 28: 125 고성능 web view-deview 2013 발표 자료_공유용

Replace Canvas 2D (Android)

// Replace built-in CanvasRenderingContext2D prototype with yourown

CanvasRenderingContext2D.prototype.fillText = function(..) { NativeCanvas2DContext.fillText(...);};

CanvasRenderingContext2D.prototype.drawImage = function(..) { if (arguments.length == 9) { NativeCanvas2DContext.drawImage(...); } else if (arguments.length == 3) { ... } else { }};

Override CanvasRendering2DContext•

Page 29: 125 고성능 web view-deview 2013 발표 자료_공유용

Replace Canvas 2D (Android)

// Replace built-in constructor of Image object with my ownImage = function() { var image = {}; var imageId = NativeCanvas2DContext.getImageId();

image.__defineSetter__("src", function(val) { NativeCanvas2DContext.setImageSrc(imageId, val); this._src = val; });

image.__defineGetter__("width", function() { return NativeCanvas2DContext.getImageWidth(imageId); }); image.__defineGetter__("height", function() { return NativeCanvas2DContext.getImageHeight(imageId); }); ...

return image;};

Override Image•

Page 30: 125 고성능 web view-deview 2013 발표 자료_공유용

// Define Bridge Interfaceclass NativeCanvas2DContext { public SurfaceView nativeView; public Bitmap image; public void createCanvas(int width, int height) { ... } public void fillText(..) { ... } public void drawImage(..) { ... } public void drawArc(..) { ...} ... public String getImageId() { ... } public void setImageSrc(..) { ... } ...}...// Register NativeCanvas2DContextwebview.addJavascriptInterface(new NativeCanvas2DContext(),“NativeCanvas2DContext”);

Replace Canvas 2D (Android)Define Native Canvas / Register•

Page 31: 125 고성능 web view-deview 2013 발표 자료_공유용

Replace Canvas 2D (Android)Install canvas2d_shim.js!•

webview.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { // evaluate your javascript code here! view.loadUrl(“javascript:“ + <canvas2d_shim.js 파일 내용>); }});

Page 32: 125 고성능 web view-deview 2013 발표 자료_공유용

Demo

Page 33: 125 고성능 web view-deview 2013 발표 자료_공유용
Page 34: 125 고성능 web view-deview 2013 발표 자료_공유용

Lessons Learned

Page 35: 125 고성능 web view-deview 2013 발표 자료_공유용

Do as many implementations as possible injavascript worldMinimize Javascript ⬌ Native

communicationsWatch out threads (PostMessage)

General Lessons

Page 36: 125 고성능 web view-deview 2013 발표 자료_공유용

We Can’t Override Native Properties InWebView

Object.defineProperty Doesn’t Work for NativeProperties

-

Android Specific Lessons

Object Instance MixinAdd Getter/Setter into CanvasRendering2DContext’s

Instance

Object.defineProperty bugsUse __defineGetter__, __defineSetter__ instead

•-

•-

Page 37: 125 고성능 web view-deview 2013 발표 자료_공유용

Q&A