Advanced Angular Elements

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Thank you for this nice overview.

Why do you prefer using your own calculation on element visibility instead of using the IntersectionObserver API?

👍︎︎ 3 👤︎︎ u/huppys 📅︎︎ Dec 07 2018 🗫︎ replies

When you record the video do you write out the code then delete it section by section then keyboard shortcut undo as you talk about it?

👍︎︎ 2 👤︎︎ u/Mr_Nice_ 📅︎︎ Dec 07 2018 🗫︎ replies

Awesome video! I'd love to see a video similar to this one going in more details about the use of slots. Also, why even use slots when Angular has things like ng-container, which also lets us pass a context to it:

<ng-container *ngTemplateOutlet="myTemplate; context: { $implicit: myContext }"></ng-container>

Not sure how to do that with slots...

👍︎︎ 1 👤︎︎ u/cactussss 📅︎︎ Dec 07 2018 🗫︎ replies
Captions
[Music] one of the most exciting trends happening in web development is the adoption of web components because they allow us to build applications that don't walk us in to a specific framework or a programming style I'm going to be using web components in production very soon so I wanted to share some advanced concepts that I've learned working with angular elements and I'll even show you how to achieve a near perfect white house performance score with the full power of angular and firebase in your Java Script bundle if you're new here like and subscribe and congrats to Damian right who's last week's t-shirt winner but don't worry if you missed out there's another one of a kind t-shirt going out this week all you have to do is leave a comment below over the last few months I've been building a product called fire ship IO which is just a better way for me to deliver my content to you this project needs to be very fast in search engine optimized but it also needs to use firebase for user authentication and dynamic data the beauty of web components is that I can pre render all of my static content and then bootstrap in custom elements when they're needed throughout this journey I've used pretty much every web component tool that's out there and I found that angular elements is the most productive for a larger project but you'll also want to check out stencil and lit element which I think are both very promising the big advantage of elements is that a you get the full power of angular and B your components can share the same dependency injector tree which means you can easily share data or functionality between your custom elements and see the API is stable and being used in production at Google today we're going to build a custom element that can lazy load an image based on the user scroll position in the browser when the image is loading it will show this Facebook style shimmer placeholder then replace it with the image when it's fully loaded now we'll jump into some code but if you haven't already seen my original angular elements video you'll want to check that one out which is a little more basic level the first thing I want to do is go into your angular app and then run ng add at angular elements this will install the dependencies and also add the polyfills to ensure that your elements are compatible with all browsers then you can go into the app directory and you'll want to just go ahead and delete everything except for the app module you'll also notice I've generated a couple of regular components in here as well the first thing I want to do is register our components as custom elements I'm assuming angular will have a better way to do this in the future but currently we import injector from angular core and create custom element from angular elements now if you want to use your elements within the context of an angular app you want to add them to the entry components array the important thing is that we go down here to the app module and add the injector to the constructor if you have a big project there's probably a whole bunch of different elements to register it's the way I like to set this up is to create an array of tuples so the first item is the angular class name and then the second item is the name of the custom element so that's how you'll actually use it in the Dom so now we can loop over these elements and we can actually de structure them directly in the for loop which i think is a really nice-looking piece of JavaScript from there we can call create custom element and that gives us a dry way to register a large number of components now let's switch gears and see how we can create a single JavaScript bundle that we can use outside of angular what you're looking at here is the build script that I wrote from my original angular elements video it just takes all of your production build files and then concatenates them into a single file in the public directory so this works fine but it's kind of a hack I'd recommend checking out ngx build plus to extend the default behavior of the CLI and hopefully the CLI will just support this out-of-the-box in the future we'll stick with the simple approach for now and I've added a couple of build and serve scripts to my package JSON it first runs ng build prod and then it runs the build script with node so now that we have our Java Script bundled I'm going to put it to use and just a static HTML page by adding it as a script to the head of the document and you can see down here I'm using this image lazy custom element which we'll build here in a few minutes now I'll go ahead and run a light house audit and keep in mind I'm also not lazy loading the images at this point either we get a first contentful pain in 2.5 seconds and time to interactive is 4 seconds I've also added firebase to my JavaScript bundle so we have 342 kilobytes here and total that needs to be loaded before the rest of the page can render but the great thing about elements is that we can defer this script until after the page is rendered so how do we do that we just go into our script tag and add defer and we're done if we run the audit again we get a first paint in 600 milliseconds which might as well just be 0 and 3 seconds later we have the full power of angular and firebase ready on the page so you can already get amazing performance with elements but it's only going to get better in the next few months here as angular IV becomes production ready so that's pretty awesome stuff but I want to share a few advanced pro tips that I've learned throughout my experience working with element the first thing I'd recommend doing is disabling angular's automatic change detection or ng zones which you can do here in the main TS file the reason for this is that I've run into some really hard to debug issues that only happen in production so you'll find that life is much easier when you tell the component explicitly when to re-render now if we go into the component itself you can see I have imported everything under the kitchen sink here from angular core you won't need all these things in your elements I just want to show you a few different techniques at your disposal and also if you don't want to turn off zones globally you can do it here at the component level by doing change detection strategy on push the next big decision is whether or not to use the shadow Dom so the term web components encompasses a few different features one of which is obviously custom elements but another one is the shadow Dom if you turn the shadow Dom on it means that your CSS Styles will be encapsulated in this component that can be a good thing if you don't want your CSS to bleed out but it can also make your components harder to style so it's a trade-off and the shadow Dom also supports slots which is something that we'll look at towards the end of this video now there are two things that I commonly inject in the constructor element ref will give us a reference to the actual Dom api's that exist on this element the next one is the change detection ref which allows us to re-render this component manually instead of relying on the automatic change detection because we're displaying an image we'll have our custom element behave just like a regular image tag we'll give it a source attribute and an alt attribute now the special thing about our custom element is that it only displays an image when it's actually visible in the viewport so for that we're going to emit our own custom event called is visible now when it comes to your internal component State I recommend keeping the input values as immutable then you have the flexibility to manage the state however you want but here's the pattern that I find especially effective so we'll create an object with a couple of properties on it and we only want to re-render our component if this state changes then we'll set up a method here called set state which takes a key and a value as its arguments and then we can go ahead and use the spread syntax to create a new object and set that as the new state on the component then we can guarantee a rerender here by calling detect changes on the change detection ref this code might look familiar because it's inspired by the way react works contrary to popular belief I do not hate react overall I found this to be a very reliable way to work with elements but there's definitely many different ways you could do this let's go ahead and switch over to the HT and put this to use first we'll set up a div and if the loaded state is false then we'll go ahead and show that placeholder you can check out the full CSS for that animation in the source code then we'll set up a figure to wrap the image itself and we'll only show this if it's visible based on the user scroll position on the window then we'll add an image tag inside of here which will only be loaded over the network when this visible property flips to true just because it's visible doesn't mean it's loaded yet so we'll also hide the image until it's fully loaded and then we'll run an event handler once that event takes place and the last thing to make note of is that we're passing our input source to the actual image source here so again our custom element feels just like a regular image tag with some added benefit so now the challenge is determining whether or not the user has scrolled to this element to make that happen we're going to need to access some native Dom API s we've already set up a reference to the native element in the constructor of this component we can go ahead and call it here and then we can call get bounding client rect which will give us the actual measurements of that dawn element at the top of the window is less than or equal to the window inner height then we know that that element has been scrolled too and we also want to check that the element is not already visible because if it is and there's no point in running this code but if it is visible for the first time then we'll go ahead and run our set state method which will change the state and then re render the component another thing we want to do is emit a custom event when the element becomes visible I'll cover the implementation of that in just a minute so there are two different situations where we want to calculate the visibility of the element first when the component is initialized because if the element is already in the viewport then we don't want to wait for the user to scroll to load it then to listen to the scroll position we can add host listener then window : scroll to listen to the global window scroll event and when that happens we'll go ahead and calculate the visibility of the element so that's how we determine when an elements visible and also rerender at when it state changes for the image itself there's a built-in load event which will fire when the image is fully loaded so when that takes place we'll go ahead and set the loaded state to true again re rendering the component so the end result looks like this we start with a placeholder when the image loads it's displayed and the placeholder is removed again the great thing about web components is that we can interact with them use vanilla JavaScript in the Dom so we could use document query selector to grab the element and append it somewhere or change its CSS styles or whatever by default the internal properties and methods on the component are not available when you grab it from the Dom like this but it can be very useful to expose a public method that can be used by the developers working with your elements for example let's set up a log method that logs out the internal state of the component the method that I found works best although I'd like to see this improved in future versions of angular elements is to use the input decorator the reason we do it this way and not just attach input to a method is that it gives us context to this or this component instance so we can console.log this state which would otherwise be undefined if it was a regular method now another thing that's really useful on the same note is to emit a custom event that can be listened to in the browser so we already have an event you made or set up on this component and we can emit through that just like we normally would an angular and we'll also set up a custom event in the Dom we'll give that a name of is visible and then we can reference our native element and dispatch the event through it if we go back to the browser we can now grab this element from the Dom attach an event listener to it and handle it however we want using vanilla JavaScript or some other framework so I've set up the is visible listener and then I'm going to console like the event when it occurs as soon as the image becomes visible in the viewport it logs that custom event to the console so that takes care of that the next thing I want to show you is content projection using slots if you look at the image on the left here you'll notice a caption underneath that has a default header and default caption if we revisit our static HTML you can see that I have a couple of spans that are inside of the Lazy image tags the spans have a slot attribute which corresponds to a certain place that they'll be displayed which will define inside of our custom element so now I'll switch over to the component HTML and we'll go ahead and add a figure caption then we can include slot tags that have a specific name that defines where this content will be displayed this is super useful when you have components that can be customized but you don't want the end-user to have to worry about adding the required markup to it and if you want the user to just be able to transclude some markup inside your component you can simply drop in a slot tag that be considered the default slot and the user can just pass in whatever HTML they want and it will be rendered here I'm gonna go ahead and wrap things up there I have a whole bunch of other ideas for angular element for future videos so make sure to LIKE and subscribe and if you want to take your development to the next level consider becoming a pro member at angular firebase com go get access to my following courses my book as well as a whole bunch of other resources designed to help you build and ship apps faster thanks for watching and I'll talk to you soon
Info
Channel: Fireship
Views: 55,020
Rating: 4.9375 out of 5
Keywords: angular, firebase, webdev, app development, typescript, javascript, lesson, tutorial, angular 7, angular elements, web compnents, custom elements, shadow DOM, angular shadow dom, angular web components, polymer, stencil, lit-element
Id: ujaMvl5M8nY
Channel Id: undefined
Length: 11min 45sec (705 seconds)
Published: Thu Dec 06 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.