Weak JavaScript - HTTP 203

Chrome for Developers · Intermediate ·📰 AI News & Updates ·5y ago

Key Takeaways

This video teaches WeakMap, WeakSet, and WeakRefs in JavaScript

Full Transcript

so it's my turn to tell you about something new in javascript land or and the web land actually and um kind of proposal had we started by the way i thought so oh sorry i i realized that but you were still just like oh might just start soon [Music] so so we're we're trying this once more another episode like ah here we are again i'm having to talk to jake and this time i have to present something come on be a mature this is this is youtube you know people don't watch it for more than five minutes unless you're like oh my god this is the most amazing thing that's ever happened to javascript this is gonna be incredible you know you're gonna learn so much in this episode you're going to come away with your brain to be like three times the size it was it's just it's this is going to be the best part of your day if not isn't yours and how you die if your brain grows to three times the original size i think i think you die i think the idea is the skull would have to uh also inflate oh so you look like brain from pinky in the brain yes shall we now we need to put a disclaimer on the show might make your skull grow if you watch too much of this seriously that's the new tagline for the show http 203 might break your skull great so i i found a new javascript thing that intrigued me um mostly in my role as the the maintainer of comlink where you know values in workers and main thread they pretend to be in both places but they're actually not and then you know you get into garbage collection issues because things that you share will never get garbage collected because you know they're being shared there's been references being held and so i have learned more about this new proposal that is now shipped to chrome stable which is weak refs and i thought you know what let's make a little episode about all this weak stuff that javascript has anyway oh so we're not just covering weak references this is going to be the well we have a short intro bit about what's been there so far and why it is the way it is because there are some weird rough edges well stop teasing me and just give me the information let's let's do it shall we okay so i thought we start with what actually is a week reference because it's been thrown around a lot and just want to make sure everybody knows what we're talking about really what it means is whenever you have an object and you save quote unquote say the object and variable that variable is a strong reference to that object and as long as there's any variable in your code that you know has this object this object will not get garbage collected because that would be bad if the stuff you have in variables suddenly disappeared now a weak reference is the kind of reference that doesn't prevent garbage collection so if there was a way to have a variable being a weak reference to an object if there is no references to an object or only weak references basically no strong references that object is free to get garbage collected at any point in time and you might see your value actually disappear okay so so weak reference is kind of like like if if your weak reference is actually pointing to the object then that's your way of you you kind of know there's probably something else that's using this right now maybe you basically know that it has not been garbage collected yet that's pretty much as much you can deduce from that um and there's already one little difference that you mentioned there because just because you give up all strong references to an object doesn't necessarily imply that it will be immediately garbage collected so a weak reference could theoretically still give you an object even though there is no strong references to it anymore and that's a detail that we're going to get more into a little bit later because that's it it's an important distinction to make it was i i heard that because i um i'm glad you're doing this talk because i did read the article on weak references and i came away still being quite confused um and it was some of the uncertainty that was a bit like i don't know this uncertainty sounds bad um it so we're going to have a lot of that because basically we have had week two two week data types in javascript for actually quite a while and those are the weak map and the weak set and some might be surprised that these are fairly old they were in ie11 so they've been around for a long time yes and what these two do is basically in the weak map the key is weak meaning you can only get to the value when you have the key but the key itself is not prevented from being garbage collected just by the fact that it's being used in the map so if you know if you use a dom node as the key in the weak map um and don't save this dom node anywhere else if it gets garbage collected your key and your value can disappear from that map and that can be incredibly helpful i often get see questions on twitter sometimes working at me some others what the use cases for weak map and weak set are and so one of the primary uses for me is that for the longest time in javascript uh expand those as they're called have been fairly common you just take an object and you throw new properties on it like you put just an underscore my stuff and put your stuff in there and you know that's javascript it works but one of the downsides is that it's bad etiquette basically to transform objects that you don't own also because that can cause the javascript runtime to de-optimize because you're changing the shape as a call of an object and so generated binary code might not work anymore and they would have to regenerate it and so mutating objects you don't own is often a bad practice and there's an ownership issue here as well isn't that because now anything else that gets that profile node can see that internal data uh yeah because it's not really private and you can never be 100 sure that you're not creating a name clash maybe in this case you know some library code actually does use underscore internal who knows and so what you should be doing instead is you create a weak map so in this case we're getting something from the dom and instead of putting something on the dom node itself we use the dom node as a key in our weak map and put our extra data into the value of the weak map and that means as long as the download exists the value will continue to exist but when the dom node gets garbage collected so will the value and that's really useful and for a weak set it's basically for the use case whenever you find yourself doing a weak map where you store true in the value that's like by for example where you just want to remember have you visited a certain object have you already seen it have it hasn't already been processed those kind of things that's where a weak set comes in um however and that is something that trips some people up or raises question marks at least is that neither of these are iterable you cannot iterate over the keys in the weak map you cannot iterate over the entries in a weak set weak stuff in general was never iterable and that kind of comes from the fact that one of the fundamental principles i think by the w3c was you should never expose garbage collection and the reason for it is actually from security because exposing garbage collection is what is what i learned when i researched this is called a covert channel because now two pieces of javascript can communicate without ever knowing really of each other's existence you can think about a little bit that if you bundle two libraries um and you pass you know just an object from one library to another now the one library might be able to track when the other library stops using that and that could actually if those two libraries do it in coordination you can communicate a lot through that without ever accessing each other's data um and that's i mean we if you think about cookies that's how tracking happens and i think something like this could be expected the same way and so they never wanted to open this can of worms basically however over time there were more and more demands and use cases for actual weak references and exposing garbage collection and so over time they spent a lot of design work and collaboration between the engine authors to figure out how they can make this happen without making this covert channel an actual problem and so the wheatgrass proposal was born before we move on to that like one of the like this model with weak sets and weak references where you can't iterate on the keys that in some ways it almost makes more sense to me because like it's that idea of like you you can only open the door with a key right and and if you lose the key you can no longer open the door um the the equivalence here with like because we don't just have weak map and weak set there's also map and sets which can iterate and that seems like a kind of model where i've lost my keys ah i better go and ask the door for them back you know which fair it would be problematic in general wouldn't it so that yeah let's let's not let real doors be inspired by computer science in maps that no i don't think that's a good idea so yeah so this is where we now can talk about we graph this is marked as advanced because it can be fairly hard to reason about the second garbage collection is involved it becomes undeterministic unpredictable but also because whenever you use it think really really hard if there isn't a way you can solve the problem without it because this will be likely to introduce more bugs than it fixes because it is a fairly hand wavy spec almost and we'll talk about that a bit more um well garbage collection happens isn't specked at all isn't spec and that's one of the other underlying problems for this entire thing in fact someone even said to me i was like well javascript engines are not required to garbage collect like inspectors we'll get to that because that's oh actually basically we have regress now and in the end they do violate the principle of exposing garbage collection they do create that covert channel but they did spend a lot of time in the design to make sure that on the one hand engines are still able to optimize and you know iterate on their internal architecture freely without being constrained by this weak graph existing and also to limit the bandwidth of this covert channel to such an extent that the risks are extremely low to that actually being a real problem what are these actual problems why is this actually such a quote unquote advanced topic well the first problem is that garbage collection is non-obvious or non-deterministic for example if two values become unreachable at the same time like you give up your strong references at the same time that does not mean they will get garbage collect at the same time or and that is also something that you might notice like um it might look like you made something unreachable but it is in fact not because the way that internal data structures work or they like a native data structure to javascript or closures there might still be a reference you're just not aware of and so your reasoning might just be flawed and really hard to figure out where it is going wrong engines will garbage collect differently from each other so something that might work in one browser or when when something gets garbage click in one browser it might not in another it actually might get covered in one previous release of your browser but not in the current one or it might get actually gauging in the first run but not in the second run of the same code on the same website because there's so many factors that the engine incorporates when to run garbage collection that it is inherently unpredictable and this is what i brought up earlier garbage collection and something being unreachable are inherently separate things something being unreachable is a requirement for getting garbage collected but they basically can be an arbitrary and infinitely long time in between most browsers run their garbage collector when they feel like the browser has downtime and only when it's under memory pressure so you know if you're running on a super beefy machine garbage collection might just not happen as a trader for keeping the page for responsive snappy and fast um and so that's just something to really keep in mind also for the rest of the discussion that when we talk about garbage collection we mean we mean the moment in time when a value is being deleted from memory and the memory is being freed up not the point where it's becoming unreachable for your code yeah it's an optimization pass like garbage collection is optimization it was weird when i heard that yet browsers aren't required to garbage collect or javascript engines aren't required to garbage collect because it's like but all the code everywhere would break if they didn't garbage collect it's like well yeah but never mind it is something they all do it's just when uh when they do it and how they do it is completely unspecified yeah and just to give it a separate point it gc will happen late or sometimes not at all that can happen and actually there is a little details to this that this well i will talk about a bit later all right let's look about at the actual weak ref api it is a very very tiny slim api which is nice so you create a value that value has to be an object because only object gets garbage collected things like numbers strings the primitives don't get garbage collected and you just put it in a weak graph and now you have a weak graph to the value wait no wait wait wait wait i'm confused no no no no no i okay strings do get garbage collected right if i create a 100 megabyte string and then lose my reference to it it will be garbage collected i think the i think the difference is that you can recreate that exact string later whereas you can't but once you lose access to an object you can't recreate that exact object again it would be a different instance of that object i'm not 100 sure on strings now you say that i think strings are special in that they're not objects and that two strings you create separately will be considered identical and i think strings are shared in a in like a string pool because of this identity uh reference identity that they have and so i so i think they will probably be removed from that pool especially large strings but i think that's a considered garbage collection i'm not sure on this one so we'll probably add something in the notes of this video i'm pretty sure you cannot create a weak graph to a string yeah it's probably similar to how it can't be the key to a weak map or a set um because you can recreate them again so it's the same goes for like numbers and symbols and like nolan undefined that kind of thing so this is now a weak graph the weak ref is a weak reference to the value i create above and even if we didn't put the value in its own variable which is a strong reference like if we didn't have a single strong reference we would be guaranteed that this value would continue to exist until the next task so that way we can make sure it doesn't get governed immediately we might you know we might have a promised chain where we want to process use this value in the next microtask that much is guaranteed and this is not only you know for code to work as you expect but also one of these mitigations for the bandwidth in that the the lifetime of the value is elongated so that you can't communicate it as much through garbage collection just because now it's until the next next task and now we could basically call draft on the weak reference to see if the value is still there at some point later and then this maybe value will be undefined if the value had been gct at some point between these calls or it will be the actual value if it hasn't and if we call draft and get the value again that's a new point in time where we say okay now the value will continue to exist until the next task at the very least again for this guarantee and to limit the amount of communication that you can do so one you've called d ref like all right two questions can you call drf multiple times yes as many times as you like and so and that and then the thing you've got is now a strong reference draft gives you a strong reference yes it gives you yeah basically and so once until that variable ceases to exist but even then the value will not be garbage at the very least until the next task this is actually one of the consistency guarantees so you can have multiple weak refs to the same value and the calling draft on all of them will always yield the same result there is no way that one weak ref will still have it and the other one won't those will always be consistent so with this we can have weak reference and hold on to a value without preventing it from being garbage collected but actually sometimes it's more helpful to have it the other way around where we get informed uh when something has been garbage clicked because this way we don't we always have to check i guess every frame or something like it's really hard to you would have to do polling and that's bad you want to have the inversion where you get notified when something gets garbage checked and that's the other part the other half of this proposal and that is called the finalization registry the finalization registry takes a callback that will be called whenever a value that you have registered with a registry gets garbage collected and you basically register that value with a held value and now this is something um that might be confusing to some people at first because the value that you wait to that will be called whenever's not the value gets passed into the callback and that's simply because at the time the callback is called the value has already been garbage collected doing it the other way around where you pass the value in just before it gets garbage click it could allow you to store a new strong reference then the garbage collector would have to undo its thing and it would be way more complicated so what you do instead you get a separate value that you can pass in and that can be something of for your internal bookkeeping to know which value it originally was or maybe it's the underlying resource you want to free up whatever can you pass the same object in twice no that's not going to work because it has to have a strong reference then yeah so the health value is called held value because it is strongly held so if you i mean you could call register some value some value but that would prevent garbage collection from ever happening on some value so this is this is your optimization step so if you've got like if you've vended an object and you've got some sort of system where i want to keep this websocket open while this object is still being used this is the pattern you would use because you get that callback and you go oh that object's gone now now i can do my related optimizations like close the websocket yeah and it is also important to note that you know the the callback will be called at the same time the value gets garbage cracked or at some point later in time so and again this is up for interpretation by the engine it can be very very long between the actual garbage collection and when this callback will actually be invoked but what about then is there is there guarantees there like it like could there be a situation where if i d-ref a weak reference it returns like undefined or whatever but this callback fires like an hour later or something yes i think that is a possibility so i think if the callback has been called drf will definitely return undefined drf returning undefined doesn't require that this callback has been called because it isn't required to get called at all and this is what i want to talk about dex because there is no guarantee the callback will run and that's why it's so important that this callback isn't used for critical work this callback should be used if a value being garbage collected means you can free up even more memory internally it is supposed to allow you to reduce memory pressure further it is not supposed to be used to actually do um business logic cleanup work because it might not ever get called and so in that case you might actually be more wasteful with these resources than necessary yeah you couldn't build like an analytic system that tells you how many objects are around using this because it doesn't come with those guarantees yes so that's one of the reasons for example why this has been tailored with webassembly in mind because webassembly often passes values to javascript that represent something is actually in webassembly memory and so in that case it makes sense because if the representation in javascript gets garbage collected meaning the engine thinks it's under memory pressure then code can run to free up even more memory in webassembly lands but if that memory doesn't get freed it doesn't inhibit the functionality of the app or waste user resources to an unnecessary extent so as i said there is no guarantee that this will run and there's some two things that they point out makes especially unlikely for them to run one is if you close a tab or if you kill the process there is no need for the engine or no requirement for the engine to run all the registered callbacks if you just kill the process so it shouldn't be used to like do cleanup work when somebody leaves the page and it's also very unlikely for these callbacks to run if the registry itself becomes unreachable by your code um so i guess if the registry gets garbage creek unreachable um there is no guarantee that these callbacks will ever be called in the future now that we've registered something to get cleaned up sometimes we might discover later on actually we don't want this callback handler to run ever we want to unregister a certain value for that to work the function register takes a third parameter which is the unregistered token it's similar to the held value in that it symbolizes what you need to have to unregister this one value in this case however unregistered token could be the same thing as some value because it is not strongly held but sometimes it might be easier for you to use a different value altogether just for bookkeeping purposes or keeping it simple or something like that and then you can just call unregister with this unregistered token and that will prevent remove your value from the registry and now one last method on the finalization registry which actually i found really interesting because it's the first time that i have seen a normative optional api that means this api is in the spec is specked out but implementers are not required to implement it i think the only other api on the web that has a similar fate currently are shared array buffers in that they are specced they're agreed upon they're emerged and everything but they're not required to be implemented to be fully spec compliance is this the same reason is it is a security timing thing yes i mean sure all right we all know that the you know what we have probably heard of the the history shared array buffer that was removed because of spectre meltdown and now it's slowly being incorporated but they still leave it up to the engine to decide whether they want to enable them if they don't basically browse who hadn't shipped any mitigation or found a good mitigation shouldn't be considered spec incomple uncompliant in compliance uh incomplete i think it is i don't know it is don't don't say that about the browser that doesn't have array buffer because it's a very tough problem that's basically thinking behind it and this apparently had a long discussion behind it which i'm not going to try to summarize but some browsers didn't want to ship this other browsers didn't want to ship if there were basically a big contention around should this ever be because it's a synchronous api that runs callbacks on amount of values that might have been garbage collected oh sorry i should explain what this function does first so the function is called cleanup sum and that is basically you saying hey if you have a chance call all the callbacks for the values that have been garbage collected but you haven't called the callback on just yet and so you're kind of opting like hey i would like to process these things now um i actually kind of surprised they made it optional because it would just be just a spec compliant to make it a no up because you don't have to run the callbacks you can just say like nah not running anything it's just a little it's a little poke isn't it it's just like please please please but there were browser vendors disagreeing on whether this is good for the main thread or not and so in the end they just made it normative optional to implement this and it currently looks like that at least on the web we will only be shipping it in workers not on the main thread uh which i thought is quite interesting so you do have to check whether this method exists before calling it and this is where optional chaining comes in super handy we just do like the question mark dot parentheses and then it will be called only if that function actually exists and that's not the first thing that that's happened with with in javascript right because we've got um there's the atomic stuff right there's there's methods on atomics that are only in workers as well yeah and so um yeah just keep in mind you need to check before it's there and again this method is just a request to run these callbacks there is no requirement from the browser to actually process call any callbacks or process any values um that's what i mean like this entire api is very much trying to leave this freedom for the engine implementers to allow them to implement better garbage collection algorithms in the future um so they're not constrained by weak graphs and finalization registry and and so it is very it is a you need to be very careful when working with this one thing i want to close with that with this you can now actually build an iterable weak map and interestingly enough there's an entire implementation of this in the explainer that is i have a link here bitly slash interval week map if you want to look at that i'm not going to go through it here because a lot of things to track to make sure that everything is garbage correctly and so on and so forth but if you're curious uh take a look the weak graphs implementation has shipped in current stable chrome i have actually merged it into comlink so if your browser supports weak graphs i will automatically garbage collect stuff across the worker boundary now which i think is kind of cool um so yeah builds try try it out play around with it but remain careful too do we have enough time for you to quickly describe how you use the income link comlink what it does is you have a valid value in a worker and you basically create a proxy on the main thread saying like you proxy behave like that object in the worker and then under the hood i use a a message passing protocol to say this person wants to access property a sent me the value of property a place and then this round trip happens um what i'm doing now is basically have a simple reference counting algorithm whenever a proxy is created i increment that counter and previously i had a an explicit release function i still have that an explicit release function like i don't need this proxy anymore that decreases the counter and when the counter reaches zero that thing can get garbage collected um on the worker side that is now you basically implicitly call that function when the proxy gets garbage collected and you can opt in of that you can opt out of that but this again like this is if if there is memory pressure it might be useful for the engine that i release unused objects in the worker side as well and so i pretty much just use a weak graph uh a finalization registry sorry to no get a notification this proxy has been released and then i can decrease the counter on the worker side and just let go of the message channels once that counter reaches zero you should say like this is super advanced stuff and anyone watching this shouldn't be like oh my code doesn't use weak references i should go and add them in somehow like don't do that please don't yeah don't okay so but it is just enabling these like couple of edge cases where you can make extra optimizations or like you say you can avoid a case where you have to call an explicit um destructor like release function or something like that yeah and yeah for me obviously it is the most exciting part is the web assembly bit where you now get a deeper integration between the garbage collector and javascript and your memory and web assembly so this is the first stepping stone towards getting garbage collected languages to webassembly without having to ship your own garbage collector code in webassembly so that's not true it's not the whole story but it's the first puzzle piece and so i'm obviously thinking ahead and quite excited about the prospect of having managed languages be smaller and i guess better in the web assembly cool well we'll link to the va article and uh into com link we'll we'll show where you're using it um yeah that's good actually i do now understand it a lot better than i did i'm glad well well done sir well done me it's super advanced this stuff and like anyone watching this and anyone watching this shouldn't of christ jesus out of practice we should say though that this is super advanced stuff

Original Description

Surma and Jake take a look at 'weak' JavaScript, specifically WeakMap, WeakSet, and the new and shiny WeakRefs. Surma mentions his comlink library again so I guess we have to link to it → https://goo.gle/2VLcr6V More details on WeakRefs → https://goo.gle/3dDdj3p Also, if you enjoyed this, you might like the HTTP 203 podcast! → https://goo.gle/2y0I5Uo Other videos in the series → https://goo.gle/2wneQLl Subscribe to Google Chrome Developers here → https://goo.gle/ChromeDevs Also, if you enjoyed this, you might like the HTTP203 podcast! → https://goo.gle/2y0I5Uo
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 Polymer Performance Patterns (The Polymer Summit 2015)
Polymer Performance Patterns (The Polymer Summit 2015)
Chrome for Developers
2 Polymer Power Tools (The Polymer Summit 2015)
Polymer Power Tools (The Polymer Summit 2015)
Chrome for Developers
3 Chrome Dev Summit 2014 – Chrome Case Studies
Chrome Dev Summit 2014 – Chrome Case Studies
Chrome for Developers
4 Web Directions Code 2015 round up
Web Directions Code 2015 round up
Chrome for Developers
5 Maintainable Code - HTTP203
Maintainable Code - HTTP203
Chrome for Developers
6 iron-ajax… wat?! -- Polycasts #26
iron-ajax… wat?! -- Polycasts #26
Chrome for Developers
7 The Guardian - Supercharged
The Guardian - Supercharged
Chrome for Developers
8 ES2015 (next version of JavaScript), Totally Tooling Tips (S2 Ep1)
ES2015 (next version of JavaScript), Totally Tooling Tips (S2 Ep1)
Chrome for Developers
9 #AskPolymer: Rob answers all the questions ever -- Polycasts #27
#AskPolymer: Rob answers all the questions ever -- Polycasts #27
Chrome for Developers
10 The Future of JavaScript - HTTP203
The Future of JavaScript - HTTP203
Chrome for Developers
11 Data Binding 101 -- Polycasts #28
Data Binding 101 -- Polycasts #28
Chrome for Developers
12 The Guardian part 2 - Supercharged
The Guardian part 2 - Supercharged
Chrome for Developers
13 The Future of Web Audio: with Chris Wilson and Chris Lowis
The Future of Web Audio: with Chris Wilson and Chris Lowis
Chrome for Developers
14 Chrome 46: New motion-path animations, client hints and service worker improvements
Chrome 46: New motion-path animations, client hints and service worker improvements
Chrome for Developers
15 Sublime Snippets, Totally Tooling Tips (S2 Ep2)
Sublime Snippets, Totally Tooling Tips (S2 Ep2)
Chrome for Developers
16 #AskPolymer: How do you make the show? -- Polycasts #29
#AskPolymer: How do you make the show? -- Polycasts #29
Chrome for Developers
17 Critical Path CSS, Totally Tooling Tips (S2 Mini Tip #1)
Critical Path CSS, Totally Tooling Tips (S2 Mini Tip #1)
Chrome for Developers
18 Binding to Objects -- Polycasts #30
Binding to Objects -- Polycasts #30
Chrome for Developers
19 Player FM - Supercharged
Player FM - Supercharged
Chrome for Developers
20 Where’s the Designer? #AskPolymer -- Polycasts #31
Where’s the Designer? #AskPolymer -- Polycasts #31
Chrome for Developers
21 Jake Beats Wikipedia - HTTP203
Jake Beats Wikipedia - HTTP203
Chrome for Developers
22 Supercharged Observers! -- Polycasts #32
Supercharged Observers! -- Polycasts #32
Chrome for Developers
23 Jai's Web blog - Supercharged
Jai's Web blog - Supercharged
Chrome for Developers
24 Windows Command-line Tooling, Totally Tooling Tips (S2, Ep4)
Windows Command-line Tooling, Totally Tooling Tips (S2, Ep4)
Chrome for Developers
25 What about internationalization? #AskPolymer -- Polycasts #33
What about internationalization? #AskPolymer -- Polycasts #33
Chrome for Developers
26 Developing for Billions (Chrome Dev Summit 2015)
Developing for Billions (Chrome Dev Summit 2015)
Chrome for Developers
27 Google+ Performance Improvement Comparison
Google+ Performance Improvement Comparison
Chrome for Developers
28 Deploying HTTPS: The Green Lock and Beyond (Chrome Dev Summit 2015)
Deploying HTTPS: The Green Lock and Beyond (Chrome Dev Summit 2015)
Chrome for Developers
29 Progressive Web Apps (Chrome Dev Summit 2015)
Progressive Web Apps (Chrome Dev Summit 2015)
Chrome for Developers
30 Instant Loading with Service Workers (Chrome Dev Summit 2015)
Instant Loading with Service Workers (Chrome Dev Summit 2015)
Chrome for Developers
31 Increase Engagement with Web Push Notifications (Chrome Dev Summit 2015)
Increase Engagement with Web Push Notifications (Chrome Dev Summit 2015)
Chrome for Developers
32 Engaging with the Real World: Web Bluetooth and Physical Web (Chrome Dev Summit 2015)
Engaging with the Real World: Web Bluetooth and Physical Web (Chrome Dev Summit 2015)
Chrome for Developers
33 Asking for Permission: respectful, opinionated UI (Chrome Dev Summit 2015)
Asking for Permission: respectful, opinionated UI (Chrome Dev Summit 2015)
Chrome for Developers
34 Polymer - State of the Union (Chrome Dev Summit 2015)
Polymer - State of the Union (Chrome Dev Summit 2015)
Chrome for Developers
35 Building Progressive Web Apps with Polymer (Chrome Dev Summit 2015)
Building Progressive Web Apps with Polymer (Chrome Dev Summit 2015)
Chrome for Developers
36 Introduction to RAIL (Chrome Dev Summit 2015)
Introduction to RAIL (Chrome Dev Summit 2015)
Chrome for Developers
37 DevTools in 2015: Authoring to the max (Chrome Dev Summit 2015)
DevTools in 2015: Authoring to the max (Chrome Dev Summit 2015)
Chrome for Developers
38 RAIL in the real world (Chrome Dev Summit 2015)
RAIL in the real world (Chrome Dev Summit 2015)
Chrome for Developers
39 #ChromeDevSummit talks are up - W00T! -- Polycast #34
#ChromeDevSummit talks are up - W00T! -- Polycast #34
Chrome for Developers
40 V8 Performance from the Driver's Seat (Chrome Dev Summit 2015)
V8 Performance from the Driver's Seat (Chrome Dev Summit 2015)
Chrome for Developers
41 Quantify and improve real-world RAIL (Chrome Dev Summit 2015)
Quantify and improve real-world RAIL (Chrome Dev Summit 2015)
Chrome for Developers
42 Owning your performance: RAIL (Chrome Dev Summit 2015)
Owning your performance: RAIL (Chrome Dev Summit 2015)
Chrome for Developers
43 HTTP/2 101 (Chrome Dev Summit 2015)
HTTP/2 101 (Chrome Dev Summit 2015)
Chrome for Developers
44 Leadership Panel (Chrome Dev Summit 2015)
Leadership Panel (Chrome Dev Summit 2015)
Chrome for Developers
45 Build Processes, Totally Tooling Tips (S2, Ep 5)
Build Processes, Totally Tooling Tips (S2, Ep 5)
Chrome for Developers
46 Accessibility (Chrome Dev Summit 2015)
Accessibility (Chrome Dev Summit 2015)
Chrome for Developers
47 Binding to Arrays -- Polycasts #35
Binding to Arrays -- Polycasts #35
Chrome for Developers
48 HTTP2 - HTTP203
HTTP2 - HTTP203
Chrome for Developers
49 Chrome 47: Splash Screens, requestIdleCallback and better desktop notifications (New in Chrome)
Chrome 47: Splash Screens, requestIdleCallback and better desktop notifications (New in Chrome)
Chrome for Developers
50 Call For Submissions - Supercharged
Call For Submissions - Supercharged
Chrome for Developers
51 Cross Device Testing, Totally Tooling Tips (S2 Ep6)
Cross Device Testing, Totally Tooling Tips (S2 Ep6)
Chrome for Developers
52 Testing AJAX with Web Component Tester -- Polycasts #37
Testing AJAX with Web Component Tester -- Polycasts #37
Chrome for Developers
53 Slack: Extended Xmas Special - Supercharged
Slack: Extended Xmas Special - Supercharged
Chrome for Developers
54 Browser testing with Travis & Sauce Labs -- Polycasts #38
Browser testing with Travis & Sauce Labs -- Polycasts #38
Chrome for Developers
55 Optimize for production with Vulcanize -- Polycasts #39
Optimize for production with Vulcanize -- Polycasts #39
Chrome for Developers
56 Highlights from Chrome Dev Summit 2015
Highlights from Chrome Dev Summit 2015
Chrome for Developers
57 Chrome 48: Custom buttons in notifications, DevTools Security panel, and Presentation mode
Chrome 48: Custom buttons in notifications, DevTools Security panel, and Presentation mode
Chrome for Developers
58 Crisper: Protecting your Polymer app with CSP -- Polycasts #40
Crisper: Protecting your Polymer app with CSP -- Polycasts #40
Chrome for Developers
59 How do I use Sass with Polymer? #AskPolymer -- Polycasts #41
How do I use Sass with Polymer? #AskPolymer -- Polycasts #41
Chrome for Developers
60 Colors – DevTools Tonight #0 (Pilot)
Colors – DevTools Tonight #0 (Pilot)
Chrome for Developers

Related AI Lessons

Up next
News At 10
Channels Television
Watch →