vue打包、网站运行速度优化

最近在做公司的官网,遇到的首要问题就是初次进入网站时,加载很慢,首页的视频和字体甚至需要30秒才能完全展示出来,用户体验可以说时很差了。接下来说几个优化的点。

一、减小图片的体积
如果项目中的图片过于多,并且体积大时,势必会加大打包的体积,影响网站的运行速率,推荐大家使用 TinyPNG,这是一个在线压缩图片的网站,5M以下的图片都能压缩,也不失真。

二、路由懒加载
利用以下写法进行懒加载

component: () => import('@/views/article')

三、打包不生成 .map文件
在vue.config.js文件中设置productionSourceMap为false
vue打包、网站运行速度优化_第1张图片
四、无用文件删除
在反复修改代码的过程中,如果项目中图片很多的话,可能会有很多无用的文件或图片存在。我们可以用插件 useless-files-webpack-plugin 来查找无用文件。
一般此类包不需要安装到项目中,减少node_modules体积(以项目实际情况决定-S/-D)

npm i useless-files-webpack-plugin -S

在vue.config.js中

const UselessFile = require('useless-files-webpack-plugin') //无用文件检查
module.exports = {
  publicPath:"./",
  productionSourceMap: false, // 生产环境是否生成 sourceMap 文件,一般情况不建议打开
  chainWebpack: (config) => {
    config.resolve.alias
      // .set('路径别名', resolve('vue.config文件的相对路径'))
      .set('@$', resolve('src'))
    // 无用文件检查(添加下面这一段)
    config.plugin('uselessFile')
      .use(
        new UselessFile({
          root: path.resolve(__dirname, './src'), // 项目目录
          out: './fileList.json', // 输出文件列表
          clean: false, // 是否删除文件,(为true的话会自动删除文件)
          exclude: /node_modules/ // 排除文件列表
        })
      )
  },
}

vue打包、网站运行速度优化_第2张图片
新生成这个文件,里面包含了所有未被使用的文件。

五、字体包压缩
展示类的网站往往会使用特定的字体,一般大家都会上网寻找字体包,目前我做的网站一共是用到了5个字体包,每个基本 都超过了10M,字体包在初次进入网站时就会进行加载,外加在首页还有视频的情况下,极大地拖慢了网站的加载速度。实际上我们是不需要字体包中的所有字的。所以需要提取我们项目中的所有用到的字。
Vue项目在vue.config.js同级目录新建一个word.js文件。这个文件是在网上找的,引用的哪位大佬的忘记了。

// 项目启动就会提取项目中的所有文字
const fs = require('fs');
const path = require('path');
let filesList = [];//vue 文件路径列表
let jsFilesList = [];//ts 文件路径列表
function readFileList(dir, filesList = []) {  
    const files = fs.readdirSync(dir); 
        files.forEach((item) => { 
            var fullPath = path.join(dir, item);    
            const stat = fs.statSync(fullPath); 
            if (stat.isDirectory()) {         
                readFileList(path.join(dir, item), filesList); //递归读取文件    
            } else if(fullPath.endsWith('.vue')) {              
                filesList.push(fullPath);              
            }else if (/(.ts|.js)$/g.test(fullPath)){
                jsFilesList.push(fullPath)
            }
         });  
        return filesList;
    }
    readFileList(path.resolve(__dirname, 'src'),filesList);

    fs.stat(path.resolve(__dirname, 'src/local'),function(err,statObj){
        // 判断local文件是否存在,如果不存在则创建,如果创建则直接处理json文件
        if(!statObj){
            fs.mkdir(path.resolve(__dirname, 'src/local'),function(err){
                writeFile(filesList,'index');
                writeFile(jsFilesList,'jsIndex');
            })
        }else{
            writeFile(filesList,'index');
            writeFile(jsFilesList,'jsIndex');
        }
    })
    
    function writeFile (fileArr,fileName){
       const reg_1 = /(?/g
        const obj = fileArr.reduce((pre,cur)=>{
            let  fileSuffix = cur.match(/(.ts|.js|.vue)$/g)?.[0];
            let pathName = path.basename(cur,fileSuffix)
            // 如果文件名是index,取父级文件名
            if(pathName === 'index'){
               const pathArr =  cur.split(path.sep);
               pathName = pathArr[pathArr.length-2];
            }
            pre[pathName] = {};
            let pkg = fs.readFileSync(cur,'utf-8');
            const strArr = pkg.match(reg_1); 
            if(strArr?.length){
                strArr.forEach((item,index)=>{
                    if(item.includes('{')){
                        let index = 0
                        item = item.replace(/\$?{{0,2}\w*\.*\w*}{0,2}/g,function(val){
                            if(val){
                                index ++ 
                                return `{${index-1}}`
                            }else{
                                return ''
                            }
                        })
                       
                    }
                    // 如果匹配的字符串的字数大于10,处理key 值
                    if(item.length){
                        let str = item.length >=10? `${item.substring(0,7)}...`:item;
                        pre[pathName][str] = item;
                    }
                   
                })
            }
            return pre
        },{})
        // 创建json文件
        fs.writeFile(path.resolve(__dirname, `src/local/${fileName}.json`),JSON.stringify(obj), 'utf8',function(err){
            // console.log(err)
        })
   }
    

项目运行以后就会生成一个local文件夹,里面分别是index.json和jsIndex.json,提取了.vue文件和.js文件中的所有文字。然后 就可以根据这些字进行字体包压缩了。(不过建议自己提取的时候 标点符号和 ‘撞‘ 这个字再写一下’),我项目中有撞这个字但没提取到。

压缩字体包推荐使用font-spider(字蛛),需要提前有node环境。

npm install font-spider -g


输入font-spider -V 出现版本就说明安装好了。在电脑新建一个文件夹,把需要压缩的ttf字体包放进去。新建index.html,

<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!--link rel="stylesheet" href="./index.css"-->
    <!-- style部分可以提取出来放在css文件中,使用link引入,也可以直接写在html文件内 -->
    <style>
        @font-face {
  			font-family: 'PingFang-Medium';
  			src: url('./PingFang-Medium.ttf')  format('truetype');
  			font-weight: normal;
  			font-style: normal;
		}

        .myFont{
          font-family: 'PingFang-Medium';
        }
    </style>
</head>
<body>
	//  这里写需要压缩的字,可以把项目中用到的字都放到这里来
	<h1 class="myFont">字体包压缩测试</h1>
</body>

ttf文件与index.html文件, css文件看个人要不要。样式我是直接写在index.html里面了。
vue打包、网站运行速度优化_第3张图片
之后在控制台执行

font-spider index.html

注意两种情况,一是报错,这说明你命令执行的路径不对,font-spider index.html主要在index.html同级下执行。第二个是我纠结很久的问题,在一开始我压缩的时候,压缩包的体积和原字体包的体积一直是一样的,不改变。如果出现这种情况就说明你找的ttf文件本来就不能压缩,我是压缩苹方字体,最后是在github才找到了能压缩的字体包。
vue打包、网站运行速度优化_第4张图片
成功的话则如上图所示,字体包极大地压缩了。最后说一下如果你实在找不到能压缩的字体包,并且你用的字体很少的情况下,你可以把不能压缩的字体包用FontCreator软件打开进行文字的提取,这个具体操作可以在网上搜一下这个软件怎么用的。这里就不赘述了,也比较麻烦。
以上内容有用的话麻烦大家点个赞喔,转载麻烦标明出处。

你可能感兴趣的:(vue.js,前端,javascript)