Vue-Cli项目优化操作的实现_vue.js_脚本之家

来源:http://www.chinese-glasses.com 作者:Web前端 人气:112 发布时间:2020-05-06
摘要:时间: 2019-09-13阅读: 164标签: 性能 起源 在开发 web应用程序时候,性能都是必不可少的话题。而大部分的前端优化机制都已经被集成到前端打包工具webpack 中去了,当然,事实上仍旧会有

时间: 2019-09-13阅读: 164标签: 性能

起源

在开发 web 应用程序时候,性能都是必不可少的话题。而大部分的前端优化机制都已经被集成到前端打包工具 webpack 中去了,当然,事实上仍旧会有一些有趣的机制可以帮助 web 应用进行性能提升,在这里我们来聊一聊能够优化 web 应用程序的一些机制,同时也谈一谈这些机制背后的原理。

由Vue-Cli生成的Vue项目中存在着首屏加载过慢,编译资源过大等问题,主要针对这些问题对项目进行相应的优化,提升项目响应速度,优化项目性能。

Chrome Corverage 分析代码覆盖率

操作

在讲解这些机制前,先来谈一个 Chrome 工具 Corverage。该工具可以帮助查找在当前页面使用或者未使用的 JavaScript 和 CSS 代码。

路由懒加载

工具的打开流程为:

在Vue-router官方文档中有针对懒加载的介绍,主要是将整个大的js进行切片,对当前路由的资源进行一个按需加载。在Vue-cli生成的路由组件引用方法是这样的

打开浏览器控制台 consolectrl+shift+p 打开命令窗口在命令窗口输入 show Coverage 显示选项卡

import HelloWorld from '@/components/HelloWorld'

webpackjs

只需将组件的引用方式改为

其中如果想要查询页面加载时候使用的代码,请点击 reload button如果您想查看与页面交互后使用的代码,请点击record buton

const HelloWorld = () => import ('@/components/HelloWorld')

这里以淘宝网为例子,介绍一下如何使用

开启预加载/优先加载

10bet,上面两张分别为 reload 与 record 点击后的分析。

使用webpack插件PreloadWebpackPlugin 进行预加载prefetch和优先加载preload。 主要做的是用preload加载vendor、manifest与app三个js而用prefetch去加载所有路由对应的文件。 首先要 安装插件

其中从左到右分别为

npm install --save preload-webpack-plugin

所需要的资源 URL资源中包含的 js 与 css总资源大小当前未使用的资源大小

在webpack.prod.conf.js 中修改,加入预加载的代码 (注意放在new HtmlWebpackPlugin

左下角有一份总述。说明在当前页面加载的资源大小以及没有使用的百分比。可以看到淘宝网对于首页代码的未使用率仅仅只有 36%。

new PreloadWebpackPlugin,new PreloadWebpackPlugin({ rel: 'preload', as { if  return 'style' return 'script'; }, include: ['app', 'vendor', 'manifest']})

介绍该功能的目的并不是要求各位重构代码库以便于每个页面仅仅只包含所需的 js 与 css。这个是难以做到的甚至是不可能的。但是这种指标可以提升我们对当前项目的认知以便于性能提升。

开启GZip

提升代码覆盖率的收益是所有性能优化机制中最高的,这意味着可以加载更少的代码,执行更少的代码,消耗更少的资源,缓存更少的资源。

gzip,使用gzip压缩资源可以更快地加载资源。客户端http请求头声明浏览器支持的压缩方式,服务端配置启用压缩,压缩的文件类型,压缩方式。当客户端请求到服务端的时候,服务器解析请求头,如果客户端支持gzip压缩,响应时对请求的资源进行压缩并返回给客户端,浏览器按照自己的方式解析,在http响应头,我们可以看到content-encoding:gzip ,这是指服务端使用了gzip的压缩方式。

webpack externals 获取外部 CDN 资源

启用gzip,在nginx的site-conf中开启gzip

一般来说,我们基本上都会使用 Vue,React 以及相对应的组件库来搭建 SPA 单页面项目。但是在构建时候,把这些框架代码直接打包到项目中,并非是一个十分明智的选择。

server { gzip on; gzip_types text/xml text/css text/plain text/javascript application/javascript application/x-javascript;}

我们可以直接在项目的 index.html 中添加如下代码

webpack处理,需要先安装插件

 script src="//cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.runtime.min.js" crossorigin="anonymous"/script script src="//-router@3.1.3/dist/vue-router.min.js" crossorigin="anonymous"/script
npm install --save-dev compression-webpack-plugin

然后可以在 webpack.config.js 中这样配置

然后在config的index.js中 ,将productionGzip改为true,开启Gzip压缩。

module.exports = { //... externals: { 'vue': 'Vue', 'vue-router': 'VueRouter', }};

PS:如果编译报错,则安装compression-webpack-plugin@1.1.12 版本

webpack externals的作用是 不会在构建时将 Vue 打包到最终项目中去,而是在运行时获取这些外部依赖项。这对于项目初期没有实力搭建自身而又需要使用 CDN 服务的团队有着不错的效果。

对第三方工具库进行额外处理

原理

本项目中Vender中主要是Vue,Vue-router,axios等固定依赖的代码,工具库的代码一般不会改动,所以可以将这些工具库的代码抽出来,单独走CDN加载以减少编译JS文件的大小。 具体操作 : 选择相应的工具库版本的cdn,加入到index.html中

这些项目被打包成为第三方库的时候,同时还会以全局变量的形式导出。从而可以直接在浏览器的 window 对象上得到与使用。即是

之后去到webpack中修改相应的打包配置

window.Vue // ƒ bn(t){this._init(t)}
externals: { 'vue': 'Vue', 'vue-router': 'VueRouter', 'vuex': 'Vuex', 'axios': 'axios'}

这也就是为什么我们直接可以在 html 页面中直接使用

ps:倘若main.js中有关于公共库的引用 请记得清除掉 这时再去编译 打包 就会发现编译的Vender.js小了很多

div  {{ message }}/div// Vue 就是 挂载到 window 上的,所以可以直接在页面使用var app = new Vue({ el: '#app', data: { message: 'Hello Vue!' }})

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

此时我们可以通过webpack Authoring Libraries来了解如何利用 webpack 开发第三方包。

优势与缺陷优势

对于这种既无法进行代码分割又无法进行 Tree Shaking 的依赖库而言,把这些需求的依赖库放置到公用 cdn 中,收益是非常大的。

缺陷

对于类似 Vue React 此类库而言,CDN 服务出现问题意味着完全无法使用项目。需要经常浏览所使用 CDN 服务商的公告(不再提供服务等公告),以及在代码中添加类似的出错弥补方案。

script src="//cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.runtime.min.js" crossorigin="anonymous"/scriptscriptwindow.Vue || ...其他处理 /script

webpack dynamic import 提升代码覆盖率

我们可以利用 webpack 动态导入,可以在需要利用代码时候调用 getComponent。在此之前,需要对 webpack 进行配置。

在配置完成之后,我们就可以写如下代码。

 async function getComponent() { const element = document.createElement('div'); /** webpackChunkName,相同的名称会打包到一个 chunk 中 */ const { default: _ } = await import(/* webpackChunkName: "lodash" */ 'lodash'); element.innerHTML = _.join(['Hello', 'webpack'], ' '); return element; } getComponent().then(component = { document.body.appendChild(component); });

优势与缺陷优势

通过动态导入配置,可以搞定多个 chunk,在需要时候才会加载而后执行。对于该用户不会使用的资源(路由控制,权限控制)不会进行加载,从而直接提升了代码的覆盖率。

缺陷

Tree Shaking,可以理解为死代码消除,即不需要的代码不进行构建与打包。但当我们使用动态导入时候,无法使用 Tree Shaking 优化,因为两者直接按存在着兼容性问题。因为 webpack 无法假设用户如何使用动态导入的情况。

 基础代码X 模块A 模块B-----------------------------------业务代码A 业务代码B 业务代码... 

当在业务中使用多个异步块时后,业务代码A 需求 模块A,业务代码 B 需求 模块B,但是 webpack 无法去假设用户在代码中 A 与 B 这两个模块在同一时间是互斥还是互补。所以必然会假设同时可以加载模块 A 与 B,此时基础代码 X 出现两个导出状态,这个是做不到的!从这方面来说,动态导入和 Tree Shaking 很难兼容。

当然,利用动态导入,也会有一定的性能降低,毕竟一个是本地函数调用,另一个涉及网络请求与编译。但是与其说这是一种缺陷,倒不如说是一种决策。究竟是哪一种对自身的项目帮助更大?

使用 loadjs 来辅助加载第三方 cdn 资源

在普通的业务代码我们可以使用动态导入,在当今的前端项目中,总有一些库是我们必需而又使用率很低的库,比如在只会在统计模块出现的 ECharts 数据图表库,或者只会在文档或者网页编辑时候出现的富文本编辑器库。

对于这些苦库其实我们可以使用页面或组件挂载时候 loadjs 加载。因为使用动态导入这些第三方库没有 Tree shaking 增强,所以其实效果差不多,但是 loadjs 可以去取公用 CDN 资源。具体可以参考github loadjs来进行使用。因为该库较为简单,这里暂时就不进行深入探讨。

使用 output.publicPath 托管代码

因为无论是使用 webpack externals 或者 loadjs 来使用公用 cdn 都是一种折衷方案。如果公司可以花钱购买 oss + cdn 服务的话,就可以直接将打包的资源托管上去。

module.exports = { //... output: { // 每个块的前缀 publicPath: '', chunkFilename: '[id].chunk.js' }};// 此时打包出来的数据前缀会变为script src= 

此时业务服务器仅仅只需要加载 index.html。

利用 prefetch 在空缺时间加载资源

本文由10bet发布于Web前端,转载请注明出处:Vue-Cli项目优化操作的实现_vue.js_脚本之家

关键词:

最火资讯