文章目录[隐藏]
- 一、代码层面的优化
- 1.2、computed 和 watch 区分使用场景
- 1.3、v-for 遍历一定为 item 添加 key。且避免同一时间使用 v-if
- 不讲解:
- 1.4、长列表性能优化
- 1.5、事件的销毁
- 1.6、图片资源懒加载
- 1.7、路由懒加载
- 1.8、第三方插件的按需引入
- 1.9、优化没有极限列表性能
- 1.10、服务端渲染 SSR or 预渲染
- (2)服务端渲染的缺点:
- 二、Webpack 层面的优化
- 2.1、Webpack 对图片进行压缩
- 2.2、减少 ES6 转为 ES5 的冗余代码
- 2.3、提取公共代码
- 2.4、模板预编译
- 2.5、提取组件的 CSS
- 2.6、优化 SourceMap
- 2.7、构建结果输出分析
- 2.8、Vue 项目的编译优化
- 三、基础的 Web 技术优化
- 3.1、开启 gzip 压缩
- 安装:
- 添加代码逻辑:
- 3.2、浏览器缓存
- 3.3、CDN 的使用
- 3.4、使用 Chrome Performance 查找性能瓶颈
- 总结
Vue 框架通过资料双向绑定和虚拟 DOM 技术。帮我们处理了前端研究中最脏最累的 DOM 操作部分。 我们不再需要去思考怎么样操作 DOM 以及怎么样最高效地操作 DOM;但 Vue 项目中依然存在项目首屏优化、Webpack 编译配置优化等问题。所以我们依然需要去关注 Vue 项目性能方面的优化。使项目有着更高效的性能、更加好的客户体验。
本文是作者通过实际项目的优化实践进行总结而来。希望读者读完本文。有一定的启发思考。从而对自己的项目进行优化起到帮助。本文内容分为以下三部分组成:
Vue 代码层面的优化;
webpack 配置层面的优化;
基础的 Web 技术层面的优化。
一、代码层面的优化
1.1、v-if 和 v-show 区分使用场景
v-if 是 真正 的条件渲染。因为它会保证在更改过程中条件块内的事件监听器和子组件适当地被销毁和重建;也是惰性的:如果在初始渲染时条件为假。则什么也不做——直到条件第一次变为真时。才会开始渲染条件块。v-show 就无脑得多。 不管初始条件是什么。元素总是会被渲染。并且只是无脑地基于 css 的 display 属性进行更改。所以。v-if 适合用来在运行时很少变化条件。不需要频繁更改条件的场景;v-show 则适合用来需要超级频繁更改条件的场景。
1.2、computed 和 watch 区分使用场景
computed: 是计算属性。依赖其它属性值。并且 computed 的值有缓存。只有它依赖的属性值发生变化。下一次获取 computed 的值时才会从头开始计算 computed 的值;watch: 再多的是「研究」的作用。类似于某些资料的监听回调 。每次监听的资料变化时都会执行回调进行后面操作;使用场景:
当我们需要进行数值计算。并且依赖于其它资料时。大概使用 computed。因为应该使用 computed 的缓存特性。避免每次获取值时。都要从头开始计算;
当我们需要在资料变化时执行异步或开销较大的操作时。大概使用 watch。使用 watch 选项允许我们执行异步操作 ( 访问一个 API )。压制我们执行该操作的频率。并在我们获取最终结果前。设置中间状态。这些都是计算属性无法做到的。
1.3、v-for 遍历一定为 item 添加 key。且避免同一时间使用 v-if
(1)v-for 遍历一定为 item 添加 key在列表资料进行遍历渲染时。需要为每一项 item 设置唯一 key 值。方便 Vue.js 内部机制准确寻找该条列表资料。当 state 更新时。新的状态值和旧的状态值对比。较快地定位到 diff 。(2)v-for 遍历避免同一时间使用 v-ifv-for 比 v-if 第一时间级高。如果每一次都需要遍历整个数组。将会波及速度。尤其是当之需要渲染很小一部分的时候。必须状态下大概代替成 computed 属性。讲解
不讲解:
1.4、长列表性能优化
Vue 会通过 Object.defineProperty 对资料进行劫持。来实现视图响应资料的变化。然而一些时候我们的组件只是精粹的资料展示。不会有所有变化。我们就不需要 Vue 来劫持我们的资料。在超级多的资料展示的状态下。这能够很显然的减少组件初始化的时间。那怎么样禁止 Vue 劫持我们的资料呢?应该通过 Object.freeze 方法来冻结一个对象。只要被冻结的对象就再也不应该被改写了。
1.5、事件的销毁
Vue 组件销毁时。会全自动清理它与其它实例的连接。解绑它的全部指令及事件监听器。但是仅限于组件本身的事件。如果在 js 内使用 addEventListene 等方法是不会全自动销毁的。我们需要在组件销毁时手动移除这些事件的监听。以免造成内存泄露。如:
1.6、图片资源懒加载
对于图片过多的页面。为了加速页面加载速度。所以一大半时候我们需要将页面内未出现在可视地区内的图片先不做加载。 等到滚动到可视地区后再去加载。这样对于页面加载性能上会有蛮大的提高。也提高了客户体验。我们在项目中使用 Vue 的 vue-lazyload 插件:(1)安装插件
import VueLazyload from 'vue-lazyload'
(2)在入口文件 man.js 中引入并使用
import VueLazyload from 'vue-lazyload'
之后再 vue 中直接使用
Vue.use(VueLazyload)
或者添加自己定义设置选项
Vue.use(VueLazyload, {preLoad: 1.3,error: 'dist/error.png',loading: 'dist/loading.gif',attempt: 1})
(3)在 vue 文件中将 img 标签的 src 属性直接改为 v-lazy 。从而将图片展现方法更改为懒加载展现:
<img v-lazy=/static/img/1.png>
以上为 vue-lazyload 插件的无脑使用。如果要看插件的再多参数选项。应该查看 vue-lazyload 的 github 地址。
1.7、路由懒加载
Vue 是单页面应用。可能会有很多的路由引入 。这样使用 webpcak 打包后的文件很大。当进入首页时。加载的资源过多。页面会出现白屏的状态。不利于客户体验。如果我们能把不一样路由对应的组件分割成不一样的代码块。之后当路由被访问的时候才加载对应的组件。这样就更加高效了。这样会大大提高首屏展现的速度。但是可能很多的的页面的速度就会降下来。路由懒加载:
const Foo = () => import('./Foo.vue')const router = new VueRouter({routes: [ { path: '/foo', component: Foo } ] })
1.8、第三方插件的按需引入
我们在项目中总是会需要引入第三方插件。如果我们直接引入整个插件。会导致项目的体积太大。我们应该借助 babel-plugin-component 。之后应该只引入需要的组件。以达到减小项目体积的目的。以下为项目中引入 element-ui 组件库为例:(1)首先。安装 babel-plugin-component :
npm install babel-plugin-component -D
(2)之后。将 .babelrc 改写为:
{presets: [[es2015, { modules: false }]],plugins: [ [component, {libraryName: element-ui,styleLibraryName: theme-chalk } ] ]}
(3)在 main.js 中引入部分组件:
import Vue from 'vue';import { Button, Select } from 'element-ui'; Vue.use(Button) Vue.use(Select)
1.9、优化没有极限列表性能
如果你的应用存在超级长或者没有极限滚动的列表。那么需要选用 窗口化 的技术来优化性能。只要渲染少部分地区的内容。减少从头开始渲染组件和创建 dom 节点的时间。你应该参考以下开源项目 vue-virtual-scroll-list 和 vue-virtual-scroller 来优化这种没有极限列表的场景的。
1.10、服务端渲染 SSR or 预渲染
服务端渲染是指 Vue 在软件将标签渲染成的整个 html 片段的事件在服务端完成。服务端形成的 html 片段直接返回给软件这种过程就叫做服务端渲染。(1)服务端渲染的优点:
更加好的 SEO:因为 SPA 页面的内容是通过 Ajax 获取。而搜索网址引擎爬取工具并不会等待 Ajax 异步完成后再抓取页面内容。所以在 SPA 中是抓取不到页面通过 Ajax 获获取的内容;而 SSR 是直接由服务端返回已经渲染好的页面(资料已经包含在页面中)。所以搜索网址引擎爬取工具应该抓取渲染好的页面;
更快的内容到达时间(首屏加载更快):SPA 会等待全部 Vue 编译后的 js 文件都安装完成后。才开始进行页面的渲染。文件安装等需要一定的时间等。所以首屏渲染需要一定的时间;SSR 直接由服务端渲染好页面直接返回展现。不用等待安装 js 文件及再去渲染等。所以 SSR 有更快的内容到达时间;
(2)服务端渲染的缺点:
再多的研究条件压制:例如服务端渲染只支持 beforCreate 和 created 两个钩子函数。这会导致一些外部扩展库需要特别处理。才能在服务端渲染应用应用程序中运行;并且与应该部署在所有静态文件服务器上的完整静态单页面应用应用程序 SPA 不一样。服务端渲染应用应用程序。需要处于 Node.js server 运行环境;
再多的服务器负载:在 Node.js 中渲染完美的应用应用程序。显然会比仅仅提供静态文件的 server 更加超级多的占用cpu 资源。因此如果你预料在高流量环境下使用。请准备相对应的服务器负载。并明智地选用缓存策略。
如果你的项目的 SEO 和 首屏渲染是评价项目的关键指标。那么你的项目就需要服务端渲染来帮助你实现最好的初始加载性能和 SEO。详细的 Vue SSR 怎么样实现。应该参考作者的另一篇文章《Vue SSR 踩坑之路》。如果你的 Vue 项目只需改善较少数营销页面(例如 /。 /about。 /contact 等)的 SEO。那么你可能需要预渲染。在构建时 (build time) 无脑地生成针对特殊路由的静态 HTML 文件。优点是设置预渲染更无脑。并应该将你的前端作为一个完整静态的网址。详细你应该使用 prerender-spa-plugin 就应该轻松地添加预渲染 。
二、Webpack 层面的优化
2.1、Webpack 对图片进行压缩
在 vue 项目中除了应该在 webpack.base.conf.js 中 url-loader 中设置 limit 大小来对图片处理。对小于 limit 的图片转化为 base64 格式。其余的不做操作。所以对一些较大的图片资源。在请求资源的时候。加载会很慢。我们应该用 image-webpack-loader来压缩图片:(1)首先。安装 image-webpack-loader :
npm install image-webpack-loader –save-dev
(2)之后。在 webpack.base.conf.js 中进行配置:
{test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, use:[ { loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('img/[name].[hash:7].[ext]') } }, { loader: 'image-webpack-loader', options: { bypassOnDebug: true, } } ]}
2.2、减少 ES6 转为 ES5 的冗余代码
Babel 插件会在将
ES6
代码转换成 ES5 代码时会注入一些辅助函数。例如下面的 ES6 代码:
class HelloWebpack extends Component{…}
这段代码再被转换成能正常运行的 ES5 代码时需要以下两个辅助函数:
babel-runtime/helpers/createClass // 用来实现 class 语法babel-runtime/helpers/inherits // 用来实现 extends 语法
在默认状态下。 Babel 会在每一个输出文件中内嵌这些依赖的辅助函数代码。如果多个源代码文件都依赖这些辅助函数。那么这些辅助函数的代码将会出现很多次。造成代码冗余。为了不让这些辅助函数的代码重复出现。应该在依赖它们时通过 require('babel-runtime/helpers/createClass') 的方法导入。这样就能做到只让它们出现一次。babel-plugin-transform-runtime 插件只是用来实现这种作用的。将有关辅助函数进行代替成导入语句。从而减小 babel 编译出去的代码的文件大小。(1)首先。安装 babel-plugin-transform-runtime :
npm install babel-plugin-transform-runtime –save-dev
(2)之后。改写 .babelrc 配置文件为:
plugins: [transform-runtime]
如果要看插件的再多仔细内容。应该查看babel-plugin-transform-runtime 的 仔细讲解。
2.3、提取公共代码
如果项目中没有去将每一个页面的第三方库和公共模块提取出去。则项目会存在以下问题:
相同的资源被重复加载。浪费客户的流量和服务器的成本。
每一个页面需要加载的资源太大。导致网页首屏加载慢慢。波及客户体验。
所以我们需要将多个页面的公共代码抽离成单独的文件。来优化以上问题 。Webpack 内置了专门用来提取多个Chunk 中的公共部分的插件 CommonsChunkPlugin。我们在项目中 CommonsChunkPlugin 的配置如下:
// 全部在 package.json 里面依赖的包。都会被打包进 vendor.js 这种文件中。
new webpack.optimize.CommonsChunkPlugin( { name: 'vendor', minChunks: function(module, count) { return (module.resource &&/\.js$/.test(module.resource) &&module.resource.indexOf( path.join(__dirname, '../node_modules')) === 0 ); } }),// 抽取出代码模块的映射关系new webpack.optimize.CommonsChunkPlugin({name: 'manifest',chunks: ['vendor']})
如果要看插件的再多仔细内容。应该查看 CommonsChunkPlugin 的 仔细讲解。
2.4、模板预编译
当使用 DOM 内模板或 javaScript 内的字符串模板时。模板会在运行时被编译为渲染函数。往往一般状态下这种过程已经足够快了。但对性能敏感的应用还是最好避免这种用法。预编译模板最无脑的方法只是使用单文件组件——有关的构建设置会全自动把预编译处理好。所以构建好的代码已经内含了编译出去的渲染函数而不是原始的模板字符串。如果你使用 webpack。并且热爱分离 JavaScript 和模板文件。你应该使用 vue-template-loader。它也应该在构建过程中把模板文件转换变成 JavaScript 渲染函数。
2.5、提取组件的 CSS
当使用单文件组件时。组件内的 CSS 会以 style 标签的方法通过 JavaScript 动态注入。这有一些小小的运行时开销。如果你使用服务端渲染。这会导致一段 “无样式内容闪烁 (fouc) ” 。将全部组件的 CSS 提取到同一个文件应该避免这种问题。也会让 CSS 更好地进行压缩和缓存。查阅这种构建工具各自的文档来了解再多:
webpack + vue-loader ( vue-cli 的 webpack 模板已经预先配置好)
Browserify + vueify
Rollup + rollup-plugin-vue
2.6、优化 SourceMap
我们在项目进行打包后。会将研究中的多个文件代码打包到一个文件中。并且经历过压缩、去掉多余的空格、babel编译化后。最终将编译获取的代码会用来线上环境。那么这样处理后的代码和源代码会有蛮大的差别。当有 bug的时候。我们就只能定位到压缩处理后的代码地点。无法定位到研究环境中的代码。对于研究来说不好调式定位问题。因此 sourceMap 出现了。它只是为了解决不好调式代码问题的。SourceMap 的可选值如下(+ 号越多。代表速度越快。- 号越多。代表速度越慢, o 代表中等速度 )
生产环境讲解:cheap-module-source-map原因如下:
cheap:源代码中的列消息是没有所有作用。因此我们打包后的文件不希望包含列有关消息。只有行消息能建立打包前后的依赖关系。因此不管是研究环境或生产环境。我们都希望添加 cheap 的基础类别来忽略打包前后的列消息;
module :不管是研究环境还是正式环境。我们都希望能定位到bug的源代码详细的地点。例如说某个 Vue 文件报错了。我们希望能定位到详细的 Vue 文件。因此我们也需要 module 配置;
soure-map :source-map 会为每一个打包后的模块生成独立的 soucemap 文件 。因此我们需要增加source-map 属性;
eval-source-map:eval 打包代码的速度超级快。因为它不生成 map 文件。但是应该对 eval 配合使用 eval-source-map 使用会将 map 文件以 DataURL 的形式存在打包后的 js 文件中。在正式环境中不要使用 eval-source-map, 因为它会增加文件的大小。但是在研究环境中。应该试用下。因为他们打包的速度很快。
2.7、构建结果输出分析
Webpack 输出的代码可读性超级差而且文件超级大。让我们超级头疼。为了更无脑、直观地分析输出结果。社区中出现了超级多可视化分析工具。这些工具以图形的方法将结果更直观地展示出去。让我们急速了解问题所在。接下来教学我们在 Vue 项目中用到的分析工具:webpack-bundle-analyzer 。我们在项目中 webpack.prod.conf.js 进行配置:
if (config.build.bundleAnalyzerReport) { var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; webpackConfig.plugins.push(new BundleAnalyzerPlugin());}
执行 $ npm run build –report 后生成分析结果报告如下:
2.8、Vue 项目的编译优化
如果你的 Vue 项目使用 Webpack 编译。需要你喝一杯咖啡的时间。那么也许你需要对项目的 Webpack 配置进行优化。提高 Webpack 的构建效率。详细怎么样进行 Vue 项目的 Webpack 构建优化。应该参考作者的另一篇文章《
Vue 项目
Webpack 优化实践》
三、基础的 Web 技术优化
3.1、开启 gzip 压缩
gzip 是 GNUzip 的缩写。最先用来 UNIX 系统的文件压缩。HTTP 协议上的 gzip 编码是一种用来改进 web 应用应用程序性能的技术。web 服务器和软件(浏览器)一定齐心全力支持 gzip。目前大众的浏览器。Chrome。firefox。IE等都支持该协议。常见的服务器如 Apache。Nginx。IIS 一样支持。gzip 压缩效率超级高。往往一般应该达到 70% 的压缩率。也只是说。如果你的网页有 30K。压缩之后就变成了 9K 差不多以下我们以服务端使用我们熟悉的 express 为例。开启 gzip 超级无脑。有关步骤如下:
安装:
npm install compression –save
添加代码逻辑:
var compression = require('compression');var app = express();app.use(compression())
重启服务。研究网络面板里面的 response header。如果观看到的如下红圈里的字段则表明 gzip 开启成功 :
3.2、浏览器缓存
为了提高客户加载页面的速度。对静态资源进行缓存是超级必须的。根据是否需要从头开始向服务器发起请求来分类。将 HTTP 缓存玩法分为两大类(强力缓存。对比缓存)。如果对缓存机制还不是了解很清楚的。应该参考作者写的关于 HTTP 缓存的文章《深入理解HTTP缓存机制及原理》。这里不再陈诉。
3.3、CDN 的使用
浏览器从服务器上安装
CSS
、js 和图片等文件时都要和服务器连接。而一大半服务器的带宽有限。如果超过压制。网页就半天反应不过来。而 CDN 应该通过不一样的域名来加载文件。从而使安装文件的并发连接数大大的增加。且CDN 有着更加好的可用性。更低的网络延迟和丢包率 。
3.4、使用 Chrome Performance 查找性能瓶颈
Chrome 的 Performance 面板应该录制一段时间内的 js 执行细节及时间。使用 Chrome 研究者工具分析页面性能的步骤如下。
打开 Chrome 研究者工具。更改到 Performance 面板
点一下 Record 开始录制
刷新页面或展开某个节点
点一下 Stop 终止录制
总结
本文通过以下三部分组成:
Vue
代码层面的优化、webpack 配置层面的优化、基础的 Web 技术层面的优化;来讲解怎么去优化 Vue 项目的性能。希望对读完本文的你有帮助、有启发。如果有不足之处。欢迎批评指正交流!作者:我是你的超级英雄https://juejin.im/post/5d548b83f265da03ab42471d
以上就是由优质生活领域创作者 生活常识网 整理编辑的,如果觉得有帮助欢迎收藏转发~
本文地址:http://www.shenzhoubaby.com/14992.html,转载请说明来源于:生活常识网
声明:本站部分文章来自网络,如无特殊说明或标注,均为本站原创发布。如若本站内容侵犯了原著者的合法权益,可联系@qq.com进行处理。分享目的仅供大家学习与参考,不代表本站立场。