The original addressThe copyright address is here. I have to copy everything I read

preface

What technical difficulties did you encounter in this project and how did you solve them?

Do not make the interviewer think you are just an API Caller

Because:

However, many people would say that my project is not big and there are no difficulties, or it is not difficult, but only some problems, which can be solved by Google. If I have to ask my colleagues, these problems have not bothered me for a long time. In fact, I have also encountered the same situation. It is not good to tell the interviewer how to solve these problems through search engines, which makes the interviewer think that you are just an API Caller, but there is nothing worth talking aboutCopy the code

You can

Trying to encapsulate a few common components, while also trying to analyze the project's performance bottlenecks and looking for optimization solutions, will also give the interviewer an overall picture of youCopy the code

Next, the author will share the process of how to make the whole system look new while meeting the business requirements in my current company’s project.

Because the code is highly coupled, I’m going to rewrite the entire project

Thanks to vue-element-admin in The Underpants, I decided to start a new project to rewrite all the previous code

The project structure

Project directory structure optimization

│ ├─ Heavy Metal Exercises │ ├─ Heavy Metal Exercises │ ├─ Heavy Metal Exercises │ ├─ Heavy Metal Exercises │ ├─ Heavy Metal Exercises │ ├─ Heavy Metal Exercises │ ├─ Heavy Metal Exercises │ ├─ Heavy Metal Guitar School │ ├─ Heavy Metal Flag School │ ├─ Heavy Metal Flag School │ ├─ Heavy Metal Flag School │ ├─ Heavy Metal Flag School - Heavy Metal Flag School - Heavy metal Flag School - Heavy metal Flag School - Heavy metal Flag School - Heavy metal Flag School - Heavy metal Flag School - Heavy metal Flag School - Heavy metal Flag School - Heavy metal Flag School - Heavy metal Flag School - Heavy metal Flag School ├ ─ TableOptions / / business components (Table is surrounding The form related to group) │ ├ ─ TheBreadcrumb / / bread crumbs components (is The beginning of each page component will only introduce a stateless components) | ├ ─ TheSidebar │ / / sidebar components ├ ─ TransitionSildeDown / / business components (the Transition animation component) │ └ ─ index. The js / / global components automatically registered script │ ├ ─ directives / / custom instruction ├ ─ element / / elementui ├ ─ errorLog / / error trapping ├ ─ filters / / global filter ├ ─ the ICONS/store/SVG icon folder ├ ─ interface / / TypeScript interface ├ ─ mixins / / local mixed with ├ ─ the router / / vue - the router │ ├ ─ modules │ └ ─ index. The js ├ ─ store / / vuex │ ├ ─ modules │ └ ─ index. The js ├ ─ style / / global style/local page reusable style ├ ─ util ├─ ├─ exercises - ├─ exercises - ├─ exercisesCopy the code

A good project layering allows you to quickly find the corresponding module to change during a business iteration, rather than finding a single line of code in a sea of code

Performance optimization

1. Shorten packing.

2. Start from four aspects to make the system “fly”

Network request correlation build correlation static resource optimization code correlation

Network request correlation

CDN

In addition, CDN can redirect users’ requests to the service node nearest to users in real time according to comprehensive information such as network traffic, connection of each node, load status, distance to users and response time

In addition, since the domain name of CDN and server are generally different, it can alleviate the limitation of the number of concurrent HTTP requests of the same domain name, effectively divert traffic and reduce the sending of redundant cookies (static resource requests on CDN do not need to carry any cookies).

Externals applies only to the default import of ES Module

Here, it is recommended to put as much as possible on the company's dedicated CDN, not recommended to use the public CDN, because it is easy to hang, the production environment is mainly stable

A reasonable caching strategy

Set the third-party libraries or static resources that will not change for a long time to strong cache, set max-age to a very long time, and then add the access path hash to reach the hash value changed after the guarantee to obtain the latest resources (VUe-CLI3 will automatically build, build their own Webpack scaffolding need to configure their own contentHa sh,chunkHash)

The cache policy on the CDN is very large, so that the next access will only read the resources cached in the local disk/memory:

For multimedia resources such as index.html and some images, you can choose to negotiate the cache (max-age<=0, last-Modified,ETag) to ensure that the latest resources are returned to the server

A good caching strategy can help reduce the strain on the server and significantly improve the user experience

gzip

If your project uses Nginx as a Web server, simply configure the appropriate gzip option in the nginx configuration file to enable gzip compression for your static resource server

    Enable and disable gzip mode
    gzip on;
    #gizp compression starting point, files greater than 1K to compress
    gzip_min_length 1k;
    # gzip compression level, 1-9, the larger the compression, the better, also more CPU time
    gzip_comp_level 6;
    The type of file to compress.
    gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript ;
    #nginx for static file processing module, when enabled, will look for files ending with.gz, directly return, do not use CPU compression, if not found, do not compress
    gzip_static on
    Whether to add Vary: accept-encoding to the HTTP header is recommended
    gzip_vary on;
    Set the HTTP protocol version for gzip compressionGzip_http_version 1.1;Copy the code

But what we are talking about here is the front-end output of gzip files, using compression-webpack-plugin to make webpack output of.gz zip files at packaging time

This way we can already get the gzip file without the server actively compressing it, as can be found in the nginx configuration item above

#nginx for static file processing module, when enabled, will look for files ending with.gz, directly return, do not use CPU compression, if not found, do not compress
gzip_static on
Copy the code

Gz files on the server, and start gzip_static to enable the server to preferentially return. Gz files, in the face of high traffic, can also reduce the pressure on the server to a certain extent, it is a space for time (.gz files will occupy extra space on the server).

Resource sniffer

For modern browsers, you can add preload,prefetch, and dnS-prefetch attributes to the link tag

preload

For SPA applications, DOM nodes will be generated after the browser parses the script. If you do not use server-side rendering in your project and need to load a time-consuming first screen image, you can consider placing this first screen image in the preload tag for the browser to pre-request and load execution, so that when the script script is executed The image is loaded immediately after the line is finished (otherwise you need to wait until the script is finished to request the image from the background)

It is also a good choice to use Preload to preload the CSS styles required for the first screen

Preload is not used

prefetch

Prefetch allows the browser to pre-load resources that may be needed for the next page. Vue-cli3 adds prefetch to all lazy-loaded routes by default so that you can access lazy-loaded routes faster

The difference between Preload and Prefetch is that preload loads resources in parallel with static resources required by the page, whereas Prefetch loads resources marked as PreFETCH at idle time after the browser has loaded the necessary resources

dns-prefetch

Dns-prefetch enables the browser to resolve the domain name in advance, reducing the cost of DNS search. If your static resource and back-end interface are not the same server, you can add the domain name of your backend to the link tag

Dns-prefetch technology is also used on the homepage of JD

http2

Http2 has gone through four years since its inception in 2015, and now has more than 50% coverage in China. Thanks to http2’s frame transfer, it can greatly reduce HTTP (S) request overhead

Comparison of performance differences between HTTP2 and HTTP1.1

If a large number of static resources need to be loaded on the first screen of the system at the same time, but the browser has a limit on the number of TCP connections in the same domain name (chrome has a limit of six), the system cannot continue sending requests until the previous requests are received. Http2, on the other hand, can allow multiple concurrent requests within a TCP connection without limitation, especially in poor network environments

It is highly recommended to use http2 on servers that support HTTPS, either via Nginx, a Web server, or by having the server support Http2 directly

Nginx enables http2 simply by adding http2 to the listener port in nginx.conf, provided that your VERSION of Nginx is at least 1.95 and HTTPS is already enabled

listen 443 ssl http2; Copy the codeCopy the code

On a network, you can view the version of HTTP through which the current resource is transmitted through protocol

The h2 represents http2

Building related

In terms of construction, reasonable configuration of construction tools can reduce the volume of code in production environment, reduce packaging time and shorten page loading time

Route lazy loading

Traditional routing components are statically packaged into the project through import. The disadvantage of this is that all page components are packaged in the same script file, resulting in a noticeable lag (white screen) in the first screen in production environment due to the amount of code loaded.

Import () enables the module of ES6 to have the ability of dynamic loading. When the URL matches the corresponding path, the page components will be dynamically loaded, so the amount of code on the first screen will be greatly reduced. Webpack will separate the dynamically loaded page components into a separate chunk.js file

pre-rendered

As the browser needs to load and parse corresponding HTML, CSS and JS files before rendering the page, there will be a blank screen for a period of time. How to reduce the impact of blank screen on users as much as possible? At present, I choose to inject a loading animation into the HTML template. Here I use loading animation in D2-admin as an example

When the user visits your project, the script is not executed yet, but the loading animation can be displayed, because it is directly injected into THE HTML. After the script is executed, Vue will generate a new node of app and delete the old node with the same name. This can effectively transition the white screen time

Loading animation is a static page with no function

In addition, pre-rendering can also use server side rendering (SSR), through the back-end output of a home page template, or the use of skeleton screen scheme, here I have no in-depth understanding, interested friends can go to practice

Small skills in the development process

Use require.context, the Webpack API, to avoid having to explicitly import a file every time you import it. It can scan the file you specify and import it all into the specified file

  • Vue-router Automatically imports routes
  • Vuex modules are automatically imported
  • Automatic import of SVG ICONS
  • Automatic import of global components

Vuex:

When creating a new module, you don’t need to import it in index.js and declare it again in modules

Global components and SVG ICONS:

Instead of having to import each global component you create, Vue.com Ponent is called once, and when loaded into Svg the component will automatically scan the ICONS folder and import all Svg ICONS in

The source code

Part of the optimized scheme is put on my Github, you can have a look if you are interested

The source address