Architect's Guide to Frontend Frameworks - Tomasz Ducin

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
okay so hello everyone thank you for coming to a JavaScript talk at a Java conference I think it's a very wise choice there are three certain things in life death taxes and the fact that somebody has just published a new JavaScript framework today what's even worse is the fact that front-end developers tend to rewrite their code bases over and over again all too often so if there are lots of tools out there we could choose from so a question arises when is it worth to invest to migrate our codebase into something newer the motivation behind this talk is to discuss fundamental design decisions behind the most important frameworks you will not learn how to code in these this is not a tutorial instead we will focus on the trade-offs behind these design decisions we will focus on weaknesses and strengths and we will get a big overview of what we can expect from certain decisions my name is Tomas du chien I help developers create better software I work as a consultant the products we've worked on are used by very big companies including fortune 500 apart from team project work I also do developer trainings on front-end technologies this include JavaScript typescript angular react and last but not least architecture so if you're in need of consultancy or training please feel free to reach out to me so having coded in over 10 different front-end tool stacks I came up with a conclusion that the most important difference between those is actually how does a framework know that something has changed and now which part of the view should get rear-ended and when this boils down often to pool versus push architectures and an example we might get is if I have a dependency inside my codebase for instance unit a depends on unit B and now if my framework requires me to explicitly define this dependence see then I know that or if it explicit or requires it or if it could come up with this implicitly then I could expect that if B value of B gets updated then a gets rear-ended by but nothing else gets rear-ended because nothing else depends on it however if my framework is unaware of that dependency potentially it would have to rerender everything in order to guarantee that the view is basically refreshed simultaneously for the user so and this second approach might have a very bad in effect on the performance so these are going to be the most important differences so let's start with something that we all know which is lingua franca of the web jQuery jQuery was introduced in 2006 which was a long time ago and jQuery is a tiny facet over built-in browser API its main purpose was to make it more convenient to use JavaScript and CSS at all today nowadays in 2019 using benefit using a jQuery will not make you benefit at all because both javascript and CSS and the browser API has improved tremendously so if you are considering using jQuery you will not benefit more comparing to using just native platform so let's take a look at a sample application in jQuery if we hit the dashboard button link we get the red box rendered now if I click a link I would like to have the tiles updated finally if I type something into the search input and I hit enter I would expect that both my tiles and the red box updates now the problem with jQuery is that nobody actually keeps track of the state of the application nobody owns the state so basically all different pieces of the application would share a little bit of the state and we know that if we have multiple sources of truth then we might fall into trouble with this synchronization or if we want to think we would have to do this manually because jQuery will not do this for us another thing if we have dynamic pieces of UI as this red box which would have to attach new event listeners it means that we have a dynamic event listener if we click dashboard multiple times it would mean that potentially we would have to attach event listeners multiple times so either we have to detach them manually or we would have a memory leak in JavaScript moreover if we attach an event listener to the dashboard button and we render this red box then we have a tight coupling between them there is no proxy right and of course we could introduce a proxy but apparently almost nobody did that because doing tight coupling is just the most straightforward there is a solution right here right morover finally if we have a bug in a jQuery code it's very difficult to reason where did this bug come from from just reading the code most often we would have to end up doing a long debugging session just to go piece by piece line by line what is the state of certain pieces because in jQuery everybody could talk to everybody in all directions so it's opened for quite a bit of chaos so not only for the reason of browser API is being a lot better nowadays and also due to a lack of architecture there is absolutely no good reason to use jQuery nowadays all in all it ended up with this approach which we don't want to carry on with so the first most important framework in JavaScript ecosystem was angularjs introduced in 2009 it introduced two very important features into JS ecosystem the first one was dependency injection so let's take a look at few lines of code here we could define a module that has a dependency on another module we could define a service the department's model service that depends on HTTP service and on a base URL constant which is defined somewhere else finally we could define a user page component that depends on the scope user context and departments model service defined just above there is nothing special or peculiar about this dependency injection however it is very important that angularjs team introduce it because back then ah sorry back then JavaScript had no built-in modularity no built-in system to declare dependency so basically front-end developers ended up adding lots of script tags so it was inconvenient for not only adding multiple script tags but also what was even worse maintaining the order between them even if I took my application code and squashed that into one file being it concatenated ugly fight minify does matter I still had to care about the order which was really very difficult to cope with so basically what dependency injection did was I could add those script files in any order and only in runtime the write dependencies would get resolved because here I just define what are the dependencies so dependency injection solved a very big issue it's not such a good idea to use dependency injection in angular 2 plus but we will get to this later on at this time it was a very good idea the second and feature of angularjs was introducing to a data binding basically I do have my view and I have my model model is just some JavaScript objects that live in RAM memory so if I want to synchronize model with the view I just get the value of a variable and display it or if I want to do it the other way I attach an event listener with just the famous ng model directive and I want to update the value of the input into JavaScript memory so I could do it one way or the second way or both ways at the same time so it was very convenient for developers to write very little code to get lots of stuff achieved angularjs is super performance for developers to prototype applications but the engine that fuels this to a data binding and actually all data bindings is not the best let's say piece of software design so it's called the digest cycle so basically if I want to an update model to the view or view to the model I create a single water for every piece of this update an angularjs application is structured with components so we can see that there are components here in this application each box is representing one component so one component or directive will have multiple Watchers so when when there is any change in the application just anywhere it's important anywhere then the whole application would have to rerender so it's a lot of work to do so basically the route component would have to run all the Watchers see if the value that the new value is different than the previous value iterate through all the Watchers then iterate through the tree of components iterate through all the waters of this component and again and again and again again and so on so I would have to render the whole application finally it might happen that I have a service that shares some memory and I would like to update a value of the service that another component depends on and this dependent component was already rendered so I would have this my guarantee of updating the view broken right so I would have to go through the whole cycle again and this it happens that at the end of this digest cycle there would be yet another update then I have to go through this digest cycle again and again so you can see how killing for the performance this algorithm is this was angularjs it was not meant to to be a production wise application system at least not such big system as we have nowadays the problem here is that when we were updating the values of the services it was a pool based approach so basically we were updating just a property and the property does not let anybody know that it has changed right so angularjs does not track what should I update if a certain of my application updates so in order to guarantee the freshness of the application I have to update everything because everybody talks to everybody in all directions so the less framework knows about my applications the work or worse performance we can we can get so a completely different approach has been chosen by the react team which suggested something completely different the virtual Dom idea but before we dive into it let's take a look at how react components look by the way how many of you are using react ok some of you maybe 20% of the audience so just a quick reminder we create a react component just by creating a class that extends react component there is the most important render method internally it has to be implemented and the render method rep returns some piece of the view some markup what is important it's not being injected into the Dom yet what render returns is a virtual representation of the view and this is a very complex inversion of control technique that react is going to work on a virtual representation of the Dom a lot until it actually touches the Dom in order to get better performance we will see this in a while so a component will often have some state so what react changes is react introduces ownership of the state it has to be explicitly said that this component on some state it will be very important in a while our example component has a button on click handler so basically when we click the button a function will be called and this function calls visited set state set state is the gatekeeper of react this is a method that tells that the state of this component has been updated so potentially the view needs to get rendered so whenever we update the state react we'll have to render this still we are in the virtual phase so we will rerender and we can see that this this dot state that count has a new value already so it will create a new representation so not only the current component have had to rerender but potentially this component might have child components either one or multiple children that may depend on its state or not in this case child component gets account property called prop it gets some piece of data from the parent and also this means that not only this component will render but also all its children recursively so the improvement that we have here is that not every another old application will get rendered by but when a certain piece of state gets updated this component gets updated and all its children but nothing else no neither of the siblings nor the parents there is basically no need react introduces one-way dataflow so now it's not that everybody can talk to everybody no we introduced one-way dataflow the data will flow only from up to down there is only one direction possible so we have seen a class component so far a class component is basically an object service it has an identity it reside resides in RAM memory which is pretty obvious and we have function components that do not have any identity there is no this so there is basically no piece of memory that this component would reside in react introduced view as a function approach so that forgiving props I would like to have some markup I would like to get some view so it's making as little code to define our view as possible reacts probably requires us to write the least code comparing to for example angularjs and angular these two are equivalent there are some additional features like react whose that are not going to cover in this presentation because it could not basically fit into one talk so reactive code system react community came up with an idea of component architecture which basically introduces a distinction between smart and dumb components or being more politically correct container components and presentational components the distinction is based on the fact that presentational components are responsible for how the component looks like so just HTML CSS this kind of concerns and the container is responsible for doing the whole application logic which is doing what services calls managing state managing user data cache cache invalidation and so on and so forth so if the presentational component has a button and this button is clicked this button this component should not know what is its purpose so basically the parent the smart of the container component would create a function that would have encapsulated call to this dot set state and it would pass this function it was it would be a closure it would pass this function into the child so and the child will basically get a function it's like command handler pattern in object-oriented programming when I'm when the button is clicked I call a function but I don't have any idea what this function is doing so it's just a very nice separation of concerns component architecture makes so much sense that it's used nowadays in react angularjs the new versions angular view and so on and so forth it's it's a very general approach to do modern front-end nowadays so let's get back to renders as in all platforms there are operations that are cheaper and more expensive in back-end programming we know that the operations on processor are the fastest because everything is already in the processor operations on RAM memory are still quite fast but if you want to process something from files we would have to open these files read the data right and we have to wait on IO operations and the worst ones are network operations because not only we have to wait for them but they're also prone to network policies and similarly to the expensive operations in the browser the most expensive operation to do is to manipulate the Dom so for instance if I want to add a Dom node or remove a Dom node or I add a class or remove a class potentially I would have to recalculate all the coordinates of all the diffs pans articles P DS and so on and afterwards I would have to repaint the whole application so the thing is I have to do it anyway because there is no way to update the view for the user but the thing is I would like to do the manipulations on the Dom in the shortest period of time that is possible so the idea behind react is to collect all small atomic changes and when I have already collected them just walking to the Dom do pick pick pick to do the changes and go back so that there is only one recalculation of the Dom thanks to it the user experience is a lot better because the the application is fluent so let's take a look at this this is a simplified structure of the Dom it's just a tree structure we have a div with two body with two divs and a span and and some more elements you might be familiar with the same concept that looks more kind of like this right that's just the tree structure of the Dom so now what react introduced is so-called virtual Dom we still have the Dom in place but you want to encapsulate some pieces of the real Dom with the structure of react components so we have one component and the second component and yet the third component their parent is encapsulating all of them and the parent has to be mounted somewhere it might be a div it might be even the body tag finally virtual Dom is not yet the real Dom it's just a JavaScript object representation which we'll see right now so you might be wondering how does react work how is it written in JavaScript with this funny syntax of HTML tags put here actually it's also a nice example that that the good practices of yesterday are tomorrow's anti-patterns some time ago there was an approach to write non obfuscated JavaScript so that JavaScript code is in JavaScript files not in HTML similarly CSS resides in CSS files not in HTML and that was a good practice some time ago but now react breaks it in one direction angular breaks it in another direction so it's not a good practice anymore anyway JSX is being transparent raw JavaScript with a very very simple translation process basically whenever I have a single sorry there is a delay whenever I have a simple tag it's going to be transpired down to one react create element call so we have one div this div has an heading one child and another IMG child so react dot create element returns just a JavaScript object that represents this virtual piece of Dom it's just a JavaScript object with some properties now what is important this is already pure JavaScript so if we want to do static typing we might just use typescript for this reason right so we have with very little effort already made by the typescript team there is not only JSX but also TSX thanks to this we have statically typed templates which is a phenomenal improvement for front-end because now we will get all the typos during compilation phase not only all the typos but we would also know that a string is not an array so certain methods are not available it would not get them in runtime we would not get some obfuscated JSP or JSF error messages we would get plain types with math error messages which is super cool because if I'm using a simple template engine which is close to the native language then potentially it's very easy to adapt typescript and react support for typescript is very very good actually it's better than angular which template engine is a lot more complex it's just more more far away from JavaScript so that is just not easy to use typescript for this reason so when we hit render we are actually retrieving an object that represents this virtual piece of memory now let's get to the heart of react the diffing algorithm which is also called the reconciliation so as we have initially rendered our page and we get the tree at the top that we can see so this is just a representation of what the view should look like now at some point in time it gets rendered into the Dom so there is basically a snapshot to the visual part at some point in time there will be a you this dot set state update and at this point all the components would have to rerender so we would get another representation what react is doing in the first phase the render phase the virtual one it's comparing the two trees and creating a sequence of changes as you can see this diff item here it's creating a sequence of atomic changes that has to be pushed it has to be just injected into the Dom this is an asynchronous process because during this difficult some more write it cannot be it should not be synchronous because there would be multiple Dom updates if I make it a synchronous I could just collect them asynchronously so finally when I have collected all the changes that I need then I can just go to the Dom do the updates in a very short period of time and basically I'm done and this is the comet face so this is huge a tremendous improvement over jQuery and angularjs so now we have already spoken about one-way data flow in react going back the idea is that the prob the state or the props of components will be pushed down to all the children so if a component state changes then we have to rerender it right potentially render the the whole the whole tree so now what a state of apparent becomes properties or so-called profs of the children and now this component also has to render potentially propagate some props down to the children so this is just the idea as you can see if I would update this component there is no need to update another piece of the tree you might be thinking where does the react name comes from what is actually reactive in react so the answer is pretty simple the inversion of control technique be kind react makes me as a developer only responsible for declaring what the view is how it looks like but I don't ever care about when I should do it or which part of the view I should rerender so I don't care about this react will do it for me as long as I use the API to update the state so basically as long as I'm doing this dots at state or hooks I'm safe now you so react react to state changes with updating the Dom that's the idea you might be thinking well if a component state changes it passes some props down to a child and if it happens that a child is receiving the same props over and over again still in react view is a function if we have if we have class components still we are calling the render method so still a view is a function if I get the same data to a function I should expect the same result right pure functions and all this kind of functional programming stuff so basically I would like to have a functionality that if I get the same props over and over again there is no need to render right and this is what I can use pure components or memo components for so if I find out that the previous props that I have already rendered are the same as the new props I don't do anything right so there are no new renders because I have already done this job this is based on immutability it's very straightforward if I have a functional component the only thing that I change is I have to wrap this component with a react that memo call that's all I do in functional components and in class components all that I do is to change extent reactive component with react dot pure component that's basically it now comes the important part about immutability if a component receives props and it could receive quite a lot of these props if I had to compare two objects which are pretty big I would have to compare all the properties recursively and if I do it often and in react I rerender the components pretty often this would be pretty heavy in terms of performance so what I could do is to use a lot more memory so that each change of an object will create a new snapshot right so I'm come I'm doing immutable data structures I'm using significantly more memory but thanks to it if I compare two objects I only compare their reference and there is basically no faster operation possible to compare two big objects than just to compare two numbers to addresses of memory so this is how we achieved thanks to bigger consumption of RAM that's the trade-off obviously we can improve performance sorry when speaking about react and angular it's very often discussed along with state management this is probably the most hot topic in JavaScript ecosystem right now so basically either some piece of state might be private privately owned by a component or it could be shared across a bigger piece in the application the most important player here is Redux if we didn't have Redux and we would like to propagate a change from a child component we would have to call the callbacks to a via each step to reach the parent and then the parent would have to propagate the change down to all the children so there would be lots of code required the maintenance of this would be also very expensive in terms of our development because if there would be any change we would have to touch lots of places so the trouble we have here is solved by Redux it's just going to be a proxy that would be a shortcut across different components so one component would dispatch an action an action is basically an event something has happened for instance I changed a country from a drop down it's not Poland anymore it's Czech Republic I am letting Redux know about this this change so lots of the state that has been private to a component now becomes a part of Redux store Redux is owning lots of the state that used to be part of components right now so Redux is holding a lot of state Android it receives actions from some components and now comes the heart of Redux which is reducers for a given state object and an action object calculate a new state object which is pretty trivial reducers have to be pure functions bla bla bla I'm not going to cover Redux tutorial so basically when a new state object is being calculated certain components are being notified about the the change so again we know which parts do depend on this item and potentially all its children also would have to get pre-rendered so we are making a shortcut that's one thing another thing is it's not an observer pattern it's more kind of a pop sub pattern that still it's an observable but the two components the publisher and subscribers do not know about each other so there are a lot they're loosely coupled between each other so it's easier to work on this and easier to refactor now Redux is centralized it said that it has to be a single source of truth this is a singleton as long as in back-end system Singleton's are considered an anti-pattern because it's a lot more difficult to leverage scalability to put a system in a cloud if we have lots of Singleton's that share state in front end it's not a problem because if we execute an application we usually do it on one screen we don't run one application across various screens right it's just one screen one browser tap one thread right so having a singleton is not a problem actually having a centralized source of a centralized state source is very good because there is no problem with D things and this is why Dan Abramov author of redux decided to go this way so I another feature of redux is even sourcing so basically Redux keeps track of all atomic operations that has happened all the actions all the events and I would like to demonstrate a small demo of its capabilities so this is to do MVC application a pretty famous approach to compare various JavaScript implementations so let's say we on our to-do list we want to come to Krakow oh sorry to enjoy devoxx PL of course and now well we came to Krakow we are already enjoying the box and let's say I want to keep my list clear so I clear completed items and now I would like to learn about something that is cool and popular in Java community let it be calf calf dreams I guess that's the thing right now and to listen about JavaScript architectures so there has been some actions that I have dispatched and now what Redux is capable of is doing lots of very useful operations within redux dev tools so first of all Redux keeps tracks of everything that has happened so it's like keeping a database of all the events that has happened in the application like it's not a persistent database but as long as I'm running this application I do have them in state what I can do is reason about the application using time traveling so I can see how did I get to the point no system before Redux was capable of doing this what even sourcing allows me to do is for instance what we had in Back to the Future movie I help you you we all know this when Marty McFly came back thirty years ago to the times of his parent he has given the Almanac to bad guy and there was a new branch of history right that arrived relax is also capable of doing it I could see what would happen if some action has not taken place so if I didn't clear the marked items what would the history be so let's take a look how this would look like it's just not cleared or for instance if I have cleared but I didn't let's say mark enjoy devoxx conference as done because devoxx is still taking place so I'm still enjoying the box so I could see alternative branches of history now let's say that we do have a bug in this application and I'm submitting a back to some bug tracking system I should declare what are the steps to reproduce a bug but additionally I would download what are the actions here so I'm basically downloading a JSON file just a JSON file that would include all the actions and now when I submit a bug another developer would open my application and that developer would simply upload the state of JSON and voila the person knows what what was the state how did I get there so it's a lot easier to reason not to mention that this developer could see what would happen if and so on and so forth imagine all the situations where you came to an old legacy system where you had to fix bugs that were introduced by some developers who have left the company lots of years ago right and there is nobody who would know how does this code work now having everything in place it's a lot easier to reason so we cover time traveling we covered alternative branches of history of what happened in our application one more feature of redux I would like to discuss is hot module replacement so basically the thing sorry the thing is if I have to click all these events and I would have to modify how does Redux interpret the actions that have been dispatched if I get my application reloaded then I lose all my state and I don't want to to lose it so what I can do is to tell webpack that if you change the reducers please do not reload the whole application only inject the new reducer so inject the new way that you interpret what does it mean that an action has been dispatched but please leave the whole ram memory and leave all the actions in memory as they were so we might for instance change that instead of having just a text string we would like to have text to uppercase and without any additional workload we get the things or if we want it to do something more like no james hetfield style yep we can get the same things over and over again yeah so hell yeah now imagine that we are working in a banking banking system and there is a bug in banking scheduling transfer process it's a multi-step process first we have to open a model we define a model window we define whom do we want to pay when how much etc in the second step the system asks us are you sure that you want to pay this amount to this person bla bla bla in the third step we need to validate the transfer with token or an SMS token and finally in the fourth step the final step we get a confirmation your transfer has been correctly scheduled and now imagine you have this is a situation that I had some time ago in a in a Polish Bank but I have an error in the fourth step and I am NOT receiving real sms's but I am saving some kind of mocked emails that not only I receive about the whole IT department receives so that was pretty cumbersome to use now what I would do in this case is I would basically click through all this process to the final step once and then I would only modify the logic of the reducer this would make it a lot easier so this is hot module replacement in redux sorry having said that Redux is pretty powerful I need to be fair and to say that this even sourcing is really really powerful but it comes out quite a bit cost so we have to implement constants we have to implement action creators reducers themselves we have to learn about functional programming patterns we if we want redux to be performant we also have to implement selectors to leverage immutability if we want to have more complex application flow we would use plugins for redux called middle words the most important ones are redox tank redox Agha or redox observable so the epics reactive ones and last but not least finally we would have to implement a bridge between redux and specific framework components like react Redux or some other implementation so there is quite a lot overhead that we would have to do so we can get a lot using this front and even sourcing but the price is pretty high now there comes a question what if I would like to get the benefit of not drilling this application down through all the steps but I am not sure if my application is big enough or complex enough that I do really want to pay the price for this even sourcing my choice of preference for small applications or applications that I don't know if they will grow much is to basically introduce a custom a small pops up for small piece of the state anywhere so basically this could be a two liner three liner so if I implement it very fast I don't regret removing it very because there was not much investor I can basically remove but the thing is these components would be already customized to subscribe to some source of data obviously if the number of these pops ups will be growing too much then I would consider replacing multiple single topic pub subs with one even bus so there would be just a one pub sub but it would handle multiple topics so it would not be that kind of chaotic like the other of the art of architecture in some way based on the fact that I should not necessarily make the decisions up front I do not know if my application is going to grow big or not I would like to delay the decisions so this is an example way to do this and if my application grows very big and if I'm failing that there would be more developers coming or this application would last for many years from this point I would decide to go one step further to increment this and basically to replace this very tiny layer of pops up with a hole reducer so it's not either/or it's not that I would have to throw out a lot of implementation no I just do an incremental change I don't have to start with Redux a very good implementation of both single topic pops up and an even bus are rxjs subjects basically rxjs and rx Java is pretty much the same concept the same stuff the differences are only a and syntax and the constraints of the platform itself for instance Java Script is single threaded and so on and so forth sorry let's go forward and talk about angular angular has continued with many decisions from angularjs some of them are a good idea some of them are not including dependency injection to a data binding and so on angular also leverages lots of ideas that come from react itself for instance mordom components component architecture and so on so I would like to start with a collision between dependency injection and lazy loading so at the times of angularjs our applications were not as big as they are today so today we don't want a user to load ten megabytes of an application because it's just too much especially for mobile devices so we would like to download only the main page or the main piece of the application and only if I get to some specific tab in my application which very few users are doing then I would synchronously load this module into my application now how this falls in conflict with with dependency injection is that dependency injection would like to know what are possible classes what are possible instances that I would like to use and in server technologies like Java or C sharp is perfectly for Python whatever is perfectly fine because if I start an application I do have all the files locally so there is no problem to basically read the files right bootstrap might take longer but the runtime of the application is important I do have access to all the files but if I lazy load my modules and I do it very frequently in modern front-end then I don't have access to the source code of the whole application so how can i declare dependencies over the things that I don't have yet so this falls in conflict so if I want to create boundaries of what is possible for the dependency injection container to handle I have to create yet another boundary for this and this is unnecessary that's the of the key point so javascript since es6 introduces import and export keywords so we have modularity built into the platform which is very useful so this is the reason like there was no import and export and this is why angularjs introduced the dependency injection now once it's built into the platform it's not needed anymore moreover javascript has npm node package manager which modularized is not only single files but the whole packages just like maven in java finally angularjs unfortunately introduces yet another system of modularity which looks kind of like this we declare a module ng module which has declarations of components at filters I could pipe and I could use I could import another module so that I could use their features if I want my component or my local pipe to be available in other components I have to export it manually sometimes I have to go down into some angular black magic and declare some provider this is one of the most convoluted parts of the framework and finally for the main module there is a main view that bootstrap the whole application the root component which is basically the bootstrap so this information are important but the problem is that I do have to import and export them on native JavaScript level anyway and if I'm doing multiple products on some kind of shared component library I also have to handle javis and PM packages so it's not that angular layer replaces or works on top of the native modules I have to handle all of them not to mention that this is one of the most over complicated part of the framework unfortunately so at the top I would have to have all the imports and exports anyway so basically I'm doing this stuff twice at least twice so what I could do in new JavaScript I can export a class obviously so this is what happens in Java in a class I can in a file I can have a class which is basically automatically exported within a package I don't have to write the expert because it's exported by default in JavaScript I have to do it explicitly I can export an instance this is how I can make an instance shared across the whole application because if multiple files import an object this is going to be the same object moreover I could export a primitive an object literal a function that returns a fresh literal or I could even enforce that when I call this get literal singleton I would like to have the value returned by that function and it's also going to be cached so if I call it multiple times I call it lazily I am guaranteed that there would be only one instance so this is a very thin alternative to dependency injection which actually react uses you might say that okay but your tests are going to be flaky because if you share the same instance for many tests then those tests would be dependent on each other which is very bad in terms of tests so no problem instead of instead of exporting a single instance which an application is going to use you can additionally export a function that will produce a new literal or a new object whenever you need it so that each test can have fresh data this is a lot simpler and this is pure JavaScript so if you know the language you're good to go and you don't need to go through any additional black magic so I have covered this kind of this piece of flaky design in angular now let's take a look at how a component is structured so basically a components in angular are always classes there is no API for functions so angular is a lot more imperative than compared to read X which is declarative I also have so called typescript decorator attacks from decorator is like Java Java on notation or a c-sharp attribute basically the same concept I have some metadata there the most important metadata is the template so this template looks more or less pretty simple but I have some custom syntax there like ng if ng for which does not translate to JavaScript that easily and unfortunately angular templates are not capable of using typescript out of the box so there has to be an NG Factory a custom implementation with an angular that would compile this template and do lots of black magic stuff that would build some typescript on top of that so it's a lot more complex we don't get type scripts and supports so easily we do have them but the error messages for instance are quite a lot obfuscated so instead of props in react we have inputs they play exactly the same role and we have outputs in react parent component was pushing a function to the child so whenever a button is clicked the presentational component will call the function being of what it does angular takes a different approach this component is going to emit emit an event and potentially the parent will would subscribe to this event this is all fueled by rxjs so basically we have an output which is an event emitter it's an Rx subject basically it's an Rx subject so when this button is called then we are emitting the value and we modify the internal state in to some degree so these are angular components now important piece of angular is its chain detection algorithm so in angular j/s there were everybody was talking in all directions and the problem was that the control flow in angularjs was pool based so basically if I was depend on a service that has a property I don't know when does this property change its value and that's a problem right so we want to invert the control to make it better and now change detection in angular bases on rxjs reactive streams so basically instead of having a variable I am going to subscribe so I know exactly when the change had taken place but I don't know where it took place and we'll see this in a while if I have a component that is emitting an event and this event has a concert this event has yet another event as a consequence and once one more event as a consequence this could be events or this could be a chain of promises I believe you have seen a chain of promises like do HTP that get dot then dot then don't then so another step another step another step the limitation of JavaScript is that through all these steps javascript is losing the context of who have called this for instance a promise would push the return value of the promise to the next step of in the chain but it would not push any additional information for instance who initialize the call so we know what has happened but we don't know who has started this thing so angular introduces what is called zone J s zone J is basically wraps all async api's in the browser events promises async await our extremes and so on and so forth with injecting the information about who started all the thing so basically when I'm done I know who was the initial caller of the thing so I know whom to update in the end so again we're trying not to render the whole application but only a certain part of it so that was a very good idea another good ideas was to introduce typescript as the source of angular framework itself so angular was the first framework first major framer to introduce types up to a massive scale now nowadays all major framework support typescript react view angular angularjs but angular 2 was the first one to introduce it so even though the framework could benefit from it slightly more as the community has tremendously benefited from this because typescript got a lot more popular thanks to it your Java developers so I don't have to convince you that static typing is a good idea especially in big projects or project that will long for a for a lot of time lasts for a long period of time another good idea in angular was to introduce rxjs reactive control flow to the system basically in interfaces like we could have interfaces that have really big forms that there is nothing going on in such an application I would not necessarily use our exists because it would not make me benefit but if I have an application that data is changing in real time or I have for event forums that are very interactive for instance if I check a select a checkbox then some piece of the form will show up if I change a select drop-down item then something else would change I could have a forms that I could play with so R with rxjs I can basically what are the reactions between the items and I exactly know when they happen because instead of having a variable I will have an observable that will basically let me know when it happened so we'll take a look at this right now I would like to start with reactivity from imperative code to compare with so this is the easiest piece of code that I think I could illustrate reactivity I want to exchange my local currency to foreign currency for instance exchanging Poly's Lotus to Euro I have rate variable I have an amount variable and I have an exchange variable that declares that it's amount divided by rate now if I change the value the exchange has an initial value obviously if I change the value of rate we can see that exchange is distinct right I have to update the value myself so you could think like that's so obvious right but the problem is if I have if I have an application that has not as it doesn't have three variables but it have 300 variables or 3000 variables more likely then it's very easy to forget about this kind of dependency so what we actually have here is that exchange has an invariant that exchange should always reflect amount divided by rate now if any of these pieces change I have to update the thing and the problem is this is my responsibility if I am coding imperatively so this is the benefit that I get from reactive programming so this is a pseudo code this is not real rxjs code this is a simplification but basically instead of having variables i define observables so a snapshot of a value that will let me know when it changes so i have an observable of rate observable of amount and i have an observable of exchange that will subscribe to amount it will subscribe to right if they both have an initial value then exchange will also have an initial value the thing is if I change rate or I change amount exchange would recalculate because it knows when its sources have pushed a new value so it would also propagate a new push of its own value so the heart of reactivity is I am I've got this invariant that is basically put natively into the platform if I define it once I never ever have to care about updating the value manually and in big codebase this really helps the cost of this is learning reactivity which is not that easy in real code we would have to do amount dot combined latest with rates who basically get the latest value of amount combine it with the latest value of rate and whenever we have any change basically run this function combine latest is one of our X J's operators there are around 100 or 130 depending on the convention different operators so there is quite a lot of them to learn and operators is only the first step of learning reactivity so there is quite a lot to learn but there is also quite a lot to benefit from so three so I could say that reactive extensions whether it's rx dotnet rx Java rxjs and so on and so forth reactive extensions redefine what a variable is instead of having a variable which is a snapshot of a piece of memory I get an observable stream that will let me know when a value has changed so that this invariant of my application logic is basically baked into the platform and it makes it a lot easier to use so the key takeaways from this presentation first of all all major frameworks support typescript so please use it whether you're doing angularjs or security old ones you will have very good typings despite the fact that those frameworks were not written in typescript reactors also not written in typescript react view and all these tools will make you benefit a lot Redux is very powerful and so is even sourcing also it support for all the frameworks we could use Redux for react we could use ng rx for angular which is absolutely the same thing but is more reactive we could use view X and other similar tools however implementing this comes at a big cost so if you're unsure if you want to make that investment go with a pub/sub implementation now if you want to choose a framer that's a debatable topic but if you're not scared of functional programming if you're familiar with functional programming react seems to be the state of art of front-end 2019 according to lots of survey's you write potentially small code that would be very performant and it's very clear what is nice and react is that you don't have to learn many things but if you forget something you can deduce it you can think it out in angular more you have to learn by heart things are not that easy to deduce you basically have to go through documentation over and over again and you have lots of custom syntax but if I had a team of Java developers who are very proficient in object-oriented and not necessarily proficient ways functional I would go with angular because going react and redux would force the team to first learn functional programming for a few weeks or a few months and then to become productive finally if I find myself in a situation where I have multiple code base code bases written in various frameworks there is no need to rewrite the code base to make it in a single let's say tool stack we could leverage micro front-end and that's a very broad topic and apparently there is another talk about this but basically I could go with either iframes or bundled applications with a host app that when I click one link a new application would be bootstrapped either linked via iframes or basically bootstrapped with bundled web pack application I would be bootstrapping this application I would be destroying them and I could basically the host app would collect events from the suburb locations all in all this is a separate topic standalone topic but I don't have to rewrite these things go and learn about micro Franzen's so that you don't have to rewrite the code basis so that was quite a lot of stuff I guess that's all I've got thank you very much [Applause]
Info
Channel: Devoxx
Views: 5,090
Rating: undefined out of 5
Keywords: DVXPL19
Id: HI2vFGxiwkM
Channel Id: undefined
Length: 60min 43sec (3643 seconds)
Published: Mon Jul 29 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.