Просмотр исходного кода

Simple performance optimization

陈帅 7 лет назад
Родитель
Сommit
c035a5fc71
4 измененных файлов с 55 добавлено и 42 удалено
  1. 1 0
      package.json
  2. 11 12
      src/components/ActiveChart/index.js
  3. 15 11
      src/components/PageHeader/index.js
  4. 28 19
      src/pages/layouts/BasicLayout.js

+ 1 - 0
package.json

@@ -31,6 +31,7 @@
     "lodash-decorators": "^6.0.0",
     "lodash.isequal": "^4.5.0",
     "moment": "^2.22.2",
+    "memoize-one": "^3.1.1",
     "numeral": "^2.0.6",
     "omit.js": "^1.0.0",
     "path-to-regexp": "^2.1.0",

+ 11 - 12
src/components/ActiveChart/index.js

@@ -1,5 +1,4 @@
 import React, { Component } from 'react';
-
 import { MiniArea } from '../Charts';
 import NumberInfo from '../NumberInfo';
 
@@ -34,18 +33,18 @@ export default class ActiveChart extends Component {
   }
 
   loopData = () => {
-    this.timer = setTimeout(() => {
-      this.setState(
-        {
-          activeData: getActiveData(),
-        },
-        () => {
-          requestAnimationFrame(() => {
+    requestAnimationFrame(() => {
+      this.timer = setTimeout(() => {
+        this.setState(
+          {
+            activeData: getActiveData(),
+          },
+          () => {
             this.loopData();
-          });
-        }
-      );
-    }, 1000);
+          }
+        );
+      }, 1000);
+    });
   };
 
   render() {

+ 15 - 11
src/components/PageHeader/index.js

@@ -1,12 +1,14 @@
 import React, { PureComponent, createElement } from 'react';
 import pathToRegexp from 'path-to-regexp';
 import { Breadcrumb, Tabs, Card } from 'antd';
+import memoizeOne from 'memoize-one';
+import deepEqual from 'lodash.isequal';
 import classNames from 'classnames';
 import styles from './index.less';
 import { urlToList } from '../_utils/pathTools';
 
 const { TabPane } = Tabs;
-export function getBreadcrumb(breadcrumbNameMap, url) {
+export const getBreadcrumb = (breadcrumbNameMap, url) => {
   let breadcrumb = breadcrumbNameMap[url];
   if (!breadcrumb) {
     Object.keys(breadcrumbNameMap).forEach(item => {
@@ -16,8 +18,14 @@ export function getBreadcrumb(breadcrumbNameMap, url) {
     });
   }
   return breadcrumb || {};
-}
+};
+
 export default class PageHeader extends PureComponent {
+  constructor(props) {
+    super(props);
+    this.conversionFromLocation = memoizeOne(this.conversionFromLocation, deepEqual);
+  }
+
   state = {
     breadcrumb: null,
   };
@@ -59,12 +67,11 @@ export default class PageHeader extends PureComponent {
 
   // Generated according to props
   conversionFromProps = () => {
-    const { breadcrumbList, breadcrumbSeparator, linkElement = 'a' } = this.props;
-
+    const { breadcrumbList, breadcrumbSeparator, itemRender, linkElement = 'a' } = this.props;
     return (
       <Breadcrumb className={styles.breadcrumb} separator={breadcrumbSeparator}>
         {breadcrumbList.map(item => {
-          const title = this.props.itemRender ? this.props.itemRender(item) : item.title;
+          const title = itemRender ? itemRender(item) : item.title;
           return (
             <Breadcrumb.Item key={item.title}>
               {item.href
@@ -84,17 +91,14 @@ export default class PageHeader extends PureComponent {
   };
 
   conversionFromLocation = (routerLocation, breadcrumbNameMap) => {
-    const { breadcrumbSeparator, linkElement = 'a' } = this.props;
+    const { breadcrumbSeparator, home, itemRender, linkElement = 'a' } = this.props;
     // Convert the url to an array
     const pathSnippets = urlToList(routerLocation.pathname);
     // Loop data mosaic routing
     const extraBreadcrumbItems = pathSnippets.map((url, index) => {
-      console.log(url);
       const currentBreadcrumb = getBreadcrumb(breadcrumbNameMap, url);
       const isLinkable = index !== pathSnippets.length - 1 && currentBreadcrumb.component;
-      const name = this.props.itemRender
-        ? this.props.itemRender(currentBreadcrumb)
-        : currentBreadcrumb.name;
+      const name = itemRender ? itemRender(currentBreadcrumb) : currentBreadcrumb.name;
       return currentBreadcrumb.name && !currentBreadcrumb.hideInBreadcrumb ? (
         <Breadcrumb.Item key={url}>
           {createElement(
@@ -113,7 +117,7 @@ export default class PageHeader extends PureComponent {
           {
             [linkElement === 'a' ? 'href' : 'to']: '/',
           },
-          this.props.home || 'Home'
+          home || 'Home'
         )}
       </Breadcrumb.Item>
     );

+ 28 - 19
src/pages/layouts/BasicLayout.js

@@ -3,6 +3,8 @@
 import React from 'react';
 import { Layout } from 'antd';
 import DocumentTitle from 'react-document-title';
+import { injectIntl } from 'react-intl';
+import memoizeOne from 'memoize-one';
 import { connect } from 'dva';
 // import { Route, Redirect, Switch } from 'dva/router';
 import { ContainerQuery } from 'react-container-query';
@@ -26,7 +28,7 @@ const { AuthorizedRoute, check } = Authorized;
  * @param {Object} menuData 菜单配置
  * @param {Object} routerData 路由配置
  */
-const getBreadcrumbNameMap = (meun, router) => {
+const getBreadcrumbNameMap = memoizeOne((meun, router) => {
   const routerMap = {};
   const mergeMeunAndRouter = meunData => {
     meunData.forEach(meunItem => {
@@ -38,7 +40,7 @@ const getBreadcrumbNameMap = (meun, router) => {
   };
   mergeMeunAndRouter(meun);
   return routerMap;
-};
+});
 
 const query = {
   'screen-xs': {
@@ -66,31 +68,38 @@ const query = {
 };
 
 class BasicLayout extends React.PureComponent {
+  constructor(props) {
+    super(props);
+    const { routerData, menuData } = this.props;
+    this.breadcrumbNameMap = getBreadcrumbNameMap(menuData, routerData);
+  }
+
   getContext() {
-    const { location, routerData, menuData } = this.props;
-    console.log(getBreadcrumbNameMap(menuData, routerData));
+    const { location } = this.props;
     return {
       location,
-      breadcrumbNameMap: getBreadcrumbNameMap(menuData, routerData),
+      breadcrumbNameMap: this.breadcrumbNameMap,
     };
   }
 
-  getPageTitle() {
-    const { routerData, location } = this.props;
-    const { pathname } = location;
-    let title = 'Ant Design Pro';
+  getPageTitle = pathname => {
     let currRouterData = null;
+    const { intl } = this.props;
     // match params path
-    Object.keys(routerData).forEach(key => {
+    Object.keys(this.breadcrumbNameMap).forEach(key => {
       if (pathToRegexp(key).test(pathname)) {
-        currRouterData = routerData[key];
+        currRouterData = this.breadcrumbNameMap[key];
       }
     });
-    if (currRouterData && currRouterData.name) {
-      title = `${currRouterData.name} - Ant Design Pro`;
+    if (!currRouterData) {
+      return 'Ant Design Pro';
     }
-    return title;
-  }
+    const message = intl.formatMessage({
+      id: currRouterData.locale || currRouterData.name,
+      defaultMessage: currRouterData.name,
+    });
+    return `${message} - Ant Design Pro`;
+  };
 
   getLayoutStyle = () => {
     const { fixSiderbar, collapsed, layout } = this.props;
@@ -148,7 +157,7 @@ class BasicLayout extends React.PureComponent {
       silderTheme,
       layout: PropsLayout,
       children,
-      // match,
+      location: { pathname },
     } = this.props;
     const isTop = PropsLayout === 'topmenu';
     // const bashRedirect = this.getBashRedirect();
@@ -190,9 +199,9 @@ class BasicLayout extends React.PureComponent {
         </Layout>
       </Layout>
     );
-
+    const getPageTitle = memoizeOne(this.getPageTitle);
     return (
-      <DocumentTitle title={this.getPageTitle()}>
+      <DocumentTitle title={getPageTitle(pathname)}>
         <ContainerQuery query={query}>
           {params => (
             <Context.Provider value={this.getContext()}>
@@ -212,4 +221,4 @@ export default connect(({ global, setting }) => ({
   collapsed: global.collapsed,
   layout: setting.layout,
   ...setting,
-}))(BasicLayout);
+}))(injectIntl(BasicLayout));