This is the first article in a series of articles by Shfshanyue on advanced front-end engineering. For the previous m-1 article, you can find it on my Github repo shfshanyue/blog. If you click on it, you can give it a thumbs up. If not, give the post a thumbs up. Today’s article begins

This article is in the Front-end Engineering series. Please subscribe.


When it comes to packaging in the front end, webPack is definitely mentioned, after all, it is now the most popular packaging tool. But Webpack is more about art, so I decided to write this article to explain more about tao.

For a front-end, static resource optimization in production environment, which is not only a frequent question in interviews, but also the most easy to become OKR/KPI in daily work. If you’re constantly working on optimizing front-end packaging references, you’re bound to be extremely sensitive to numbers like:

  1. lodashreactWhat is the volume after Gzip (qualitative, range can be given)
  2. packagingmomentWhat might go wrong
  3. What is the volume of the first screen static resource gzip for your online front-end project

If you’re in charge of packaging optimization for your front-end project, it doesn’t make sense to not know one of the above. In my two years of experience as an interviewer, candidates tend to know more about packaging and Webpack if they know anything about these issues

The principle of

Generally speaking of packaging will have two aspects of meaning, the first is to improve the speed of packaging, the second is to optimize the static resources after packaging. Optimization for static resources is more than just a reduction in packaging.

The general principle of packaged resource optimization is to minimize or delay module references as much as possible. It mainly follows the following three points

  1. Reduce the overall volume of packaging
  2. Code Splitting: Load on demand, optimize the volume of first page loading. For example, load routes on demand based on whether they are visible
  3. Bundle Splitting: Subcontracting, hierarchical packaging according to the frequency of module changes, making full use of the cache

The following article will illustrate these three points with examples

01 Reduce the overall volume of packaging

The first method is to reduce the overall volume of packaging. There are many ways to reduce the total volume of packaging, which is often the focus of packaging resource optimization. On the one hand, it is highly operational and easy to practice. On the other hand, it is easy to write PPT to promote with specific data support. I from the site performance optimization practice point of view, to the following aspects

Code compression

Code compression can significantly reduce the resource packaging volume, but it leaves too little room for manoeuvre. Low operability means that this item is not easy to appear on the PPT of promotion review, just as the importance of CDN in website performance optimization is important but not your responsibility (or fool configuration).

It’s so well modularized that WebPack has taken it upon itself to do this by default in production.

So how does it compress the code? The two most typical methods are whitespace substitution and shortening variable names, which, as the code shows, compress javascript resources considerably:

/ / before compression
function sum (first, second) {
  return first + second;  
}

/ / after the compression
function s(x,y){return a+b}
Copy the code

For code compression, see Yamatsuki’s Front-end Advanced Series how does the volume of javascript code get compressed

Remove unnecessary modules

This one sounds like crap, but it’s really useful and extremely easy to implement.

In the following code, the loDash module is introduced, but it is not used in the following code. Will the module continue to be packaged in Webpack?

Unfortunately, it will still be packaged. But the good news is that it’s pretty easy to optimize.

// Simply introduced but not used in code, the module will still be packaged
import _ from 'lodash'
Copy the code

Such problems should always be nip in the bud. This is where ESLint comes in. In addition to unifying the team’s code style, it can also be used to improve the quality and performance of the team’s code.

Select alternative smaller modules

A prime example of this is the notoriously bulky moment.js module, which is only used for DateTime formatting and various calculations. But after you import it it’s 200KB + and after gzip it’s still 69KB. So much so that there’s a github repository dedicated to how to optimize it,

  • How to optimize moment.js with webpack

Here’s another picture to get a feel for its sheer size:

You can choose a smaller module that can replace its function. Day.js is compatible with the moment.js API, which is only 2KB after gzip.

Import modules as needed

When you’re faced with a huge, bundled module, you probably don’t use all of its functionality, you just need to introduce the module to your needs. What are some of the big modules that are often available?

Lodash (after a fashion), ANTD, and Echarts, I’m sure all three of these modules are used to some extent by the React oriented front-end engineers. Introduce separate modules that you need to use:

import DatePicker from 'antd/es/date-picker'; // for js
import 'antd/es/date-picker/style/css'; // for css

import get from 'lodash.get'
Copy the code

02 Code Splitting: Load on demand, optimize the first page loading volume

Lazy. If lazy is mentioned in an interview, there’s a good chance the interviewer is asking you about lazy pictures.

How to realize lazy loading of pictures in front-end development

Code Splitting allows you to load only the core resources you currently need:

  1. If you’re on the home page and you have a chart that’s too resource-intensive, you need to load the chart lazily, otherwise it will significantly slow down your app’s first rendering and increase the white screen time
  2. If you’re on the home page, you don’t need to load complex components that are currently invisible below the screen
  3. If you’re on page A, you don’t have to load the resources on page B

They all require extra code to implement, so they are moderately operable, but the good news is that they offer great benefits, a high return on investment, and are extremely simple to operate. The next step is manual labor:

  • useimport()Dynamic loading module
  • useReact.lazy()Dynamically loading components
  • uselodable-componentDynamically load routes, components, or modules

In most cases, all you have to do is be a dumb API engineer and call these three apis to solve the problem, drastically reducing the first load volume of the page. But on your way to a senior front end engineer, you’ll probably need to understand the rationale (or not, data is more important than rationale) to do more fine-grained controls, such as for caching.

What is the principle of Code Splitting?

03 Bundle Splitting

In addition to resource volume optimization, another big optimization is caching. One of the best aspects of a single page application is that all resources are fingerprinted, which means that all resources can be permanently cached.

But is that all?

If all your JS resources are packaged into one file, it does have the advantage of permanent caching. But when a line of files is modified, the fingerprint information of the large package changes and the permanent cache is invalidated.

So what we need to do now is: when modifying files, cause the minimum range of cache invalidation, so that we can make full use of cache, reduce bandwidth, and reduce server costs. The good news is that packaging tools like WebPack, which have a lot of performance optimizations built into Optimization, don’t do it for you. They don’t know what modules you have and how important and urgent they are, and you’re ready to go.

At this point we can carry out hierarchical caching of resources packaging scheme, this is a recommended scheme

  1. webpack-runtime: In applicationwebpackThe version of the more stable, separated, to ensure long-term permanent cache
  2. react-runtime: reactAre also updated less frequently
  3. vundor: Common third-party modules are packaged together, such aslodash.classnamesAlmost every page is referenced, but they are updated more frequently

With the development of HTTP2, especially multiplexing, the static resources of the initial page are not affected by the number of resources. Therefore, for better caching and on-demand loading, there are also many solutions that suggest packing all third-party modules into a single module.

In webpack, use splitchunks.cacheGroups

{
  splitChunks: {
    cacheGroups: {
      react: {
        test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/.name: 'react'.chunks: 'all'
      },
      vendor: {}}},runtimeChunk: {
    name: entrypoint= > `runtime-${entrypoint.name}`,}}Copy the code

summary

There is no doubt in the front end to better optimize the packaging of resources belongs to the top priority of the strong operational part of the site performance optimization, sorting out the next article on all the resources optimization

  1. Reduce the overall volume of packaging
    • Code compression
    • Remove unnecessary modules
    • Import modules as needed
    • Choose smaller modules that can be replaced
  2. Code Splitting: Load on demand, optimize the volume of first page loading. For example, load routes on demand based on whether they are visible
    1. useimport()Dynamic loading module
    2. useReact.lazy()Dynamically loading components
    3. uselodable-componentDynamically load routes, components, or modules
  3. Bundle Splitting: Subcontracting, hierarchical packaging according to the frequency of module changes, making full use of the cache

Communicate with me

Scan code to add my robot wechat and it will automatically pull you into the front end advanced advanced learning group (automatic pull program is under development)

I am Shanyue94. Please add shanyue94 on wechat to communicate with me. In addition, you can pay attention to my public account [The road to full stack Growth].