From 29048908df7cb4be642880f9fedba8766dbefa17 Mon Sep 17 00:00:00 2001 From: Haishan Date: Sun, 13 Jan 2019 23:37:22 +0800 Subject: perf(logs): optimize with windowed scrolling --- src/components/Logs.js | 68 ++++++++++++++++++++++++++--------------- src/components/Logs.module.scss | 11 +++---- 2 files changed, 47 insertions(+), 32 deletions(-) (limited to 'src/components') diff --git a/src/components/Logs.js b/src/components/Logs.js index ad551ee..43f64a9 100644 --- a/src/components/Logs.js +++ b/src/components/Logs.js @@ -1,11 +1,13 @@ -import React, { useState, useEffect } from 'react'; +import React, { memo, useState, useEffect } from 'react'; import PropTypes from 'prop-types'; import cx from 'classnames'; import { useStoreState, useActions } from 'm/store'; import { getClashAPIConfig } from 'd/app'; import Icon from 'c/Icon'; +import { FixedSizeList as List, areEqual } from 'react-window'; import ContentHeader from 'c/ContentHeader'; +import useRemainingViewPortHeight from '../hooks/useRemainingViewPortHeight'; // TODO move this into a redux action import { fetchLogs } from '../api/logs'; import { getLogsForDisplay, appendLog } from 'd/logs'; @@ -13,6 +15,7 @@ import { getLogsForDisplay, appendLog } from 'd/logs'; import yacd from 's/yacd.svg'; import s0 from 'c/Logs.module.scss'; +const paddingBottom = 30; const colors = { debug: 'none', // debug: '#8a8a8a', @@ -23,9 +26,9 @@ const colors = { }; function LogLine({ time, even, payload, type }) { - const className = cx({ even }); + const className = cx({ even }, s0.log); return ( -
  • +
    {time}
    @@ -33,16 +36,23 @@ function LogLine({ time, even, payload, type }) {
    {payload}
    -
  • + ); } -LogLine.propTypes = { - time: PropTypes.string, - even: PropTypes.bool, - type: PropTypes.string.isRequired, - payload: PropTypes.string.isRequired -}; +function itemKey(index, data) { + const item = data[index]; + return item.id; +} + +const Row = memo(({ index, style, data }) => { + const r = data[index]; + return ( +
    + +
    + ); +}, areEqual); const actions = { appendLog }; @@ -57,26 +67,34 @@ export default function Logs() { }, [hostname, port, secret] ); + const [refLogsContainer, containerHeight] = useRemainingViewPortHeight(); return (
    - {logs.length === 0 ? ( -
    -
    - +
    + {logs.length === 0 ? ( +
    +
    + +
    +
    No logs yet, hang tight...
    -
    No logs yet, hang tight...
    -
    - ) : ( -
    -
      - {logs.map(l => ( - - ))} -
    -
    - )} + ) : ( +
    + + {Row} + +
    + )} +
    ); } diff --git a/src/components/Logs.module.scss b/src/components/Logs.module.scss index adc6f0f..4351bcb 100644 --- a/src/components/Logs.module.scss +++ b/src/components/Logs.module.scss @@ -40,10 +40,9 @@ $heightHeader: 76px; ////////// -.logUl { +.logsWrapper { margin: 0; padding: 0; - list-style: none; color: var(--color-text); :global { @@ -56,14 +55,12 @@ $heightHeader: 76px; } } -///////// - -.logs { +.log { padding: 10px 40px; - height: calc(100vh - #{$heightHeader}); - overflow: scroll; } +///////// + .logPlaceholder { height: calc(100vh - #{$heightHeader}); display: flex; -- cgit v1.3.1