执笔看墨花开💜千千 执笔看墨花开💜千千
首页
  • JavaScript
  • Vue
  • React
  • HTML
  • CSS
  • 算法
  • 工具教程
  • 面试题清单
  • 大前端
  • HTML
  • CSS
  • JS
  • Vue
  • React
  • 零碎
  • 杂言碎语
  • 前端
  • 工具
  • 设计 & CSS
  • 社区 & 平台 & 博客
  • 网站
  • 推荐库
  • 值得一读
  • 分类
  • 标签
  • 归档
  • 心情杂货
  • 友情链接
  • 关于
GitHub (opens new window)

执笔看墨花开

顺其自然
首页
  • JavaScript
  • Vue
  • React
  • HTML
  • CSS
  • 算法
  • 工具教程
  • 面试题清单
  • 大前端
  • HTML
  • CSS
  • JS
  • Vue
  • React
  • 零碎
  • 杂言碎语
  • 前端
  • 工具
  • 设计 & CSS
  • 社区 & 平台 & 博客
  • 网站
  • 推荐库
  • 值得一读
  • 分类
  • 标签
  • 归档
  • 心情杂货
  • 友情链接
  • 关于
GitHub (opens new window)
  • JS文章

  • Vue文章

  • 跨端开发

  • React文章

  • 杂文

    • Webstorm排查插件问题
    • 为什么前端监控要用GIF打点
    • Bilibili短链生成器
    • Typora Bilibili图床插件
    • 防盗链那些事之referer
    • 获取B站SESSDATA
    • serverless+webpack解决node_modules空间大的问题
    • SPA单页应用直接使用百度统计
    • 先concat再去重引发的性能问题
    • 利用引用与时间戳解决一次性能问题
      • 批量新建工作项界面卡顿
      • 大用户数量加载慢分析
    • CSS

    • 前端
    • 杂文
    执笔看墨花开
    2021-08-03

    利用引用与时间戳解决一次性能问题

    # 利用引用与时间戳解决一次性能问题

    由于是项目管理系统,用户在很多地方都需要根据redux中拿到的工作项属性进行一些逻辑处理,所以需要经常通过uuid查询相应的field对象。再一次批量选择的场景中,发现页面非常卡。

    # 问题代码

    const maxMemoizeLength = 3;
    export const fieldGetterSelector = memoize(state => memoize((fieldUUID) => {
      const field = Object.assign({}, get(state.entities, [DataKeys.FIELD_ENTITY, fieldUUID]));
      if (field.options) {
        field.options = field.options.map((optionUUID) => {
          return get(state.entities, [DataKeys.FIELD_OPTION_ENTITY, optionUUID]);
        });
      }
      if (field.projects) {
        field.projects = field.projects.map((projectUUID) => {
          return get(state.entities, [DataKeys.PROJECT_NAME_ENTITY, projectUUID]);
        });
      }
      if (field && FieldTypeEnum.isValidType(field.type)) {
        return field;
      }
      return null;
    }, {
      max: maxMemoizeLength,
      normalizer: (args) => {
        // args is arguments object as accessible in memoized function
        const fieldUUID = args[0];
        const field = get(state.entities, [DataKeys.FIELD_ENTITY, fieldUUID]);
        return JSON.stringify(field);
      },
    }), {
      max: maxMemoizeLength,
      normalizer: (args) => {
        // args is arguments object as accessible in memoized function
        const checkState = args[0];
        return JSON.stringify(get(checkState.entities, [DataKeys.FIELD_ENTITY]));
      },
    });
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34

    问题就出现JSON.stringify。

    # 解决办法

    由于之前对fieldGetterSelector使用memoize缓存,需要使用normalizer和JSON.stringify进行参数的对比, 但是其中的两个对象都是一个非常庞大的对象,导致性能更差了,于是采取以下这个函数进行时间戳记录和引用比较, 来记录两个对象是否有改变

    const maxMemoizeLength = 3;
    let prevState = null;
    let memoryStamp = null;
    const getMemoryStamp = (checkState) => {
      if (prevState == null) {
        prevState = checkState;
        memoryStamp = new Date().getTime();
        return memoryStamp;
      }
      
      const fieldEntity = get(checkState.entities, [DataKeys.FIELD_ENTITY]);
      const prefFieldEntity = get(prevState.entities, [DataKeys.FIELD_ENTITY]);
      if (fieldEntity !== prefFieldEntity) {
        prevState = checkState;
        memoryStamp = new Date().getTime();
        return memoryStamp;
      }
      
      const fieldOptionEntity = get(checkState.entities, [DataKeys.FIELD_OPTION_ENTITY]);
      const prefFieldOptionEntity = get(prevState.entities, [DataKeys.FIELD_OPTION_ENTITY]);
      if (fieldOptionEntity !== prefFieldOptionEntity) {
        prevState = checkState;
        memoryStamp = new Date().getTime();
        return memoryStamp;
      }
      return memoryStamp;
    };
    export const fieldGetterSelector = memoize(state => memoize((fieldUUID) => {
      const field = Object.assign({}, get(state.entities, [DataKeys.FIELD_ENTITY, fieldUUID]));
      if (field.options) {
        field.options = field.options.map((optionUUID) => {
          return get(state.entities, [DataKeys.FIELD_OPTION_ENTITY, optionUUID]);
        });
      }
      if (field.projects) {
        field.projects = field.projects.map((projectUUID) => {
          return get(state.entities, [DataKeys.PROJECT_NAME_ENTITY, projectUUID]);
        });
      }
      if (field && FieldTypeEnum.isValidType(field.type)) {
        return field;
      }
      return null;
    }, {
      max: maxMemoizeLength,
      normalizer: (args) => {
        // args is arguments object as accessible in memoized function
        const fieldUUID = args[0];
        const field = get(state.entities, [DataKeys.FIELD_ENTITY, fieldUUID]);
        return JSON.stringify(field);
      },
    }), {
      max: maxMemoizeLength,
      normalizer: (args) => {
        // args is arguments object as accessible in memoized function
        const checkState = args[0];
        return getMemoryStamp(checkState);
      },
    });
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    编辑 (opens new window)
    #性能优化
    上次更新: 2021/08/09, 21:37:36
    先concat再去重引发的性能问题
    批量新建工作项界面卡顿

    ← 先concat再去重引发的性能问题 批量新建工作项界面卡顿→

    最近更新
    01
    Vue2
    08-26
    02
    JS编程题
    08-26
    03
    前言
    08-26
    更多文章>
    Theme by Vdoing

    © 2021-2021 执笔看墨花开

    粤ICP备2021110554号
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式
    ×