Git Product home page Git Product logo

oodle-demo's Introduction

Oodle Theatre

An unofficial Google Doodles web app built as a demo for Google I/O 2018

Build Setup

yarn install

Build Setup

Development:

npm run dev

Build for deployment

npm run build

Report Issues

For any issues or feature requests, we would really appreciate it if you report using our issue tracker.

Contributing

Contributing to Oodle is subject to the guidelines in the CONTRIBUTING.md file, which, in brief, requires that contributors sign the Individual Contributor License Agreement (CLA).

Credits

Oodle is made possible thanks to the tireless work of the Doodles created by the Google Doodles team. We also extend our thanks to the numerous open-source projects we rely on, including Vue and webpack.

oodle-demo's People

Contributors

addyosmani avatar devnook avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

oodle-demo's Issues

JavaScript optimizations

Roughly:

  • Capture screenshots of JS size/processing time analysis before we make any improvements
  • Start dynamically importing more of our routes as they are needed (code-splitting)
  • Look at whether we need better vendor splitting of library code
  • Are we using any large libraries? May be worth highlighting how easy this can be a problem
  • Attempt to use webpack bundle analyzer to find wins (or something like bundle buddy)
  • Show the before/after impact of these changes.

Improve speed

I spent the evening investigating ways to improve how quickly we load (which might affect some of the slides we still need to tweak like preloading).

The current version of our app in development scores as follows on 3G/Moto G4 on WebPageTest:

https://www.webpagetest.org/lighthouse.php?test=180426_QT_fb3fc55d0f626c1dae9c0aaeef69a394&run=3

image

which is a little worse than our local tests have shown (but is expected).

To try bringing these numbers down before Friday, I'm going to try the following this morning:

  1. Preload our JavaScript bundles. My initial tests showed this improved first meaningful paint and TTI
  2. Compare what (if any real impact) optimizing critical path CSS has once 1. is done.
  3. Investigate if there are any other JS optimizations we can make.

Design assets

This thread is to share design assets in case we need them for the future.

Improve accessibility

We currently score a 74 in accessibility. I'm able to navigate around the app pretty okay, but when we enter an individual Doodle route, you can't trigger the iframe to play. We do have a fallback option via the 'View Doodle' link:

image

Web Font optimization

Looking at the network panel for the initial route, we see two references to Web Font files. Both of these are referenced from gstatic:

image

some of our web fonts are flagged in the Lighthouse render-blocking stylesheet audit, delaying paints by ~1.5s:

image

Lighthouse's text visible during font-loads audit passes as well:

image

What are things we want to do here?

  • Our fonts are delaying paint by up to 1.5s. That's unideal. We may want to switch to SVGs for icons instead of relying on the Material Icons package.
  • Do we need Roboto? 'Montserrat', sans-serif appears to be in use for most of our text. Worth dropping Roboto entirely?
  • Do we want to self-host Montserrat so we can configure font-display on it ourselves? Per CSS Tricks "If you embed fonts using a third party service like Google Fonts or TypeKit, there's not much you can do at the moment. Third party services control the content of a @font-face they host, so perhaps consider hosting your own fonts"
  • Consider if we should use https://github.com/typekit/webfontloader

References:

  <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" type="text/css">
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Montserrat:400,600|Teko:300,400,500,600" type="text/css">
  <script src="https://use.fontawesome.com/releases/v5.0.10/js/all.js"></script>

Dropping Roboto will reduce the paint delays down to 740ms:

image

Compression/Brotli

Unfortunately, Firebase Hosting's Brotli experiments got switched off. As GCP doesn't really support this either, our best bet might be using Cloudflare for Brotli just to show off the improvements with it.

Reminder: https://twitter.com/dassurma/status/924346557864054785?lang=en

Alternatively, we could just stick with gzip and remind folks that many large companies have managed to see strong wins with Brotli (e.g LinkedIn improved page load by 7% with it in India).

Another stat:

According to Http Archive data stats, for mid-Match'18 brotli replaced gzip in more than 15% responses. More and more CDNs and services (e.g. BunnyCDN, yandex, jsdelivr, addtoany) support brotli encoding.

HTTP ARCHIVE.xlsx

Support for working without JavaScript

This might be a tricky one as a lot of the Doodles here are powered using JavaScript. We could have a fallback story that relies on <noscript> for Doodle image versions instead as an MVP.

If we had time to do something more clever, we could aim for Puppeteer serving a server-rendered version of each page, but we might not have time for this (I could see the noscript version taking an hour or two otherwise).

Filing an issue for us to think about this in a while.

Introduce performance issues

This should be fun ๐Ÿ”ฅ ๐Ÿ˜„ Consider these all bad ideas. We can keep adding to the pile and see what we like @devnook

image header

The app doesn't content a lot of graphic design in the homepage. What I love about the current version is it's very Google.com like in simplicity. The downside is that it doesn't contain too many images we could optimize ๐Ÿ™ƒ We could introduce an image header, similar to what is done for blog.google:

image

logo

The app currently doesn't have a logo. If we didn't want to go for the image header approach, we could use a logo (uncompressed, too large) and use that to talk about optimizing images and remind folks to consider SVGs.

image

As a note: We're not allowed to use "Google Doodles" or "Doodles" in our app title but might want to come up with something short and fun before I/O. e.g "For legal reasons, this app is called Oodles because its oodles of fun and doesn't get us fired, which is also oodles of fun".

carousel

The way you've currently implemented the carousel is clever in that we don't go preloading the rest of the carousel entries ahead of time. One thing that could be optimized is the main Doodle that gets iframed in as interactive. If it's loading a lot of third-party content, we could suggest folks render a static image of the third-party content with "click to start".

image

images with content

We don't have a lot of editorial content in the app right now. If we wanted, we could have one or two "featured" Doodles where we even pull in some of the Google-created content for those games. One example is the content for the "Doodles Halloween" experience, which had lots of larger images:

image

https://www.google.com/doodles/halloween-global-candy-cup-2015

lazy load images

image

In the "browse by year" views, I've used the images returned by the JSON feed for each year's list of Doodles. We could do something where we lazily load those in that are below the fold (or say, only load in the top 3-4 and lazy-load the rest) if we think it would improve performance.

Use animated GIFs somewhere

Some Doodles include a preview in an animated GIF form. We could use this to highlight how an MP4 using <video> would have been more efficient (and we'll have a Lighthouse audit for this in time for the talk).

YouTube video

image

A common performance issue I see is folks embedding YouTube videos, which, while they don't autoplay can still load a lot of JavaScript in. We could show how to just use a static screenshot of a video with click-to-view to avoid a user paying for this upfront.

Enable text compression

From the development branch:

image

There are two possible fixes here: we can deploy to Firebase or GCP which will gzip by default. We'd need to do extra work to enable Brotli.

Deploying the app to Firebase we're able to pass this audit:

Deployed development to https://doodles-test.firebaseapp.com/

Passing the audit:
image

Final updates

  • Push development to a perf branch
  • Development -> merge it to master

Implement offline experience

From @devnook

I'd like it to be our "offline strategy" take, like a Downosaur or a PWA offline crossword from Guardian, as in "hey, you have no connection, but you can at least play this!". We could touch a bit on PWA offline responsibility point, e.g. that it's not a great idea to save ALL the doodles to the user's device memory.

I like this idea. We just need to remove the links to the game from the main navigation and setup the particular path as what we offline. We still need to add in Workbox somewhere to accomplish this.

Doodle mini perf-audits

I thought it could be useful to take a look at how well some of the current Google Doodles perform and what performance opportunities they might have (in case we were going to import one or two directly).

Feel free to comment or add to these @devnook. Mostly looked at these out of curiosity :)


Halloween 2016

https://www.google.com/logos/2016/halloween16/halloween16.html?hl=en

  • 312KB on page-load before you hit play to start the game. Largest assets are images and a ~160+KB audio file.
  • 1.8MB-2MB of content is lazy-loaded in after you hit play. This grows as you play the game, but the assets are still dynamically loaded as needed. Most of the heavy additions are images, JavaScript and audio files. 944KB is images.
  • Minimal savings (using compression alone with ImageOptim) could be found for these interestingly. Even converting some of the sprites to WebP resulted in larger (rather than smaller images). Maybe smaller sprites are needed?
  • On initial load, 44% of the JavaScript is not immediately used and could be split up. As we start playing the game this goes down to about 40% unused.
  • Traces suggest heavy time spent in JavaScript (6s during a typical game load) with a lot of this spent parsing and compiling code. Even image decodes take a few hundred milliseconds.
  • Resource prioritization could be better. The audio for the game (the OGG file) has a higher loading priority than the JavaScript or images. We could fix this with .

Lighthouse

JavaScript Boot-up Time is high - 12s. TTCI takes 12s which aligns here.

  • With better code-splitting, we could maybe reduce 40% off this (see earlier number) taking it down by 5s
  • Main Thread Processing time is high: 13s. Lots of time compositing layers

Interestingly, even with the newer audits, little else was flagged. This is primarily due to the game not loading in the rest of the content until you hit play.

image
image
image
image
image
image
image
image

Pony Express

Site: https://www.google.com/logos/2015/ponyexpress/ponyexpress15.html?hl=en

WPT: https://www.webpagetest.org/result/180330DX26ade93eaa73b00353dcacee844ef9ee/ (LH audit failed)

  • Initial load experience requires 238KB - largest resources are image sprites and JS. Running these images through ImageOptim would save ~10% (about 14% per file). I would go as far as saying the only two things you should need here are the 8.5KB static preview image for the game and the JavaScript, prefetching (or loading in as needed) the rest of the game assets.
  • Experience uses lazy-loading to avoid pulling in all the resources at once. Theyโ€™re only pulled in when you hit play otherwise.
  • The largest bottlenecks are images. Image sprites are heavily used as this is a game, but there are still opportunities to improve compression.

image

As soon as you hit play, 2.6MB of content is requested overall.

image

2.5MB of these are images

image

The largest sprite is 634KB.

Code coverage tells us that 37% of the JS isnโ€™t used upfront:

image

This stays steady of about 30% unused as we play the first level, so we could shave off about 10KB on the compressed bundle.

image

Most of the time spent on the main thread is in JavaScript

image

On mobile using real-world CrUX data, we see that Doodle-site content has an average FCP of 1.9s and there are plenty of opportunities to optimize content being loaded from this part of the site.

image alt text
image

takeaway: If we're going to embed Pony Express, I'd suggest that we do the minimal amount to improve page load time before you press play, but note that after that it is a game and they appear to have done their best to compress assets. They probably could have broken up some of those sprites a little further but I don't know that we should spend as much time on that.

Error: Cannot read property url of undefined

This happens after running the importer followed by npm run serve. The initial page load has issues (throwing the below error) but tapping on the next arrow loads the Doodles correctly into view.

image

image

I wonder if this is an indices problem.

Mocks

I put together some very early mocks for a few UX concepts we could use:

  • Calendar-based filtering for the carousel
  • List view for browsing Doodles
  • Fullscreen "play" view for interactive Doodles

google-doodle-preview 3

CSS Optimization

Starting from the development branch.

npm run dev

Lighthouse Opportunities
image

Our CSS is unminified, which Vue will do when we run a production build. Lots of unused CSS too (left over from MDC):

image

If we look at our theme file, we see that we're still importing MDC styles, which are bloating up the build:

image

/* theme.scss */
$mdc-theme-primary: #212121;
$mdc-theme-accent: #41b883;
$mdc-theme-background: #fff;

@import 'vue-mdc-adapter/dist/vue-mdc-adapter.css';

I don't think we're using these styles any more so let's drop them.

Our application CSS goes down to under 10KB:

image

Looking at our application again, the only real style change is there's a background color and different arrows in the slider:

image

We can introduce these back ourselves without requiring all of the MDC library.

We have almost no unused CSS and our CSS is minified since we ran it through npm run build:

image

We can bring back this styling (roughly) in just a few extra lines of CSS we stole directly from MDC:

image

Unused styles are still minimal:

image

Overall we shaved 184KB from our CSS bundle just be remembering to remove resources we didn't really need any more. When in doubt, we can just use the exact styles we want from a library.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.