一、资源制作性能优化


1、性能优化

1.1、富文本框的事件监听问题

  滚动页面时,😄发现页面卡顿,通过浏览器开发者工具的performance分析,发现鼠标在页面滑动的时候在不断的执行一个方法,找到对应的代码位置后发现这里写了一个mousemove。这种事件的触发频率非常之高,会导致使用不流畅,卡帧的现象。

解决办法:

  • 防抖节流,可以设置500ms执行一次
  • 使用webAPI,IntersectionObserverAPI,元素与视口交叉执行
  • 直接将mousemove替换成mouseenter,鼠标进入时触发
<template>
  <div  @mousemove.stop="changeToEdit">
    //....
  </div>
</template>

public changeToEdit (e) {
  if (!this.isEdit) {
    this.isEdit = true;
    this.setAudio();
    if (this.type === 'richText') {
      this.$nextTick(() => {
        this.createEditorFun();
      });
    } else if (this.type === 'textarea' || this.type === 'text') {
      this.$nextTick(() => {
        this.createTextareaEditorFun();
      });
    }
  }
}

1.2、js执行时间过长导致的页面书写卡顿问题(已完成)

  我们在使用的时候有着很明显的卡顿和卡帧问题,通过浏览器开发者工具的performance分析,发现我们在输入内容时在不断的执行一个函数watchMenuInfo,并且这个js函数执行周期比较长,那么一定是会影响页面渲染的。定位到代码位置分析,代码的逻辑是我们右边展示的数据都是存在左边侧边栏的,当我们输入内容或者做其他事情的时候,需要同步更新侧边栏。

如下截取的一部分代码

@Watch('menuInfo', {
  deep: true,
  immediate: true
})
public watchMenuInfo (newValue, oldValue) {
  this.menuList = deepClone(newValue);
  this.total = this.menuList.length;
}

@Watch('menuList', {
  deep: true,
  immediate: true
})
public menuListChane (newValue, oldValue) {
  if (JSON.stringify(newValue) === JSON.stringify(oldValue)) return
  this.showList = this.setCurrentShowList()
}

代码中存在的两个问题

  • 不必要的监听:vue组件之间传值,对与引用类型的数据是双向的,我们在更改右侧内容的时候侧边的数据是直接同步的,不需要做额外的监听操作。
  • 大数据的深拷贝:侧边栏的数据一般是很大的,大体积的数据做深拷贝是很耗时的,这里实际上是不需要做深拷贝的,直接用即可

解决以上两个问题,性能会有很大提升。

但是以前这样的写法可能是出于一些其它考虑,所以在做更改的时候,需要小心谨慎,避免引出其它问题。

1.3、完成后的效果对比

优化前后的对比

图表:

优化前

优化前:由图可以看出,当素材数量在5以下时,看不出明显的时间变化,此时平台性能基本稳定。但是随着素材数量的增加,耗时情况越严重,平台的素材上限是15,此时首次进入到渲染完成需要接近20秒。

优化后

优化后:由图可以看出,随着素材数量的增加,时间上的损耗无明显变化,平台性能基本稳定,始终维持在5秒左右,无论是首次进入的渲染还是切换素材以及输入内容,都比较平稳流畅。

前后对比

优化前后对比:由上图可以看出,随着素材数量的增加,优化效果会显著提升。当数量控制在5以下时,效果整体差别不大,但是数量为10、15的时候,优化前会变得异常卡顿,严重影响制作流程。优化后会有一个明显的性能提升的效果。

优化前(gif见附件):

优化后(gif见附件):

1.4、同步课文设计存在的缺陷(未开始)

  • 请求当前页的所有课文
public async getResouceQuestionList (reset = false) {
  const postData = {...}
  const res = await getWordList(postData);
  if (res) {
    this.getBatchStInfo(list, 'mounted');
  }
}

  • 便利请求过来的数据,按顺序执行编译过程getBatchStInfo –>getTemplateData–>parseContent,说白了就是准备好所有的右侧需要展示的数据,这一步是一个极其耗时的过程,有着很长的数据处理流程,带来的体验就是首次进入课文包,首次加载很慢,同时涉及到请求侧边栏数据的操作都会耗时卡顿,比如切换页码,批量标签,批量标注后返回的主页面都会卡顿。

解决办法:不需要一次性处理侧边栏所有的数据,而是只处理第一条数据,后续切换素材的时候切换的哪个素材就做哪个素材的数据处理,可以大大优化卡顿问题。

public getBatchStInfo (data, type?, reset?) {
  data.forEach((item, index) => {
    if (template) {
      getTemplateData(template, this.$route.query.identifier as string, (returnObj) => {
        this.setTempObj(tempObj, !reset ? length + index : index, type);
      })
    }
  })
}


public setTempObj (newVlaue: any, index?, type?) {
  const parseTempObj = parseContent(newVlaue, newVlaue.isMultPaper);
}

1.5、依赖分析(未开始)

npm包:depCheck

depcheck 是一款用于检测项目中未使用依赖项的工具,特别适用于前端和Node.js项目。它的主要目的是帮助开发者识别并移除那些在项目中未被实际引用的依赖,从而优化项目结构,减少不必要的依赖,提高项目的运行效率和安全性。

npm install -g depcheck
// 根目录
depcheck

执行后,depcheck会输出三个主要部分的结果:

未使用的依赖:列出项目中未使用的依赖项。

缺失的依赖:列出项目中实际使用但未在package.json中声明的依赖项。

无用的文件:列出项目中未使用的文件。

这个不可以完全相信,但是可以作为分析依赖的依据,基本可以排查荣誉的依赖,这些依赖的存在占用体积,去除这些无用的包,或者利用率比较小的包可以加快打包速度,减小打包体积,以获得更好的体验。

1.6、打包优化(未开始)

插件:webpack-bundle-analyzer

webpack-bundle-analyzer 是一个用于分析和可视化Webpack打包结果的工具。它能够生成一个交互式的可缩放树状图,展示每个模块在打包文件中的大小,帮助开发者识别和优化不必要的依赖和代码,从而减小最终打包文件的体积。

npm install --save-dev webpack-bundle-analyzer

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

config.plugins = [
  new BundleAnalyzerPlugin()
]

资源平台项目打包后的视图如下

从这里可以看出平台的打包分的还是比较细致的,而且第三方库和业务代码是分开的,这样的好处就是第三方代码可以完全利用http缓存,不需要多次请求资源,只需要请求变更后的业务代码即可。

在第三方模块里发现了很多可以改进的地方,比如第三方库中的monaco-editor占用了很大的体积,我们查看后发现这个包并没有被使用,这个是可以删除的,此外向jquery这种落后的第三方完全可以删掉,不再使用。除此之外像其它第三方库比如e-charts,element-ui可以用按需导入,减小体积。

在业务模块里,发现很多没有用上的大体积的文件,比如stJson.ts引入了根本用不上。这张是完全可以删除的,以此类推可以排查出很多大体积打包文件,提升构建速度和用户体验。


文章作者: 吴俊杰
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 吴俊杰 !
  目录