金九银十,带你复盘大厂常问的项目难点(四)

简介: 金九银十,带你复盘大厂常问的项目难点

如何实现高性能Tree组件


实现Tree组件的核心思路是什么?


Tree组件的核心思路是将原始的嵌套children数据结构平铺成一维数组,然后通过计算每个节点的深度(deep)、层级关系等信息,在渲染时动态计算缩进宽度、连接线等,从而实现树形结构的可视化。


Tree组件如何实现高性能大数据渲染?


  • 将原始树形数据平铺为一维数组,便于后续计算
  • 计算出实际需要渲染的节点数据,过滤隐藏的节点
  • 利用虚拟列表技术只渲染可视区域的数据,实现大数据量的高效渲染
function flattenTreeData(treeData = [], parent = null) {
  const nodes = [];
  treeData.forEach((node) => {
    const newNode = {
      ...node,
      parent,
    };
    nodes.push(newNode);
    if (newNode.children) {
      nodes.push(...flattenTreeData(newNode.children, newNode));
    }
  });
  return nodes;
}

如何计算Tree组件中节点的各种状态(展开/折叠、选中等)?


  • 展开/折叠状态根据ExpandedKeys计算
  • 复选框选中状态需要考虑受控/非受控,严格受控模式,及父子节点关联
  • 需要递归计算父节点和子节点的状态
  • 利用平铺后的索引进行相关节点查询
function flattenTreeData(treeData = [], parent = null) {
  const nodes = [];
  treeData.forEach((node) => {
    const newNode = {
      ...node,
      parent,
    };
    nodes.push(newNode);
    if (newNode.children) {
      nodes.push(...flattenTreeData(newNode.children, newNode));
    }
  });
  return nodes;
}


Tree组件的交互如何实现?点击节点展开折叠,复选框状态切换等


  • 点击展开折叠通过更新节点自身状态、可视状态及ExpandedKeys实现
  • 点击复选框需要递归更新父子节点的状态,及相关keys
  • 计算并保存实时状态,通过回调函数通知外部
function toggleExpanded(nodes, node) {
  return nodes.map((currentNode) => {
    if (currentNode === node) {
      return {
        ...currentNode,
        expanded: !currentNode.expanded,
      };
    }
    return currentNode;
  });
}
// 在渲染时计算缩进:
function renderNode(node) {
  const indentLevel = getIndentLevel(node);
  const style = {
    paddingLeft: `${indentLevel * 16}px`,
  };
  return (
    <div style={style} onClick={() => handleNodeClick(node)}>
      {node.label}
    </div>
  );
}


如何实现高性能表格Table组件?


可参考ali-react-table:高性能 React 表格组件


表格组件的性能瓶颈主要在哪里?


  • 渲染大量 DOM;
  • 频繁的更新渲染,如选中行状态改变引起整个表格重新渲染。


如何优化表格组件的渲染性能?


  1. 只渲染必要的列:
const columnsToRender = columns.filter(column => column.shouldRender);
return (
  <table>
    <thead>
      <tr>
        {columnsToRender.map(column => (
          <th key={column.key}>{column.title}</th>
        ))}
      </tr>
    </thead>
    <tbody>
      {data.map(row => (
        <tr key={row.id}>
          {columnsToRender.map(column => (
            <td key={column.key}>{row[column.key]}</td>
          ))}
        </tr>
      ))}
    </tbody>
  </table>
);
  1. 细粒度更新,只更新变化行/列。在React中,可以使用React.memo或者shouldComponentUpdate来避免不必要的重渲染:
function Row({ data, columns }) {
  return (
    <tr>
      {columns.map(column => (
        <Cell key={column.key} data={data[column.key]} />
      ))}
    </tr>
  );
}
const areEqual = (prevProps, nextProps) => {
  return prevProps.data === nextProps.data && prevProps.columns === nextProps.columns;
};
export default React.memo(Row, areEqual);
  1. 采用虚拟化技术,只渲染可视区的行。可以使用第三方库如react-window或者react-virtualized来实现:
import { FixedSizeList as List } from "react-window";
function Table({ data, columns }) {
  const Row = ({ index, style }) => (
    <div style={style}>
      {columns.map(column => (
        <Cell key={column.key} data={data[index][column.key]} />
      ))}
    </div>
  );
  return (
    <List
      height={500}
      itemCount={data.length}
      itemSize={35}
    >
      {Row}
    </List>
  );
}

使用Web Workers来处理数据处理或计算密集型任务:

// 创建一个新的 worker
const worker = new Worker('worker.js');
// 向 worker 发送数据
worker.postMessage(data);
// 监听 worker 的消息
worker.addEventListener('message', (event) => {
  // 更新表格数据
  updateTable(event.data);
});

worker.js中:

self.addEventListener('message', (event) => {
  // 处理数据
  const processedData = processData(event.data);
  // 发送处理后的数据
  self.postMessage(processedData);
});


基于Web Components封装组件库

这个可以当做拓展了解一下,目前有越来越多的开源组件库往这个方向发展,可以参考这篇文章如何基于 WebComponents 封装 UI 组件库


图解算法小册

image.png

微前端

组件库

axios

nginx

docekr

git

nodejs

HTTP

webpack

react

vue3

vue

TypeScript

JavaScript

Linux

CSS

CSS3

小程序



目录
相关文章
for、foreach、stream 哪家的效率更高,你真的用对了吗?
昨天在《SQL中那么多函数,Java8为什么还要提供重复的Stream方法,多此一举?》一文中,有同学指出Stream在数据量不庞大的情况,效率不如for循环。
|
10月前
|
机器学习/深度学习 自然语言处理 算法
自监督学习:机器学习的未来新方向
自监督学习(Self-Supervised Learning, SSL)是近年来机器学习领域的一个重要发展方向,迅速成为许多研究和应用的热点。与传统的监督学习不同,自监督学习利用未标注数据,通过设计自我生成标签的任务,帮助模型从数据中提取有用的特征。这种方法不仅减少了对大量人工标注数据的依赖,也极大地提高了模型在多种任务上的性能。
|
消息中间件 缓存 Java
面试官:你的项目有哪些难点?
面试官:你的项目有哪些难点?
689 2
|
Python 计算机视觉
2024年Python最新利用python进行数学公式识别_python 识别图片中的数学公式,2024年最新字节跳动技术岗位面试
2024年Python最新利用python进行数学公式识别_python 识别图片中的数学公式,2024年最新字节跳动技术岗位面试
2024年Python最新利用python进行数学公式识别_python 识别图片中的数学公式,2024年最新字节跳动技术岗位面试
|
移动开发 前端开发 JavaScript
金九银十,带你复盘大厂常问的项目难点(一)
金九银十,带你复盘大厂常问的项目难点
515 0
|
机器学习/深度学习 人工智能 自然语言处理
《零基础实践深度学习》1.4.1飞桨产业级深度学习开源开放平台介绍
这篇文章详细介绍了飞桨(PaddlePaddle)这一产业级深度学习开源开放平台,阐述了其在深度学习领域的广泛应用和重要性,以及飞桨平台的核心框架、开发套件、工具组件和预训练模型等,旨在帮助开发者快速实现AI想法并推动产业智能化升级。
|
Linux 数据安全/隐私保护 Python
LInux下 python混淆代码打包产出exe
安装 PyArmor 加密Python程序:使用`pip install pyarmor`。为避免混淆 venv 目录,可指定排除此目录:`.\/venv\/bin\/pyarmor-7 pack -e \"--onefile\" -x \"--exclude venv\" main.py`。查阅详细文档:[官方指南](https://pyarmor.readthedocs.io/zh/v7.x/advanced.html)。
|
关系型数据库 MySQL
mysql 5.5.62版本建表语句报错: Index column size too large. The maximum column size is 767 bytes
mysql 5.5.62版本建表语句报错: Index column size too large. The maximum column size is 767 bytes
698 0
|
数据采集 缓存 前端开发
金九银十,带你复盘大厂常问的项目难点(二)
金九银十,带你复盘大厂常问的项目难点
629 0