现在项目架构是啥

  • 技术栈
  • 脚手架
  • 开发规范
  • css样式 less
  • 响应式布局 pxToRem
  • 组件库 mand-mobile
  • 异步请求封装,拦截器统一处理请求和响应
  • 路由 hash模式
  • 开发和设计文档

目前架构的优势有哪些

  • 多页面应用,设计器端和渲染端独立分开,应用分离,各自读各自的静态资源

  • 路由页面按需加载,虽然渲染端是单页面应用

  • 本地开发项目的时候通过env环境参数配置

  • 响应式布局,根据屏幕的宽度定义跟字体,同时利用postcss中的pxToRem,实现响应式布局

  • 移动端采用的第三方ui组件 按需引入,体积较小

  • 跨域通过node服务转发,还有一种是在域名不一致的情况下打开H5页面,需要设置document.domain=’.xx.com’

架构有哪些缺陷

  • 设计器端和渲染端SFC/js方法不要互相引用,如果有公共函数,抽离出来

  • 对于常用的类型声明,定义声明全局类型声明,不要在每个文件使用的时候显式导入

  • class类里继承的属性太多,层层继承

  • 静态资源没有压缩(图片和字体)

  • 数据流管理混乱

    • 渲染端的很多数据没有放到vuex集中管理
    • action中随便更改state中的数据,导致数据来源不清晰
    • postMessage事件名容易冲突,渲染端和设计器端通信通过postMessage来解决,定义事件名称的时候没有集中统一管理,会导致后面的通信名称跟之前的冲突
      1
      2
      3
      4
      topPostMessage({
      name: 'changeZIndex',
      zIndex:99
      })
  • 业务层面: 最重要的查询逻辑没有抽离,放到了每个图表组件本身。这样查询接口每次有改动,12个图表组件都得跟着改,维护性太差

  • ts没有发会类型编程的优势,反而成为一种累赘。这个需要自我检讨,后面再码代码的时候,还是会去定义和约束数据解构和类型

  • 滥用this去读取data中数据,会多次重复地收集依赖,从而产生性能问题
    Vue中避免滥用this去读取data中数据

怎么补充完善

  • 减少两端的互相引用

  • 项目根目录下创建typings目录,在目录下创建index.d.ts,定义全局声明

    1
    interface baseMode = 'same' | 'base

    修改tsconfig.json,添加如下行

    1
    2
    3
    4
    5
    {
    "compilerOptions": {
    "typeRoots": ["./node_modules/@types/", "./typings"],
    }
    }
  • 关于class继承层级太深的问题

  • 优化图片 使用image-webpack-loader优化图片

  • 字体文件可以使用CompressionWebpackPlugin进行压缩

项目是如何优化性能的

前端工程化方面

  • 项目配置 externals 常用的库采用本地资源引入 减少构建包体积

  • 路由页面配置按需加载

  • 第三方Ui组件按需引入,比如手机端的ui库mand-mobile,import Toast from 'mand-mobile/lib/toast'

    1
    2
    3
    4
    5
    6
    7
    8
    {
    "plugins": [
    ["import", {
    "libraryName": "mand-mobile",
    "libraryDirectory": "lib"
    }]
    ]
    }

vue方面

  • V-if和v-for禁止一起使用
  • sscoped css 当前vue组件的css只作用于当前组件的元素
  • 组件keep alive,包裹动态组件,缓存组件实例,主要是用于保留组件状态或避免重新渲染
  • v-once只会渲染一次的组件
  • 离开组件时,移除绑定事件,手动销毁事件监听器,以免造成内存泄漏
    1
    2
    3
    private beforeDestroy() {
    window.removeEventListener('message', this.dataSetting)
    }
  • 组件渲染列表的时候,key绑定唯一的值

js编程方面

  • 合理使用合成层,如使用transform: translateZ(0)开启硬件加速

  • axios封装 ajax请求都集中到了api目录下,所有的请求放在一个文件夹集中管理

  • 返回顶部的时候,采用了请求动画帧来处理

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    public scrollToTop() {
    const dom = this.domRef
    let timer = null
    if (dom) {
    cancelAnimationFrame(timer);
    timer = requestAnimationFrame(
    function fn() {
    const oTop = dom.scrollTop
    if (oTop > 0) {
    dom.scrollTop = oTop - 100; // 距离顶部的距离
    timer = requestAnimationFrame(fn)
    } else {
    cancelAnimationFrame(timer)
    }
    }
    )
    }
    }