Performance is a virtue
It’s not about how fast you can ride, it’s about how much time you need to put all the load > fire the engine > go out on the road > don’t hurt yourself or others AND arrive at the destination!
Let’s face it, Front-End is one of the most disliked Eco-systems. Weirdly enough it’s one of the most loved platforms as well.
Performance is not a luxury though, it became a requirement. In the land of E-commerce, reducing rendering time / page load is directly affecting the conversion rates. Which means your web app either perform well or you loose money, simple as that.
Try to be honest with yourself now… How many times have you removed or even were thinking about removing event listeners you attached to the window object?
Imagine that you have SPA, or any kind of client rich app, where navigation can happen on the level of Front-End. You add some component to the current view and it sets resize handler to the window object, which points to one of its own methods. If you don’t remove the handler from the window once that component is unmounted, it will continue to call now nonexisting method.
Beware of memory leaks in Front-End. They are a real threat to the performance.
Server Side Rendering (re)flow
SSR is tricky, and to understand why let’s think for a moment about what Phil Karlton once said …
Guess what? The tricky part here is not naming! Not dealing with cache invalidation in a careful way can ruin your SSR experience. Since it will actually make your app performance worst than it would be without it. I saw way too many complete page re-renders after the React was served from the server. Most of the time there is a slight difference in the DOM, which made cache invalid and BOOM re-render occur.
3rd party “evil” is the most common cause for that. Imagine that you have some part of your code base which does additional calculations and repopulates the DOM after it is done. Most cases for that are 3rd party scripts which are provided by some external providers. Problem may happen when the script executes document.write() or modify the DOM in any way. In some cases we can handle with it on the SSR level; but most of the time it is not so possible.
Please don’t get me wrong, I love the idea of Babel and similar tools. They do bring the future to the present; just that they actually don’t… Transpiling brings pseudo-future. Kind of not so cheap imitation of what will become a standard tomorrow.
Still, transpiled code performance is most of the time very close to native implementation of the feature. But sadly things will probably change long-term. Further optimization of the V8 and other JS engines will introduce the performance gap which will obviously work for the native implementation. Good news is that Babel maintainers already know this and am sure that they will figure out the smart way to handle with it.
Back in 2009 John Resig (creator of jQuery) had talk at Yahoo: The DOM is a Mess to be honest I am not sure if jQuery in the following years contributed to the state of the Front-End performance in a good or in a bad way. It as Eco-system provided the platform in which re-usability of awfully written and poorly performing plugins was desirable behavior…
DOM today is sure much less of a mess than it was 8 years ago. We have cool new Web APIs that improved the way we work with the DOM. Let’s just compare: document.getElementsByClassName() vs document.querySelectorAll()
We stopped thinking in special cases and started handling the selectors in a generic way.
While working with DOM, the single most important thing is avoiding unnecessary reflows / repaints. Libraries such is React or Vue actually solve that for us mostly or even in total. Which is one of the lesser known, yet very important reasoning for deciding to use framework / library instead of going vanilla.
They do that by either doing all in-between steps on the virtual DOM > apply the final state to the DOM once. Or by grouping DOM reads and DOM writes in general.
Sure that there is no perfect choice. But there are better choices. Thus jQuery rewrote slideUp / SlideDown to use window.requestAnimationFrame() for the animations. Which is waaaay more performant than recursive setTimeout! Still less performant than CSS (even with the reflows triggered).
Building it smaller
Good programmers automate the stuff that should not be done manually. Build process brought revolution to the Front-End. Among being used for the usual stuff, like bundling your modules, transpiling etc. build process can be used for additional code optimization. Such is something that looks like this…
Those funny looking classes don’t look like that in the dev environment. They are obfuscated during the build process. Even if it may not sound like much, it can seriously reduce your bundle size. It works because in this approach you modify both HTML and CSS, so that styles can work.
This can be done via PostCSS, either by using some already made solution (like this one) or writing your own.
I have seen things that you would not even believe exist. Business logic implemented within the React component in a form of nested conditionals.
While I would not preach not to implement some parts of your business logic on the Front-End. I am for sure going to warn you to be wise about it and never, never do it on the level of component or any other kind of “view” alike place.
Framework agnostic UI
If you work for big or any kind of company which have a need for multiple apps / products… Sooner or later you will realize that your UI is not consistent and even worse its implementations are full of duplicated work.
Introduction of framework agnostic (plain HTML / CSS) UI pattern library which can be easily be included in any app will fix your problems. So instead of recreating almost the same stuff on each project you consume the shared UI. Where introduction of new elements is always doable and is handled from within the lib.
Scalable UI is like a game of Tetris.
Why is this performant you may ask? Because performance is not only a virtue on the code execution level. It’s also about the way you couple HTML / CSS / JS. Which will no matter how much layers of abstractions you add, always be consumed together by the users of your app.
There is much more to Front-End performance than what I wrote in the article above. This was my random thoughts on always interesting and ever evolving topic.
We do live in the imperfect world and it’s not realistic to emphasize the importance of writing code which performs well, while being pushed by unrealistic deadlines. Unless of course, we know / can write only the code-base which is performant by default. In that scenario there is no such thing as bad choice. Still there are better choices, which we must never stop searching for…
Originally published on develoger.com
Sign up now and apply for roles at companies that interest you.