性能优化

提炼函数:避免出现超大函数,独立出来的函数更容易被复写且有利于代码复用

juejin.im/post/5b73ef…

原则:多使用内存,缓存等其他方法、减少CPU计算量,减少网络加载耗时即用空间换时间的一个概念

让加载、渲染更快

加载:

  • 减少资源体积:压缩代码
  • 控制并发请求:减少访问次数:合并代码,SSR服务端渲染
  • 使用更快的网络:CDN

渲染:

  • 文件放置位置:css放head中,js放body下
  • 懒加载:组件/路由的懒加载
  • 缓存:对DOM查询进行缓存、频繁DOM操作,合并到一起插入DOM结构
  • 节流和防抖

缓存策略:expires、Cache-Control、

Last-Modified/If-Modified-Since:本地缓存没有过期

Etag/f-None-Match:缓存过期了

webpack中使用contenthash:静态资源加hash后缀,根据文件内容计算hash,文件内容不变则hash、url不变、url和文件不变则会自动触发http缓存机制,返回304

Vue 代码层面的优化

合理使用v-if,v-show

合理使用computed

v-for中加key,避免与v-if同时使用

合理使用异步组件

合理使用缓存组件keep-alive

data层级不要太深:导致响应式在做监听时计算的深度比较多,定位的次数比较多,会导致页面卡顿

使用vue-loader在开发环境做模板编译?

长列表性能优化:Vue 会通过 Object.defineProperty 对数据进行劫持,来实现视图响应数据的变化,然而有些时候我们的组件就是纯粹的数据展示,不会有任何改变,我们就不需要 Vue 来劫持我们的数据,在大量数据展示的情况下,这能够很明显的减少组件初始化的时间,通过使用Object.freeze

export default { data: () => ({ users: {} }), async created() { const users = await axios.get("/api/users"); this.users = Object.freeze(users); }};
复制代码

自定义事件,DOM事件及时销毁:Vue 组件销毁时,会自动清理它与其它实例的连接,解绑它的全部指令及事件监听器,但是仅限于组件本身的事件。如果在 js 内使用 addEventListene 等方式是不会自动销毁的,我们需要在组件销毁时手动移除这些事件的监听,以免造成内存泄露

created() { addEventListener('click', this.click, false)},beforeDestroy() { removeEventListener('click', this.click, false)}
复制代码

使用路由懒加载:把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应的组件,这样就更加高效了。这样会大大提高首屏显示的速度,但是可能其他的页面的速度就会降下来

webpack 配置层面的优化

减少 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 编译出来的代码的文件大小,安装该插件后修改 .babelrc 配置文件为

“plugins”: [“transform-runtime”]

提取公共代码

如果项目中没有去将每个页面的第三方库和公共模块提取出来,则项目会存在以下问题:

  • 相同的资源被重复加载,浪费用户的流量和服务器的成本。
  • 每个页面需要加载的资源太大,导致网页首屏加载缓慢,影响用户体验

所以需要把公共的代码抽离成单独的文件,来优化以上问题,Webpack 内置了专门用于提取多个Chunk 中的公共部分的插件 CommonsChunkPlugin,项目中 CommonsChunkPlugin 的配置如下

image.png

优化 SourceMap

在项目进行打包后,会将开发中的多个文件代码打包到一个文件中,并且经过压缩、去掉多余的空格、babel编译化后,最终将编译得到的代码会用于线上环境,那么这样处理后的代码和源代码会有很大的差别,当有 bug的时候,我们只能定位到压缩处理后的代码位置,无法定位到开发环境中的代码,对于开发来说不好调式定位问题,因此 sourceMap 出现了,它就是为了解决不好调式代码问题的

  • 开发环境推荐:cheap-module-eval-source-map
  • 生产环境推荐: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, 因为它会增加文件的大小,但是在开发环境中,可以试用下,因为他们打包的速度很快

构建结果输出分析

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 后生成分析报告如下

image.png

开启 gzip 压缩

compression-webpack-plugin、在webpack.prod.conf.js中的配置

image.png
配置完后执行build命令,会发现生成的静态文件里面新增了后缀为gz的文件

如果此时将项目部署到已开启了gzip的服务器如nginx里面之后,访问浏览器即可看到浏览器下载的是已压缩的文件

image.png
服务器配置gzip,只是为了可以兼容这种格式,可以读取这种格式,压缩为gzip还是需要前端做的2:服务器把gzip发送给浏览器,浏览器认识这种格式所以能解读他3:用处就是用户获取的文件体积减小了,下载的快了

基础的 Web 技术层面的优化

浏览器缓存

为了提高用户加载页面的速度,对静态资源进行缓存是非常必要的,根据是否需要重新向服务器发起请求来分类,将 HTTP 缓存规则分为两大类(强制缓存,对比缓存)

CDN的使用

浏览器从服务器上下载 CSS、js 和图片等文件时都要和服务器连接,而大部分服务器的带宽有限,如果超过限制,网页就半天反应不过来。而 CDN 可以通过不同的域名来加载文件,从而使下载文件的并发连接数大大增加,且CDN 具有更好的可用性,更低的网络延迟和丢包率

使用 Chrome Performance 查找性能瓶颈

Chrome 的 Performance 面板可以录制一段时间内的 js 执行细节及时间。使用 Chrome 开发者工具分析页面性能的步骤如下。

  1. 打开 Chrome 开发者工具,切换到 Performance 面板
  2. 点击 Record 开始录制
  3. 刷新页面或展开某个节点
  4. 点击 Stop 停止录制

image.png

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享