干巴爹兔的博客 干巴爹兔的博客
首页
  • 前端文章

    • JavaScript
    • HTML
    • Vue
  • 学习笔记

    • JavaScript教程
    • React学习笔记
    • Electron学习笔记
  • 开源项目

    • cloud-app-admin
    • 下班了吗Vscode插件
    • Subversion变更单插件
  • Server

    • Django
  • 学习笔记

    • MySQL学习笔记
  • 运维

    • 服务器部署
    • Linux
  • 日常学习

    • 学习方法
关于
收藏
友链
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

干巴爹兔

卑微的前端打工人
首页
  • 前端文章

    • JavaScript
    • HTML
    • Vue
  • 学习笔记

    • JavaScript教程
    • React学习笔记
    • Electron学习笔记
  • 开源项目

    • cloud-app-admin
    • 下班了吗Vscode插件
    • Subversion变更单插件
  • Server

    • Django
  • 学习笔记

    • MySQL学习笔记
  • 运维

    • 服务器部署
    • Linux
  • 日常学习

    • 学习方法
关于
收藏
友链
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • JavaScript文章

  • 学习笔记

  • 开源项目

  • HTML

  • Vue

    • 分享一个用于Vue的markdown插件
    • Vue分享QQ却只能访问首页的解决方法
    • 自己封装的一个Vue全局Toast插件
    • 使用Vue3.0 beta4与Vite0.6.0制作一个todoList
    • Vue首屏加载提升
      • Vue生成markdown目录索引
      • Vite简单上手
    • 前端
    • Vue
    干巴爹兔
    2020-04-29
    目录

    Vue首屏加载提升

    本文部分思路源自:

    vue-cli 3.0 build包太大导致首屏过长的解决方案 (opens new window)

    发布前端项目时因chunk-vendors过大导致首屏加载太慢,Vue Build时chunk-vendors的优化方案 (opens new window)

    # 开头

    在没有进行优化之前,我的网站加载js文件需要25s,这大大的降低了其他人访问我网站的兴趣,所以适当的优化是不可少的。

    # 优化点一

    压缩成gzip格式:

    安装插件

    npm install --save-dev compression-webpack-plugin
    
    1

    vue.config.js配置插件

    const CompressionWebpackPlugin = require('compression-webpack-plugin');
    const productionGzipExtensions = ['js', 'css'];
    const isProduction = process.env.NODE_ENV === 'production';
    module.exports = {
      transpileDependencies: ["vuetify"],
      outputDir: __dirname + "/../server/web",
      publicPath: process.env.NODE_ENV === 'production'
        ? '/web/'
        : '/',
        configureWebpack: config => {
          if (isProduction) {
            config.plugins.push(new CompressionWebpackPlugin({
              algorithm: 'gzip',
              test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
              threshold: 10240,
              minRatio: 0.8
            }))
          }
        }
    };
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

    nginx配置

    # gzip config
        gzip on;
        gzip_min_length 1k;
        gzip_comp_level 9;
        gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
        gzip_vary on;
        gzip_disable "MSIE [1-6]\.";
    
    1
    2
    3
    4
    5
    6
    7

    完整示例

    server {
        listen 80;
        # gzip config
        gzip on;
        gzip_min_length 1k;
        gzip_comp_level 9;
        gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
        gzip_vary on;
        gzip_disable "MSIE [1-6]\.";
    
        root /usr/share/nginx/html;
    
        location / {
            # 用于配合 browserHistory 使用
            try_files $uri $uri/ /index.html;
    
            # 如果有资源,建议使用 https + http2,配合按需加载可以获得更好的体验 
            # rewrite ^/(.*)$ https://preview.pro.loacg.com/$1 permanent;
    
        }
        location /api {
            proxy_pass https://preview.pro.loacg.com;
            proxy_set_header   X-Forwarded-Proto $scheme;
            proxy_set_header   Host              $http_host;
            proxy_set_header   X-Real-IP         $remote_addr;
        }
    }
    
    server {
      # 如果有资源,建议使用 https + http2,配合按需加载可以获得更好的体验 
      listen 443 ssl http2 default_server;
    
      # 证书的公私钥
      ssl_certificate /path/to/public.crt;
      ssl_certificate_key /path/to/private.key;
    
      location / {
            # 用于配合 browserHistory 使用
            try_files $uri $uri/ /index.html;
    
      }
      location /api {
          proxy_pass https://preview.pro.loacg.com;
          proxy_set_header   X-Forwarded-Proto $scheme;
          proxy_set_header   Host              $http_host;
          proxy_set_header   X-Real-IP         $remote_addr;
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48

    image-20200429194525739

    打包后的gzip文件可以达到原有的20%

    # 优化点二

    路由懒加载

    结合Vue的异步组件再结合webpack的代码分割,我们可以轻松的实现路由懒加载。

    // 安装插件 syntax-dynamic-import
    cnpm install --save-dev @babel/plugin-syntax-dynamic-import
    
    // 修改babel.config.js
    module.exports = {
      presets: [
        '@vue/cli-plugin-babel/preset'
      ],
      plugins: ['@babel/plugin-syntax-dynamic-import']
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // 修改路由组件的加载(router/index.js)
    import Vue from "vue";
    import VueRouter from "vue-router";
    import NotFound from "../views/404";
    import Comment from "../views/Comment" //我这个组件有bug,就不做懒加载了
    
    Vue.use(VueRouter);
    
    const routes = [
      {
        path: "/",
        name: "home",
        component: resolve => require(['../views/Home'], resolve)
      },
      {
        path: "/home",
        component: resolve => require(['../views/Home'], resolve)
      },
      {
        path: "/home/:id",
        component: resolve => require(['../views/ArticleList'], resolve),
        props: true
      },
      {
        path: "/home/article/:id",
        component: resolve => require(['../views/Article'], resolve),
        props: true
      },
      {
        path: "/image",
        component: resolve => require(['../views/Image'], resolve),
      },
      {
        path: "/article",
        component: resolve => require(['../views/ArticleRecent'], resolve),
      },
      {
        path: "/image/:id",
        component: resolve => require(['../views/ImageList'], resolve),
        props: true
      },
      {
        path: "/site",
        component: resolve => require(['../views/Site'], resolve),
      },
      {
        path: "/site/:id",
        component: resolve => require(['../views/SiteList'], resolve),
        props: true
      },
      {
        path: "/about",
        name: "about",
        // route level code-splitting
        // this generates a separate chunk (about.[hash].js) for this route
        // which is lazy-loaded when the route is visited.
        component: () =>
          import(/* webpackChunkName: "about" */ "../views/About.vue")
      },
      {
        path: "/search/:title",
        component: resolve => require(['../views/SearchList'], resolve),
        props: true
      },
      {
        path: "/404",
        component: resolve => require(['../views/404'], resolve),
      },
      {
        path:"/privacy",
        component: resolve => require(['../views/Privacy'], resolve),
      },
      {
        path:"/log",
        component: resolve => require(['../views/Log'], resolve),
      },
      {
        path:"/link",
        component: resolve => require(['../views/Link'], resolve),
      },
      {
        path:"/comment",
        component: Comment
      },
      { path: "*", component: NotFound }
    ];
    
    const router = new VueRouter({
      routes
    });
    
    export default router;
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93

    # 优化点三

    启用CDN加速

    const CompressionWebpackPlugin = require('compression-webpack-plugin');
    const productionGzipExtensions = ['js', 'css'];
    const isProduction = process.env.NODE_ENV === 'production';
    module.exports = {
      transpileDependencies: ["vuetify"],
      outputDir: __dirname + "/../server/web",
      publicPath: process.env.NODE_ENV === 'production'
        ? '/web/'
        : '/',
        configureWebpack: config => {
          if (isProduction) {
            config.plugins.push(new CompressionWebpackPlugin({
              algorithm: 'gzip',
              test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
              threshold: 10240,
              minRatio: 0.8
            }))
          }
          #分离不常用代码库转为cdn引用
          config.externals = {
            'vue': 'Vue',
            'vue-router': 'VueRouter',
            "vuetify":"Vuetify"
          }
        }
    };
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    // 在public文件夹的index.html 加载,一些css,js能用cdn的都可以用
    
    <!-- CND -->
    <script src="https://cdn.bootcss.com/vue/2.6.10/vue.runtime.min.js"></script>
        <script src="https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js"></script>
        <script src="https://unpkg.com/vue/dist/vue.js"></script>
        <script src="https://unpkg.com/vuetify/dist/vuetify.js"></script>
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css">
        <link href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons' rel="stylesheet" type="text/css">
        <link href="https://unpkg.com/vuetify/dist/vuetify.min.css" rel="external nofollow" rel="stylesheet">
        <link href="https://cdn.bootcdn.net/ajax/libs/gitalk/1.6.0/gitalk.min.css" rel="stylesheet">
        <link href="https://cdn.jsdelivr.net/npm/vue-loading-overlay@3/dist/vue-loading.css" rel="stylesheet">
        <link href="https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/2.10.0/github-markdown.min.css" rel="stylesheet">
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    # 优化点四

    阿里云配置全站加速,这个大家自己去阿里云看加好了

    # 结果

    基于以上优化,我的js编译出来的文件大小由6m降低为1.4m,document加载时间由25s缩短为5m以内,降低了200%,所以优化是有用的。

    image-20200429195708773

    编辑 (opens new window)
    #Vue
    上次更新: 2022/08/29, 16:40:19
    使用Vue3.0 beta4与Vite0.6.0制作一个todoList
    Vue生成markdown目录索引

    ← 使用Vue3.0 beta4与Vite0.6.0制作一个todoList Vue生成markdown目录索引→

    最近更新
    01
    使用Vscode开发一个小插件
    10-21
    02
    Vscode插件配置项监听
    10-18
    03
    使用has属性构造必填效果
    10-14
    更多文章>
    Theme by Vdoing | Copyright © 2020-2023 互联网ICP备案: 闽ICP备18027236号
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式