Building UI at Enterprise Scale with Web Components (Polymer Summit 2017)


[MUSIC PLAYING] ALEXANDER ZOGHEB: Hey,
how’s it going, folks? My name is Alex Zogheb. And for the last
eight years, I’ve been working with EA as
a Technical Director. And I’m here today to share
a story of how Web Components and Polymer has
really facilitated a monumental transformation
of web at EA. From the dark ages of
building one-off pages and transient sites
to the blissful world of reusable components and rich,
engaging player experiences. So before we dig in, I’d
like to set the stage briefly about EA’s place in the world. We are a gaming company that
is driven by our core purpose and values to inspire the world
to play and to be the world’s greatest games company. We deliver on this
purpose by being organized into this concept of studios,
such as BioWare, DICE, and EA Sports to name a few. These 22 studios are comprised
of approximately 10,000 people in 30 locations worldwide. Each studio has one
or more franchises. And a franchise is kind
of like a movie series. Each game in a
franchise is usually a bit of a different story,
characters, et cetera, but generally follows some
consistent thematic elements or overall based fiction. Many of you have heard of
franchises such as “Dragon Age,” “Mass Effect.” “Battlefield,” and “FIFA.” EA’s player-facing web
is managed and delivered for the most part in
a centralized model by about the 100 person team
that I work with, Pulse. Through this
centralization model, we can achieve efficiency
through economy of scale in our efforts,
and overall, just ensure an engaging and
consistent experience across that diverse
EA ecosystem. This means that our group must
meet the needs of those 22 studios, totaling over
50 franchises that release 20 plus games to
our players every year. So today, I’d like to
go over three topics. First, our journey
and decision-making, the process of kind of how we
ended up with Web Components and Polymer. Second, an overview of the
design system and component library we’ve created
over the last two years. And last, some highlights of how
we’ve been applying this design system and how it’s been a huge
win for EA and our players. So let’s start with
the story of how we landed with Web Components. So we need to go back about
2 and 1/2 years, so basically a decade in front-end
world, to February 2015 when we really started our
journey with Web Components and Polymer. EA’s approach to web was
very different back then. We embodied Conway’s
law to the fullest in how we delivered our
disjointed web ecosystem. And for the most part, we
designed and developed EA’s web more like an internal agency,
one project, one site at a time. This siloed and
disjointed web was really a sad place for our
players, and equally, a sad place for our designers
and developers, too. We were spending 80% of
our time on commodity web, such as navigation, footers,
news articles, media galleries, video player,
pre-order and buy page, leaving only a fraction of
our time to innovate, excite, and engage our
players with custom game-specific experiences. So naturally, in the world
we wanted to live in, we would flip this
allocation of time and focus around and spend
the majority of our time on the fun, engaging
stuff instead. So we started really thinking
and talking about, OK, how do we go from this 80/20
bad to this 80/20 good? And voila, the Network Design
System project was born. Project name aside,
this was really about applying well-known
concepts of a design system, a pattern library, or a
UI framework to how we did web. The idea was that by having
all of our team members, from product managers to
designers to developers to QA, embracing the
complexity of the web with a component-based
approach, we could drive efficiency and make
our commodity core web features turnkey. But before we started
to hit the keyboard, we took an introspective
look at ourselves. What other requirements,
needs, wants did we have beyond those of a
standard component-based design system? What special challenges did
our context bring to the table? In the end, our
special needs and wants for the NDS distilled
down to these four items. Number one, to facilitate
deep theming capabilities, to work with any language
and any framework, to support our
micro-site architecture, and to deliver user
interface as a service. So let’s look at these
each in more detail, starting with facilitating
deep theming capabilities. Now, ideally, we would have
a solution that worked with our entire spectrum of
branding and theming needs, from one extreme
being the broad, out-of-the-box kind of EA
corporate brand to the opposing extreme being one that is
heavily themed in a very focused and specific
manner for a single game. And in some cases, meeting
the very stringent style guide requirements and
approvals from a licensor, such as the cases with Lucasfilm
for the “Star Wars” franchise. OK, number two, let’s talk about
our desire for the solution to be language and
framework agnostic. Recall, this is
early 2015 still. And our group at that
time was the result of several internal team
mergers and reshuffles. And as an outcome,
we had a plethora of technologies,
languages, and paradigms in play, from frameworks
and libraries, such as Drupal, Symfony,
Grails, Spring, Angular, Drop Wizard, and even jQuery, to
languages, including PHP, Java, and Groovy, and content
management systems, such as Adobe Experience
Manager, Vignette, and Alfresco. We had technology divergence. So unsure where we would end up
with our stack in the future, we didn’t want to get
locked in with any one particular back-end or front-end
framework and language. This must work for the
unknown future us as well as the rest of EA. So all right, number three,
our micro-site architecture. We had, and to some
extent still have, many discrete web applications
that have their own lifecycle, teams, budgets, et cetera,
but are assembled together to be perceived as one single
cohesive player experience. What this means is that
some design elements, such as global navigation,
responsive UI breakpoints and grid, log-in
flow, pre-order page, need to be centrally controlled
and consistent across all of our sites, whilst
other design elements can be more customized
for each site. OK, last up, number four,
user interface as a service. So given this
micro-site architecture, how do we avoid projects that
aren’t being actively developed from falling behind
and getting out of sync with the rest
of the EA ecosystem? How do we keep all
the projects pointing to the latest version
of this design system with minimal effort? By delivering our UI
conceptually as a live service, we hope to address these issues
and really embody the mindset of leave no site behind. OK, so given our goals to build
this component-based network design system, coupled with
our four special needs, where do we start? I mean, what’s the approach– the architecture, the
systems, the tech, the tools? I mean, there’s a
lot of questions. So just like the
purple patterned states and like any developer
should be, I am lazy. There’s so much out there. And there’s so many people
to learn and leverage from. So we began reading,
listening, experimenting with, and consuming anything and
everything we could possibly get our eyeballs, ears,
and hands on in regards to the topic of style guides,
design systems, and UI frameworks. Serendipitously, a new
podcast from styleguides.io was out and posting fresh
episodes on this topic right around the time of early 2015. What a bonus. So I’d like to talk about
three particular paradigms and systems that were
quite inspirational and key to our path to Web Components– Bootstrap and sort of
friends, Lonely Planet, and the government of the UK. Starting with the ever popular
Bootstrap, and more generally, UI frameworks that follow
this same approach. So here’s a simplified
example of what integration of a Bootstrap-like
component library might look like. You include a pre-bundled
CSS and JavaScript file from some CDM location. And off you go using the
components the system provides. Seems easy. Seems awesome. Seems good, right? So let’s use this pagination
component as an example. It’s a good one, because
it has some reason to be complex UI, different
states, some brains inside. And it really needs to interact
with other components in code to actually do something
that’s meaningful. So let’s see how we
integrate this component. We start by going
to the documentation for the paginater, find
the sample HTML snippet. Then we copy and paste
this large chunk of code into our application. OK. Now, it’s obviously
not good from a reusability and
upgradability standpoint, as we have essentially
forked this chunk of code. And we’ll now need to
manually merge those updates as they come along. Additionally, there’s
little to no encapsulation. All of the internal structure
and all of the style are exposed to me
as an integrator. I mean, what really
is the public API? Is it all of it? So we’re not done. We still need to hook up some
behavior now to this pager by means of JavaScript. And this is generally completed
by grabbing a reference to the root element
of the component and passing it to some factory
or constructor as shown here. OK, so the Bootstrap model
shows us one way to do it. Let’s move on to Lonely
Planet and see their approach. Much like us, Lonely Planet
had a micro-site architecture comprised of many sites, each
with their own stack and team around them, that
need to work together to provide a single
cohesive user experience. Their initial approach
was to create a shared UI layer following the
Bootstrap-like model we just explored. And in this diagram
taken out of a talk by Ian Feather of
Lonely Planet, you can see the two core problems
around risk and reuse depicted. The shared layer
has the most reuse. But as changes here can affect
all the applications that use it, risk is high when
making modifications, especially without a clear API boundary. Due to this lack
of API, you really don’t know what people are
doing with your component. So over time,
engineers naturally will shy away from
making changes and doing things in the shared
layer, because they’re afraid of breaking stuff. So the shared layer
shrinks and atrophies while the site-specific
layers grow, basically the anti-vision of
any shared component UI system. So what Lonely Planet did with
their design system dubbed Rizzo was move away from
the copy paste approach by encapsulating each component
into a Ruby on Rails helper that took two parameters– one being the name
of the component and the second parameter being
the clean and minimal set of data that that
component needed to render. This is much, much better. So by implementing this
component layer and API between the shared layer
and the specific sites, they’re able to reduce or remove
the risk of making changes to those components, as well as
really ease overall integration efforts significantly. So the Lonely
Planet folks really plus-oned the Bootstrap model
with their Rizzo system. Naturally, this is my face
after coming across Rizzo, so excited, and essentially,
ready to lock in and go with this approach. But not so fast. Some time after Rizzo had been
humming along in production, Ian Feather put up a blog post
titled “What We Would Change About Rizzo.” First, the solution was tied
very tightly to Ruby on Rails and ERB templates, and hence
was not portable or usable by applications that
employed different languages or frameworks. He hypothesized about
using mustache templates or similar to sort of
mitigate that issue. Second, all of that CSS,
HTML, JavaScript, and Ruby that made up Rizzo was
bundled and integrated into each site via a Ruby Gem. So each update to
Rizzo meant you had to go through a
dependency update, build, test, and
release cycle to each of their 10-plus
integrating sites. OK, so Lonely Planet’s Rizzo was
an excellent overall approach, clean API data-driven
components. But before we move on,
being Canadian and all, we figured it would be a good
idea to check in with the Queen over at the
government of the UK. Inspired by the Lonely
Planet approach, Edd Sowden, working with
the government of the UK, really wanted to resolve that
issue of the effort and cost of propagating those changes
from the component UI layer into those integrating sites. So building on the
core approach of Rizzo, they added the concept
of a template resolver, whereas all those ERB templates
were moved out of the gem out to some shared
network location. And then they’re lazy
loaded from this location and cached locally for
a short period of time. This, combined with pre-bundling
the CSS and JavaScript onto that CDM location,
allowed for changes to be propagated with minimal
effort to all of their apps. As you can see, the Gov UK folks
really took the already awesome Lonely Planet approach
and plus-oned it big time with the addition of
that template resolver. Now, we got quite excited
about this approach. It really felt like a
viable option for us to start heading down. But before we dove
in too deep, we went back to our
four special needs just to make sure and see
how things measure up. So number one– deep
theming capabilities. Now, reminder, this
is still early 2015. So CSS custom properties were
only available in about 10% of user’s browsers. OK, so I’m not sure how
we can do this exactly. I guess we can
figure something out. Perhaps, each site can
build their own CSS override file that just has
the CSS rule sets that need to be modified to
theme those components. OK, but what happens
when we refactor some CSS or we introduce a new component? I guess we’ll need to
rebuild those override files. OK, well, I mean, we’ve
got some tools to build. I’ve got a process to
document, some people to train. All right, number
two, let’s see– working with any
language, any framework. Well, I mean, we could
just use mustache templates coupled with the same UK
template resolver approach. That would do the trick. We just need to build
client libraries now for every language
that we need to support. OK, so that’s like PHP, Java,
JavaScript, I mean, at minimum. And then ideally, we’d have
first class integration into the front-end back-end
frameworks that we might use. So let’s see, that’s at
least four frameworks. Oh, boy. Now, there’s already a lot
of open questions, plumbing, and miscellaneous pieces to
worry about here already. Now, remember, I am
a lazy developer. I don’t want to write
and maintain code if I don’t have to. I really wish that there was
just an off-the-shelf solution that I could just
grab, read some docs, gives me everything I need in
one nice, cohesive package. OK, so back to
the drawing board. What else? What else? What else? I mean, we have designs
for all our components now. We need to start getting on
some code, like, really soon. So I remember this
hipster tech that was brewing for what
feels like years now, sounds cool on paper. Web Components and Google
Polymer, I think it was. Oh, yeah. That’s right. I remember. There was talk at
Google I/O in 2013. Oh, yes. Now, I remember– a fun looking
toy, terrible performance due to some nasty invasive DOM
polyfills, basically Chrome only. I mean, like, way too
hipster for this job. I mean, this is all of EA’s
web hinging on this decision. I need a solution that is ready
for production at EA’s scale, like today. But wait, what is this? Polymer 1.0 just
released, like, now. Production-ready web components. Really? All right, sounds
good on first glance– backed by Google,
focused around components and not full-blown applications. All right, all right,
chill out, Alex. Back to our special
needs, first. And let’s see how
things measure up. So number one– OK, deep
theming capabilities. Well, we get theming right out
of the box using CSS custom properties and mix-ins with
a shim that works everywhere. Cool. We can theme these
components at runtime, too. No build step necessary–
that’s pretty awesome. All right, number two– working with any
language, any framework. Well, I mean, it’s really
just an HTML element at the end of the day, an
almost standard DOM interface. So hypothetically,
anybody or anything that can put an HTML
tag into a document could technically use our
components built with Polymer. Oh, and all the CSS,
HTML, and JavaScript is bundled up together
into an HTML import for client-side
inclusion, so no tie-in to any specific back-end or
front-end language or framework needed. Awesome. This is sounding really good. All right, number three– support our micro-site
architecture. Well, it seems that we can
control the API however we want on a per component basis. So that should work well. And last up– user
interface as a service. Well, it’s just
client-side integration. HDMI import seems
like it has some of the basic working
pieces to make this happen. So yeah, this is
looking really good. So my mind is blown
at this point– an off-the-shelf solution
that meets all of our special needs and lots more,
tooling, docs, et cetera. Less code for my team to
write makes me very happy. And bonus is that most of
the gnarly parts of Polymer are promised to be native web
platform primitives sometime soon, too. I mean, a frameworks
roadmap that states that it wants to get
smaller, do less over time, and eventually may not
even need to exist? I mean, that’s amazing. So with Polymer, this
hipster web components thing just became our top contender. So compared with the already
awesome approaches of Lonely Planet and the
government of the UK, Web Components and Polymer
1.0 was like a plus 100. So in September of 2015,
we decided to officially lock in with Web
Components and Polymer as the core technology for
the Network Design System. Now, let’s fast
forward two years later down our journey with
Web Components, Polymer, and the NDS. What did we end up building? How did our four special
needs hold up in real life? Did Web Components
and Polymer meet my mind-blown expectations? I’m pleased to say that we have
approximately 75 components that are arranged into one of
six component families, which are just logical
groupings of components based on their purpose. Let’s look at a few
examples, starting with our most commonly
used component, our call to action
or button component. You know, it’s
quite polymorphic. And it supports different types
for text, text with icons, images, and so on. And this component also comes
with Google Analytics Tracking out of the box, ensuring that
every button on every site sends consistent
and meaningful data. Next up is our
pagination component, something with quite a bit more
logic and state than a button. To me, this paginater
really showcases the power of Web Components. All of that complex
structure, style, and behavior are nicely encapsulated away
behind this minimal, clean, declarative, and imperative API. In this example, we
just simply listen to that page change
event and do what we need to do with the data. We also have some very
high level components that are almost like
encapsulated in mini applications all on their own. This Newsletter Signup
has various states for anonymous users,
authenticated user, already signed up, as well as it
provides a multi-step flow complete with error handling,
localization, and integration with a few external
service APIs. All right, so now with that
sample of components in mind, let’s review our
special needs again and see how we’ve applied Web
Components and Polymer to bring these to fruition,
starting with facilitating that broad spectrum
of brand specificity and fidelity that we needed. Now, we have about 300
CSS custom properties that are set at the system-wide
level that are there to mostly control color and typography. We love that even back in 2015,
when CSS custom properties were not widely available, the shim
that came with Polymer 1.0 allowed us to use this powerful
tool to theme dynamically at runtime with no
build necessary. In fact, we now
control these primarily through our content
management system. So a designer and a product
manager can spin up a site and theme it without
any developers involved. We also have many
CSS custom properties that are used as
internal design tokens and are really
there just to keep things dry from a
development standpoint. But they should not really
ever be exposed or altered by our integrators in any way. And so these are rules such as
our responsive grid, gutter, and column widths. So what we do is that at
build time using post-CSS, we substitute and compile
in these static values for these design tokens, making
them essentially immutable and leaving only the themable
CSS custom properties exposed. So this is our tile
or our card component. And it’s used in
most places where we have a list of
items to display, such as a news article,
videos, characters, or weapons. And although CSS
custom properties are great for granular
CSS level control, using HTML attributes as
another way to theme and control a component has deemed
to be very powerful. The example that illustrates
this well is the type attribute on this tile that
has two possible values, horizontal and vertical. Using the host
pseudo-selector, we can have that single
HTML attribute impact the entire
presentation of the component, from placement and size of
the media asset to margins and padding to different
layouts completely, at mobile versus desktop, all
by letting CSS and the browser do all the hard work. No imperative JavaScript needed. So just by using
those system-wide, themable CSS custom properties
and the per component HTML attributes, we can
deliver all four of these tiles using the
exact same component, all themed at runtime to boot. OK, number two–
let’s talk about how the need to be language and
framework agnostic has gone. Here’s a very simplified view
of our overall stack today. We have Adobe
Experience Manager. That’s our CMS in the back-end,
Lightbend’s Play Framework as our middleware,
and of course, Polymer in the front-end. Now, we have taken
the approach that when we think about a
component, we think about how it manifests
across this entire stack, not just in the
front-end, ensuring that we can drag and drop
a component onto a page in the CMS, pull that
component into the middleware, and serve out the custom element
for Polymer to then render. So for our stack, each component
has first class integration top to bottom in this
example of a button. But this does not
mean that integrators must use our full stack to
get the benefit of the Network Design System. As each layer of the
stack is loosely coupled and has clear API
boundaries, it’s really easy to just use that front-end
Polymer component all on its own. No gem. No template service,
client library, just a simple HTML import. OK, so number three– our micro-site architecture. So recall that some
components need to be centrally
controlled and consistent, whilst others can be
more customizable. Web Components and Polymer
makes this really easy, as we get to control how
narrow or how broad the API is on a per component basis. Components that we really
need to be nearly 100% consistent across all sites,
we just simply severely restrict the API
into that component. And others that are meant
to be super flexible have all sorts of
knobs and switches in the form of CSS
custom properties, HTML attributes, and use
of slot-based composition. So our pre-order, buy
widget, newsletter signup, footer, network navigation are
all examples of where we really keep that API minimal. OK, last up, number four– user interface as a service. Now, we apply SemVer
very, very diligently, being super careful to keep
the NDS backwards and forwards compatible, with a
strong focus on not bumping our major version
number for as long as possible, sticking to backwards
compatible changes resulting in minor version bumps only. So this mindset has
worked really well, as we are currently
at version 1.31.0. And in practice, we could update
a site from 1.2.0 to 1.31.0 without any code
changes or issues. Currently, we deploy a
pre-built version of the NDS to a CDM location using a
naming convention as shown here. So this gives the URL meaning
as to the version, the artifact type, and the artifact
that’s being referenced. By supporting fuzzy version mask
on the major release version means that the sites can
ask for a 1.*, a 1.x, and get back a 302 that actually
redirects them to the latest 1.x release, which as it is a
tagged and unchanging artifact, is sent back with a very
aggressive caching policy. So as you can see,
our special needs have come to fruition thanks
to Web Components and Polymer. Now, I’d like to briefly
cover a few more wins and show off some of our sites. So as mentioned, we have 75
components in production. They’re now powering
about 30 sites in total. And that number is
growing rapidly every day. On the left is ea.com corporate
site using the out-of-the-box default theme. And on the right is the more
heavily styled “Titanfall 2” site, but both using the same
NDS version and the same HTML import. And here are a couple more
with “Mass Effect” on the left, and on the right, an upcoming
new franchise from BioWare, “Anthem.” And we have gone from a previous
tedious and lengthy process to bring up a site to
now only taking about 1 and 1/2 weeks of content-only. That means no
development effort. So component-type
thinking is really just how we operate across
all functions now. We don’t design and
build pages anymore. We are always looking
to decompose and then compose with component-based
building blocks. And as a bonus, to the delight
of our digital intelligence team, we have been very
consistent and complete analytics tracking across
all of our components, allowing us to compare apples to
apples between different sites. And of course, efficiency
and economy of scale. We’ve reduced duplication. We have better
engineering mobility between projects and teams. And with a predictable,
proven, and streamlined system, we have much, much lower project
risk and a far more dependable schedule. So going back to
this original goal of living in a world
of making our commodity web turnkey, low-effort, and
maintainable, how have we done? I would say a resounding
success thanks to Web Components and Polymer. Thank you very much. [APPLAUSE] [MUSIC PLAYING]

Be the first to comment

Leave a Reply

Your email address will not be published.


*