5 ms·
I completely agree with the author. A few months back I examined the number of network requests required to populate the data for a page I was trying to improve
by lucasyvas 5y ago
I completely agree with the author. A few months back I examined the number of network requests required to populate the data for a page I was trying to improve performance on.
Let's just say it did not go well. Despite best intentions of being API-first with a SPA front-end, when you have a data-heavy and query-heavy application, it is absolutely the wrong choice ten times out of ten.
It leads to (not so) hilarious situations where the older, server-side rendered version of your app that uses jQuery absolutely demolishes your new hotness in performance. Try explaining that one with a straight face.
- ovao 5y agoDid you consider endpoint composition? Instead of making 7 API requests (via fetch, or whatever), provide an endpoint that’s simply the composition of the 7 endpoints.
- lucasyvas 5y agoGreat question! Yes, this was thought of and it's an approach that might still be taken. That said, I consider this to be a band-aid solution - IMO, just have a back-end to your app or a heavily optimized query interface like GraphQL. Once you are adding special endpoints for mostly just your UI, it's no longer strictly a general purpose API and the entire point of the design is moot. If you end up in this position I consider it a design failure - most data-heavy apps are probably better off with a command/query API.
- dlisboa 5y ago> Once you are adding special endpoints for mostly just your UI, it's no longer strictly a general purpose API and the entire point of the design is moot. Not really, it's a very valid solution when you have multiple clients (Web, Mobile, TV, etc) and multiple API calls in the backend. Netflix had a similar solution back in the day (not sure they still do) to solve the issue of clients calling multiple APIs.[1] Which isn't much different from calling multiple endpoints of the same API. When you have one client and know everyone else isn't going to use your API, it might be overkill. But if you have a very granulated API for general purpose (like, say, Twitter) but want your Web or Mobile clients to have a very narrow and specialized one, it makes sense. I wouldn't consider this solution a failure, just the outcrop of a highly distributed backend system. [1] - https://www.nginx.com/blog/building-microservices-using-an-api-gateway/ https://www.nginx.com/blog/building-microservices-using-an-a...
- ehnto 5y agoI feel like your last example is a known tradeoff not an exception. Frontend frameworks never intended to solve performance, it had usually been at the cost of performance that we get a more powerful/dev friendly experience. They are heavier applications not simple websites, and you pay for that in performance and often UX latency. The modern web feels slower than it did in 2010 in many situations. Latency and lazy developers not implementing affordances for when things are loading or the page is changing. Your app is probably slow for everyoelse, you need loading spinners! Especially if you are hijacking the browser navigation.
- lucasyvas 5y agoI would argue that mature frameworks like Rails or Django are peak productivity though - but, by all means, throw in a front-end framework like React to fill in the gaps if you need it. I personally don't think the performance trade off is worth it. And it drastically increases front-end complexity in terms of state managment, which you now have to also manage in the client. The complexity is just moved further away from the server and productivity is gained on the visual part but lost everywhere else.
- afurculita 5y agoWith HTTP2's multiplexing feature, it doesn't really matter how many requests the frontend is firing up. Just use HTTP 2 when you have multiple requests on a page.
- scns 5y agoWhat do you win by downloading MBs of JS over a multiplexed connection? You still need to parse it all on one core.
- lucasyvas 5y agoI think the problem in this case is less the number of requests, and more what it implies. If certain endpoints are even a little slower than they should ideally be to fulfill the requests, you now have a metric ton of not-efficient-enough requests, which adds up very quickly. It's not a problem of making the connection, but the abstraction level. You could argue, well, fix the API performance right? That would be a valid suggestion. However, if the API is general purpose, what performance level is acceptable? Should it be able to perform tasks as fast as the average API consumer would expect, or should it be fast enough to serve the UI as well? It creates a requirements problem in my opinion. If you were to have an API team, is this really on them, or is it on you for trying to use it in a way it wasn't necessarily built for? This disconnect is why I don't believe a UI should ever be written against a generic API that is data or query heavy. It would involve too much coordination to get it right, which removes the advantage of having components and teams separated in this way (which is often done nowadays).