Building a Simple Virtual DOM from Scratch - Jason Yu

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Great energy, knows his environment, types like a champ. A+.

👍︎︎ 6 👤︎︎ u/txmail 📅︎︎ Dec 07 2018 🗫︎ replies

Anyone knows what is the IDE he's using?

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

Holy shit, this guy is awesome

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

Reconciliation is unnecessary overhead with more modern approaches like lit-html. The way it works is that instead of updating a VDOM and then walking it and checking where it differs from the real DOM (reconciliation), it creates the DOM tree (efficiently, using <template>) and then just compares the current arguments to the previous using === and updates the nodes directly if the arguments differ. For example:

html`<span>${123}</span>` // tagged template literal, returns a template

The html tag function receives ["<span>", "</span>"] (roughly) as the first argument and 123 as the second, and it caches these globally, and maps to a <template> for instantiating the DOM quickly next time it's called with the same markup. Calling html`<span>${123}</span> produces the same template as the cached one, so it knows not to re-render it; if the arguments change, it updates the placeholders in the template instead of re-building the DOM.

Sorry if the explanation was a bit convoluted, but the gist is that VDOM was a good idea but is essentially obsolete, and React hasn't caught up yet, and probably isn't straightforwardly adaptable to the newer approach.

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

This is really good!

👍︎︎ 1 👤︎︎ u/iZeitgeist 📅︎︎ Dec 07 2018 🗫︎ replies
Captions
[Music] say we can build a special down from scratch who have heard opportu bomb who have worked with special doll who have implement the protocol by yourself okay that's great okay that's that's great so we all we always talk about her to vampire and we always use well we know the fandom is amazing we always praise about it but nobody actually knows what that is so I'm going to demonstrate well first explain what / - Thomas and then I will try to implement one for you but I need to ask you only have 30 minutes according to the plan but I might over run a little bit let me do a timer and stopwatch right so / - Tom so who knows what the Thomas Tom is just for example if you have a tip right so a virtual Dom is just trained object that were to send don't bone structure all right that's it so let's do that right so hmm so to start I will just go to my temp directory and then create feed zone and go into that oh that's the other one obviously I practiced that and then I will do get in it and I get well time to Selman my own thing I built this git ignore ax which will create you're kidding No so I ended it with the node profile and then I will do MPM in there as well with - why would you accept everything and then let me turn on Tomas right Pete okay so now we've got some files and let's do our first commit initial commit awesome so as I said so there's a few dependencies that we want well actually just one that is the parcel if anyone of you heard of Paso bundler there's a few so posit no configuration needed so you just install paso fun walk okay so while it's installing let's create this source directory with the in destination node so what we're going to build today is an app if you can't hear me just shout right and if you can't follow anything just leave just ask yourself the question that you have in mind right so we're just going to build this simple HTML structure and by the time I hope that password will be installed so we'll source this main ojs hello world and in the main will also do console.log hello world just to check the passo works right so now we've got passive installed unless at the script to the package.json so paso you simply give it the entry file so that would be that our index.html and just by doing this and if we do NPM runs that now it's just start a development server it will it will look through the index.html and you'll see that oh you're importing the main thought yes and then you load the main part yes into your app it's amazing so now the deferment server is up and you see how the world and in the console you see how the world as well that's amazing yeah we did the first part okay click step we need our fur to thumb so let's create feet on and in the P Dom so in virtual Dom we well basically throw to them is just a plain object so we can do whatever to represent it so we can say V app our app so the Dom to represent our app is just for some tag where the tech name is deaf and then we we have some attributes where the ID is app and we have some children say we have high hello world something like that so this will approach the dog this is this is a virtual Dom it's just a plain object right but in react or few you see this H function right the H function represent create element so let's do that function so what create element does create element what does is it would just take in the tag name and take in some options and it will return you some virtual Dom so the first one as I said is just plain object so it will have the tag name and you have some attributes options or attributes Nesi and then it has some children so options dog children right so here's the create element function nothing special about it so so here we can of make it nicer by D structuring the stuff so let's do that right and by doing this now we can import the create element from our teeth all smashed and then we can replace this part by the create element function so we'll say it if and then in the options will say octopus would be ID app and children would be nothing now and then less bounce a lot our virtual app oh right and if we go back to our browser refresh and there you go I'll first to a song instead the question so far well I did it's just simply creating alright nothing special so this is for children basically and next we need to put our fur to them or the paper so we need to render the virtual Dom into actual Dom's right so let's create that so let's let's say we have a random function so so let's let's talk about what we want right so we want to somehow import some friends a function and with the render function we'll put in our first app and what you should return should be something a Dom right so I thought for this for this talk I will prepare all the Dom parable with a dollar sign has nothing to do with jQuery don't worry so it's just names right so I'll do dollar sign apps that represent the actual Dom of the app and then we will try to lock the app it wouldn't work now but will reboot the render yes so what rendered audience does is render it will take in some virtual note and you would do something unless exported export render right so what we want to do is basically look at the tag name right so first of all let's create a tag name first so less the element would be document dot create element so this will create the actual Dom for you will pass in the tag name which is which is fee mode talk tag name and then this attributes and children right so we loop through all the attributes by doing for const we have the key and value in that appears right so we can do alt text dot entries to get an array of all entries in is in the object everybody ok so we will do P note top attributes right and then we'll just do set attribute to the attribute to the element with the key add value and this should set the attribute and if we go back to our site well let's do this somewhere than why but I know that's let's go on so we have some attributes right and then we'll this will set experts and then we meet our Trojan set children so again we look through all the children for child of feed note children so true this is just an array of virtual Dom right so we can just render child so that by well leap of faith means when you use recursion you just assume that the function that we're defining works this is how recursion works so you just assume that random would work for all the other search hole whatever and then this should give you the child that is a to Dom right and then what you do is you append this child to your element oh and then you return I'll click Network what does it say let's have a look at the area oh it's probably some issue with the caching it works now don't you possibly sometimes doesn't work so well it's kind of stupid okay but anyway as weak as you can see we have locked our actual Dom hmm so let's test that our our to DreamWorks right because now we don't have children so let's create element again and we put an image this time less sauce from Jaffe that's a favorite placeholder for images just looks cool why does it do that image okay anyway let's use this cat okay oh should be Toma and let's save this and go back and go back to our app and we see an error the reason is because we haven't put our children so we are trying to disrupt chair children but we are not having the children so let's give it some default values right so the default of children will be empty and the default of attributes will be a empty object and the options could be emptier throughout as well so let's be fought the whole thing to an empty object right so is there any problem with this part any question just shout right although I don't have so many time so okay let's go on so now we have created our yeah it works always this sauce that's weird oh it should be sorry it should be a trapeze it should be like this we go back refresh yeah here we go you go out app ready so next we just need to put this app into our page so the way that I would do it is so usually in react or feel you have this bit IDE goes will follow that pattern and then in the main let's say we have this mount function and what mount does is it will just take in some Dom app for this case and then we'll take in the target which is document dot get element by ID app and this should mount our app into the app and if you save it you see errors that's expected and then let's create the amount of GS and what manages dust is pretty simple it just take in the note everything in the target and then it will call target thought it plays with it doesn't work for ie by the way but okay so and then we will return those as well for this instance so I was saving this and let's save this again and you'll see okay so more stuff to do so next let's let's make this into an actual well make it's more similar to react right so say in in react a component within some props so let's say this is in stuff the app will say create fear and it will take in some props and say it's count and you'll return an element and let's use that count somewhere say later count is count and try to put some count here let's pass in the string so in my same weird here that we are passing a natural string while we are expecting some personal but actually there are two types of well actually there are four types of notes but our only focus of tune currently so the two types of clothes the first and I'm talking about actual bomb the first note is text node we just plain awesome this is what's representing it the second one is where you have some inmate or so this represent the test note this represent elemental questions right so so we need to handle that you know in our render function because we have a handle and you should Sierra here yeah the era is irrelevant anyway so so if you go go back to Miranda and now we know that this brand new function is expecting either a string or a virtual element right so what we can do is let's rename this function to be virtual LM and rename this less destructive because LM has tag name anyway and ash and children and we're going to do this oops oops oh I think that will work I think that's the same function I just renamed it to render LM and then we'll we define render so random will actually take in the first one note and if the type of the first one note is a string then what we'll do is we will return document so the way to create the actual test note is by doing create test note so this will create the test note and otherwise we'll just assume that is virtual element if they're not passing info to adamant it's their fault it's not out so we'll do a render LM denote right so this will handle two type of rendering the first is the test note the second is the element that's also and if we go back here and if we save and we go back and if we refresh it says the app is not defined because we have changed the app to create app so now let's define the app to be create the app passing some count and say the count is sorry is zero if you save this refresh there we go we see the count here and we see the cameras out let's do it okay so next thing yeah where am I now okay next thing so when the count is so let's set an interval right into fo and let's set it to every second this is millisecond by the way and for every second what we would do is we'll mound the thing again this time to sum well well because man will return if you remember what my only return man will return the note the first first Tom so what we'll do is we'll let the root element to be this and then we'll do root element to be this yeah so we need to redefine applicants actually for for distances less the speed he's make it quicker and to create the app count and we need to increment up how so doesn't make sense is it too quick we're just creating another pair to app and render it and a mountain right so now for every second as you can see it's blinking and the problem so now when what every second the whole app is being rendered so do you guys see any problem with this the problem is I'll show you and say we have say this is a lock in form right so we have some inputs and save this go back here you see the input and we try to type our email and because every second because every second the inputs being replaced so you lose focus so that's what oh it's a picture it's just a picture so so that's obviously but by doing this we have the advantage of defining how the Act should be rendered within the state so that's what we active you try it gives you the way to based on the stage of renders the stop logically I'm not sure if that's right in the old days when we just jQuery we tend to change things here and nobody knows whatever turns out they like but with this model you know that we'll always have to input the stray and image so this is a better model but some problem so that's solved so how many minutes do I go I don't I'm in this mall so the next thing is anyone knows what's the next thing yes cific so we need a different algorithm to look at the oaktree old virtual street and look at the new for 2-3 and find the differences between them and I'm kind of patches to the natural dog all right so let's do it so so let's think about API first right so let's go back to the main 30s and say we have some diff function and so instead of rendering the whole app again and mount it we won't do this anymore what we would do is we we need to still create our virtual app right but we don't we don't render the whole thing so what we'll do if will is we'll do this so we need to let this and we'll do the diff between the V app and the new app so let's call the new app virtual new app and we'll do a virtual new app and what should the district turn right this is a problem so let's say it returns some function that we'll patch your stuff so how to use this function will Co patch and pass in the root element right so that the patch gets the root and then do it stuff and at the end we'll assign to your app to the new app let's it make sense any question no okay great you guys are awesome okay so let's create this dysfunction right so there's one thing about this patch so if the root element is being replaced we need to change the element as well so so let's say the patch will return a new root element it might be the same it might be the same as this one but it might not be but so so just depends on how your virtual arm looks like so now let's create that if whoops 50s okay so yeah so you have the virtual ode node and you have the first whole new note note right and what you do is you return some function that takes in the note and Epoque do something to it right and let's explode it's poor people this right so there's some assumption to this because to calculate the minimal differences between two trees takes all the n cube I think according to some paper that I read obvious I think we do so with some assumption in mind we can make the calculation to be order n which is much more efficient and according to react they say that those all the time is good for practical users so let's do so that okay I haven't talked about that assumption is when two texts have different tag name so yeah one is this one is image so I assume that they're different so I don't I've had I just placed the image to the day that seems I have completely reasonable some certain right so let's do that passwords right that that seems easy so if we owed note tag name it's not opposed to be new node dot tag name then we'll just return a patch which fits in the note and it will replace the note with well we need to render the new note now right and we need to import the Brenda import Brenda from Brenda right this part is the new node with the older but remember the patch function returns the new root so we need to return the new root note so new node will become this and we return new node so this will match our API so next thing is well it's obvious that if the new node is undefined I know that's not the right way to do and defined but let's do it that way now and that's obvious right we just well remove the whole note because there's nothing there anymore so you just move it and return undefined it says cool and okay so if we go good if we simple right so so we will somehow diff the attributes so we would we pass on the old attributes and new attributes and we would lift the children by passing the old children and the new children - and look what they will return is a patch for your attributes had attributes and a patch for your children and what we return here is obvious and you just patch the attributes and pass on the note and patch the children and pass on the node plus it makes sense so we just need to define those two right one more thing remember the virtual note could be either the virtual element or the virtual strain so now they're only taking care of the virtual edit so important is to - that's handled easy case which is straight so if either that is a strength let me write that out if the type of threshold note is a string or the type of new node is a string then we need to do with them differently what we'll do is well if they're both there might be a case where they're both string right if they're both strings and we check it there you go there you code well actually I should check if they're not equal yeah if they're not equal then I will just return the patch where I would do these lines actually a render the new note every place the old one because in this case not they're not the same training line did it could be a few pieces these are not the same string or the one not demonstrating the other one is smart string or the other one is variable this one is loitering but anyway we face old note with new note yes that's right that's right thanks for pointing that out I can intentionally do that it's a feature or not but I I intentionally do that to see if you are awake so okay so there's this an else case as well if they're the same then we just return the patch that that's nothing um is it yeah we just do nothing yeah that's it return on the flank so we handle the string case ok now go back to our dipping attributes and dipping children I'm doing the overrun by the way sorry so let's do pip attributes right so what I did thing attributes does is it's it will take in two attributes the old attributes and the new attributes and what you do is so think thing about it this way so you have the old activism in Africa so you said the new attribute so just look through the new one and set to the end of it anyway and you have some old one so you just if you look through each of your old one and check if is in the new one if not then remove that right ok cool so let's loop through the new one object entries and what we'll do is we will return catchy we need two patches so let's have a an array of patches and we'll push a patch to it so what it would do is it would do notice set attribute key and value and return you know the self it says this sets all the new attributes and then set a new attribute and then we want to remove the old attributes all right so we look through something again we look through the old attribute this time but and if the key is in it's not in the new attribute then we'll push a new patch that will do no dot remove a triple remove the key and then return the note again as you can see we don't need the value here so just do K in all attributes it says so now we have all the patches and we just return a rapper rapper patch that will catch everything so we do a for cons patch of patches we'll just call patch passing in note it says this will pass unless let's test if this actually worked if we comment out this part and this part and save this and if we go back here and and save this again one more time and look at the well why is it only playing to once okay there must be some problem with my let me have a look I haven't returned the note that's why let's save this again Oh save this again go back applause so next we just need to do with the children but we don't have so much time am I allowed to okay so I'll do the rest okay so I'll be quick I promise so next we just need to lift the children right so let's go through the children so let's uncomment these right so we're going to pass with doing it if the children so let's define that this children so what this dip children does is it will take in the old virtual children and you're thinking the new virtual children and you would do something do something to it and you'll prom it will return some note if you return a function that returns the note again obviously because we need to match the API so now what we want to do it is so you can think about something like this so the new children my hat differently Oh children I have two different thing so so you can basically look through all the ultras and dip into the new one so all right so if it is the case that the intruder is shorter then we'll existing one to twenty five but we handled that already so we'll remove these these these things and if the other way around if the new one is longer then we just do all the old one default one and there are some additional notes that those are special cases that we need so they're only two cases the first one is the first look is to put all the old children and do this and then handle themselves and if there are some additional notes you just look through each additional note and add them to the enemy does it make sense I'll show you so the first loop you look through each Oh children Oh child of Oh children and what we want to do is but we have some children patch for child child patches right and okay now I can use for off loop because I lose track of the in - so let's do actually you guys know about the SIP function so sin is just kicking into a race and despite easy to understand so let's say the SIP function is taking to arraign why xs and ys and you'll return some sip function sit array where it was just look through let I equals 0 I less than math dot min except not link and why desktop link and you look through what whichever is shorter and then what you'll do is it will push an array with the I element and I'd enemy in the ys and returns it yeah so it's like it says so so whichever is shorter that the outcome the output array would be that one yeah cool so let's do it so so now we can sip the old pro tutorial with the new virtual children right and if we stick them up we will have altered old chum one new top one old town two new tattoo and up till whichever is shorter right so if we sit them up sit the old children Oh fie children and it is seven with the new three children and what we will get is we can be structured right you can get that old speech out and a newbie child yeah and what we do is just give that we've got lists and this will give us a patch and let's put that patch in our patches push and just to remind you that it's not expecting the parent so well to make that a little bit clearer the function that we're returning is actually expecting the parent and will return a parent and what we will do is to apply these patches we simply do uh guess what I'm going to sit again we will sit the old feed children oh actually I'll sit there I'll sit without patches with the parens child notes so parents how knows it will give you an no list of elements so yeah you'll have some test test test mode you have to an element node and we destructed so we'll get the patch and we will get a child so because we got challenged now we can apply the patch to the child yeah so clean and then next thing is the additional notes right so we have you need some additional patches and for each additional child so to get the additional child is quite it should be a third child it's quite easy right we just get them for new virtual child and slice it with the length of old child so this might be an empty list but we don't care because this problem without run then if it is an emptiness so if it's not an empty list you know you have some additional virtual children and what we will do is will render the additional third child and we will well push a patch taking the note and what we'll do is we'll note what we do we should we should we should append child right and we return and this time this additional patches are expecting the parent so we just move food cons patch I'm almost there guys sorry this for no patches and then we will apply the patch to the parent I hope that's it any questions so far before we see the result okay no question no no be transported okay so okay so there's no error that's a good sign hopefully it's working already look at it guys and you can't right now so amazing yeah so so to just show one more how amazing this is the thing that bill of course is amazing but just to show off right what we're doing is in account we will spread an array we create an array that is of length count and each each array will become a element I'm missing a second oh that's right okay so what this will do is will create however many pounds image and you shall see how the image will grow and as you can see we're doing minimal changes so that makes it fast do it say and say if the count one more thing sorry we can instead of incrementing the count let's do some random stuff so let's put a random 10 for the random integer in there so what will happen is every second you will have some random number well okay that's great there's some problem with my code there's some feature in my code but that's the idea behind I hope you enjoy it thank you
Info
Channel: Tech Talks YLD
Views: 17,736
Rating: 4.9537573 out of 5
Keywords: Meetup, Tech Talk, YLD, yld meetup, jason yu, manchester web meetup
Id: 85gJMUEcnkc
Channel Id: undefined
Length: 43min 16sec (2596 seconds)
Published: Wed Dec 05 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.