Summary of front-end performance optimization (SPA articles)

performance optimization

A problem that all developers cannot avoid is the performance optimization of the project. Performance optimization is an enduring problem that runs through almost the entire project development process. Projects with good performance optimization can not only provide better user experience, but also make the allocation of service resources more reasonable.

About optimization of SPA (single page) application

Front-end developers basically know that single-page programs have a common problem. The loading of the first screen is too slow, because there are too many things to load when the first visit is made, and the amount of resources is so large that the experience may not be so friendly. The following point can be targeted to optimize.

1. Route lazy loading

For SPA projects, one route corresponds to one page. If no processing is done, all pages will be packaged into one file after the project is packaged. When the user opens the homepage, all resources will be loaded at one time, causing the homepage to load very slowly and reducing user experience. .

The official actually gave an answer to this question. We only need to change the code according to their prompts, and then we can improve the running speed of the project to a certain extent.

// 通过webpackChunkName设置分割后代码块的名字
const Home = () => import(/* webpackChunkName: "home" */ "@/views/home/index.vue");
const MetricGroup = () => import(/* webpackChunkName: "metricGroup" */ "@/views/metricGroup/index.vue");
…………
const routes = [
    {
    
    
       path: "/",
       name: "home",
       component: Home
    },
    {
    
    
       path: "/metricGroup",
       name: "metricGroup",
       component: MetricGroup
    },
    …………
]

2. Lazy loading of components

Lazy loading of components is the same as lazy loading of routes, separating resources and introducing them into our pages when needed, thus saving resources and optimizing page loading speed.

For example, lazy loading of pop-up window components.

<script>
const dialogInfo = () => import(/* webpackChunkName: "dialogInfo" */ '@/components/dialogInfo');
export default {
    
    
  name: 'homeView',
  components: {
    
    
    dialogInfo
  }
}
</script>

After repackaging, home.js and about.js do not have the code of the pop-up component. This component is packaged independently as dialogInfo.js. When the user clicks the button, dialogInfo.js and dialogInfo.css will be loaded

Component lazy loading usage scenarios

Sometimes it is not good to split resources too carefully, which may cause an increase in browser http requests.
Three scenarios suitable for lazy loading of components are summarized:
1) The JS file of this page is large in size, which makes the page open slowly. You can use lazy loading of components Split resources, use the browser to download resources in parallel, and increase the download speed (such as the home page)
2) This component is not displayed as soon as it enters the page, it needs to be triggered under certain conditions (such as the bullet box component)
3) This component is highly reusable , many pages are introduced, and the component is extracted by lazy loading. On the one hand, it can make good use of the cache, and at the same time, it can also reduce the JS file size of the page (such as table components, graphics components, etc.)

The principle of lazy loading

The realization of the premise of lazy loading: ES6's dynamic loading module-import().

To achieve lazy loading, you must first separate the submodules for lazy loading and package them into a separate file

The role of webpackChunkName is to set the name of the code block when webpack splits the library code (lodash) imported asynchronously when packaging. webpack will combine any async module with the same chunk name into the same async chunk

In short, after using lazy loading, the program will only load the resources required by your current page, and will not request resources that are not needed for the time being, and will not make requests if repeated resources are used in the future. Thus consuming our browser resources.

3. Optimization of Tree shaking

The principle of tree-shaking:
depends on the module characteristics of ES6, ES6 module dependencies are deterministic, independent of the runtime state, and reliable static analysis can be performed. This is the basic static analysis of tree-shaking. It does not need to execute code,
just Code can be analyzed literally. Modularization before ES6, such as CommonJS, is dynamically loaded. Only after execution can you know what module is referenced, and you cannot optimize it through static analysis. It is based on this basis that tree-shaking becomes possible.

The role of Tree shaking:
Eliminate useless JS code and reduce code size

Compare the following two ends of the code

// 第一段
export function targetType(target) {
    
    
  return Object.prototype.toString.call(target).slice(8, -1).toLowerCase();
}
export function deepClone(target) {
    
    
  return JSON.parse(JSON.stringify(target));
}


// 第二段
export default {
    
    
  targetType(target) {
    
    
    return Object.prototype.toString.call(target).slice(8, -1).toLowerCase();
  },
  deepClone(target) {
    
    
    return JSON.parse(JSON.stringify(target));
  }
};

// 引入并使用
import util from '../util';
util.targetType(null)

In fact, there is not much difference in use between the two, except that the second section has an extra layer of encapsulation, but such encapsulation will invalidate tree shaking, increase the package size of the project, and reduce the precise allocation of our resource packages. Because our encapsulation will import all the functions in the file into the component page by default, resulting in some useless codes.

The reason is that export default exports an object, and it is impossible to determine which variables of an object are not used through static analysis, so tree-shaking only takes effect for variables exported using export, which is why functional programming is becoming more and more popular
. , because you can make good use of tree-shaking to simplify the size of the project, and it is also one of the reasons why vue3 fully embraces functional programming

4. The skeleton screen optimizes the duration of the white screen

insert image description here

Using the skeleton screen can shorten the white screen time and improve the user experience. Most mainstream websites in China use skeleton screens, especially SPA single-page applications for mobile projects
. Regardless of vue or react, the initial html is blank, and the content needs to be mounted on the root node by loading JS. This set Side effects of the mechanism: it will cause a long white screen

The common skeleton screen plug-in is based on this principle. When the project is packaged, the content of the skeleton screen is directly placed in the root node of the html file. Using the skeleton screen
plug-in, the packaged html file (the skeleton screen inside the root node):

Skeleton screen plug-in

① Install the plug-in

npm i vue-skeleton-webpack-plugin 

②vue.config.js configuration

const SkeletonWebpackPlugin = require("vue-skeleton-webpack-plugin");
module.exports = {
    
    
   configureWebpack: {
    
    
      plugins: [
       new SkeletonWebpackPlugin({
    
    
        // 实例化插件对象
        webpackConfig: {
    
    
          entry: {
    
    
            app: path.join(__dirname, './src/skeleton.js') // 引入骨架屏入口文件
          }
        },
        minimize: true, // SPA 下是否需要压缩注入 HTML 的 JS 代码
        quiet: true, // 在服务端渲染时是否需要输出信息到控制台
        router: {
    
    
          mode: 'hash', // 路由模式
          routes: [
            // 不同页面可以配置不同骨架屏
            // 对应路径所需要的骨架屏组件id,id的定义在入口文件内
            {
    
     path: /^\/home(?:\/)?/i, skeletonId: 'homeSkeleton' },
            {
    
     path: /^\/detail(?:\/)?/i, skeletonId: 'detailSkeleton' }
          ]
        }
      })        
      ]
   }
}

③Create a new skeleton.js entry file

// skeleton.js
import Vue from "vue";
// 引入对应的骨架屏页面
import homeSkeleton from "./views/homeSkeleton";
import detailSkeleton from "./views/detailSkeleton";

export default new Vue({
    
    
    components: {
    
    
        homeSkeleton,
        detailSkeleton,
    },
    template: `
    <div>
      <homeSkeleton id="homeSkeleton" style="display:none;" />
      <detailSkeleton id="detailSkeleton" style="display:none;" />
    </div>
  `,
});

The above are the optimization methods of SPA projects. There are many other optimization methods, but we should consider such solutions during the development stage of the project, otherwise the cost of subsequent maintenance and optimization will increase. Therefore, if necessary, we should try to intervene in the optimization progress and performance level of the project as early as possible, so that we can continue to output products with quality and easy maintenance.

Guess you like

Origin blog.csdn.net/huangzhixin1996/article/details/130347186