Your SlideShare is downloading. ×
Tips You Should Know Before Distributing Your HTML5 Web App on Mobile (MBL301) | AWS re:Invent 2013
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Tips You Should Know Before Distributing Your HTML5 Web App on Mobile (MBL301) | AWS re:Invent 2013

1,383
views

Published on

Before you surface your web app through a mobile marketplace, you should be aware of common errors and performance tips to optimize your web app for mobile devices. This session teaches you the …

Before you surface your web app through a mobile marketplace, you should be aware of common errors and performance tips to optimize your web app for mobile devices. This session teaches you the important things you need to know, like the best practices around improving frame rate and ways to optimize . We also help you avoid mistakes, such as common cases that kill scrolling performance. Through a case study, we dive deep into the subtleties of CSS animations and improving rendering speed by reducing composite layers in your web apps. We also show you how to profile performance bottlenecks on-device using the Web App Tester tool. You get a peek into the Chromium-based web runtime on Kindle Fire devices and learn how to accommodate device rotation, touch feedback, device resolution, and screen aspect ratios to fine-tune your web app experience on mobile devices.

Published in: Technology, Design

0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,383
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
34
Comments
0
Likes
3
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Coding Tips You Should Know Before Distributing Your HTML5 Web App on Mobile Devices Russell Beattie, Amazon November 15, 2013 © 2013 Amazon.com, Inc. and its affiliates. All rights reserved. May not be copied, modified, or distributed in whole or in part without the express consent of Amazon.com, Inc. Friday, November 15, 13
  • 2. Agenda • Welcome • HTML5 Mobile Web App Basics • Setup • DevTools Demo • Coding Tips and Best Practices • • • • HTML CSS Javascript Offline Friday, November 15, 13
  • 3. HTML5 Mobile Web App Basics Friday, November 15, 13
  • 4. Setup • Text Editor • Modern Desktop Browser • Chrome, Firefox, Safari, IE 11, etc. • Modern Mobile Browser or Tester • Amazon Web App Tester, Chrome, etc. • Android SDK • For remote debugging Friday, November 15, 13
  • 5. Basic HTML5 Web App Template <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Basic Template</title> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1"> <style> html, body {height: 100%; margin: 0; padding: 0; background: #000; color: #FFF} </style> <link rel="stylesheet" href="main.css"> </head> <body> <div id="content"></div> <script src="main.js"></script> </body> </html> Friday, November 15, 13
  • 6. Basic HTML5 Web App Template <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Basic Template</title> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1"> <style> html, body {height: 100%; margin: 0; padding: 0; background: #000; color: #FFF} </style> <link rel="stylesheet" href="main.css"> </head> <body> <div id="content"></div> <script src="main.js"></script> </body> </html> Friday, November 15, 13
  • 7. Basic HTML5 Web App Template <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Basic Template</title> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1"> <style> html, body {height: 100%; margin: 0; padding: 0; background: #000; color: #FFF} </style> <link rel="stylesheet" href="main.css"> </head> <body> <div id="content"></div> <script src="main.js"></script> </body> </html> Friday, November 15, 13
  • 8. Basic HTML5 Web App Template <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Basic Template</title> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1"> <style> html, body {height: 100%; margin: 0; padding: 0; background: #000; color: #FFF} </style> <link rel="stylesheet" href="main.css"> </head> <body> <div id="content"></div> <script src="main.js"></script> </body> </html> Friday, November 15, 13
  • 9. Basic HTML5 Web App Template <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Basic Template</title> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1"> <style> html, body {height: 100%; margin: 0; padding: 0; background: #000; color: #FFF} </style> <link rel="stylesheet" href="main.css"> </head> <body> <div id="content"></div> <script src="main.js"></script> </body> </html> Friday, November 15, 13
  • 10. Basic HTML5 Web App Template <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Basic Template</title> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1"> <style> html, body {height: 100%; margin: 0; padding: 0; background: #000; color: #FFF} </style> <link rel="stylesheet" href="main.css"> </head> <body> <div id="content"></div> <script src="main.js"></script> </body> </html> Friday, November 15, 13
  • 11. Basic HTML5 Web App Template <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Basic Template</title> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1"> <style> html, body {height: 100%; margin: 0; padding: 0; background: #000; color: #FFF} </style> <link rel="stylesheet" href="main.css"> </head> <body> <div id="content"></div> <script src="main.js"></script> </body> </html> Friday, November 15, 13
  • 12. Basic HTML5 Web App Template <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Basic Template</title> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1"> <style> html, body {height: 100%; margin: 0; padding: 0; background: #000; color: #FFF} </style> <link rel="stylesheet" href="main.css"> </head> <body> <div id="content"></div> <script src="main.js"></script> </body> </html> Friday, November 15, 13
  • 13. Basic HTML5 Web App Template <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Basic Template</title> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1"> <style> html, body {height: 100%; margin: 0; padding: 0; background: #000; color: #FFF} </style> <link rel="stylesheet" href="main.css"> </head> <body> <div id="content"></div> <script src="main.js"></script> </body> </html> Friday, November 15, 13
  • 14. Basic HTML5 Web App Template <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Basic Template</title> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1"> <style> html, body {height: 100%; margin: 0; padding: 0; background: #000; color: #FFF} </style> <link rel="stylesheet" href="main.css"> </head> <body> <div id="content"></div> <script src="main.js"></script> </body> </html> Friday, November 15, 13
  • 15. Basic HTML5 Web App Template <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Basic Template</title> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1"> <style> html, body {height: 100%; margin: 0; padding: 0; background: #000; color: #FFF} </style> <link rel="stylesheet" href="main.css"> </head> <body> <div id="content"></div> <script src="main.js"></script> </body> </html> Friday, November 15, 13
  • 16. Basic HTML5 Web App Template <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Basic Template</title> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1"> <style> html, body {height: 100%; margin: 0; padding: 0; background: #000; color: #FFF} </style> <link rel="stylesheet" href="main.css"> </head> <body> <div id="content"></div> <script src="main.js"></script> </body> </html> Friday, November 15, 13
  • 17. Basic HTML5 Web App Template <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Basic Template</title> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1"> <style> html, body {height: 100%; margin: 0; padding: 0; background: #000; color: #FFF} </style> <link rel="stylesheet" href="main.css"> </head> <body> <div id="content"></div> <script src="main.js"></script> </body> </html> Friday, November 15, 13
  • 18. Basic HTML5 Web App Template <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Basic Template</title> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1"> <style> html, body {height: 100%; margin: 0; padding: 0; background: #000; color: #FFF} </style> <link rel="stylesheet" href="main.css"> </head> <body> <div id="content"></div> <script src="main.js"></script> </body> </html> Friday, November 15, 13
  • 19. DevTools Demo • Connecting (via WebSockets or TCP/IP) • Live modification of page (CSS, HTML) • Interaction with device via inspection button • Debugging (JavaScript, Network, etc.) • Frame-rate / GPU • Profiling Friday, November 15, 13
  • 20. Coding Tips and Best Practices Friday, November 15, 13
  • 21. HTML Friday, November 15, 13
  • 22. Headers - Apple <meta name="apple-touch-fullscreen" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <meta name="apple-mobile-web-app-title" content="UVM Home"> <link rel="apple-touch-startup-image" href="/startup.png"> <link rel="apple-touch-icon" sizes="128x128" href="niceicon.png"> <link rel="apple-touch-icon-precomposed" sizes="144x144" href="img/touch/apple-touchicon-144x144-precomposed.png"> <link rel="apple-touch-icon-precomposed" href="img/touch/apple-touch-icon-57x57precomposed.png"> <link rel="shortcut icon" href="img/touch/apple-touch-icon.png"> Friday, November 15, 13
  • 23. Headers - Google, Blackberry, Microsoft <!-- Google --> <meta name="mobile-web-app-capable" content="yes"> <link rel="shortcut icon" sizes="196x196" href="nice-highres.png"> <link rel="shortcut icon" sizes="128x128" href="niceicon.png"> <!-- Blackberry --> <meta name="HandheldFriendly" content="true"> <meta name="cursor-event-mode" value="native"> <meta http-equiv="x-rim-auto-match" content="none"> <!-- Microsoft --> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="cleartype" content="on"> <meta name="msapplication-TileImage" content="pics/logowin8pin.png"/> <meta name="msapplication-TileColor" content="#B20099"/> <meta name="msapplication-badge" value="frequency=1440;polling-uri=http:// www.example.com/Win8TileNotification.php" /> Friday, November 15, 13
  • 24. Headers - Firefox, W3C, etc. <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"/> <link rel="shortcut icon" href="favicon.ico" /> <meta name="format-detection" content="telephone=no"> <meta name="format-detection" content="address=no"/> <link rel="dns-prefetch" href="page2.html"> <meta name="description" content=""/> <meta name="keywords" content=""/> Friday, November 15, 13
  • 25. Input Field Types <form> Date: <input type="date" value="2013-09-03" name="dateInput"> Datetime: <input type="datetime" name="datetimeInput"> Datetime-local: <input type="datetime-local" value="2013-09-03T20:00" name="datetime-local"> Email: <input type="email" name="emailInput"> Month: <input type="month" value="2013-09" name="monthInput"> Number: <input type="number" name="numberInput"> Password: <input type="password" name="passwordInput"> Range: <input type="range" name="rangeInput"> Search: <input type="search" name="searchInput"> Tel: <input type="tel" name="telInput"> Time: <input type="time" name="timeInput"> Url: <input type="url" name="urlInput"> </form> Friday, November 15, 13
  • 26. Required and Validation <input type="url" name="urlInput" required pattern="https?://.+"> ... input:required:invalid, input:focus:invalid { background-image: url(/images/invalid.png); background-position: right top; background-repeat: no-repeat; } input:required:valid { background-image: url(/images/valid.png); background-position: right top; background-repeat: no-repeat; } Friday, November 15, 13
  • 27. CSS Friday, November 15, 13
  • 28. Interaction html { -webkit-tap-highlight-color: rgba(0, 0, 0, 0); -webkit-user-select: none; } body{ -webkit-font-smoothing: antialiased; /* Fix for webkit rendering */ -webkit-text-size-adjust: 100%; } /* don't let "actions" dialog to come up when element is touch/held */ .prevent-action { -webkit-touch-callout: none; } Friday, November 15, 13
  • 29. Interaction continued /* no dragging of element at all */ .content p.no-drag { -webkit-user-drag: none; } /* drags entire element, not the text/selection */ .sidebar div.element-drag { -webkit-user-drag: element; } /* change the character used to hide user passwords */ input[type="password"] { -webkit-text-security: square; } textarea[contenteditable] { -webkit-appearance: none; } Friday, November 15, 13
  • 30. Hardware acceleration /* position */ -webkit-transform: translate(0, 0); -webkit-transform: translateZ(0); -webkit-transform: translate3d(0, 0, 0); /* scale */ -webkit-transform: scale(0); /* rotation */ -webkit-transform: rotate(0); /* opacity */ opacity: 0.5; Friday, November 15, 13
  • 31. Animations @-webkit-keyframes pulse { from { -webkit-transform: scale(.1); } to { -webkit-transform: scale(1); } } div { -webkit-animation-name: pulse; -webkit-animation-duration: 2s; -webkit-animation-iteration-count: infinite; -webkit-animation-timing-function: ease-in-out; -webkit-animation-direction: alternate; } // Javascript content.addEventListener("webkitAnimationIteration", countAnims, false); Friday, November 15, 13
  • 32. Transitions // CSS .box { left: 40px; -webkit-transition: all 0.3s ease-out; } div.box.totheleft { -webkit-transform: translate3d(0, 0, 0); } div.box.totheright { -webkit-transform: translate3d(80px, 0, 0); } // Javascript window.addEventListener("webkitTransitionEnd", function() { // Handle the end of the transition }, false); Friday, November 15, 13
  • 33. Media Queries @media screen and (orientation:portrait) { /* portrait-specific styles */ } @media screen and (orientation:landscape) { /* landscape-specific styles */ } @media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (minresolution: 144dpi) { /* Style adjustments for viewports that meet the condition */ } Friday, November 15, 13
  • 34. JavaScript Friday, November 15, 13
  • 35. Orientation Detection var mql = window.matchMedia("(orientation: portrait)"); if(mql.matches) { // Portrait orientation } else { // Landscape orientation } mql.addListener(function(m) { if(m.matches) { // Changed to portrait } else { // Changed to landscape } }); // Resizing window.addEventListener("resize", function() { // window.innerHeight > window.innerWidth ... }, false); Friday, November 15, 13
  • 36. Device Resolution var meta = document.createElement("meta"); meta.setAttribute('name','viewport'); var content = 'initial-scale='; content += 1 / window.devicePixelRatio; content += ',user-scalable=no'; meta.setAttribute('content', content); document.getElementsByTagName('head')[0].appendChild(meta); Friday, November 15, 13
  • 37. Canvas pre-rendering // no pre-rendering function render() { drawSpaceShip(context); requestAnimationFrame(render); } // pre-rendering var sprite = document.createElement('canvas'); sprite.width = 64; sprite.height = 64; var spriteCtx = sprite.getContext('2d'); drawSpaceShip(spriteCtx); function render() { context.drawImage(sprite, 0, 0); requestAnimationFrame(render); } Friday, November 15, 13
  • 38. Canvas batch calls // Slower for (var i = 0; i < points.length - 1; i++) { var p1 = points[i]; var p2 = points[i+1]; context.beginPath(); context.moveTo(p1.x, p1.y); context.lineTo(p2.x, p2.y); context.stroke(); } // Faster context.beginPath(); for (var i = 0; i < points.length - 1; i++) { var p1 = points[i]; var p2 = points[i+1]; context.moveTo(p1.x, p1.y); context.lineTo(p2.x, p2.y); } context.stroke(); Friday, November 15, 13
  • 39. Canvas Redraw Regions // redraw entire canvas context.fillRect(0, 0, canvas.width, canvas.height); // redraw only 'dirty' areas context.fillRect(last.x, last.y, last.width, last.height); // faster way to redraw canvas context.clearRect(0, 0, canvas.width, canvas.height) Friday, November 15, 13
  • 40. RequestAnimationFrame function animate(time){ //random drawing context.clearRect(0, 0, canvas.width, canvas.height); context.beginPath(); context.rect(x, y, 50, 50); context.fillStyle = '#8ED6FF'; context.fill(); // Old way: // window.setTimeout(animate, 1000/60); // New way: window.requestAnimationFrame(animate); } Friday, November 15, 13
  • 41. Reflows and repaints var bstyle = document.body.style; // cache bstyle.padding = "20px"; // reflow, repaint bstyle.border = "10px solid red"; // another reflow and a repaint bstyle.color = "blue"; // repaint only, no dimensions changed bstyle.backgroundColor = "#fad"; // repaint bstyle.fontSize = "2em"; // reflow, repaint // new DOM element - reflow, repaint document.body.appendChild(document.createTextNode('hello...')); Friday, November 15, 13
  • 42. Minimize dimension or location queries // Slower var elem = document.getElementById('animated'); elem.style.fontSize = (elem.offsetWidth / 10) + 'px'; elem.firstChild.style.marginleft = (elem.offsetWidth / 20) + 'px'; // Faster var elem = document.getElementById('animated'), elemWidth = elem.offsetWidth; elem.style.fontSize = (elemWidth / 10) + 'px'; elem.firstChild.style.marginleft = (elemWidth / 20) + 'px'; Friday, November 15, 13
  • 43. Debounce Events function SomeObject() { var self = this; this.lastExecThrottle = 500; // limit to one call every "n" msec this.lastExec = new Date(); this.timer = null; this.resizeHandler = function() { var d = new Date(); if (d-self.lastExec < self.lastExecThrottle) { if (self.timer) { window.clearTimeout(self.timer); } self.timer = window.setTimeout(self.resizeHandler, self.lastExecThrottle); return false; // exit } self.lastExec = d; // update "last exec" time self.callResizeHandlerFunctions(); } } var someObject = new SomeObject(); window.onresize = someObject.resizeHandler; Friday, November 15, 13
  • 44. Offline Friday, November 15, 13
  • 45. Server MIME Types AddType text/cache-manifest .manifest AddType text/cache-manifest .appcache AddType application/x-web-app-manifest+json .webapp Friday, November 15, 13
  • 46. App cache manifest CACHE MANIFEST # Version 1.0 # filename: app.manifest or name.appcache CACHE: index.html Game-Break.mp3 Game-Death.mp3 Game-Shot.mp3 Game-Spawn.mp3 main.js main.css three.min.js ... <html manifest="app.manifest"> Friday, November 15, 13
  • 47. W3C Web App Manifest { "name": "Flip.io", "description": "Flip.io - 999 Word Puzzles. A simple, yet challenging word puzzle that will entertain novices and lexicographers alike. Presented with 10 word definitions and scrambled tiles of letter combos, can you find all the words?", "launch_path": "/", "icons": { "60": "/flip60.png", "128": "/flip128.png" }, "developer": { "name": "Russell Beattie", "url": "http://flip.io" }, "default_locale": "en", "fullscreen": "true" } Friday, November 15, 13
  • 48. Amazon Mobile Web App Platform Manifest { "verification_key": "insert your verification key from the App File(s) tab", "launch_path": "index.html", "permissions": [ "iap", "geolocation", "auth" ], "type": "web", "version": "0.1a", "last_update": "2013-04-08 13:30:00-0800", "created_by": "webappdev" } Friday, November 15, 13
  • 49. Real World App Demo Friday, November 15, 13
  • 50. Please give us your feedback on this presentation MBL301 As a thank you, we will select prize winners daily for completed surveys! Thank You @RussB • beattier@amazon.com developer.amazon.com/webapps Friday, November 15, 13