You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by bb...@apache.org on 2022/03/10 18:23:44 UTC
[airflow] 01/01: Reduce rerendering of TaskName component
This is an automated email from the ASF dual-hosted git repository.
bbovenzi pushed a commit to branch memoize-task-name
in repository https://gitbox.apache.org/repos/asf/airflow.git
commit c55280f04eace2e02523b31cd2760a6bc5e7e4eb
Author: Brent Bovenzi <br...@gmail.com>
AuthorDate: Thu Mar 10 13:22:31 2022 -0500
Reduce rerendering of TaskName component
---
airflow/www/static/js/tree/TaskName.jsx | 64 +++++++++++++++++++++++++++
airflow/www/static/js/tree/renderTaskRows.jsx | 46 ++++---------------
2 files changed, 73 insertions(+), 37 deletions(-)
diff --git a/airflow/www/static/js/tree/TaskName.jsx b/airflow/www/static/js/tree/TaskName.jsx
new file mode 100644
index 0000000..a80f4d5
--- /dev/null
+++ b/airflow/www/static/js/tree/TaskName.jsx
@@ -0,0 +1,64 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import React from 'react';
+import {
+ Box,
+ Text,
+ Flex,
+} from '@chakra-ui/react';
+import { FiChevronUp, FiChevronDown } from 'react-icons/fi';
+
+const TaskName = ({
+ isGroup = false, isMapped = false, onToggle, isOpen, level, taskName,
+}) => (
+ <Box _groupHover={{ backgroundColor: 'rgba(113, 128, 150, 0.1)' }} transition="background-color 0.2s">
+ <Flex
+ as={isGroup ? 'button' : 'div'}
+ onClick={onToggle}
+ color={level > 4 && 'white'}
+ aria-label={taskName}
+ title={taskName}
+ mr={4}
+ width="100%"
+ backgroundColor={`rgba(203, 213, 224, ${0.25 * level})`}
+ alignItems="center"
+ >
+ <Text
+ display="inline"
+ fontSize="12px"
+ ml={level * 4 + 4}
+ isTruncated
+ >
+ {taskName}
+ {isMapped && (
+ ' [ ]'
+ )}
+ </Text>
+ {isGroup && (
+ isOpen ? <FiChevronDown data-testid="open-group" /> : <FiChevronUp data-testid="closed-group" />
+ )}
+ </Flex>
+ </Box>
+);
+
+// Only rerender the component if props change
+const MemoizedTaskName = React.memo(TaskName);
+
+export default MemoizedTaskName;
diff --git a/airflow/www/static/js/tree/renderTaskRows.jsx b/airflow/www/static/js/tree/renderTaskRows.jsx
index 170c6c4..89e0a53 100644
--- a/airflow/www/static/js/tree/renderTaskRows.jsx
+++ b/airflow/www/static/js/tree/renderTaskRows.jsx
@@ -19,19 +19,18 @@
/* global localStorage */
-import React from 'react';
+import React, { useCallback } from 'react';
import {
Tr,
Td,
Box,
- Text,
Flex,
useDisclosure,
Collapse,
} from '@chakra-ui/react';
-import { FiChevronUp, FiChevronDown } from 'react-icons/fi';
import StatusBox from './StatusBox';
+import TaskName from './TaskName';
import { getMetaValue } from '../utils';
@@ -52,39 +51,6 @@ const renderTaskRows = ({
/>
));
-const TaskName = ({
- isGroup = false, isMapped = false, onToggle, isOpen, level, taskName,
-}) => (
- <Box _groupHover={{ backgroundColor: 'rgba(113, 128, 150, 0.1)' }} transition="background-color 0.2s">
- <Flex
- as={isGroup ? 'button' : 'div'}
- onClick={() => isGroup && onToggle()}
- color={level > 4 && 'white'}
- aria-label={taskName}
- title={taskName}
- mr={4}
- width="100%"
- backgroundColor={`rgba(203, 213, 224, ${0.25 * level})`}
- alignItems="center"
- >
- <Text
- display="inline"
- fontSize="12px"
- ml={level * 4 + 4}
- isTruncated
- >
- {taskName}
- {isMapped && (
- ' [ ]'
- )}
- </Text>
- {isGroup && (
- isOpen ? <FiChevronDown data-testid="open-group" /> : <FiChevronUp data-testid="closed-group" />
- )}
- </Flex>
- </Box>
-);
-
const TaskInstances = ({ task, containerRef, dagRunIds }) => (
<Flex justifyContent="flex-end">
{dagRunIds.map((runId) => {
@@ -124,6 +90,12 @@ const Row = (props) => {
};
const { isOpen, onToggle } = useDisclosure({ defaultIsOpen: isGroupId, onClose, onOpen });
+ // assure the function is the same across renders
+ const memoizedToggle = useCallback(
+ () => isGroup && onToggle(),
+ [onToggle, isGroup],
+ );
+
const parentTasks = task.id.split('.');
parentTasks.splice(-1);
@@ -150,7 +122,7 @@ const Row = (props) => {
>
<Collapse in={isFullyOpen}>
<TaskName
- onToggle={onToggle}
+ onToggle={memoizedToggle}
isGroup={isGroup}
isMapped={task.isMapped}
taskName={taskName}