About this talk
UX and design seem completely separate from development for a lot of engineers. However, frontend developers are often the last team that has impact on final product, and that is why improving the UX is their job. Frontend devs should provide the best possible quality. Kuba will explain what the key UX topics to address by frontend are (being fast, feeling native, indicate current state and handling errors) and how Ember and its ecosystem can help achieve these.
Hi. Nice to see you all, guys. My name is Kuba Niechcial, called Jacob also. I will today try to tell you why improving the UX of Ember application is developer's, or actually, our job. First, let me tell you a few words about me. I'm Kuba Niechcial. I'm senior tech leader. I was senior developer. Right now I'm senior tech leader at Netguru. For last three years, I was mainly focused on Ember.js. I took part in couple of commercial projects, I wrote couple blog posts, and did some small open source. Right now, I move throughout the pre-session development but I'm still very interested in Ember and that's why I'm here. A few words about my company. Netguru is one of the top software services in Poland. We have grown pretty fast over the last two years from 50 people to over 220 right now. And I think that 40 or 50 of us are working or have been working with Ember. So, today we will be talking about UX but what, what actually is UX as seen by developers? Because I think that most of us have been working with design guys or UX guys and at least saw how they approach problems with data, with user service, personas, and so on. Actually, it's not our job. Our job is coding, so... On the other hand, I still believe that in a little bit different manner UX is still our responsibility and I will try to show you why. So, what does it mean to have good UX actually in single page application? Do you have any ideas, insights? What's the most important about UX in single page application? - [Voiceover] So you can really orate. So, again, do you have an idea of what's really important about the UX in single page application? Um... Okay. So, in my... I thought so. I was prepared. So, I have key... Four key indicators. I think that to say that the single page application has good UX is it means that it is fast, it feels native, it indicate current state in understandable manner, and it handle errors gracefully. Today I will talk about two out of these four things. I will talk about being fast and indicating current state because I think these two things are the easiest to actually achieve. So, to understand my tips and tricks which are deceptively easy to implement, and to understand why I chose actually them, I want to show you what are common problems with single page applications and what are the common problems when you try to achieve good UX. So, I asked tens of Netguru engineers about this, about what are the feelings about common problems with Ember. And here are the insights. So, the most common problem is simultaneous asynchronous requests. So, a creme de la creme of single page applications, actually, is the most common thing that makes our UX bad. Asynchronous relationships and lazily loaded data. Everyone knows Ember data and I think that most of us agree that this is pretty great, but haters gonna hate so asynchronous relationships and lazily loaded data can bring a lot of problems, especially when we don't expect them. If we expect lazily loaded data everything is fine but when we don't, our UX probably is broken. Multiple data sources. We have our backend as API. We have S3 as image storage. External services, external data, and so on. So it's also pretty hard to handle all of these things. Last but not least, huge assets and libraries. Like the simplest example is that we need one function from lodash and we basically import the full library, which is not very sensible, right? These things, these were the most common problems for guys at Netguru. And I hope that you agree with at least a couple of them. With few simple tricks that will follow right now I will try to show you how we can embrace these problems, how we can improve our UX and how we can get a huge impact on performance of our application without doing a lot of work. I also believe that even though all of these tips are pretty easy, it's really valuable to see them grouped in context of talking about UX. So, first, the most trivial, actually, is Ember Routing management. When we build Ember application we always take advantage of Ember Routing and we also take advantage of nesting mechanism. But we shouldn't forget about one simple rule. That we always... We can't consider our nested routes from URL perspective. We should always consider them from the view-nesting perspective. And with this simple rule you can always reuse models that are already fetched in your parent routes. And you can avoid fetching models that are not even visible. Couple of examples. Like, this is the most trivial. Basically, these routes are not nested at all, but the URL looks like they are. If you try to somehow nest them, you will eventually end up fetching something that you shouldn't. Next example is more... More familiar to Rails guys. Because when you take experience from Ruby on Rails you always try to nest your show view under the index view which is totally bad. In this case. Because even though that URL looks like it's nested, it's not. Even if we nest it and we somehow add some additional logic to hide dumb elements from index view, we still will fetch all the index model which is total waste of time, right? But here is other example, and the URL has not changed at all. However, these routes are nested. So, when we consider the nesting from view perspective, we can clearly say when we need nesting and when not. But URL is not an indicator at all. Next thing is to use non-blocking data fetching, which is also... I think that most of us know about it. We should define which is crucial, which data is crucial for our user. We fetch it in model hook and the rest should be fetched in setupController. It's pretty easy, when you think about it, but it's also easy to forget when you're implementing a feature. So it's good to remember about this. Again, pretty simple example, when we have a post model with comments and we fetch both of them in model hook, we end up with user waiting couple of seconds, let's say, to see anything. And eventually he or she just see everything. Where we can define that our post is crucial and fetch it first and comments only as... as extra, in separate controller. This way, pretty fast user gets the content that is crucial for him and see the extras later. I don't want to talk about ember-concurrency a lot. I just want to underline maybe... Just make sure that you remember about this because I feel that is pretty good. It's notably ca-ter-y to use, of course. But it enhance creating, restarting, cancelling, and queuing asynchronous requests. I won't cover this topic today, but if you haven't, check out ember-concurrency. You definitely should. First of all, despite the fact that it enhance your starting and so on, it brings a lot of help for your UI to take advantage of properties on ember-concurrency objects such as is ee-do is running and so on. So check it out. Side-loading and testing your routes. I think that most of us know what is side-loading but I will try to explain. Side-loading means having some JSON that is additional to your model, next to your model, next to the model you're fetching in your request. It is very good for situations when you fetch a model with a lot of relationships and you want to avoid lazily loaded data. And then you don't have lazily loaded relationships but they are immediately better. However, side-loading has its disadvantages. When you fetch model with side-loading it's definitely slower than if you don't fetch it with side-loading. Because your backend has to make query for relationships, dig a JSON, and so on. To take advantage of lazily loaded data and on the other hand, don't forget about it, we should test our routes. Testing acceptance mode and at least add one asset okay to make sure that our mocking service, which is pretender or mirage, which actually we use pretender, will fail you on any request that we didn't define earlier. So if we make a route, we write simple acceptance test in the very beginning. And we make sure that there is no lazily loaded unexpected data. Because when it's expected, we can, you know, take promise, show spinner, show user that something is happening, but if we don't expect it then, for example, we'll develop a machine when you are developing feature we had this relationship somehow in store and in Ember data store, and it looks good. It might not look good on your end user. This is a little bit strange tip. I use it only once. But it might be good for your use cases. Let's try to split models to index and show views. When the use case is proper, of course. It might be okay to create super limited index model that will have only attributes that are visible for a user. And we still have our regular model that is full of relationships and so on. In this way, let's say that we have a index view and a show view without this tip. We have a situation when we fetch an index view with index models that are very heavy, for example, and our backend takes five, up to ten seconds to fetch it. And our user basically see nothing. He or she sees spinner, and don't know when the data will arrive. And eventually the data is here and, for example, he or she can open the side view to see the full regular model. But if we try to split these models and make the index model super limited, we can achieve a situation where fetching this super limited model is pretty fast. And right after model hook and setupController, we can start fetching full regular models in background and the user is not like... He doesn't know that we are doing in background, but we do. And when, for example, in my use case, it was emails. It were emails. So, each time a user was seeing this view, he was reading a couple of subjects to decide which one he or she wants to open. So I had like four or five seconds to fetch these regular models and it was enough to have a truly native experience because fetching the index was super, super fast from 10 seconds to... Maybe not. Maybe from five seconds to 100 milliseconds. And I have these five seconds to fetch the full models and eventually the transition to show view was also immediate because I already fetch these models. So if your use case might be appropriate here is definitely something to consider. This tip I got from Mike Knoff while watching his Ember... While watching his presentation on San Francisco Ember meetup. I liked it a lot. Because I think that welcome pages are pretty cool when they are well-designed. It's like a truly beautiful experience from the very beginning and it's pretty easy to do. All you have to do is instal an item from Mike and you have it. And last tip that is actually the most important and also the easiest, is to always react to your user's behaviour by showing that something is going on. Because users, after one second, they lose chain of reasons and results, basically, and may be really confused when nothing happens on the application and also he or she can get really confused when actually something happens out of nothing. For me, it's super crucial to actually react to every user behaviour and to remember that each promise that you write I hope that you're not using callbacks and so on to remember that all promise, each promise should have its then clause and catch clause. The easiest thing is to basically show spinners. It's not perfect design, but it is design somehow. Another thing from Facebook is fake content or we can even go deeper and we can show both. A spinner, a fake content, and even an engaging message. To make sure that the user is happy. And actually it makes me happy each time when I open Slack. These messages are pretty cool. So, to sum up, I think that UX is our responsibility as front end developers. Even though we are not responsible for the design of the application we are the last element in the process of creating the application. So we are actually the last step that can do something about this. I have seen designs where... Design for single page applications where designers didn't provide any transitions between states and so on. So an inexperienced guy might basically came and told, "There are no design for spinners so it's not my job." But such application is not good. It's actually totally bad and I hate such situations when I don't know what's going on on web on application that I'm using. I think that we should take responsibility on our products and on UX and I believe that the tips that I have shown you are basically so easy to implement and are so easy to remember that there is no excuse right now. So I hope that you like it. Fun fact, I have a birthday today. Really. So do you have any questions? Thank you very much. - [Voiceover] So I've got a question. When new people join the team, do you give them this talk? And explain to them these facets of UX when it comes to working on your projects? - So, actually not, because I prepared it for this evening tonight. But each, I'm not in projects anymore because of my position at Netguru right now. But when I was I always tried to somehow make sure that guys remember about this. It's not like I remembered and I knew all of these things even though they are pretty easy from the very beginning. It's a process of learning, basically. Even if you are a one-year under developer you still might basically forget about I don't know, showing a spinner or something like this. Especially you can forget about that not every data is crucial, for example. You basically want to do such the new route the same as somebody else did, so you just provide, I don't know, RSVP.hash or something like this, to fetch all the data in model hook and basically is bad. Okay. Thanks you. Thank you.