Vue首屏优化方案

2024-03-12 09:04

本文主要是介绍Vue首屏优化方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在Vue项目中,引入到工程中的所有js、css文件,编译时都会被打包进vendor.js,浏览器在加载该文件之后才能开始显示首屏。若是引入的库众多,那么vendor.js文件体积将会相当的大,影响首屏的体验。可以看个例子:

这是优化前的页面加载状态:执行 npm run build 打包项目,出来的vendeor.js文件,基本都是1M以上的的巨大文件,没有用户能忍受5s以上的loading而不关闭页面的,如图所示:

 

当项目在挂载到服务器上,平均都是10S+以上加载出来,好家伙这加载时间,仿佛过了半个世纪,很烦人,心态boom, 开发者甚至都有种想砸电脑的冲动 

一、分析下前端加载速度慢原因 

第一步:首先安装webpack的可视化资源分析工具,命令行执行:

 npm i webpack-bundle-analyzer -D

第二步:然后在webpack的dev开发模式配置中,引入插件,代码如下:

const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')plugins: [new BundleAnalyzerPlugin()
]

第三步:最后命令行执行 npm run build --report  , 浏览器会自动打开分析结果,如下所示:

 

 可以看到vue全家桶相关依赖占用了很大的空间,对webpack的构建速度和网站加载速度都会有比较大的影响。单页应用会随着项目越大,导致首屏加载速度很慢,针对目前所暴露出来的问题,有以下几种优化方案可以参考: 

二、优化方案

0.初步优化

初步优化,减少全局组件引入(是否放在main.js),按需引入需要的模块(echarts按需引入等),使用轻量级数据库(moment.js 切换 data-fns等) 

1.采用懒加载的方式

路由懒加载和组件懒加载:

访问到当前页面才会加载相关的资源,异步方式分模块加载文件,默认的文件名是随机的id。如果在output中配置了chunkFilename,可以在component中添加WebpackChunkName,是为了方便调试,在页面加载时候,会显示加载的对应文件名+hash值,如下图:

{path: '/Login',name: 'Login',component: () = >import( /* webpackChunkName: "Login" */  '@/view/Login')
}

 

图片懒加载:使用vue-lazyload插件

//引入vue懒加载
import VueLazyload from 'vue-lazyload'//方法一:  没有页面加载中的图片和页面图片加载错误的图片显示
// Vue.use(VueLazyload)//方法二:  显示页面图片加载中的图片和页面图片加载错误的图片
//引入图片
import loading from '@/assets/images/load.jpg'
//注册图片懒加载  
Vue.use(VueLazyload, {// preLoad: 1.3,error: '@/assets/images/error.jpg',//图片错误的替换图片路径(可以使用变量存储)loading: loading,//正在加载的图片路径(可以使用变量存储)// attempt: 1
})

2.webpack开启gzip压缩文件传输模式

gizp压缩是一种http请求优化方式,通过减少文件体积来提高加载速度。html、js、css文件甚至json数据都可以用它压缩,可以减小60%以上的体积。

前端配置gzip压缩,并且服务端使用nginx开启gzip,用来减小网络传输的流量大小。

 webpack打包时借助 compression webpack plugin实现gzip压缩,安装插件如下:

npm i -D compression-webpack-plugin

在vue-cli 3.0 中,vue.config.js配置如下:

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

启用gzip压缩打包之后,会变成下面这样,自动生成gz包。目前大部分主流浏览器客户端都是支持gzip的,就算小部分非主流浏览器不支持也不用担心,不支持gzip格式文件的会默认访问源文件的,所以不要配置清除源文件。

在nginx中开启gzip:

server {gzip on;gzip_buffers 32 4K;gzip_comp_level 6;gzip_min_length 100;gzip_types application/javascript text/css text/xml application/json;gzip_vary on;listen       80;listen       [::]:80 ;。。。。。。。。

配置好之后,打开浏览器访问线上,F12查看控制台,如果该文件资源的响应头里显示有Content-Encoding: gzip,表示浏览器支持并且启用了Gzip压缩的资源

 

3.依赖模块采用第三方cdn资源(对于第三方js库的优化,分离打包) 

生产环境是内网的话,就把资源放内网,通过静态文件引入,会比node_modules和外网CDN的打包加载快很多。如果有外网的话,可以通过CDN方式引入,因为不用占用访问外网的带宽,不仅可以为您节省流量,还能通过CDN加速,获得更快的访问速度。但是要注意下,如果你引用的CDN 资源存在于第三方服务器,在安全性上并不完全可控。国内的CDN服务推荐使用 BootCDN

目前采用引入依赖包生产环境的js文件方式加载,直接通过window可以访问暴露出的全局变量,不必通过import引入,Vue.use去注册

在webpack的dev开发配置文件中, 加入如下参数,可以分离打包第三方资源包,key为依赖包名称,value是源码抛出来的全局变量。对于一些其他的工具库,尽量采用按需引入的方式。

使用 CDN 的好处有以下几个方面

(1)加快打包速度。分离公共库以后,每次重新打包就不会再把这些打包进 vendors 文件中。
(2)CDN减轻自己服务器的访问压力,并且能实现资源的并行下载。浏览器对 src 资源的加载是并行的(执行是按照顺序的)。

第一步:修改vue.config.js

module.exports = {...externals: {'vue': 'Vue','vuex': 'Vuex','vue-router': 'VueRouter','axios': 'axios','element-ui': 'ELEMENT','underscore' : {commonjs: 'underscore',amd: 'underscore',root: '_'},'jquery': {commonjs: 'jQuery',amd: 'jQuery',root: '$'}}    ...
}

如果想引用一个库,但是又不想让webpack打包,且又不影响我们在程序中以CMD、AMD或者window/global全局等方式进行使用,那就可以通过配置externals

第二步:在index.html中添加cdn

    <link href="https://cdn.bootcss.com/element-ui/2.7.2/theme-chalk/index.css" rel="stylesheet"></head><body><div id="app"></div><script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script><script src="https://cdn.bootcss.com/vuex/3.1.0/vuex.min.js"></script><script src="https://cdn.bootcss.com/vue-router/3.0.4/vue-router.min.js"></script><script src="https://cdn.bootcss.com/axios/0.18.0/axios.min.js"></script><script src="https://cdn.bootcss.com/element-ui/2.7.2/index.js"></script><script src="https://cdn.bootcss.com/jquery/3.4.0/jquery.min.js"></script><script src="https://cdn.bootcss.com/underscore.js/1.9.1/underscore-min.js"></script></body>

第三步:去除vue.use相关代码

通过 CDN 引入,在使用 VueRouter Vuex ElementUI 的时候要改下写法。CDN会把它们挂载到window上,可以不再使用Vue.use(xxx)

main.js中 注释掉

// import Vue from 'vue';
// import iView from 'iview';
// import '../theme/index.less';

4.禁止生成map文件

vue.config.js配置:

module.exports = {productionSourceMap: false, // 生产环境是否生成 sourceMap 文件,一般情况不建议打开
}

在设置了productionSourceMap: false之后,就不会生成map文件,map文件的作用在于:项目打包后,代码都是经过压缩加密的,如果运行时报错,输出的错误信息无法准确得知是哪里的代码报错。也就是说map文件相当于是查看源码的一个东西。如果不需要定位问题,并且不想被看到源码,就把productionSourceMap 置为false,既可以减少包大小,也可以加密源码。

5.去掉代码中的console和debugger

打包之后控制台很干净,部署正式环境之前最好这样做。vue-cli3.0

configureWebpack: config => {if (process.env.NODE_ENV === 'production') {config.optimization.minimizer[0].options.terserOptions.compress.warnings = falseconfig.optimization.minimizer[0].options.terserOptions.compress.drop_console = trueconfig.optimization.minimizer[0].options.terserOptions.compress.drop_debugger = trueconfig.optimization.minimizer[0].options.terserOptions.compress.pure_funcs = ['console.log']}},

uglifyOptions去除console来减少文件大小

// 安装uglifyjs-webpack-plugin
cnpm install uglifyjs-webpack-plugin --save-dev// 修改vue.config.jsconfigureWebpack: config => {if (isProduction) {.....config.plugins.push(new UglifyJsPlugin({uglifyOptions: {compress: {warnings: false,drop_debugger: true,drop_console: true,},},sourceMap: false,parallel: true,})       )}}

6. 预渲染配置

使用插件:prerender-spa-plugin 

vue.config.js中配置如下:

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'})})]};
}

7.图片资源的压缩,icon资源使用雪碧

严格说来这一步不算在编码技术范围内,但是却对页面的加载速度影响很大。对于所有的图片文件,都可以在一个叫tinypng的网站上去压缩一下。网址:tinypng.com/,对页面上使用到的icon,可以使用在线字体图标,或者雪碧图,将众多小图标合并到同一张图上,用以减轻http请求压力。然后通过操作CSS的background属性,控制背景的位置以及大小,来展示需要的部分。

// 图片压缩设置chainWebpack: config => {// 图片打包压缩,使用了 --- image-webpack-loader --- 插件对图片进行压缩config.module.rule('images').use('image-webpack-loader').loader('image-webpack-loader').options({ bypassOnDebug: true }).end()},

8. 前端页面代码层面的优化

  1. 合理使用v-if和v-show

  2. 合理使用watch和computed

  3. 使用v-for必须添加key, 最好为唯一id, 避免使用index, 且在同一个标签上,v-for不要和v-if同时使用

  4. 定时器的销毁。可以在beforeDestroy()生命周期内执行销毁事件;也可以使用$once这个事件侦听器,在定义定时器事件的位置来清除定时器。详细见vue官网

  5. 长列表性能优化

  6. 图片资源懒加载

9.解决白屏,体验优化

 上边已经讲述了优化问题,把 所 有 的 优 化 都 做 完 之 后 , 加 载 速 度 有 了 显 著 提 升,把所有的优化都做完之后,加载速度有了显著提升}把所有的优化都做完之后,加载速度有了显著提升把所有的优化都做完之后,加载速度有了显著提升,但是再网慢的时候还是会有白屏,所以再白屏期间加骨架屏和loading就显得格外重要了。

<body>//这里亲测有效,放心使用<div id="app">// 我们只需要再这里添加loading图或者骨架屏,有人会说怎么控制它的显示隐藏啊,//不用担心,再项目初始化完成后会自动替换为你的页面。<div class="self-loading">页面正快马加鞭赶来,请耐心等待</div></div>
</body>

这篇关于Vue首屏优化方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/800766

相关文章

前端下载文件时如何后端返回的文件流一些常见方法

《前端下载文件时如何后端返回的文件流一些常见方法》:本文主要介绍前端下载文件时如何后端返回的文件流一些常见方法,包括使用Blob和URL.createObjectURL创建下载链接,以及处理带有C... 目录1. 使用 Blob 和 URL.createObjectURL 创建下载链接例子:使用 Blob

Vuex Actions多参数传递的解决方案

《VuexActions多参数传递的解决方案》在Vuex中,actions的设计默认只支持单个参数传递,这有时会限制我们的使用场景,下面我将详细介绍几种处理多参数传递的解决方案,从基础到高级,... 目录一、对象封装法(推荐)二、参数解构法三、柯里化函数法四、Payload 工厂函数五、TypeScript

Python通过模块化开发优化代码的技巧分享

《Python通过模块化开发优化代码的技巧分享》模块化开发就是把代码拆成一个个“零件”,该封装封装,该拆分拆分,下面小编就来和大家简单聊聊python如何用模块化开发进行代码优化吧... 目录什么是模块化开发如何拆分代码改进版:拆分成模块让模块更强大:使用 __init__.py你一定会遇到的问题模www.

Vue3使用router,params传参为空问题

《Vue3使用router,params传参为空问题》:本文主要介绍Vue3使用router,params传参为空问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录vue3使用China编程router,params传参为空1.使用query方式传参2.使用 Histo

Java图片压缩三种高效压缩方案详细解析

《Java图片压缩三种高效压缩方案详细解析》图片压缩通常涉及减少图片的尺寸缩放、调整图片的质量(针对JPEG、PNG等)、使用特定的算法来减少图片的数据量等,:本文主要介绍Java图片压缩三种高效... 目录一、基于OpenCV的智能尺寸压缩技术亮点:适用场景:二、JPEG质量参数压缩关键技术:压缩效果对比

SpringBoot首笔交易慢问题排查与优化方案

《SpringBoot首笔交易慢问题排查与优化方案》在我们的微服务项目中,遇到这样的问题:应用启动后,第一笔交易响应耗时高达4、5秒,而后续请求均能在毫秒级完成,这不仅触发监控告警,也极大影响了用户体... 目录问题背景排查步骤1. 日志分析2. 性能工具定位优化方案:提前预热各种资源1. Flowable

CSS Padding 和 Margin 区别全解析

《CSSPadding和Margin区别全解析》CSS中的padding和margin是两个非常基础且重要的属性,它们用于控制元素周围的空白区域,本文将详细介绍padding和... 目录css Padding 和 Margin 全解析1. Padding: 内边距2. Margin: 外边距3. Padd

CSS will-change 属性示例详解

《CSSwill-change属性示例详解》will-change是一个CSS属性,用于告诉浏览器某个元素在未来可能会发生哪些变化,本文给大家介绍CSSwill-change属性详解,感... will-change 是一个 css 属性,用于告诉浏览器某个元素在未来可能会发生哪些变化。这可以帮助浏览器优化

CSS去除a标签的下划线的几种方法

《CSS去除a标签的下划线的几种方法》本文给大家分享在CSS中,去除a标签(超链接)的下划线的几种方法,本文给大家介绍的非常详细,感兴趣的朋友一起看看吧... 在 css 中,去除a标签(超链接)的下划线主要有以下几种方法:使用text-decoration属性通用选择器设置:使用a标签选择器,将tex

前端高级CSS用法示例详解

《前端高级CSS用法示例详解》在前端开发中,CSS(层叠样式表)不仅是用来控制网页的外观和布局,更是实现复杂交互和动态效果的关键技术之一,随着前端技术的不断发展,CSS的用法也日益丰富和高级,本文将深... 前端高级css用法在前端开发中,CSS(层叠样式表)不仅是用来控制网页的外观和布局,更是实现复杂交