基于vue3 vue-cli4 线上部署及优化的问题
作者:倪风6
起因
之前部署一直是直接使用docker在服务器上npm run serve直接运行,没出现什么问题,这次部署时真的难受到我了,第一次打开的速度真的慢的要死,首次加载至少要5s左右,这谁受得了,于是开始网上找教程
过程
开始使用 npm run build
打包项目,在dist目录下,我尝试在本地打开index.html。页面完全空白,打开控制台,发现全是关于
Failed to load resource: net::ERR_FILE_NOT_FOUND
的报错
找了相关教程,这个问题解决还是挺简单的,只需要在根目录下创建一个vue.config.js的文件,添加上以下内容,重新build就行了
module.exports = { publicPath: './', };
接着,我把项目打包到服务器上,使用docker apache进行上线
docker run -p 80:80 -itd --name codetip_net_client -v /root/codetip/client:/usr/local/apache2/htdocs httpd
我直接run了httpd服务,没有镜像他会自己自动拉取,映射了本地目录 /root/codetip/client,只需要将dist中的内容上传即可。
上线成功后,我发现,好了一点(可能是错觉),但是还是特别慢,于是继续找问题,最后发现,我们在build的时候,在js目录下,会自动创建很多map文件,一个js对应一个map,这个的作用主要是在我们开发过程中,给我们错误进行定位用的,比如某个地方报错了,他会给我们指出在第几行出现的问题,但我们的线上应用可用不着这个,只需要在上面说到的vue.config.js这个文件中再添加上一段下方的代码就行了
productionSourceMap: false, // 生产环境是否生成 sourceMap 文件
配置之后少了map文件,速度确实快了不少,不过,还是不满足,可其他网站比起来还是有些差距,继续优化
路由懒加载优化
在router/index.js中将由非懒加载改成懒加载。非懒加载的情况下,会将所有的配置文件都放到一个js文件中,导致这个文件非常大,每次首次请求都会先加载这个文件;而懒加载,创建多个js文件,相当于按需加载,每个页面加载对应的js文件
开启apache gzip
这需要vue项目和服务端项目都开启gzip
vue中安装:
npm install -D compression-webpack-plugin
接着在vue.config.js中添加以下代码即可
configureWebpack: { plugins: [ new CompressionPlugin({ test: /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i,//需要压缩的文件正则 threshold: 10240,//文件大小大于这个值时启用压缩 deleteOriginalAssets: false//压缩后保留原文件 }) ] }
我们之前使用的是docker的httpd,接下来我们开启他的gzip
先进入容器
docker exec -it codetip_net_client bash
容器初始化是没有编辑器的,这里我们先安装一个vim
apt update -y apt install vim -y
接下来打开httpd的配置文件
vim /usr/local/apache2/conf/httpd.conf
打开以下两个文件的注释
LoadModule deflate_module modules/mod_deflate.so LoadModule headers_module modules/mod_headers.so
接下来在文件最后添加上以下内容:
#使用<IfModule deflate_module> 和 <IfModule mod_deflate.c> 经过测试没什么区别 <IfModule deflate_module> # 就像一个开关一样,告诉 Apache 对传输到浏览器的内容进行压缩 SetOutputFilter DEFLATE # 压缩级别 9是最高级 1是最低级,不建议使用太高的压缩比,这样会对CPU产生太大的负担 DeflateCompressionLevel 9 </IfModule> <IfModule mod_deflate.c> # 告诉 apache 对传输到浏览器的内容进行压缩 SetOutputFilter DEFLATE # 压缩等级 9 最低是1,不建议按最大级别进行压缩,压缩率过高会占更多CPU资源 DeflateCompressionLevel 9 # 设置不对后缀gif,jpg,jpeg,png的图片文件进行压缩 SetEnvIfNoCase Request_URI .(?:gif|jpe?g|png)$ no-gzip dont-vary </IfModule> <IfModule mod_deflate.c> # 压缩等级 9 DeflateCompressionLevel 9 # 压缩类型 html、xml、php、css、js 面的文件MIME类型可以根据自己情况添加 AddOutputFilterByType DEFLATE text/html text/plain text/xml application/x-javascript application/x-httpd-php AddOutputFilter DEFLATE js css </IfModule>
之后重启docker容器(或者重启apache)
docker stop codetip_net_client docker start codetip_net_client
开启之后,速度真的提升不止一点点
开启keep-alive
对于部分页面开启这个缓存功能有助于提升访问的效果,但值得注意的是,开启后我们需要将部分动态请求的数据转移到activated
这个生命周期中,因为我们开启后,我们再请求同一个页面的时候,它默认只会执行activated
这个生命周期中的内容,其他将调用缓存中的内容
添加首屏加载动画
这个功能是在我们第一次访问页面的时候出现的,相信很多人在项目搭建到服务器上的时候,会出现第一次打开白屏很久的这个问题,这是因为项目需要先请求到js和css等文件,请求完后才会渲染页面,为了解决这个问题,我在上面也说了很多方法,但总有那么一下白屏也是很难受的,所以我们可以在页面添加上一个加载功能,在项目中/public/index.html文件中添加上对应代码:
<style> @-webkit-keyframes enter { 0% { opacity: 0; top: -10px; } 5% { opacity: 1; top: 0px; } 50.9% { opacity: 1; top: 0px; } 55.9% { opacity: 0; top: 10px; } } @keyframes enter { 0% { opacity: 0; top: -10px; } 5% { opacity: 1; top: 0px; } 50.9% { opacity: 1; top: 0px; } 55.9% { opacity: 0; top: 10px; } } @-moz-keyframes enter { 0% { opacity: 0; top: -10px; } 5% { opacity: 1; top: 0px; } 50.9% { opacity: 1; top: 0px; } 55.9% { opacity: 0; top: 10px; } } body { background: #f8f8f9; } #app-loader { position: absolute; left: 50%; top: 50%; margin-left: -27.5px; margin-top: -27.5px; } #app-loader .square { background: #2d8cf0; width: 15px; height: 15px; float: left; top: -10px; margin-right: 5px; margin-top: 5px; position: relative; opacity: 0; -webkit-animation: enter 6s infinite; animation: enter 6s infinite; } #app-loader .enter { top: 0px; opacity: 1; } #app-loader .square:nth-child(1) { -webkit-animation-delay: 1.8s; -moz-animation-delay: 1.8s; animation-delay: 1.8s; } #app-loader .square:nth-child(2) { -webkit-animation-delay: 2.1s; -moz-animation-delay: 2.1s; animation-delay: 2.1s; } #app-loader .square:nth-child(3) { -webkit-animation-delay: 2.4s; -moz-animation-delay: 2.4s; animation-delay: 2.4s; background: #ff9900; } #app-loader .square:nth-child(4) { -webkit-animation-delay: 0.9s; -moz-animation-delay: 0.9s; animation-delay: 0.9s; } #app-loader .square:nth-child(5) { -webkit-animation-delay: 1.2s; -moz-animation-delay: 1.2s; animation-delay: 1.2s; } #app-loader .square:nth-child(6) { -webkit-animation-delay: 1.5s; -moz-animation-delay: 1.5s; animation-delay: 1.5s; } #app-loader .square:nth-child(8) { -webkit-animation-delay: 0.3s; -moz-animation-delay: 0.3s; animation-delay: 0.3s; } #app-loader .square:nth-child(9) { -webkit-animation-delay: 0.6s; -moz-animation-delay: 0.6s; animation-delay: 0.6s; } #app-loader .clear { clear: both; } #app-loader .last { margin-right: 0; } #app-loader .loader-content { color: #3498db; font-size: 16px; font-weight: 600; } </style>
<div id="app-loader"> <div class="square"></div> <div class="square"></div> <div class="square last"></div> <div class="square clear"></div> <div class="square"></div> <div class="square last"></div> <div class="square clear"></div> <div class="square "></div> <div class="square last"></div> <div class="loader-content"> <span>Loading...</span> </div> </div>
然后到我们APP.vue中添加上
这里的nextTick是为了在我们页面dom发生变化的时候执行,移除加载代码
import { nextTick } from "vue"; nextTick(function () { try { document.body.removeChild(document.getElementById("app-loader")); } catch (e) {} });
效果:
因为服务器速度太快,只有一小会的显示
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。