[Interview question] How to solve the Vue first screen loading is too slow and the white screen appears for a long time?

Demand scenario: The development of the official website of the company's business display. After the version is built, in the external network test environment, the loading loss of the first screen is as high as tens of seconds (the server is abroad, so the loading time is also longer), so the following methods are used to achieve speed-up Purpose.

Dachang interview questions share interview question bank

Front-end and back-end interview question banks (necessary for interviews) Recommended: ★★★★★

Address: front-end interview question bank   web front-end interview question bank VS java back-end interview question bank Daquan

Problem solving steps are as follows:

1. Use lazy loading method (it is mentioned on the official website, so I won’t describe it in detail here)

2. Webpack opens the gzip compressed file transfer mode:

  - gizp compression is an http request optimization method that improves loading speed by reducing file size. HTML, js, css files and even json data can be compressed with it, which can reduce the volume by more than 60%. - When webpack is packaged, use the compression webpack plugin to achieve gzip compression. Install the plugin as follows: npm i -D compression-webpack-plugin - In vue-cli 3.0, the configuration of vue.config.js is as follows:

const CompressionPlugin = require('compression-webpack-plugin');//引入gzip压缩插件
module.exports = {
    plugins:[
        new CompressionPlugin({//gzip压缩配置
            test:/.js$|.html$|.css/,//匹配文件名
            threshold:10240,//对超过10kb的数据进行压缩
            deleteOriginalAssets:false,//是否删除原文件
        })
    ]
}
复制代码

  - Server nginx enables gzip:

gzip on;

gzip_disable "msie6";

gzip_vary on;

gzip_proxied any;

gzip_comp_level 6; #压缩级别:1-10,数字越大压缩的越好,时间也越长

gzip_buffers 16 8k;

gzip_http_version 1.1;

gzip_min_length 256; #gzip压缩最小文件大小,超出进行压缩(自行调节)

gzip_types text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon;预渲染
复制代码

3. Dependent modules use third-party CDN resources

  - Introduced in the homepage index.html, such as:

     <script src="cdn.bootcss.com/vue/2.6.10/…"> 

     <script src="cdn.bootcss.com/vuex/3.0.1/…">

     <script src="cdn.bootcss.com/vue-router/…">

     <script src="cdn.bootcss.com/element-ui/…">

  - Modify vue.config.js, please refer to relevant information about externals configuration.

module.exports = {
    ...
    externals: {
        'vue': 'Vue',
        'vuex': 'Vuex',
        'vue-router': 'VueRouter',
        'element-ui': 'ELEMENT'
    }    
    ...
}
复制代码

  - Modify src/store/index.js

...
// 注释掉
// Vue.use(Vuex)
...
复制代码

  - Modify src/router/index.js

// import Vue from 'vue'
import VueRouter from 'vue-router'
// 注释掉
// Vue.use(VueRouter)
...
复制代码

  - Modify src/main.js

import Vue from 'vue'
import ELEMENT from 'element-ui'
import App from './App.vue'
import router from './router'
import store from './store'
import 'mint-ui/lib/style.css'
import echarts from 'echarts'
import download from './mixin/download'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import '@/static/css/reset.css'
import '@/static/css/font.css'
import '@/assets/fonts/font.css'

Vue.config.productionTip = false
Vue.use(ELEMENT)

router.afterEach(() => {
  NProgress.done()
})

new Vue({
  router,
  store,
  render: h => h(App),
  // 添加mounted,不然不会执行预编译
  mounted () {
  document.dispatchEvent(new Event('render-event'))
  }
}).$mount('#app')
这里element-ui变量名要用ELEMENT, 因为element-ui的umd模块名是ELEMENT
复制代码

 4. Pre-rendering

  - Plugin used: prerender-spa-plugin 

    yarn add prerender-spa-plugin -D

    or npm install prerender-spa-plugin --save-dev
复制代码

  - The configuration in vue.config.js is as follows:

const PrerenderSpaPlugin = require('prerender-spa-plugin');
const Render = PrerenderSpaPlugin.PuppeteerRenderer;
const path = require('path');

configureWebpack: () => {
  if (process.env.NODE_ENV !== 'production') return;
  return {
    plugins: [
      new PrerenderSPAPlugin({
        // 生成文件的路径,也可以与webpakc打包的一致。
        // 下面这句话非常重要!!!
        // 这个目录只能有一级,如果目录层次大于一级,在生成的时候不会有任何错误提示,在预渲染的时候只会卡着不动。
        staticDir: path.join(__dirname, 'dist'),

        // 对应自己的路由文件,比如a有参数,就需要写成 /a/param1。
        routes: ['/', '/Login', '/Home'],

        // 这个很重要,如果没有配置这段,也不会进行预编译
        renderer: new Renderer({
          inject: {
            foo: 'bar'
          },
          headless: false,
          // 在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。
          renderAfterDocumentEvent: 'render-event'
        })
      })
    ]
  };
}
复制代码

  - Configuration in main.js:

new Vue({
  router,
  store,
  render: h => h(App),
  // 添加mounted,不然不会执行预编译
  mounted () {
  document.dispatchEvent(new Event('render-event'))
  }
}).$mount('#app')
复制代码

  - The homepage loading generally enters the routing homepage, which can be configured through nginx to point to the pre-rendered homepage static page. The nginx configuration is as follows:

location = / {
	root    /data/release/pokio_web/client/dist;
	try_files /home/index.html /index.html;
}

location / {
	root    /data/release/pokio_web/client/dist;
	try_files $uri $uri/ /index.html;
}
复制代码

5. Problems encountered:

  - Pre-rendering solves the problem that the Baidu search engine cannot crawl the sub-links of a single page. You can write the required seo page in the page and hide it.

<div style="display: none;">
  <a href="/about/about-.../">...</a>
  <a href="/home/">home</a>
  <a href="/clubs/">home</a>
</div>
复制代码

  - After building, it is found that app.js is still very large: the resource svg introduced by the first screen has an oversized file. Pay attention to the size of the resource introduced by the first screen

Conclusion: After the whole process runs through, the loading of the first screen has taken a qualitative leap. It takes about 3 seconds for the foreign server to load the first screen in China.

 Dachang interview questions share interview question bank

Front-end and back-end interview question banks (necessary for interviews) Recommended: ★★★★★

Address: front-end interview question bank   web front-end interview question bank VS java back-end interview question bank Daquan

Guess you like

Origin blog.csdn.net/weixin_42981560/article/details/130206946