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

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

如何实现高性能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

小程序



目录
相关文章
|
3月前
|
消息中间件 缓存 Java
面试官:你的项目有哪些难点?
面试官:你的项目有哪些难点?
261 2
|
Java 调度
【Java面试八股文宝典之基础篇】备战2023 查缺补漏 你越早准备 越早成功!!!——Day13。
【Java面试八股文宝典之基础篇】备战2023 查缺补漏 你越早准备 越早成功!!!——Day13。
82 0
|
Cloud Native 算法 程序员
面试流程解析:从初面到终面,程序员需要注意什么
面试流程解析:从初面到终面,程序员需要注意什么
154 0
|
数据采集 缓存 前端开发
金九银十,带你复盘大厂常问的项目难点(二)
金九银十,带你复盘大厂常问的项目难点
331 0
|
移动开发 前端开发 JavaScript
金九银十,带你复盘大厂常问的项目难点(一)
金九银十,带你复盘大厂常问的项目难点
267 0
|
存储 缓存 前端开发
金九银十,带你复盘大厂常问的项目难点(三)
金九银十,带你复盘大厂常问的项目难点
103 0
|
设计模式 算法 Java
内卷严重~面试八股文层出不穷!唯2023版Java复盘手册有复盘之路
最近有不少小伙伴表示内卷实在是太严重了,不少程序员都有辞退失业或跳槽的想法,今天给大家分享的这份手册可以快速帮大家找到正确思路,无论你是失业还是跳槽都推荐你看一看,这份手册涵盖了市面上90%的Java面试内容,十分全面! 不到最后一刻千万不要放弃,也不要灰心,哪怕到十一月还没有拿到offer也没关系,殊不知等到年底补录的时候也是一个非常容易进大厂拿offer的机会。
|
Java 索引
【Java面试八股文宝典之基础篇】备战2023 查缺补漏 你越早准备 越早成功!!!——Day14
【Java面试八股文宝典之基础篇】备战2023 查缺补漏 你越早准备 越早成功!!!——Day14
137 0
|
缓存 Oracle NoSQL
【面试1v1实景模拟】Spring事务经典面试场景,全方位解读面试官心理,助你面试入坑~
【面试1v1实景模拟】Spring事务经典面试场景,全方位解读面试官心理,助你面试入坑~
160 0
|
SQL 搜索推荐 Java
【Java面试八股文宝典之基础篇】备战2023 查缺补漏 你越早准备 越早成功!!!——Day08
【Java面试八股文宝典之基础篇】备战2023 查缺补漏 你越早准备 越早成功!!!——Day08
137 0
【Java面试八股文宝典之基础篇】备战2023 查缺补漏 你越早准备 越早成功!!!——Day08