 I'm super excited to have Viva here. We've been in touch for a while and he's gonna be talking about optimistic UI with GraphQLs and I guess like JavaScript, maybe TypeScript, we'll see. So Viva, I guess that you can go and search your screen and start your talk. Thanks a lot for the intro Carlos. Let me share my entire test score. Is my screen visible Carlos? Yes, you are good to go and all the screen, audio, video, everything is yours. Oh, thanks a lot. Yeah, oh, first of all, thanks for having me here to be speaking and congratulations. We are still waiting for your new job update, actually. And it was an amazing talk, David. Like you just have set the bar so high that I'm already nervous. Thanks for the beautiful talk. Thank you very much. Let's start, by the way. Today, the topic will be like I explained. It's more about optimistic UI, why we need optimistic UI, what are the real-life examples that are already existing and how optimistic UI can impact real UI. That's what we are going to talk about today. Let me be programmed. It's for anybody who starts in this corona lockdown times, people get ideas to get the MVP soon. We have a program for them. Cool, let's begin. What is optimistic UI? Optimistic UI is not a very big, it's a fancy term, but it's a simple, front-end development paradigm. That's how we call it. And what it does is it just, the UI just be optimist, optimist. So it assumes that all is for every action, it's going to be positive response and it already updates the UI accordingly. So the client updating UI optimistically, assuming request is successful is the main definition of optimistic UI. Well, how it works when the real operation is happening actually, it already switches to the final state. So the user doesn't feel like the real operation is still in progress. Does it mean like are we lying to the user? No, definitely not. We're not lying to the user, but we are predicting because most of the times we believe in our code, we believe in our APIs. So we say 100 times, but 100% but no, most of the times our operations are going to be successful. And so we already predicted to be successful and start updating the UI for the user. In other words, if you have to say what is optimistic UI? Optimistic UI is a UI which knows how to manage time well unlike me, like I'm very bad in time management. So why do we need optimistic UI? First thing is it makes, it gives an impression to the user who are using it, like your app is super fast. The user don't have to wait and wait for any operation or get blocked on the screen and just wait for the operation to get completed. It just makes your app feel faster. And the major advantage is on slow devices. It gives a seamless operation, like for instance, mobile devices, even though we are in 2020 we still have Corona and all the stuff, but still mobile devices are slower at areas. It's not uniform, it's not reliable. And in devices like that, the speed, the UX is so important to have a user getting stayed or you just switch steps and goes to the next. To give a good experience to the user, mainly on slow devices, optimistic UI is the best option, I'd say. The next thing is, it doesn't break users flow. There's a reason why I highlighted flow in caps. It has nothing to do with the static type checking flow. There is a psychological concept called flow. Users or generally humans, when they get involved in work, they get into a state called flow where you would have often wondered as developers, I assume most of the people are developers who are attending, you would have often wondered, sometimes when you are working deeply or very interestingly in a topic or in a subject, you will feel like you have reduced the number of blinks or you haven't even blinked your eyes. That is because you are in the flow state. This psychological flow state gets a user completely involved in anything he's doing. The optimistic UI helps the users stay or continue in the flow state itself. It doesn't break the flow for the user. And next thing is, it stimulates the experience. Say, in olden days, we used to see the hentai screen blocking loaders. The whole screen will be blocked with a semi-transparent black ink background and the loader will be spinning in the middle and we have to wait slowly seeing when the loader will get over. So optimistic UI avoids all this stuff. These are the major advantages of optimistic UI. Okay, optimistic UI looks so cool so far. So does it mean like you can implement it everywhere? You can implement it however you want? No. There are a few things which you should consider before using optimistic UI. You should first find where to use it. That is how, that is what I mean by one second can be forward sometimes. Like in for few operations, the user is okay to wait. There, we don't have to use optimistic UI. But there are few operations where the user expects an instant feedback and that's where we should decide whether we should use optimistic UI or not based on your line of business, based on your users and other stuff. Next important thing is response to control activation. So what is this? This is again a psychological term. Response to control activation is nothing but when you do a control activation, this control activation is nothing but activating one of your controls. That can be your mouse click, that can be your keyboard key press, that can be your joystick, slide pen, whatever it may be. When the user activates a control, he expects a response in 100 to 200 milliseconds. So if you see the blink of the eyes is like 100 milliseconds. So we never feel 100 milliseconds as a time at all. We feel if something gets to us back within 100 to 200 milliseconds, say 150 milliseconds, we feel it's already instant because we are used to our blink of our eyes. We never know we are blinking actually. So that's the time, which is very optimal or very good for a user to get response after a control is activated. Hence, you should decide if you're going to use Optimistic UA, you should respond within this time. This is a very good time for using Optimistic UA. And the most important thing, API success rates. Mostly we use Optimistic UA not for something which happens in the front end or in the client alone. We use Optimistic UA in cases where the client has to interact with the backend or with the server, right? That's when it takes a lot of time. We don't know how long it will take. So it just shows the user, like already it's done, it's successful and all this stuff. But if your API fails, it's going to be so dirty. Like the user got an awesome feeling. He feels like in heaven when he's using your app and suddenly a error message comes saying that your API failed. That's going to be having a negative effect on Optimistic UA. Hence, your API success rate should be more than 97%. Only then go for Optimistic UA or just follow the traditional ways where you use loaders and all the other stuff. And like I explained flow in the previous slide, the ideal time within which we should respond to the user, otherwise exceeding the time which the users of flow gets break is two seconds. Believe me, it's just two seconds. If you get distracted for two seconds, your flow gets broken. That's the reason most of our developers like prefer big earphones wearing it overhead and like not focusing on the outer world and just getting core into the core. Reason is, this is the reason, like it's a psychological reason and this flow gets broken even if they are distracted for two seconds. That is why like when I code, I mostly code in the nights, I don't get any distractions. These are the metrics we should have in mind. So if you're even going to do Optimistic UA, of course, every time you can't give a two seconds response, but we'll see how to handle that. But it's so optimal if you can give a response in two seconds that to depending on your line of business, it can be so critical as well. These are the key metrics we should have in mind when we are implementing Optimistic UA. These are the main numbers. Now let's see what are the different types of Optimistic UA with real world examples. First thing is Subtle UI. Subtle UI is nothing but, yeah, it gives us a positive feeling. This Optimistic UA is so optimistic like you do something, immediately it gives you a response. It makes you feel happy. But if it fails, there's no way to know if it failed or if it's in still in progress. It doesn't tell us at all. It just says, you did an operation, assume it's successful, just go and do your other business. Don't worry about this. That is Subtle UI. And Subtle UI with progress is, Subtle UI again, if it fails, it doesn't show you any error messages, but it still can show you a progress. Like say you make an API call and it's in progress. It shows still it's in progress, but if it fails or if it errors, it doesn't throw an obvious message on your face. That is Subtle UI with progress. Next is UI with progress and actions. What is this? When you make a request, it updates your Optimistic UA. Like it updates your UI optimistically, assuming it's going to be successful, but at the same time it gives a clear indication that it's still in progress. And if at all it fails, it gives you a list of actions. This is one type of Optimistic UA. But it still doesn't throw a very obvious error on your face. The last one is Subtle UI with error. When you don't feel it as an Optimistic UA at all, you just keep on doing your stuff, but suddenly when the Optimistic UA breaks at some point, it throws an error on your face. I'm sure Google Docs doesn't do it anymore. That's why I'm not able to get a screenshot of it. I'll show examples or other types in the next slides. But Google Docs used to have a feature like where you keep on typing, but if you're not connected to internet, it will try to sync it for some time, but after some time it tells you on the face. It gives you a popup. It says like you are not connected to the internet, so your changes cannot be synced or saved. This type of error is like, normally the Optimistic UA is Subtle. It doesn't throw anything or it doesn't tell you anything on the face, but when it faces an error, it just throws it on the face. Remaining three things, we'll see it with examples. Subtle UA. Twitter is a beautiful example of Subtle UA. If you see here, I have liked the post and if you see in my network tabs, even so still printing, they have just started. They haven't even given a response yet, but already the UA has turned into a liked state. The post has already been liked by me. This is Subtle UA because I like this. Say after liking this post, I just scrolled down and I just moved to other post. And say if this APIs, which is supposed to increment the lights, got failed. Then it's going to be a problem because Twitter doesn't tell you that this post, this particular post is still not liked by you. It doesn't throw any error. It doesn't show any progress. It just fails silently because Twitter considers like a person not liking a post is not a very big deal. They're just fine with it. But most cases, they are so reliable or confident on their APIs, it's always successful. But there are a few cases in my past as well where I had to use my mobile network. I'll be traveling. I like a post and after sometime if I see it will not be liked at all. So that's something, live example or real world example of Subtle UA. This Facebook Messenger is a beautiful example Subtle UA with progress. You type in a message in Facebook Messenger, send it. You get a feeling like the message is already sent. Like it's so optimistic, right? But it tells you in a very subtle way that it's still in progress. If you see here in the first screenshot, below the text message, you can see an empty round. Like there's a circle, but there's nothing inside. If it fails, it turns into something else. If it's successful, it turns into a tick mark. If it's seen, it turns into a blue tick mark. So this is a beautiful example of Subtle UA with progress. Yeah, it gave us a good feeling. We are happy that our message has already been sent. But at the same time, it's telling us subtle in a subtle way, like the message is still not sent. It's still in progress. And it indicates us when it is being sent successfully. This is a real world example for Subtle UA with progress. Now comes the beautiful app, Tinder. I guess most of you are aware of it. Tinder is very, I like this feature of Tinder. What Tinder does, it shows the progress and it shows the actions live on your face abruptly. Say you send a message to your crush, saying like, hey girl and something. And if the message fails, it's a very important message, right? You can't afford to leave a message or miss a message from sending to your girl. It's very important in a day-to-day life. So it just throws on your face with red colors and highlights, saying your message is not delivered. Of course, even this UA is optimistic. As soon as you send, the message goes and gets added. It doesn't show any loader or something. But when it fails, it throws the progress and it throws the error. And on clicking off the error, it gives you options. Whether you can copy or delete or you can retry sending it. Of course, all of us will just retry sending it, right? We just have to get more matches in tinder. So these are the different types of optimistic UA's, which I could find actually, that can be even more, but I thought this can give you a good introduction or good examples actually. Okay, now we know why we need optimistic UA, what are its advantages, what we should consider and we have also seen some real-life examples. Next, next is the handling errors part. There are two ways of handling errors. We have already seen the two ways in the previous examples. One is the salience wave, like the user should be given a prompt visible error so he knows that this something is failed. This, a beautiful example for this is our tinder. When the message fails, it throws an error on the face and it tells you like your message did not pass through. Second is the casualty. This is more interesting. This is not the type which is used in Twitter. Like Twitter doesn't care about errors at all. They don't worry like if it passes or fails. They just tells you, you like it, make sure you are happy that you have liked it. Just go on with other posts. We don't care if it actually liked or not. This casualty is the type of error which is handled in Facebook Messenger. When it fails, it tells the user that it did not go through or it's still in progress or it failed, but it doesn't throw anything as such an abrupt error. The user can find the reason if he wants, but it's his efforts. It's not the US effort. These are the two ways of handling errors in case of optimistic UN. Okay, we have spoken enough about optimistic UN. What's the next thing? What's the meetup about? It's about GraphQL. So the next thing is optimistic UI plus GraphQL. That's what we are here for and that's what we are going to see now. Before we move on to the next slide, please forgive me, you are going to see the most shittiest flow diagrams in the world. Okay, how does a normal mutation, of course for people who doesn't know, mutation is the process where we write or edit or delete data from a GraphQL server. And normally when we do any changes in the data, we have a tendency to refresh the data in the UI. That's how UI works. So how it normally happens is without optimistic UI. A mutation goes as a request, the response comes. Once the mutation is successful, we refit the query and once the response of the query comes back, the UI gets updated. Imagine how long it will take. So it's going to be so many two-on-fro process, right? This is how normally UI works. We can use actually a method called update which comes by default in mutation because we know what are the things we need from mutation, right? So when a mutation goes as a request and when it succeeds, this update callback has been called and this I've seen to make a other query to the server but since it already has all the data within itself, it updates into the local store or to the local cache. In terms of Apollo, it's the Apollo cache. It updates the Apollo cache and the UI gets updated automatically. This way, we already have reduced one path and we have already may improve the user experience for the user. Now, how will it look if we use optimistic UI? It looks like this. Even before the mutation request goes and reaches the server, the UI will already be updated automatically and in a positive way. And when the response comes back, only if it fails, we revert the UI or we show some error messages and we inform the user like shit, the response has failed. So just please do it again or like just ignore us, we are a shit product. So that is the beauty of optimistic UI. Forgive me again for the flow diagrams. Hence, this is how we are going to handle optimistic UI. Now it's time for code and demo. I have created a dummy or like a dummy backend here. If you see here, I'm running, okay, I forgot the count. Okay, let me start from the first. If you see here, I'm running something in my local host and I'm running a query, 25, okay. I'm running a query where it's going to be, okay, it's a list of search history. And in the search history, I'll get the text and the ID and the type name. Just count with me. I'm counting on new people, so you count with me. One, two, three, four. It almost took four seconds for the response to come back. This is how I have made a delay. Like it's not the actual time taken. I have made a delay in the dummy backend for three seconds. So every operation will be delayed by three seconds. Same goes with mutation as well. So let us try the mutation now. Count with me. One, two, three, four. It's successful at the fourth second. I passed something like text three. Let's check our query now. One, two, three, four. I have text three here. Now, imagine I have a application where I put in some data. I make the mutation. It goes to the server and refages the queries. It's going to take fucking eight seconds to just show me the update. Let me show you it in action. This is the application. Let me run it. If you see, it took almost like three, four seconds for me to show this list. It has four items now. I'm adding a new fifth item, fifth search. I'm clicking on search. One, two, three, four, five, six, seven, eight. And on my eighth second, my history has been updated. What a beauty. And forget about the world's fastest search engine. Like it's just for a dummy search engine. It's nowhere related to Google. I'm not pulling their legs. And it doesn't show any search results. It just updates your search history. It's just a trap. So this is the time it actually takes for the native or the native implementation. Let me quickly take you through the code here. I guess you all of you are able to see me code. If not, you just let me know. And if you want me to zoom as well, just let me know. I'll zoom it. Okay. So I have two components. One is my search input component. That is this piece of area where I make the mutation. And one is my read component or the query component where I just make the query and display it. How do I hide it? Now, if you quickly have a look at my input component, I'm just making a, on click off the button, search button, and just making a mutation. And after the mutation, I'm making a refit query. So the updated data comes back. Now let me turn this into an optimistic way. First thing is let me create my update function. Update is nothing but a function which returns, which gets two parameters as a default argument. One is the store or the local state. Other is the response from the mutation. That is this update function is executed after the mutation is successful. So the response from the mutation comes as the second param for update function. Since I know my response already, okay, I just moved it, but I know it by heart. It's going to be data. And within data, I'll get my add search. And I will have to update or I'll have to modify only if my add search is successful, right? Add search.status equal to success. Okay, if it's not equal to success, then I'll just return, I'll not do anything. But if it's successful, what I'll do, first I'll get the list of local search, local search of the local cache. So let me take it const data equal to store.requery of we need to read the query, which gives us the list of searches. That is nothing but my get search history query. Now, with the data, I need to add my new text. So what I'm going to do, data.search.search is nothing but this one, this object, this array of object. Search.push, I'm going to push a new object, which will have the type name. Don't forget, when you are writing into the cache directly, type name is very important. And my type name is search. And next is my ID. Now I'm, watch carefully, I'm going to give a negative number for my ID. If you watch here, every number is positive, all the ID is positive, but I'm going to have a given negative number. So I will know whether this data, this particular piece of data is being updated optimistically or if it comes from the server. If it had come from the server, it will have a positive ID. And if it comes from the optimistic UI, it will have negative ID. Or it's, I know it's a contrary, like optimistic UI and negative ID. But yeah, that's how it works. There are better ways of identifying as well. You can add a string, you can add a prefix, you can add a suffix, but I prefer this for now. Like it's just a demo. So I'll create a random number. I'll multiply it with by one, okay, some zeros and math dot round. Now I have my ID. Third is my text. I don't have to worry about getting text somewhere because I'm still in the same component and text is already in my local state. So I can directly access it. Now that I have taken the list of search history from my local cache, added one new object to it. Next step is right back into the cache, right? So store dot write query off. Query is nothing but our get search history. And what we need to write, we need to write the data, which is nothing but our modified new updated data. This way we have written an update. But how does it, how does it much different from a normal thing? Like this update gets executed only when the mutation is successful. But already mutation is taking three, four fucking seconds for getting successful, right? Here comes our hero, optimistic response. What are we going to do in optimistic response? We are going to mimic or we are going to fake as if the UI or if the response is optimistic. So hence if the response is optimistic, update function will be executed immediately and the UI will be updated immediately. So it's going to be the add search within which I'll have status as hardcoder. I'll keep it a success because it's optimistic and type name search. Now I have created optimistic response and after the optimistic response, I have created update function to update the cache thereby updating the store. Let's see how it works right now. Okay, let me refresh the page. It has five list. Now I'm typing something new, optimistic. And watch the magic, clicking on search, it got added immediately, but it's in yellow color. Now after eight seconds, it will turn white. That's how we achieve optimistic UI in our applications. So what happens here is last time the user was not sure whether the search history got added or not. Now he can do as many as he want and he can keep on adding. He don't have to wait for the previous one. And after everything gets added, it will get resolved automatically. So there is a race condition. I just noticed. I'll refresh again so you people don't see it. Okay, end of the day it's just here, okay. So this is the beauty of optimistic UI. For the user, he feels it got added automatically or immediately, but only we know that it took like five, six seconds for it to get added. And it's completely optional for you to whether let the user know by differentiating using colors or just leave it without doing anything. So the user believes it got added already. That depends again on your confidence on your APIs. So this is how we achieve optimistic UI on any application for instance. So that's it. Follow me on Twitter for more updates. And if you guys want a quality product or something just contact, send an email to contact at productright.com. Our website is still in building phase. We haven't completed it yet. We'll be launching it soon. And also please do drop some suggestions and feedbacks so I can get better every time. Yeah, thank you. And any questions? Okay. Do you have questions? Yeah. Yeah, first like it was a really, really, really good talk. I think you might want to like stop sharing the screen. That's right. Yeah, such a cruel thought. I think that you has given like such a, like detailed way of like explaining optimistic response from like what is going on like with your reflection query when you're using the cast but also when you're using optimistic response with Apollo. You should apply to work with them because it's one of the best explanation that I've seen about Apollo optimistic update. So we have a question. Yeah. So Tobias actually he's curious about your opinion when using like the difference between using a state and used to meet the UI. So, you know, like maybe you want to use Apollo cast or you want to double yourself, right? With a used state or like a X state like a machine or like reduce or whatever. In which cases do you really prefer to use like the Apollo cast or do you want to do that manually? Whenever it's going to be a mutation Apollo is my only choice. Like because I don't have to do stuff manually maintaining everything myself. If I decide to use GraphQL in application my entire state results around like my entire application results around GraphQL even for local state management I use Apollo. So, Apollo is the out of box solution but not for every project I decide to use GraphQL. So when I don't use GraphQL I do my own methods I have reusable functions which updates the states and looks for changes. I use observer observables at times when I have to look for this, that's how we use it. Oh, that sounds really good. And yeah, I totally agree with that. It's super interesting like the new feature from the Apollo cast in the person 3.0. So that's going to be also like interesting like we might check this out in our like upcoming events and I might have that probably the last question before we wrap it up. I would like to hear your thoughts about let's say that we are going to have the optimities out there, right? How would you deal with kind of like if you are using Apollo and you want to invalidate cash some values, how would you like to do that or how you are doing that in your like current projects? Currently it's a hell I'll say because currently it's a huge, Apollo cash is a huge chunk of objects and mostly we try not to invalid separate cash and we just remove it completely and or like we take the entire cash object, manipulate it and put it back. We have a library called Apollo cash persist which lets us manipulate cash and persist cash. We make few features of it but I'm just waiting for the new version to be stable soon because I have already gone through the updates of cash like invalidating cash, emitting a part of it garbage collection, everything is super cool with it and it will definitely remove huge chunk of quotes from our code base. Like the custom code which we have written, the pain in the ash we have, everything will be taken off. That sounds, yeah, I thought I would get that so yeah. Perfect. So I think we can wrap it up. So like firstly, thank you so much for joining us today for giving this incredible poll. We have a lot of proposal but you reached us out like long time ago so I said, goodbye has to be here, the first one. And so yeah, thanks so much for like coming here and just like joining and like sharing your knowledge. So yeah, I really, really hope to see you sometime soon. Yeah, sure Carlos. Maybe after all this lockdown shit gets over we should meet somewhere. Yeah, that would be great. So I think like we can, now we are gonna like a jump into kind of like, oh.