I am trying to do some analysis on Angular 2 and React. One of the things I'm interested in is the size of the core libraries. In others, the minimum needed to get a "hello world" app to run in both.
From my understanding, React just requires the react.min.js file (https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.min.js).
For Angular though, I'm confused. I look at the quick start on Plunkr, and I see four JavaScript files loaded. From my understanding, is optional, but recommended. But then I see zone.js, system.js and systemjs.config.web.js. Are all of these necessary? I just want the bare minimum.
Thank you
Related
Not specifically a Rails question, but a question within a Rails app.
In my app I am using the jsbundling-rails gem configured with esbuild.
This gem adds a build line to my package.json file. It works and compiles all my JS and runs fine. However, I found that the generated file is rather large so I started looking at ways to optimise it.
My esbuild statement at this point looks like:
"build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds"
Firstly I thought I could try making my imports conditional. Eg, only import them when they are actually required. I asked another question on how to do that here.
I learned quite a lot digging into that, but at the end of the day it's made no difference to the output of my JS weirdly.
Chrome currently says that my main JS file has 91% code unused. It looks like all the imports are still being compiled together, whether they are statically or dynamically imported. Why can this be?
I then looked further into esbuild, I spotted the --splitting flag. It sounded reasonably correct so I updated my build script to be:
"build": "esbuild app/javascript/*.* --bundle --splitting --format=esm --sourcemap --outdir=app/assets/builds"
This caused a huge amount of outputted JS files (I think they are referred to as "chunks".
I ran my app, and the JS failed to load. The console stated that
Uncaught SyntaxError: Cannot use import statement outside a module
I wasn't 100% sure why was the case but I just guessed that I needed to add type: "module" to my javascript_include_tag in my Rails application layout view.
This made the JS load (which is good :-) )
BUT... The percentage of unused JS code is still 84% of my application.js
So..... my questions are as follows:
Are my dynamic importing of modules working?
Why does static or dynamic importing appear to make no difference?
How can I effectively reduce the size of the output code and reduce the unused percentage of JS on my home page?
This all started because I ran Google's Lighthouse test on my site and it reported my Structure and Accessibility to be practically perfect but performance was < 40. I am aiming to solve this.
I look forward to hearing from you with ideas on how I can try to fix this and improve my Lighthouse Performance score.
Are my dynamic importing of modules working? Why does static or
The paradigm you want is called Propshaft. Try looking at the SProckets -> Propshaft
https://github.com/rails/propshaft/blob/main/UPGRADING.md
Why dynamic importing appear to make no difference?
Because even though ESBuild allows for ES Module syntax (import statements), it still bundles everything into "1" big file. (1 big file for each javascript_include_tag you have, of course).
How can I effectively reduce the size of the output code and reduce the unused percentage of JS on my home page?
The sprockets paradigm was built for the HTTP1 web when keeping connections open and progressive download wasn't realistic. HTTP2 changed all that and now it's more efficient to do code splitting as you want to do. But the Rails world is still very behind and most apps still use Sprockets and try to optimize/minify was much as possible.
I'd recommend you take this course of action:
(1) Try the old-style way first. Remove anything unnecessary, split your app into different sections and load different manifest files for different sections. Use minification. See how far that gets you.
(2) Start experimenting with the new Propshaft for a few weeks until you fully understand it. If you feel it is solid, migrate to that.
Lets say I have 15 different views and all of them are very complicated structured.
I am planning to use meteor and react without server-side rendering. But I can t understand that what if a user is only going to check my home page, in this case isn t it inefficient to send all of the views' html-css-js to client.
You are right, it is indeed inefficient to send all of your view logic if only some of them are used. You problem boils down to this - Code splitting and chunking. This is where tools like Webpack come in handy.
Using Webpack, you can split your code into bundles, where each bundle will contain logic for a specific part of your application. For example, all code for your login page can be bundled together as login.bundle.js and once after login, you can bundle the rest of your view logic as myapp.bundle.js.
You can learn more by following the documentation here - http://webpack.github.io/docs/what-is-webpack.html. If you want a guide on how to set it up, here are couple of blogs on how to do this -
https://medium.com/#dtothefp/why-can-t-anyone-write-a-simple-webpack-tutorial-d0b075db35ed#.mdm6p8qkh
https://medium.com/#booleanhunter/webpack-for-the-fast-and-the-furious-bf8d3746adbd#.8aynlj3t4
Code-splitting is only one of the several things that Webpack can do. There are other tools too that can achieve this, like Browserify
Hope this helps!
Please look at instruments like webpack that have features like require.ensure for your case
How to organize Vue-JS project [files and directory]: Non Javascript way?
Coming from a non-javascript background, I found Vue.js very intuitive and easy to use. My earlier experience in Javascript is with JQuery and vanilla javascript on the browser.
I created an application using Vue , Vue-components and vue router. Everything works fine.
My problem is, I have ended up writing a lot of code in a single index.html file of my project. This file contains over 10 templates that I have created and attached to different component in my app. I want to know that is there a non-javascript way to organize these templates in seperate files.
I see that there are options using webpack and browserify to modularize the project. But coming from non javascript background, I don't find them intuitive. I don't want to go node - npm way because that has its own learning curve and moreover it downloads a dozen of files and dependencies in my project which I don't understand. I am old school and more comfortable downloading the files and including them in the webpages.
So probably, you understand where I am going to. I need a solution where I could put my templates as separate files and read those files in the different components.
What I have tried :
Declaring the templates inside my components. But writing all that html inside the component is not that clean. It also, makes my JS file too huge. I am better in putting all data in the index.html instead.
Storing template as smaller chunk "homepage.html","about.html" and in my components, using $.get / $.load to read different components in ready function of the component. This works but I still have to fire an additional ajax call for each component which is not efficient.
Please refrain from suggesting the obvious node-npm [webpack and browserify] way. I know thats what is supported by Vue but this needs a learning curve and complete setup. Answer to this question would actually help other developers who hesitate going the node-npm way.
Please shout back if you need more clarifications to the question.
The options you've mentioned are your only real ones... the HTML of the template needs to be available when it's needed, so you either have to have it within your html file off the bat, or load it using AJAX or an in-browser loader like RequireJS (and this extension that allows it to load HTML https://github.com/requirejs/text).
In-file templates make sense for very small projects. As your project grows, you'll need to start using the tools that are built for this. NPM rocks and every JS package that you'll ever need can be included in your project in seconds.
I highly encourage you to try the Vue CLI
It does use node, npm, webpack and downloads dozens of files. Which you've you've explicitly asked for not to use, so let me clarify:
The Vue CLI takes care of the complexity and configures webpack for you.
You don't even have to know it's using webpack.
It's very developer friendly (it even has a built-in gui) and lowers the barrier to entry compared configuring a webpack config.
I hope you'll also find it "intuitive and easy to use".
For d3, or any javascript package in general, what is the difference between the js file which has the entire source code(say, d3.v3.js) and the github repo for it(in the case of d3, it is https://github.com/mbostock/d3).
What does the github repo contain that the entire source code does not?
I read on Scott Murray's tutorials that the D3 repository contains "all of the component source code". Can someone explain what's meant by 'component'?
Let's look at the Whatever library. It does whatever. The repo for it is located at https://github.com/someone/whatever.js (this is not a real repo).
The repo itself usually contains a variety of info, including documentation, style guides, and code organization. Whatever.js is actually made up of three files: lib/whatever.js, lib/whatever-tools.js, and lib/whatever-xml.js. These get concatenated for actual use, but for development of whatever.js itself it's easier to work with separate files.
Having to deal with just commits all on a single file is absolutely horrible. Pull requests would be even worse.
The distributed version, aka whatever.js and whatever.min.js, is a version of the repo code after it's been dealt with however it needs to be. In the case of most libraries the files just get concatenated, but for some libraries fancy things happen. The .min.js version is the normal file, but after being run through a minification tool, these days usually UglifyJS2.
Some libraries will not even have all of the code in the main generated file, usually due to usage reasons. For example, Angular.js doesn't have the ng-route module in angular(.min).js, you need to include angular-route(.min).js too. This is for sanity reasons, because quite a lot of Angular uses don't need or want the routing system, and it's a fairly big addon.
it is the same as with any project in development environment and deployment environment, so in github that's a development environment for d3.js d3.v3.js is the compiled library that you need to use in your product.
Zeke Sonxx's answer is excellent. I'll just add that in the case of Javascript, because the source code can be run directly, there might be less need for a github repo. But even in the simplest cases, you get to add additional files when needed, keep track of problems and plans in the github issue system, etc. Example: The gexf-parser repo only has one main source file, src/parser.js, but there is a collection of files for testing as well, and a few other useful files. Javascript can also be "compiled", but it's not compilation in the sense of some languages (C, Java, Clojure, etc.). The application distributed will often be built from many different source files in the repo.
I've developing JavaScript since many years but have never really thought about the whole testing, developing and building stuff - but I realized it's pretty much necessary. We've just used a Subversion repository with simple release tagging (switching to git soon). As a new bigger pure JavaScript project (using jQuery) is arriving soon, I'd like to optimize the whole process.
I already did some research but never found a good starting tutorial.
It's definetly a good idea to split classes and separate code blocks into several js-files and not a big one (as Prototype or jQuery do it). These js-files must be "build" into a single file. How do I achieve that?
It's pretty much necessary to Unit-test the stuff me and my colleagues are coding. I found the js-test-driver which has an eclipse plugin that seems to be doing his job quite good. If my developer-folder contains all these src- and src-test-files, how do I integrate this in the building process?
For testing, take a look at this: https://stackoverflow.com/questions/32809/javascript-unit-testing
For merging all of your JavaScript into one file you can use something like YUI Compressor. You need to be looking for a minimizer first, compression second. A minimizer just takes the files and merges them together and gets rid of whitespace. A compressor will actually try to optimize the js for you by changing variable names and removing unnecessary code.
As for unit testing I am unsure of how you will want to do that. There are a few unit test libraries out there. A popular tool for testing is Selenium. I don't currently do unit testing so I am out of my element there..
For setting up your code you could always look at using a JavaScript framework like ExtJS or JavaScriptMVC. Those help you with setting up your code in the proper way and also helps focus your team on the proper standards and coding structure while also writing a lot of the code for you so you don't have to re-invent the wheel.
EDIT: Just a quick after thought. Even if you don't want to use a JavaScript framework, I would suggest checking them out, especially ExtJS, just to see how they organize their code and some of the tricks they do to keep it clean.
I'll answer part of your question:
These js-files must be "build" into a
single file.
This is possible only with server side language - in ASP.NET you have built in tools for that, otherwise build your own "merger" server side file and reference that file instead of the actual .js files.
These js-files must be "build" into a single file. How do I achieve that?
Definitely keep your files separate in version control, and only merge them during the build process.
The YUI compressor mentioned elsewhere is a java-based tool that will not only merge but -- of course! -- compress your files for faster download.
If you just want a simple merge of files, a simple Perl or bash-script (or other preferred scripting language) could concatenate multiple .js files into one for release -- just make sure that the build script also updates all HTML in the release to reference only the single page.