Efficient, Expressive, and Extensible HTML Templates (Polymer Summit 2017)
Key Takeaways
Efficient and expressive HTML templates for dynamic UI updates
Full Transcript
[Music] hello hello so my name is Justin and I work on polymer tools so normally I'd be up here giving you a tools talk but like Matt said I like experiments so right now I'm going to do something a little bit different and talk about or give you a sneak peek on this library we've been working on that we're very very excited about and this is only a 15-minute talk so I'm going to go really really quick so hold on alright so I'm going to talk about templates and obviously we're going to talk about HTML templates and so we're very familiar with those here because templates are pretty central to the polymer developer experience but HTML templates and other techniques for updating Dom have been around for a long time and they're constantly evolving so before I get into this library I'm so excited about I wanted to give you an extremely brief history of HTML templates so in the beginning we had manual Dom manipulation you had to create some nodes individually wire them together in a tree and then maybe hold onto some of these nodes so you could update them later and this is a lot of code it was verbose it was not very fun to write or to look at alternatively you could try to use inner HTML you could build up a string of HTML then you inject it and let the browser take care of creating the nodes but then if you wanted to update it you had to traverse this tree or use query selector or something like that it didn't end up being a lot better so then we have this Cambrian explosion of declarative template systems that embedded expressions inside of them and then control flow constructs like ifs and for loops in polymer belongs to this category here as well with systems like angular or ember and then a few years ago react introduced JFX and V Dom virtual Dom into the world which take a different approach both syntactically and functionally so JSX isn't standard JavaScript syntax it's an extension that embeds markup into JavaScript which is then compiled out with a transformer and virtual Dom took a new approach to updating the Dom instead of pinpointing exactly what data is embedded into the Dom it just goes ahead and rear enters the entire tree the entire template and it does this in a virtual tree and then it compares that to the last data head figures out what changed and it applies those changes to the Dom so with all this evolution of templating solutions what come next something does come next right there's always a next well we have one idea and since its 2017 obviously that means that idea is going to come from es 2015 and that we think is JavaScript tag template literals template literals are one of the most unsung features of es6 or ES 2015 because they're way more powerful than they appear at first they're basically strings but instead of quotes you use backticks and they can span multiple lines and you can also embed JavaScript expressions inside of them too which is great for building up strings from data and this is where people usually stop with template literals but interestingly and very powerfully they can be tagged and a tag is a special function that processes the template literal both the literal and the expression parts and it can return whatever at once it doesn't have to return a string so this is interesting temple literals are actually designed to allow domain-specific languages to be embedded in JavaScript and HTML is a domain-specific language so you can see how these features together let you write something that at least syntactically looks like the HTML templates that we're already familiar with so this seems like a promising direction to explore especially because of our move to JavaScript modules that we announced yesterday polymer templates inside of modules are just strings and when we work with this a little bit we wanted something a little bit better and we really wanted to be able to take advantage of the fact that when we're writing templates in JavaScript we can be right in the JavaScript scope that holds the values that we want to put into the templates in the first place we also wanted to take advantage of the fact that we could use real JavaScript expressions which are going to be as fast as possible the key though was figuring out how to keep updates fast and make minimal updates into the DOM and we're starting to see another a number of other libraries now that use a similar approach including libraries like hyper HTML hyper X Bell and t7 and now I'd like to introduce you to the library that we're so excited about which is called lit HTML now let HTML is still very very experimental in under development but we wanted to give you an idea of what templating in a module only the world might look like so we call it lit because well it uses literals and it's very little and we needed a name in this name was cool so what is that HTML let HTML is a combination of JavaScript template literals the HTML template element and a render function that lets you efficiently render and re render these templates to the Dom let's see what this looks like so let's tml templates are just JavaScript template literals they contain embedded JavaScript expressions and they're tagged with a CH tml HTML tag and then we have a render function which lets you render a template to someplace on the document now on the surface this looks like it we could just be building up an HTML string and using inner HTML to set it on the document but that's not what happened that's not what's happening at all if we were using inner HTML we could just replace the expressions with their values join them together into a string use inner HTML and then we've have our template but this would be very difficult to update because we've lost the locations of the expressions from our template so instead what lay HTML does is it replaces the expressions with these placeholders and it creates a string out of that and then it uses that to create your template and after it's created the template it goes through and it finds the placeholders again and it remembers where they are and we call these things these places where these templates these expressions are our parts and that we remove the placeholders from the template and now we have a template that we can use over and over again to create DOM and because we remembered the locations of these dynamic parts we can replace them with values after we've created that DOM and because we have those locations we can efficiently update them with new values when the values change now here we're probably going to use templates mostly to create shadow Dom for custom elements so what would it look like to combine the HTML with polymer well here's a polymer 3.0 element in a pure JavaScript module and we have an inline template here that's returned from a static method the template method if we convert this tool it you can see that it's very very similar except for then instead of a static method we have an instance method because we want access to that level state and even though this doesn't appear very different the develop the developer experience is actually a lot better because the expressions are real regular JavaScript so now you get all the syntax highlighting linting formatting type checking if you use typescript all those features that you're used to from your tools because it's just JavaScript it's also more powerful because it's just JavaScript you can do arithmetic in expressions you can call functions you can build up templates from parts using if statements and for loops and you don't have to hang everything that you want to access in expressions off the prototype anymore you can just import it or declare it and use it next I want to talk about the three main goals of lit GML first we want to make it efficient because quickly rendering Dom is one of the primary tests in the template system then we want to make it expressive because you should be able to build very interesting templates or with your template system and then finally we want to make it extensible because no template system can build in all the features that you're ever going to need so first let's talk about what makes a little HTML efficient so one of the things that simply literals themselves they have some really nice properties that we take advantage of one is separating static and dynamic content let's look at why this is really important so every HTML template system is responsible for creating a tree of Dom notes but only some of those nodes are ever updated after they're created so tip let's have this structure there's a separation between static and dynamic parts and then you have the updates not every dynamic part changes at once sometimes you update just one value in so when thinking about the cost of templating it's useful to have these two questions in mind how many nodes are updated and what's the cost per node and if we look at something like polymer we notice that polymer has this association directly between the data and the nodes that depend on it and so polymer can scale its cost with a number of changes that you have if you only change one thing polymer only has to do one thing to apply that change and if you look at something like V Dom it takes a very very different approach V Dom rear Enders an entire virtual tree every time any of your data changes so it actually scales with the total number of nodes that you have in a template but they try to make up for this by driving the cost of each node down very very low by using a virtual tree was lit HTML we try to be somewhere in the middle and get the best of both words worlds here we're only going to update the dynamic parts of your template so we don't update every node in the template but we also try to drive that cost down very very low so we can be as fast as possible and this all falls out quite naturally from using template literals because with template literals we know exactly what parts are dynamic and might change and what parts are static and will never change and we don't even have to do any work to figure this out the syntax of JavaScript just does it naturally for us so besides separating static and dynamic sections they also have this property where literals that are passed to a template tag are exactly the same for every call to that tag this lets us do one-time setup work like the HTML template preparation I was talking about let's take a look at example for that so let's say you have a function that takes some data and then puts it into a template so we're going to call this function we're going to say hi to Amy and this function is not going to return Dom this function is going to return a template result it contains the template that we run a render and the values that we want to render into that template and then if we call this function again now we're going to say hi to Alex we get a new template result which contains the template we want to render and the values that we want to render into it well it turns out that these template objects they're not the just the same they're exactly identical so we only have to create it one time the first time we ever see a template from then on every time we call this function all we're doing is passing along the values that came with it and that's very very very cheap so another reason why template literals are great is because parsing strings in JavaScript is extremely fast parsing streams is somewhere between three and four times faster than parsing generic JavaScript JavaScript expressions which is what most HTML nsj solutions use so also we're fast because we try to use the platform as much as possible we use the built-in JavaScript and HTML parsers we don't ship any parsing bits ourselves and we use the template tag for fast deep content cloning of our templates this is the full minimized source code of leyte ml I stole this slide from Jason Miller of pre-act where he did this one time showing pre-act on the slide and I wanted to show that we can put it all in here in 18 point font with room to spare it's less than 1.7 K minified it was conservative and I put less than 2k up there big so it's quite small and this helps us be fast too because it doesn't have to load much data over the network so that's efficiency now what what let's look at what makes it expresses let's take a look at what kinds of values you can hand off to lit so you have simple string values we can say hello from it we also have expressions inside our you can put expressions like imagine you have your showing a page number on a template and your users are probably not computer scientists so they're expecting a1 based index and you have a zero based index that represents your page number you can just add one to that inside the expression so things like this are extremely easy you can also set attributes obviously here we're setting the value attribute of an input element but you can do some more interesting things like you can directly hand knit live HTML Dom nodes so you might have some complicated structure that you want to create and it's easier to do that imperative ly by hand once you do that you can just hand the result off to lint and lint will put it in the right place in the template you don't have to worry about using query selector or some other method of finding that dynamic spot that you want to manage we also support nested templates so you can build up templates by parts and you can share these parts around with different templates here we're injecting a header into a container template and because we support master templates you can build up templates dynamically with logic so if you were going to show different methods to the users based on whether they're logged in or not we support arrays so if you hand an array tool it will just render every item in the array and this becomes extremely powerful when you combine arrays with nested templates so now you can take an array of data map it over a template and you get an array of templates you hand it to lit and lit will efficiently render that to the Dom there's some other interesting value types of a handle like promises so let's say you do a fetch of some content over the network you can just hand that promise to lint and when that promise resolves lit will render the result in your template you don't have to do anything there for it so if you put all this together you can see that we can create some really complex russer templates you can take a string and split it by new lines and generate a paragraph element for every paragraph in the string you can dynamically choose what kind of data what kind of templates you want to render based on the data and it's then at the end you can put this together in a more declarative form because we support that too so we try to give you the spectrum of doing things very dynamically and imperative ly to being able to do things declaratively and very structured alright finally let's look at extensibility there's two ways that you can extend the HTML one is with directives so directive is a function that lets you customize how a value is handled by late 80 ml so I told you about promises where you could give a little promise and when it resolved would render that content well a lot of times you want to render some default content a placeholder the renders until that promise is ready and so that's what this until directive does you give it both a promise and a placeholder it renders the placeholder then it renders the promise when it's ready and I wanted to show you how easy this is to implement so this is the entire implementation of the until directive and a directive is basically a function that gets a part and a part has an API set value as the method it has and so you can just call set value here we call set value with the default content and then you can call set value again when the promise resolves and that's your entire directive right there so it's very easy to extend and customize thank another directive that we bundle is a repeat directive this is very similar to dom repeat and polymer this lets you do efficient list where you can reorder the items in the list so if you change the order of the list and then give it back to lit it can track what data went to what dom node and then just rearrange the dom nodes without having to remember we render your entire list okay another way to customize lit is by using custom parts custom parts let you change how values are handled across an entire template and we've bundled a couple of these together in a library we called lint extended which gives you polymer style sugar on top of text nodes and attributes you get property bindings by default and we have declarative event handlers so for property bindings let's say you have a custom element and it has some property where it's expecting some rich data to be bound into it you can just go ahead and with lit extended use the normal binding syntax and you get a property binding but notice something here notice that capital P up there it turns out that because we're storing the attribute names in JavaScript we can go back and get the case preserving names of the attributes there so now we don't have to do this kabab case to camel case mapping anymore we can just use the real property names and that should eliminate a lot of errors that people accidentally get into sometimes we can also fall back to attributes if we need to by using the dollar sign suffix just like polymer and we support declarative event handlers this looks like polymer because we have the on - prefix but it's a little bit different because we actually take a function value into the binding expression and so you can write in line handlers like this or you can just reference a method on your on your custom element okay and that's what makes it extensible and that's basically all over HTML the next question is where to now like matt said this is currently a bit of an experiment so we have a lot of testing and optimization and benchmarks to do to make it real but from what we've already done we know that litt is very fast and that it works great on the modern browsers and then we want to write a mixin for polymer so that you can use this together with your polymer base classes and then finally we want to add tooling support so you can get syntax highlighting code completion hover over documentation all the features that we give you in our polymer IDE plugins so if you want to follow along there's a github repository at some polymer labs lit that HTML and you can already install this from NPM I'm going to push a new version this afternoon and you can just npm install that HTML and if you follow me on Twitter I'll be talking about this as I develop it alright thank you very much [Applause] [Music] you [Music]
Original Description
One of the most rapidly evolving areas in web development is the process of efficiently and dynamically updating the UI. From jQuery to VDOM to custom compilers, there’s been a ton of innovation. In this video, Justin Fagnani-Bell, a software engineer at Google, discusses an idea about what may come next.
Check out the rest of the Polymer Summit session videos here: https://goo.gl/KuiAXd
Subscribe to the Google Chrome Developers channel: http://goo.gl/LLLNvf
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from Chrome for Developers · Chrome for Developers · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
Polymer Performance Patterns (The Polymer Summit 2015)
Chrome for Developers
Polymer Power Tools (The Polymer Summit 2015)
Chrome for Developers
Chrome Dev Summit 2014 – Chrome Case Studies
Chrome for Developers
Web Directions Code 2015 round up
Chrome for Developers
Maintainable Code - HTTP203
Chrome for Developers
iron-ajax… wat?! -- Polycasts #26
Chrome for Developers
The Guardian - Supercharged
Chrome for Developers
ES2015 (next version of JavaScript), Totally Tooling Tips (S2 Ep1)
Chrome for Developers
#AskPolymer: Rob answers all the questions ever -- Polycasts #27
Chrome for Developers
The Future of JavaScript - HTTP203
Chrome for Developers
Data Binding 101 -- Polycasts #28
Chrome for Developers
The Guardian part 2 - Supercharged
Chrome for Developers
The Future of Web Audio: with Chris Wilson and Chris Lowis
Chrome for Developers
Chrome 46: New motion-path animations, client hints and service worker improvements
Chrome for Developers
Sublime Snippets, Totally Tooling Tips (S2 Ep2)
Chrome for Developers
#AskPolymer: How do you make the show? -- Polycasts #29
Chrome for Developers
Critical Path CSS, Totally Tooling Tips (S2 Mini Tip #1)
Chrome for Developers
Binding to Objects -- Polycasts #30
Chrome for Developers
Player FM - Supercharged
Chrome for Developers
Where’s the Designer? #AskPolymer -- Polycasts #31
Chrome for Developers
Jake Beats Wikipedia - HTTP203
Chrome for Developers
Supercharged Observers! -- Polycasts #32
Chrome for Developers
Jai's Web blog - Supercharged
Chrome for Developers
Windows Command-line Tooling, Totally Tooling Tips (S2, Ep4)
Chrome for Developers
What about internationalization? #AskPolymer -- Polycasts #33
Chrome for Developers
Developing for Billions (Chrome Dev Summit 2015)
Chrome for Developers
Google+ Performance Improvement Comparison
Chrome for Developers
Deploying HTTPS: The Green Lock and Beyond (Chrome Dev Summit 2015)
Chrome for Developers
Progressive Web Apps (Chrome Dev Summit 2015)
Chrome for Developers
Instant Loading with Service Workers (Chrome Dev Summit 2015)
Chrome for Developers
Increase Engagement with Web Push Notifications (Chrome Dev Summit 2015)
Chrome for Developers
Engaging with the Real World: Web Bluetooth and Physical Web (Chrome Dev Summit 2015)
Chrome for Developers
Asking for Permission: respectful, opinionated UI (Chrome Dev Summit 2015)
Chrome for Developers
Polymer - State of the Union (Chrome Dev Summit 2015)
Chrome for Developers
Building Progressive Web Apps with Polymer (Chrome Dev Summit 2015)
Chrome for Developers
Introduction to RAIL (Chrome Dev Summit 2015)
Chrome for Developers
DevTools in 2015: Authoring to the max (Chrome Dev Summit 2015)
Chrome for Developers
RAIL in the real world (Chrome Dev Summit 2015)
Chrome for Developers
#ChromeDevSummit talks are up - W00T! -- Polycast #34
Chrome for Developers
V8 Performance from the Driver's Seat (Chrome Dev Summit 2015)
Chrome for Developers
Quantify and improve real-world RAIL (Chrome Dev Summit 2015)
Chrome for Developers
Owning your performance: RAIL (Chrome Dev Summit 2015)
Chrome for Developers
HTTP/2 101 (Chrome Dev Summit 2015)
Chrome for Developers
Leadership Panel (Chrome Dev Summit 2015)
Chrome for Developers
Build Processes, Totally Tooling Tips (S2, Ep 5)
Chrome for Developers
Accessibility (Chrome Dev Summit 2015)
Chrome for Developers
Binding to Arrays -- Polycasts #35
Chrome for Developers
HTTP2 - HTTP203
Chrome for Developers
Chrome 47: Splash Screens, requestIdleCallback and better desktop notifications (New in Chrome)
Chrome for Developers
Call For Submissions - Supercharged
Chrome for Developers
Cross Device Testing, Totally Tooling Tips (S2 Ep6)
Chrome for Developers
Testing AJAX with Web Component Tester -- Polycasts #37
Chrome for Developers
Slack: Extended Xmas Special - Supercharged
Chrome for Developers
Browser testing with Travis & Sauce Labs -- Polycasts #38
Chrome for Developers
Optimize for production with Vulcanize -- Polycasts #39
Chrome for Developers
Highlights from Chrome Dev Summit 2015
Chrome for Developers
Chrome 48: Custom buttons in notifications, DevTools Security panel, and Presentation mode
Chrome for Developers
Crisper: Protecting your Polymer app with CSP -- Polycasts #40
Chrome for Developers
How do I use Sass with Polymer? #AskPolymer -- Polycasts #41
Chrome for Developers
Colors – DevTools Tonight #0 (Pilot)
Chrome for Developers
More on: HTML & CSS
View skill →Related Reads
📰
📰
📰
📰
10 Most Common Mistakes Java Developers Make in Interviews
Medium · Programming
# C++ Error Messages Translated — 10 Common Compilation & Link Errors Explained
Dev.to · Yilong Wu
# Picking What to Read Next: The Trade-offs of Ranked-Choice Voting in a Django App
Medium · Python
The Ultimate Rust ORM Comparison 2026: Diesel vs SQLx vs SeaORM vs Rusqlite — Pick Your Powerhouse!
Medium · Programming
🎓
Tutor Explanation
DeepCamp AI