Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Polymer and modern web APIs: In production at Google scale

Polymer and modern web APIs: In production at Google scale

Addy Osmani

May 29, 2015

More Decks by Addy Osmani

Other Decks in Programming


  1. 15 Polymer and modern web APIs: In production at Google

    scale + Matthew McNulty @mattsmcnulty +Taylor Savage @taylorthesavage +Eric Bidelman @ebidel +Addy Osmani @addyosmani
  2. ALL

  3. Theming with CSS Custom Properties <style> body { --paper-tabs: {

    background-color: red; opacity: 0.5; }; } </style> Custom Property
  4. +

  5. create a SPA - curious Polymer developer using web components?

    How do I setup i18n lazy load do routing <insert thing>
  6. <!-- route controller --> <santa-router route="{{route}}" autoHash></santa-router> <!-- scenes elements

    are upgraded on demand --> <lazy-pages selected=“{{route}}” selectedItem=“{{selectedScene}}” valueattr=“route”> <!-- scenes elements inherit from base-scene.html --> <village-scene route=“village" path=“scenes/village_{{lang}}.html” hidden>… <!-- scenes can specify their own loading image & background --> <santaselfie-scene route="santaselfie" path=“scenes/santaselfie-{{lang}}.html” loadingBgColor="#83D7F5" loadingSrc=“scenes/selfie_loading.svg” hidden>… </lazy-pages> <santa-app> </santa-app> github.com/google/santa-tracker-web
  7. App manifest, Custom Elements, CSS will-change,, Service Worker, offline caching

    & analytics, Push Notifications, Picasa API, a11y, ES6, <meta name=“theme-color”>, app HTML Imports, install banner, Polymer, <template>, Google Sheets API , Google Sign-in 2.0, Google Drive API , WebGL, Web Audio API, Web Worker, Google Cloud Messaging, App Engine, YouTube, material design, Sass, Promises, Gulp, Go , Web Animations API, Vulcanize, Google Web Components, Web Starter Kit, Add to Homescreen, <canvas> I/O web app specs
  8. +Eric Bidelman @ebidel lead +Jeff Posnick @jeffposnick service worker /

    notifications +Brendan Kenny @brendankenny WebGL globe +Alex Vaghin @crhym3 backend, API design +Ewa Gasperowicz @devnook page animations / router +Paul Lewis @aerotwist countdown / cheerleader +Rob Dodson @rob_dodson cheerleader #2
  9. <template id=“js”> I {{mood}} <b>JS</b> </template> <template id=“python”> I {{mood}}

    <b>Py</b> </template> <template id=“go”> I {{mood}} <b>Go</b> </template> <template> 101
  10. page1.html <template id=“js”> </template> page2.html <template id=“python”> I {{mood}} <b>Py</b>

    </template> page3.html <template id=“go”> I {{mood}} <b>Go</b> </template> <script> var t = document.getElementById('t'); t.ref = 'js'; </script> Template’s content is ignored when `ref` is set. That content is used instead. site_layout.html I {{mood}} <b>JS</b> <template id=“t” ref=“” bind> <span>placeholder content</span> </template> <template id=“t” ref=“js” bind> </template> I {{mood}} <b>JS</b>
  11. <body> <div class="masthead"> <template id=“template-masthead" ref bind> {% template "masthead"

    .%} </template> </div> <main> <template id=“template-content" ref bind> {% template "content" .%} </template> </main> </body> GET schedule.html Server renders markup on page load
  12. <template data-target-template=“template-masthead“> <h1>Schedule</h1><!-- Schedule page markup --> </template> <template data-target-template=“template-content“>

    <!-- Schedule page markup —> <script> (function initPage() { var page = IOWA.Elements.Template.pages[‘about’]; if (page.hasBeenLoaded) { return; } page.load = function() { … }; page.unload = function() { … }; page.load(); page.hasBeenLoaded = true; })(); </script> </template> GET schedule.html?partial Page-specific JS is part of the page’s <template>. Pages define their own load/unload handlers and configure state.
  13. Dynamic HTML Imports Router.prototype.importPage = function(page) { return new Promise(function(resolve,

    reject) { Polymer.Base.importHref(page + '?partial', function(e) { resolve(e.target.import); }, reject); }); }; importPage('schedule').then(doAnimations); Dynamically loads <link rel=“import” href=“schedule?partial”> containing the page templates. lazy loading Polymer 1.0 code
  14. Animation flow promises, promises, promises Router.prototype.runPageTransition = function() { var

    startPage = this.state.start.page; var endPage = this.state.end.page; IOWA.PageAnimation.runExitAnimation() // 1. Fires ‘page-transition-start’ event. .then(runPageHandler('unload', startPage)) // 2. Run start page's unload handler. .then(importPage(endPage.pageName)) // 3. Fetch new page content. .then(runPageHandler('load', endPage)) // 4. Run destination page's load handler. .then(renderTemplates) // 5. Swap template refs to the new page's. .then(IOWA.PageAnimation.runEnterAnimation) // 6. Play entry sequence. .then(function() { runPageHandler('onPageTransitionDone', endPage) // 7. Tell page transitions are done. // Fires ‘page-transition-done’ event. }); }
  15. 1. Gulp 2. Service Worker 3. Resources versioned in build

    step 4. “Cache then network” requests are cached on-demand Usable offline
  16. UX: enabling notifications 1. Bookmark a session 2. Get sign-in

    toast 3. Sign in 4. Enable notifications 5. Get confirmation toast
  17. Sending a notification More: chromestatus.com/features/5416033485586432 service-worker.js self.addEventListener('push', function(e) { e.waitUntil(loadToken().fetchUpdates().then(function()

    { var note = { title: 'Some events in My Schedule have been updated', body: 'Polymer and modern web APIs:...', icon: '/images/icon.png' }; return self.registration.showNotification(note.title, note); }); });
  18. self.addEventListener('notificationclick', function(e) { var url = new URL('schedule#myschedule', location.href); url.search

    += (url.search ? '&' : '') + 'utm_source=notification'; self.clients.openWindow(url.toString()); }); Re-engagement from a notification service-worker.js
  19. +Eric Bidelman @ebidel Google Santa Tracker app: santatracker.google.com src: github.com/google/santa-tracker-web

    Google I/O web app app: events.google.com/io2015/ src: github.com/GoogleChrome/ioweb2015 <thank-you>
  20. App-wide Theming #303f9f CSS custom properties --dark-primary-color --light-primary-color --accent-color --primary-text-color

    #303f9f --dark-primary-color --light-primary-color --accent-color --primary-text-color
  21. If your app doesn't work offline, you don't really have

    a mobile web experience. - Rob Dodson
  22. // While there is only one cache in this example,

    the same logic will handle the case where // there are multiple versioned caches. var expectedCacheNames = Object.keys(CURRENT_CACHES).map(function(key) { return CURRENT_CACHES[key]; }); event.waitUntil( caches.keys().then(function(cacheNames) { return Promise.all( cacheNames.map(function(cacheName) { if (expectedCacheNames.indexOf(cacheName) == -1) { // If this cache name isn't present in the array of "expected" cache names, then delete it. console.log('Deleting out of date cache:', cacheName); return caches.delete(cacheName); } }) ); }) ); }); // This sample illustrates an aggressive approach to caching, in which every valid response is
  23. Polymer Catalog New Service Worker Elements Fe Iron Elements Polymer

    core elements Md Paper Elements Material design elements Pt Service Worker Service Worker elements
  24. Service Worker caching Take your app offline with ease <script

    src="webcomponents-lite.min.js"></script> <link rel="import" href="platinum-sw-elements.html"> <platinum-sw> <platinum-sw-cache default-cache-strategy="networkFirst" precache='["image.jpg", "results.json", "page.html"]'> </platinum-sw-cache> </platinum-sw>
  25. Google Feeds Download RSS, Atom or Media RSS feeds <google-feeds

    feed=“http://www.engadget.com/rss-full.xml" count=“25"> </google-feeds>
  26. Get and set data using the Firebase APIs <firebase-collection location="https://users1.firebaseio.com/users"

    data="{{users}}"></firebase-collection> <template is="dom-repeat" items="[[users]]" as="user"> <img src="[[user.img]]"><span>[[user.name]]</span> </template>
  27. Push Notifications Stay informed of messages from your app <platinum-push-messaging

    title="You have new stories" message="4 RSS feeds have new stories" icon-url="rss.png" click-url=“feeds/new/“> </platinum-push-messaging>
  28. Components for nearly any app, out of the box. Complete

    build chain for bringing your app to production. Flexible app theming using custom properties Responsive app layout boilerplate & routing Material Design ready
  29. COMMAND-LINE TIPS $ !! # run the last command executed

    $ sudo !! # run the last command as root $ !<word> # run last command starting with a specific word $ !<word>:p # ^ list, but don’t run that last command $ <space>command # execute a command w/out saving in history $ echo "ls -l" | at midnight # execute command at given time $ caffeinate -u -t 3600 # stop your mac from sleeping for 1h $ ls -lhS # sort files by size in a directory $ qlmanage -p <file> # QuickLook preview from command-line $ top -o vsize # why is my mac slow? @addyosmani FOR MAC, BUT BASH TIPS WILL OF COURSE WORK ELSEWHERE.