web components at scale, html5devconf 2014-10-21

Post on 02-Jul-2015

319 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

At Pinterest, we've begun experimenting in production with Web Components. This talk will discuss some challenges of implementing Web Components in a large scale production environment such as SEO concerns, reasonable fallbacks for browsers not supported by Platform.js, migrating a large code base component-by-component to mitigate risk, and optimizing page load and scroll performance.

TRANSCRIPT

Chris Danford, @chrisdanfordPinterest Web Team

Web Components at Scale2014-10-20

Pinterest’s evaluation of Web ComponentsTopic Covered

• Migrating from our existing component framework• SEO impact• Page load perf• Polyfill gotchas• Browser compatibility

Background Learnings Conclusion TODO

2 years since major design decisions madeBackground

Pinterest has grownBackground

Then 7 engineers touching web

Now 70 engineers touching web

ArchitectureBackground

API

Android

Datalayer

iOSWeb

Graph ServiceSearch

Client Apps

Back-endServices

...

Web architectureBackground

Web server

Routing

Templates

Render a component tree

Behavior (event handlers)

Duplication

Existing component systemBackground

• Backbone View• Backbone Model• templates render to an HTML string, then innerHTML to

load• re-rendering a subtree throws away the old subtree

entirely

Style (.scss)

Structure (.html)

Behavior (.js)

from a template

from JS

Web Components score cardBackground

• Migrate gradually• Compatible with existing tooling• Content Security Policy• Page load performance (too much)• Don’t hurt SEO• Encapsulation of DOM and styles• Don’t cut off too many browser versions

Background Learnings Conclusion TODO

Custom Elements lifecycle functionsMigrate Gradually

Pinterest onCreated

onAddedToDomonContentReady

onRemovedFromDom

Custom Elements createdCallbackattachedCallback

—detachedCallback

Polymer created

attacheddomReadydetached

Each component renders itself in attachedCallbackQuick prototype

Migrate Gradually

Can work with existing toolingPreserve Existing Tools

• SASS• ESLint• Closure Compiler• Syntax-highlighting editors

External scripts and stylesheets are no problemPreserve Existing Tools

• Polymer docs: Separating scripts from markup

Works with Existing Tooling

Polyfill problemsDon’t break Content Security Policy

• The HTML Imports polyfill loads imports using XMLHttpRequest then evals script

Content Security PolicyRequirements

• If you keep your styles and scripts external, there’s no action needed.

• If you write inline styles or inline scripts, use the “csp” flag and Vulcanize will extract them to separate files.

grunt.initConfig({ vulcanize: { options: { csp: true, ... }, files: { 'out.html': 'comps/**.html' }, }, });

Content Security Policy

Server-side Rendering

• No story at all for Web Components/Polymer• If we can get away with it, we’d rather eliminate the Python

code path for templates/rendering• What is the impact on

• Page load times?• SEO?

Nice to havePage Load Performance

• Not critical, but don’t want to regress more than 10-20%.• The median user has < 2 page refreshes per visit. Almost

every interaction is a pushState.• Indirectly affects SEO (speed is a factor in scoring).

ExperimentPage Load Performance

• Control: Render the initial content sever-side in Python and send it as HTML in the page load

• Treatment: Serve meta tags and correct HTTP response codes, but render all of the visible content in JS.

• Measure using Web Page Test’s SpeedIndex - a measure of how early the final pixels are painted. Lower is better.

• An explanation of SpeedIndex

Page Load Performance

Server-rendered JS-rendered Difference

First View 5073 5236 3%

Repeat View 2571 3114 20%

SpeedIndex, San Jose, DSL, Chrome

Page Load Performance

A pleasant surprise!

Important to not regressSEO

• Web doesn’t have the most active users of all the Pinterest client apps.

• Web is the largest source of acquisition.

Organic search traffic by sourceSEO

In practice, we are targeting Google crawler.

Does Google’s crawler understand JS?SEO

Historically: “No”

May 23, 2014:“we decided to try to (better) understand pages by executing JavaScript”

-Google

A/B test JS-rendered pageSEO

• 10% of “Board” pages will render all of their components client-side

• Takes Google roughly 1 week to re-index all content and for us to see the true impact

SEO

5% decline in traffic vs. control group after only 1.5 days

“Fetch as Google”SEO

• A tool in Google Webmaster Tools that shows what the crawler sees.

Rendering pages with Fetch as Google post

• Crawler is seeing some client-rendered components. (yay!)

• Content area of the page was blank. (boo)

• An XHRs was needed to render the content, but the crawler blocked it. Eliminate the need for the XHR.

Next experimentSEO

• Inline the data into the page to eliminate the XHR.

SEO

But I’m optimistic!

Shadow DOMDOM Encapsulation

It’s a heroic (crazy?) effort to make this work as a polyfill.Overrides• 20 methods on HTMLElement• 44 methods on Document• 69 element contructors

Shadow DOM, continuedDOM Encapsulation

Quirks• document, window, document.body, document.head

can’t be wrapped by the polyfill, and you need to manually wrap:• wrap(document.body)

• Console shortcuts to grab elements return the unwrapped element and need to be wrapped.• wrap($0)

Shadow CSSStyle Encapsulation

A style shimmer: re-writes CSS text with a bunch of regexes

Shadow CSS - what worksStyle Encapsulation

• Replace :host with element selector• Add upper-bound encapsulation by prepending element

selector

Easy with a CSS preprocessor tooStyle Encapsulation

Shadow CSS - limitationsStyle Encapsulation

“For browsers that lack native support, Polymer’s polyfills attempt to shim some of the scoping behavior.”

-Polyfill Details

Chrome 38 (native) Firefox 32 (polyfill)

Shadow CSS - limitations galoreStyle Encapsulation

Can’t polyfill lower-bound encapsulation• Platform.ShadowCSS.strictStyling = true;• Requires that you add custom element’s name as an attribute

on all DOM nodes in the shadowRoot e.g. <span x-foo> • Nobody is going to do that without a build step, so why bother

polyfilling this at all?

Unless you like testing in different browsers

• Force the Shadow DOM polyfill to be enabled.

Shadow DOMShadow CSS

Polymer-stated supportBrowser Compatibility

IE < 10 is hopelessSafari < 6 is hopeless

https://www.polymer-project.org/resources/compatibility.html

Pinterest browsers by visitorBrowser Compatibility

5.05%+ of visitors incompatible

Pinterest browsers by visitorBrowser Compatibility

5.05%+ of visitors incompatible9.25%+

AnecdotesBrowser Compatibility

• Android Browser 4.1 and 4.3 not working with any of the demos

AnecdotesBrowser Compatibility

• Chrome 37 crashes frequently with dev tools open making tweaks to the Polymer tutorial

• iOS8 was broken well after the GM shipped and didn’t work until just before public launch

Anecdotes - IE10Browser Compat

• the renderer process locks up on an unpatched IE10 (e.g. modern.ie image that has updates turned off)

Anecdotes - IE10Browser Compat

10.0.10 10.0.20

Anecdotes - IE10Browser Compat

• Can’t tell how many users this might impact because build # isn’t in the UA string.

Browser Compatibility

Background Learnings Conclusion TODO

Conclusion

Migrate GraduallyWorks with Existing Tooling

Content Security PolicyPage Load Performance

SEOShadow DOMShadow CSS

Browser Compatibility

Polymer architecture

Polymer.js

• TemplateBinding• syntactic sugar

(polymer-element tag, on-*event* attribute binding)

• tooling (Vulcanize, Polymer Designer)

core-elements

paper-elements

Platform.js

“Prollyfills”• ShadowDOM• HTMLImports• Custom Elements• MutationObserver• Object.observe

• menus• drawers• panels• animation

framework

Background Learnings Conclusion TODO

Next Steps

• SEO• eliminate the XHR, reset the experiment

• Browser compatibility• try to measure impact on IE10• Pieces of platform.js that work on more browsers (Custom

Elements?)• Finish evaluating other framework options

engineering.pinterest.com@chrisdanford

top related