When to code split (React- Suspense and Lazy) - javascript

What bundle size in KB should I consider splitting at? At what point does weight become too heavy that I should split it out. My whole bundle without splitting is around 800KB so it loads relatively fast. I am just trying to figure out if it should be around 10KB/ 100KB, etc... Moment.js takes around 50KB, so I am trying to figure out if I should split out all modules that contain moment for example.
If I don't code split does that mean overall it provides a better user experience once they load the initial page since every other page would load faster? I get this would lead to a bad first experience of loading the page, but am just trying to figure out the tradeoffs.
Haven't found any good resources with this information. I am using create react app.

800kb is not super big but still, the smaller your bundle is, the better.
I think the main problem having only one bundle is that, if you change one single character in your app, all your clients will need to download everything again.
Let's take an example:
You see a typo in your code. You already have thousands of users who downloaded the 800kb bundle with this typo.
You push a fix (only one character change).
All your users need to download the whole bundle again (yes, they need to download Moment.js again). Be it 1*800kb or 8*100kb, they will still need to download 800kb of data. (related question)
What you want to do, is to split your chunks in a way that allows users to only download the files that changed. For the other files, they can be cached, so no need to download them again. So in the example above, you don't want your users to download Moment.js again because... it didn't change at all.
I suggest you to read this very nice article about how to split your bundle:
https://medium.com/hackernoon/the-100-correct-way-to-split-your-chunks-with-webpack-f8a9df5b7758
You can also add one level of split by creating "per page" chunks. Here is how to do it with React: https://reactjs.org/docs/code-splitting.html
If you make changes on Page A, your users won't have to download the chunks for Page B again.

Related

Advantage of using lazyload?

So i stumble on this component called lazyload.
What does it do and advantage and disadvantage of using it ??
Just curious about it because i watch some of john papa's videos and he keep mentioning it.
They idea of lazy load is that you only load something when you need it.
For example: at startup of your application you might not need a library to validate your form fields. (you only need it when someone actualy fills in a form and submits it).
Lazy loading makes sure its only loaded when needed.
The Plus:
Reduced start/load times & size.
Packages/data that are not used by the current user, will not be loaded.
Minus:
You have to have more seperate packages you can't minify and bundle them together.
More request to the server (because you can't bundle them).
could have a load on first use experience, the first time user does something the application needs to load some extra stuff.
conclusion & advice
So consider the size and the lifecycle of your application. If the application is small and you package all in one. probably the simplest approach would be to package everything in one. it's a bit of a longer load time, but after that the javascript gets cached in the browser anyways so it doesn't matter after first load.
Reasons you want to lazy load:
You want to be able to update seperate parts of the applications (thus not bundle it)
Application becoming problematically big. you want to cut it up in smaller parts.
You don't bundle your javascript files (great example here before angular was requirejs).
You have a lot of different types of users using the system each with completely different set of scripts.
Every page uses completely different set of javascript. (not likely when you use angular)

Split very large javascript file

I'm working on a web project that uses webgl content generated with unity. When trying to load the required js files the browser freezes for around 30 seconds. The main js file has 35MB size unzipped so this seems to be the cause.
I want to avoid this freeze if possible but I couldn't manage to do it using WebWorkers since the script needs access to UI. My other possible solution is to try to split the js file into smaller ones but I don't know how to do it. Do you have any suggestions?
If you add async to your script tag like this <script async src="app.min.js"></script> it will not block rendering anymore. Also caching the script in the browser or delivering it from a CDN can help reduce the download time.
35MB are, however, way too much for a website. Are you sure there isn't a lot of unused stuff like libraries in it?
We recently wrote an article with web performance best practices, with explanations to critical rendering path and other fronted concerns here
35 MB just for the JS file seems ridiculous. It could be that the entire build is probably of that size (textures, media, etc.). Have a look here on how to reduce the build size.
Though 35 MB is wayyyy to much for a JS file, you can start by following pointers:
Create utilities and reuse the code. This can be at any level. Be it generic component (HTML generating code) or validation logic, if it can be configured using arguments, make a function and use it.
If you have Hard-coded JSON in your js, move them to .josn files and load them only when they are required.
Split files based on sections in view. In SPAs, there are cases when a section is not visible. For such cases, don't load such files. Spread your code base from 1 file to 100s of file.
If you have a lot of event listeners, move them to different file. You can have section_event.js, section_data.json, section_utils.js and section_index.js. If there involves lot of data parsing, you can even have section_parser.js
Basic Idea is to split code into multiple files. Then, make code more reusable. You can even look into loading libraries to reduce your load.
Also, load a resource only when required. SPA have stages. Load concerned files when they are needed. Split download from 1 time to partial, on-demand approach. Also look into webpack or grunt or gulp to minify js.

Referencing separate JS files vs one JS file

Which would result in greater speed/efficiency: Referencing one JavaScript file for all files in the directory OR referencing a different JavaScript file for each file in the directory?
So basically, referencing the same JavaScript file in all web pages vs a unique JavaScript file for every webpage.
Note: I thought that referencing the single file would be slower as there is code in there that is obsolete to some files, thus running useless code and causing the file to run less efficient.
There are tradeoffs involved so you may ultimately need to measure your specific circumstances to be sure. But, I'll explain some of the tradeoffs.
If you have giant amounts of data or giant amounts of code that are only used in one or a few pages, then you will probably want to separate that out into its own file just so you can ONLY load it, initialize it and have it take memory when it's actually needed. But, note with the amount of memory in modern computers (even phones these days), the data or code has to be pretty large to warrant a separate download.
Other than item 1, you pretty much always want to optimize for maximum caching efficiency. Retrieving a file (even a larger file than needed) from the cache is so massively much faster than retrieving any file (even a small file) over the network that you really want to optimize for caching. And, the time to retrieve these files generally dwarfs any of the JS parse time (CPUs are pretty fast these days) so triggering an extra download to save some JS parse time is unlikely to be faster.
The best way to optimize for caching is to have most of your pages reference the same common script files. Then, they get loaded once when the viewer first hits your site and all subsequent loads come right from the browser cache. This is ideal. This caching efficiency easily overcomes having some unused or untriggered code in the master file that is not used in some pages.
Lots of small downloads (even from the cache) is less efficient than one larger download. More separate requests generally just isn't as efficient for either the browser or the server. So, combining JS files into larger concatenated files is generally a good thing.
There are limits to all of this. If you had completely separate code for 100 separate pages all concatenated together and each piece of code would search the DOM for multiple page elements (and not find them 99% of the time), then that's probably not an efficient way to do things either. But, usually you can make your shared code smarter than that by breaking things into categories based on a high level class name. So, for example, based on the presence of a class name on the <body> tag, you would then run only part of the initialization code, skipping the rest because its classification is not present. So, when combining code, much of which won't be relevant on any given page, it's wise to be smart in how you decide what initialization code in the shared file to actually run.
You need to measure for your specific case - as every site/page have its own balance between loading less files/loading extra unnecessary scripts (same apply to CSS too).
Generally single file is faster in HTTP v1 as there are restrictions on total number of parallel downloads, HTTP v2 should be removing the difference.

Multiple JavaScript files, combine into one

I am developing in ASP.NET MVC and using multiple JavaScript files. E.g. jQuery, jQuery UI, Google Maps, my own JavaScript files, etc.
For performance, should I combine these into one? If so, how?
The reason you want to combine many files into one is so to minimize latency of setting up and tearing down http requests, the fewer you make the better. However, many newer browsers are downloading JavaScript files in parallel (still executing sequentially). The consequence is that downloading a single 1Mb file may be slower than three 350Kb files. What I've come to do is to separate my files into three bundles:
External lib files (jquery, flot, plugins)
Internal lib files (shared by multiple pages)
Page specific files (used only by that page, maybe by two pages)
This way, I get the best of both worlds: not an excessive number of http requests at startup, but also, it's not a single file that can't benefit from parallel downloads
The same applies to CSS, each page load three CSS bundles. So in total, our pages download six bundled files plus the main html file. I find this to be a good compromise. You may find that a different grouping of files works better for you, but my advice is don't create a single bundle, unless it's a one page app. if you find yourself putting the same file into different bundles a lot, it's time to re-think the bundling strategy since you're downloading the same content multiple times.
What to use? Martijn's suggestions are on the money. YUI is the most widely used from my experience, that's what we used at my previous and current jobs.
For the question of whether you should, check out the link in Shoban’s comment.
For the question of how:
Google’s Closure Compiler
Yahoo!’s YUI Compressor
If they are all going to be included on all of your pages, then it doesn't really make a difference. But if some are only relevant to certain pages, it would technically be better to keep them separated and only include the relevant ones on relevant pages.
As far as I know, you should indeed : less files means less http get, hence better performance for the user when they first load the page.
So they will save a split second they will come on your page for the first page. But after, these files are cashed, and it makes then no difference at all...
I haven't digged into the javascript engines itselves, but a function in one file will be handled in the same way if it is in a big file or a small file. So it makes no difference in the execution.
So, save your time, don't change anything as it'll cost you too much time for too little reward, especially when you'll discover that you want the latest version of jquery (a new version came out today btw), and that you have to re-concatene everything...

Should Javascript be separated into files by page or consolidated into one file?

Should I be separating my js for each page assuming there is no overlap and putting references on each page instead of having one master file? what is typical practice? thanks
Everything that is common to every page of your site should be on a single file, since it will be loaded only once by the browser.
Code specific for a single (or maybe 2) page(s) should go on separate files, loaded only by the pages that need them.
That's the way I do it: you use the browser's cache to reduce your bandwidth and to accelerate the loading and rendering of the page.
For infrequently accessed pages, load the javascript inline (at bottom of all the markup) for quickest load time (one less TCP connection required as is the case for separate .js script file).
For frequently hit pages do the opposite: reference a .js script file - in this case the caching by the browser provides a greater advantage across the aggregate of page loads.
In larger projects, develop your javascript in separate .js files (you can use the module pattern for instance), then for production compile them into a single file (or a number of files per architecture of your application) with a build script.
It all depends on what kind of app you have. If your app is frequently accessed but for short periods of time then initial loading time is important and you should try to combine files.
If, however, you expect users to spend hours at a time in your app and initial load time is not critical then I would advise partitioning your .js files as much as you need to to make it readable - since they will all be cached anyway after the initial load.
Don't believe the hype. Unless you're a google search engine you should be careful not to sacrifice readability for the sake of a few seconds (or less) at initial start up. Put it another way, rules of thumb are just that, don't neurotically follow them - think first :-)

Categories

Resources