[xinxinxiu] optimize the access speed of cloud server with 1M bandwidth

Keywords: Javascript React Webpack less

A 1M bandwidth cloud server, the theoretical maximum download speed is 128kb/s
Nowadays, the file size after the front-end project is often a few meters, so it takes more than 10 seconds for users to access it
God, how could a user wait so long for you so kindly? He's already gone
So how to optimize the access speed? Listen to me
Experience the optimized server first (open about 3s)

First, compare the home page access speed before and after optimization
On the left is the access speed before optimization (over 20s)
On the right is the optimized access speed (miraculously up to 2s)


Capacity expansion

Capacity expansion? It's not going to expand in my life

Optimization Construction

To break the 1M bandwidth limit, the first thing to think about is to reduce the volume of the building package, the second is to reduce the resources loaded on the first screen, and the third is to speed up static resource access through CDN

1. How to reduce the volume of building package

Many third-party libraries (react, react router, antd, etc.) are used in the project. Extracting these libraries can reduce the volume of the construction package
The externals configuration in webpack can ignore these third-party packages when packaging, which effectively reduces package size

// webpack.config.js
module.exports = {
  // Through external configuration, set react, react DOM, react router and antd to not participate in the construction when packaging
  externals: {
    // The key on the left represents the package name when import ing
    // The value on the right indicates the variable name of the external import and export - this should be written correctly
    react: 'React',
    'react-dom': 'ReactDOM',
    'react-router': 'ReactRouter',
    antd: 'antd',

How to reference these exported packages
In html files, just use the script tag to import these packages

        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
        <link rel="stylesheet" href="bound.css">
        <link href="https://cdn.bootcss.com/animate.css/3.7.0/animate.min.css" rel="stylesheet">
        <link href="https://cdn.bootcss.com/antd/3.16.3/antd.min.css" rel="stylesheet">
        <script src="https://cdn.bootcss.com/react/16.8.6/umd/react.production.min.js"></script>
        <script src="https://cdn.bootcss.com/react-dom/16.8.6/umd/react-dom.production.min.js"></script>
        <script src="https://cdn.bootcss.com/react-router/3.2.1/ReactRouter.min.js"></script>
        <script src="https://cdn.bootcss.com/antd/3.16.3/antd.min.js"></script>

Notice the references to animate.min.css and antd.min.css in the html template above
Not only js has third-party packages, but also css. Can css also be exported using externals?
The answer is: no!
How to deal with these third-party css libraries?
Don't panic. When using the antd, the official said that using the Babel plugin import plug-in can achieve the effect of loading on demand. For example, if you only use the Button component, you can only import the Button related js code and css code, which can reduce the file size after construction
Refer to this on-demand import method to see how Babel plugin import can be used

// The principle of this plug-in is to find the package name corresponding to libraryName to import, and rewrite this line of code  
// For example: import 'animate.css' will be converted to import'. / empty. CSS'
// Point the three-party package to an empty css file, and the empty css file will be packaged after packaging, and the package volume will not be increased

// .babelrc.js
module.exports = {
    plugins: [
            libraryName: 'animate.css',
            customName: name => './empty.css',
            libraryName: 'antd/dist/antd.less',
            customName: name => './empty.css',

2. How to reduce the loading resources of the first screen

To reduce the loading resources of the first screen is to delay loading the unnecessary resources of the first screen in order to optimize the loading speed.
A site may have multiple routes, so in addition to the current route related resources that need to be loaded, the contents of other routes should be loaded lazily.
React provides the react.lazy method to lazy load components. React.lazy must be wrapped in the react.suspend tag.
To use lazy loading, you need to combine the syntax of dynamic import(), which can be supported by babel's plugin syntax dynamic import plug-in.

// A writing method of dynamic loading component
// When a route references a component, wrap the component to be referenced in this way
/* loadable.js */
import React from 'react';
const Comp = React.lazy(() => import(/* webpackChunkName: 'preview' */ './index.js'));
export default () => <React.Suspense><Comp /></React.Suspense>;

3. Accelerate static resource access through CDN

We know that accessing static resources through CDN can speed up resource acquisition. Then go to the cloud service provider to start a CDN service?
Don't bother. There are CDN images available for free on the market. You can use what they provide and save some expenses.

Free and easy-to-use cdn acceleration service

Finally, let's look at the volume of the built package. First, only focus on bound.js
On the left is the unoptimized build result js size of 1.42M, so it needs 11s for the first load
On the right is the optimized construction result. The total js file is only 486k, and the resource of the homepage is only 185k, so the theoretical loading speed only needs 2s
This is just a comparison of js loading and css loading. The performance improvement is more obvious


The optimized project github
After unremitting efforts, the first loading speed of the website was finally reduced to 3s
In fact, there are still optimization areas. We need to explore more. Let's work together

Posted by oshecho on Tue, 05 Nov 2019 18:09:42 -0800