This is an automated email from the ASF dual-hosted git repository.

juzhiyuan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix-website.git


The following commit(s) were added to refs/heads/master by this push:
     new dabe8b8b650 fix: optimize and remove useless things (#1173)
dabe8b8b650 is described below

commit dabe8b8b65012939cb4434a9b2964c0a8825271d
Author: Young <[email protected]>
AuthorDate: Thu Jun 30 15:38:51 2022 +0800

    fix: optimize and remove useless things (#1173)
---
 website/docusaurus.config.js                       |   5 +-
 website/package.json                               |   2 +
 website/src/assets/images/PatternGrouped-min.svg   |   1 +
 .../assets/images/infographs/Architecture-min.svg  |   1 +
 .../assets/images/infographs/multiplatform-min.svg |   1 +
 website/src/components/ArrowAnim.tsx               |   1 -
 website/src/components/EventPosterCard.tsx         |  57 ++++-----
 website/src/components/HeroCanvas.tsx              |   1 -
 website/src/components/ProjectCard.tsx             |   2 -
 website/src/components/sections/Architecture.tsx   | 140 ++++++---------------
 website/src/components/sections/Benefits.tsx       |  13 +-
 website/src/components/sections/Comparison.tsx     |  13 +-
 website/src/components/sections/Endcta.tsx         |   4 +-
 website/src/components/sections/Features.tsx       |  60 ++++-----
 website/src/components/sections/HeroSection.tsx    |   3 +-
 .../src/components/sections/HomeEventsSection.tsx  |   1 -
 website/src/css/customTheme.css                    |  25 ++--
 website/src/hooks/useWindowSize.ts                 |  21 ++++
 website/src/pages/docs.tsx                         |   1 -
 website/src/pages/help.tsx                         |   7 +-
 website/src/pages/index.tsx                        |  83 +++++-------
 website/src/pages/team.tsx                         |   6 +-
 yarn.lock                                          |  23 +++-
 23 files changed, 208 insertions(+), 263 deletions(-)

diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js
index 3e5cae0c856..20a0f9d5fef 100644
--- a/website/docusaurus.config.js
+++ b/website/docusaurus.config.js
@@ -80,15 +80,12 @@ module.exports = {
           blogSidebarCount: 'ALL',
         },
         theme: {
-          customCss: '../src/css/customTheme.css',
+          customCss: require.resolve('./src/css/customTheme.css'),
         },
         sitemap: {
           changefreq: 'daily',
           priority: 0.5,
         },
-        pages: {
-          exclude: ['**/downloads/ProjectCard.js'],
-        },
       },
     ],
   ],
diff --git a/website/package.json b/website/package.json
index 5d8b14d03ea..c9535296d6a 100644
--- a/website/package.json
+++ b/website/package.json
@@ -19,6 +19,7 @@
     "@tsconfig/docusaurus": "^1.0.4",
     "@types/react": "^17.0.20",
     "@types/react-helmet": "^6.1.2",
+    "@types/react-lazy-load-image-component": "^1.5.2",
     "@types/react-router-dom": "^5.1.8",
     "@types/styled-components": "^5.1.24",
     "@types/video.js": "^7.3.40",
@@ -37,6 +38,7 @@
     "rc-image": "^5.6.2",
     "react": "^17.0.2",
     "react-dom": "^17.0.2",
+    "react-lazy-load-image-component": "^1.5.4",
     "react-transition-group": "^4.4.1",
     "sass": "^1.38.2",
     "styled-components": "^5.3.3",
diff --git a/website/src/assets/images/PatternGrouped-min.svg 
b/website/src/assets/images/PatternGrouped-min.svg
new file mode 100644
index 00000000000..567e4f74b29
--- /dev/null
+++ b/website/src/assets/images/PatternGrouped-min.svg
@@ -0,0 +1 @@
+<svg preserveAspectRatio="xMidYMid meet" viewBox="0 0 1680 361" fill="none" 
xmlns="http://www.w3.org/2000/svg";><g class="PatternGrouped"><g 
class="Paths"><path class="p27" d="M-60 360c476.78 0 384.27-115.24 
899.5-115.24M1739 1.25c-492.79 0-378.93 156.23-899.5 156.23" 
stroke="#00EFC6"/><path class="p26" d="M-60 347.51c477.34 0 384.09-105.81 
899.5-105.81M1739 16.39c-492.12 0-379.16 144.78-899.5 144.78" 
stroke="#0DE2CA"/><path class="p25" d="M-60 335.06c477.89 0 383.9-96.38 
899.5-96.38M1739 [...]
\ No newline at end of file
diff --git a/website/src/assets/images/infographs/Architecture-min.svg 
b/website/src/assets/images/infographs/Architecture-min.svg
new file mode 100644
index 00000000000..169949b76a6
--- /dev/null
+++ b/website/src/assets/images/infographs/Architecture-min.svg
@@ -0,0 +1 @@
+<svg fill="none" xmlns="http://www.w3.org/2000/svg"; viewBox="0 0 1713 996"><g 
class="architecture"><path fill="#E2ECFF" stroke="#343A40" d="M732 
137h993v866H732zm-719 0h700v866H13z"/><path d="m157 464 471-1v324l-469-1" 
fill="#FD7E14"/><path d="M159 463c163 2 328 2 467-1l-467 1zm0 
0h468-468zm469-1c2 80 1 160-3 323l3-323zm-2 1c3 80 2 160 0 322V463zm1 323c-112 
0-223 1-468-1l468 1zm0-1H159h468zm-468 0c-1-73-3-142-2-321l2 321zm0 0-1-322z" 
fill="#FD7E14"/><path d="M628 463v-1 1zm0 324v1h1v-1h- [...]
\ No newline at end of file
diff --git a/website/src/assets/images/infographs/multiplatform-min.svg 
b/website/src/assets/images/infographs/multiplatform-min.svg
new file mode 100644
index 00000000000..af61a0124f0
--- /dev/null
+++ b/website/src/assets/images/infographs/multiplatform-min.svg
@@ -0,0 +1 @@
+<svg class="multi" xmlns="http://www.w3.org/2000/svg"; fill="none" viewBox="0 0 
543 244"><g class="multiplatform"><g class="dynamo"><g class="server-box"><path 
fill="#15AABF" d="M1 3h240v240H1M1 3h240H1zm0 0h240H1zm240 0v240V3zm0 
0v240V3zm0 240H1h240zm0 0H1h240zM1 243V3v240zm0 0V3z"/><path fill="#000" d="M1 
3V2H0v1h1zm240 0h1V2h-1v1zm0 240v1h1v-1h-1zM1 243H0v1h1v-1zM1 
4h240V2H1v2zm239-1v240h2V3h-2zm1 239H1v2h240v-2zM1 4h240V2H1v2zm0 
0h240V2H1v2zm239-1v240h2V3h-2zm0 0v240h2V3h-2zm1 239H1v2 [...]
\ No newline at end of file
diff --git a/website/src/components/ArrowAnim.tsx 
b/website/src/components/ArrowAnim.tsx
index 4fa392ddfb5..5469ac479ce 100644
--- a/website/src/components/ArrowAnim.tsx
+++ b/website/src/components/ArrowAnim.tsx
@@ -3,7 +3,6 @@ import React from 'react';
 import Link from '@docusaurus/Link';
 import useBaseUrl from '@docusaurus/useBaseUrl';
 
-import '../css/customTheme.css';
 import Translate from '@docusaurus/Translate';
 
 const ArrowAnim: FC = () => (
diff --git a/website/src/components/EventPosterCard.tsx 
b/website/src/components/EventPosterCard.tsx
index f05c02455fc..0a905285977 100644
--- a/website/src/components/EventPosterCard.tsx
+++ b/website/src/components/EventPosterCard.tsx
@@ -1,9 +1,8 @@
 import type { FC } from 'react';
 import React, { useState, useRef, useEffect } from 'react';
 import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
-import gsap from 'gsap';
-
-import '../css/customTheme.css';
+import { gsap } from 'gsap/gsap-core';
+import { LazyLoadImage } from 'react-lazy-load-image-component';
 
 interface EventPosterCardInfo {
   show: boolean;
@@ -15,12 +14,8 @@ interface EventPosterCardInfo {
 const LANG_STOR_KEY = 'localLang';
 const SHOW_STORE_KEY = 'SHOW_EVENT_ENTRY';
 
-const EventPosterCard:FC = () => {
-  const { siteConfig } = useDocusaurusContext();
-  const {
-    show, expire, links, image,
-  } = siteConfig.customFields.eventPosterCard as EventPosterCardInfo;
-  const [display, setDisplay] = useState(false);
+const EventPosterCard:FC<Pick<EventPosterCardInfo, 'image' | 'links'>> = 
(props) => {
+  const { image, links } = props;
   const picRef = useRef(null);
   const [link, setLink] = useState<string>('');
 
@@ -41,35 +36,17 @@ const EventPosterCard:FC = () => {
     setLink(links[lang]);
   }, []);
 
-  useEffect(() => {
-    if (show) {
-      const expireTimestamp = new Date(expire).getTime();
-      if (
-        !sessionStorage.getItem(SHOW_STORE_KEY)
-         && (expireTimestamp > new Date().getTime())
-      ) {
-        setDisplay(true);
-      }
-    }
-  }, []);
-
   const onClose = () => {
     gsap.to(picRef.current, {
       x: 500,
       opacity: 0,
       onComplete: () => {
-        setDisplay(false);
+        if (typeof window === 'undefined') return;
+        sessionStorage.setItem(SHOW_STORE_KEY, 'true');
       },
     });
-
-    if (typeof window === 'undefined') return;
-    sessionStorage.setItem(SHOW_STORE_KEY, 'true');
   };
 
-  if (!display) {
-    return null;
-  }
-
   return (
     <div ref={picRef} className="pic-wrapper">
       <button className="pic-wrapper-close" onClick={onClose} type="button">
@@ -87,10 +64,28 @@ const EventPosterCard:FC = () => {
         </svg>
       </button>
       <a href={link} onClick={onClose} target="_blank" rel="noreferrer">
-        <img src={image} alt="" />
+        <LazyLoadImage src={image} alt={link} />
       </a>
     </div>
   );
 };
 
-export default EventPosterCard;
+const EventPosterCardWrapper: FC = () => {
+  if (typeof window === 'undefined') return null;
+
+  sessionStorage.setItem(SHOW_STORE_KEY, 'true');
+
+  const { siteConfig } = useDocusaurusContext();
+  const {
+    show, expire, links, image,
+  } = siteConfig.customFields.eventPosterCard as EventPosterCardInfo;
+
+  const expireTimestamp = new Date(expire).getTime();
+  if (show && !sessionStorage.getItem(SHOW_STORE_KEY) && (expireTimestamp > 
new Date().getTime())) {
+    return <EventPosterCard links={links} image={image} />;
+  }
+
+  return null;
+};
+
+export default EventPosterCardWrapper;
diff --git a/website/src/components/HeroCanvas.tsx 
b/website/src/components/HeroCanvas.tsx
index d9c2c88df3d..a3df0090ddb 100644
--- a/website/src/components/HeroCanvas.tsx
+++ b/website/src/components/HeroCanvas.tsx
@@ -18,7 +18,6 @@ import { gsap } from 'gsap/gsap-core';
 
 import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
 
-import '../css/customTheme.css';
 // eslint-disable-next-line import/no-unresolved, 
import/no-webpack-loader-syntax, import/extensions
 import fragment from '!!raw-loader!../shaders/fragment.frag';
 // eslint-disable-next-line import/no-unresolved, 
import/no-webpack-loader-syntax, import/extensions
diff --git a/website/src/components/ProjectCard.tsx 
b/website/src/components/ProjectCard.tsx
index 233ba1f626f..e4f812e8e55 100644
--- a/website/src/components/ProjectCard.tsx
+++ b/website/src/components/ProjectCard.tsx
@@ -4,8 +4,6 @@ import styled from 'styled-components';
 
 import useOutsideClick from '../hooks/useOutsideClick';
 
-import '../css/customTheme.css';
-
 import IconInfo from '../assets/icons/info.svg';
 import IconStar from '../assets/icons/star.svg';
 import IconDocumentText from '../assets/icons/document-text.svg';
diff --git a/website/src/components/sections/Architecture.tsx 
b/website/src/components/sections/Architecture.tsx
index 42ff25673e6..2a5f03a4af7 100644
--- a/website/src/components/sections/Architecture.tsx
+++ b/website/src/components/sections/Architecture.tsx
@@ -1,112 +1,54 @@
 import type { FC } from 'react';
-import React, { useEffect } from 'react';
-import gsap from 'gsap';
+import React from 'react';
 
 import Translate from '@docusaurus/Translate';
 
-import '../../css/customTheme.css';
-import HLDesign from '../../assets/images/infographs/Architecture.svg';
-import Pattern from '../../assets/images/PatternGrouped.svg';
-
-interface ArchitectureProps {
-  screenWidth: number;
-}
-
-const Architecture: FC<ArchitectureProps> = (props) => {
-  const { screenWidth } = props;
-
-  useEffect(() => {
-    const strokePaths = [];
-    for (let i = 1; i < 28; i += 1) {
-      strokePaths.push(`.PatternGrouped_svg__p${i}`);
-    }
-
-    const tlStroke = gsap.timeline({
-      paused: true,
-      defaults: {
-        ease: 'power2.inOut',
-        yoyo: true,
-        repeat: -1,
-      },
-    });
-
-    tlStroke.fromTo(strokePaths, {
-      strokeDashoffset: 10000,
-    }, {
-      strokeDashoffset: 0,
-      duration: 5,
-      stagger: 0.3,
-      ease: 'power2.inOut',
-      stroke: 'red',
-    });
-
-    const observer = new IntersectionObserver(onIntersection, {
-      root: null,
-      threshold: 0.4,
-    });
-
-    function onIntersection(entries) {
-      entries.forEach((entry) => {
-        if (entry.isIntersecting) {
-          tlStroke.paused(false);
-        } else {
-          tlStroke.paused(true);
-        }
-      });
-    }
-
-    observer.observe(document.querySelector('.arch'));
-
-    return () => {
-      tlStroke.pause(0).kill();
-      observer.disconnect();
-    };
-  }, []);
-
-  return (
-    <div className="arch">
-      <div style={{
-        position: 'absolute', display: 'flex', justifyContent: 'center', 
alignItems: 'center', height: '120vh',
+import HLDesign from '../../assets/images/infographs/Architecture-min.svg';
+import Pattern from '../../assets/images/PatternGrouped-min.svg';
+
+const Architecture: FC = () => (
+  <div className="arch">
+    <Pattern
+      className="arch-scale-svg"
+      width="100vw"
+      style={{
+        strokeWidth: '2px',
+        opacity: '0.25',
+        strokeDasharray: '10000',
+        position: 'absolute',
+        margin: '0 auto',
+        bottom: 0,
+        zIndex: -10,
       }}
-      >
-        <Pattern
-          className="arch-scale-svg"
-          style={{
-            width: '100vw', strokeWidth: '3', zIndex: '-10', opacity: '0.25', 
strokeDasharray: '10000',
-          }}
-        />
-      </div>
-      <div>
-        <h3 className="arch-head">
-          <Translate id="architecture.component.title.name">Building for 
large-scale, high value systems</Translate>
-        </h3>
+    />
+    <h3 className="arch-head">
+      <Translate id="architecture.component.title.name">Building for 
large-scale, high value systems</Translate>
+    </h3>
+    <div className="arch-subtitle">
+      <p>
+        <Translate id="architecture.component.title.subtitle">
+          Apache APISIX provides open source API Gateway to help you manage 
microservices,
+          delivering the ultimate performance, security,
+          and scalable platform for all your APIs and microservices.
+        </Translate>
+      </p>
+    </div>
+    <div className="arch-card" style={{ position: 'relative' }}>
+      <div className="hldesign">
+        <HLDesign className="hldesign-graphic" />
       </div>
-      <div className="arch-subtitle">
+      <div className="arch-card-caption">
         <p>
-          <Translate id="architecture.component.title.subtitle">
-            Apache APISIX provides open source API Gateway to help you manage 
microservices,
-            delivering the ultimate performance, security,
-            and scalable platform for all your APIs and microservices.
+          <Translate id="architecture.component.card.caption">
+            Apache APISIX is based on NGINX and etcd.
+            Compared with traditional API Gateways,
+            APISIX has features like dynamic routing and hot-loading plugins, 
etc.
           </Translate>
         </p>
       </div>
-      <div className="arch-card" style={{ position: 'relative' }}>
-        <div className="hldesign">
-          <HLDesign className="hldesign-graphic" />
-        </div>
-        <div className="arch-card-caption">
-          <p style={{ width: screenWidth >= 768 ? '50%' : '90%' }}>
-            <Translate id="architecture.component.card.caption">
-              Apache APISIX is based on NGINX and etcd.
-              Compared with traditional API Gateways,
-              APISIX has features like dynamic routing and hot-loading 
plugins, etc.
-            </Translate>
-          </p>
-        </div>
-        <div className="arch-card-border" />
-      </div>
+      <div className="arch-card-border" />
     </div>
-  );
-};
+  </div>
+);
 
 export default Architecture;
diff --git a/website/src/components/sections/Benefits.tsx 
b/website/src/components/sections/Benefits.tsx
index 813eb232b31..396384007f0 100644
--- a/website/src/components/sections/Benefits.tsx
+++ b/website/src/components/sections/Benefits.tsx
@@ -7,29 +7,24 @@ import { ScrollTrigger } from 'gsap/ScrollTrigger';
 
 import Translate from '@docusaurus/Translate';
 
-import '../../css/customTheme.css';
-
 import Performance from '../../assets/images/infographs/performance.svg';
 import Security from '../../assets/images/infographs/security.svg';
 import Scale from '../../assets/images/infographs/scale.svg';
 import Dynamic from '../../assets/images/infographs/dynamic.svg';
 import Multiplatform from '../../assets/images/infographs/multiplatform.svg';
+import useWindowSize from '../../hooks/useWindowSize';
 
-interface BenefitsProps {
-  screenWidth: number
-}
-const Benefits: FC<BenefitsProps> = (props) => {
+const Benefits: FC = () => {
   const triggerDiv = useRef(null);
   const performance = useRef(null);
   const security = useRef(null);
   const scale = useRef(null);
   const dynamic = useRef(null);
   const multiplatform = useRef(null);
+  const [screenWidth] = useWindowSize();
 
   gsap.registerPlugin(ScrollTrigger);
 
-  const { screenWidth } = props;
-
   useEffect(() => {
     const tweenTls = [];
     const observers = [];
@@ -371,7 +366,7 @@ const Benefits: FC<BenefitsProps> = (props) => {
               <Translate id="benefits.component.security.message">
                 Apache APISIX Gateway provides multiple security plugins for 
identity
                 authentication and API verification, including CORS, JWT, Key
-                Auth, OpenID Connect (OIDC), Keycloak, etc. We put stability 
and 
+                Auth, OpenID Connect (OIDC), Keycloak, etc. We put stability 
and
                 security first. For more information, check
               </Translate>
               {' '}
diff --git a/website/src/components/sections/Comparison.tsx 
b/website/src/components/sections/Comparison.tsx
index 66006b0ec79..57ce5e639d1 100644
--- a/website/src/components/sections/Comparison.tsx
+++ b/website/src/components/sections/Comparison.tsx
@@ -3,7 +3,6 @@ import React from 'react';
 
 import Translate from '@docusaurus/Translate';
 
-import '../../css/customTheme.css';
 import Cross from '../../assets/icons/cross.svg';
 import Tick from '../../assets/icons/tick.svg';
 
@@ -16,13 +15,11 @@ const Comparison: FC = () => (
     </div>
     <div className="compare-subtitle">
       <p>
-        <strong>
-          <Translate id="comparison.component.subtitle">
-            Apache APISIX Gateway is open source and ever-evolving.
-            Here&apos;s a general comparison of APISIX with other API Gateway 
options,
-            choose your right API Gateway.
-          </Translate>
-        </strong>
+        <Translate id="comparison.component.subtitle">
+          Apache APISIX Gateway is open source and ever-evolving.
+          Here&apos;s a general comparison of APISIX with other API Gateway 
options,
+          choose your right API Gateway.
+        </Translate>
       </p>
     </div>
     <div>
diff --git a/website/src/components/sections/Endcta.tsx 
b/website/src/components/sections/Endcta.tsx
index 09fac408c53..18e14d380c5 100644
--- a/website/src/components/sections/Endcta.tsx
+++ b/website/src/components/sections/Endcta.tsx
@@ -5,7 +5,7 @@ import useBaseUrl from '@docusaurus/useBaseUrl';
 
 import Translate from '@docusaurus/Translate';
 
-import '../../css/customTheme.css';
+import { LazyLoadImage } from 'react-lazy-load-image-component';
 import ArrowAnim from '../ArrowAnim';
 
 const EndCTA: FC = () => (
@@ -22,7 +22,7 @@ const EndCTA: FC = () => (
           {' '}
         </span>
         today
-        <img className="rocket" 
src="https://static.apiseven.com/202202/rocket.gif"; alt="Rocket" />
+        <LazyLoadImage className="rocket" 
src="https://static.apiseven.com/202202/rocket.gif"; alt="Rocket" width="6vw" 
height="6vw" />
       </p>
     </div>
     <div className="endcta-btns">
diff --git a/website/src/components/sections/Features.tsx 
b/website/src/components/sections/Features.tsx
index dbffbbcdb7c..e79552ec2d6 100644
--- a/website/src/components/sections/Features.tsx
+++ b/website/src/components/sections/Features.tsx
@@ -1,5 +1,5 @@
 import type { FC } from 'react';
-import React, { useEffect, useRef, memo } from 'react';
+import React, { useEffect, useRef } from 'react';
 import Link from '@docusaurus/Link';
 import useBaseUrl from '@docusaurus/useBaseUrl';
 import { gsap } from 'gsap/gsap-core';
@@ -9,8 +9,6 @@ import Translate from '@docusaurus/Translate';
 import useWindowType from '@theme/hooks/useWindowSize';
 import ArrowAnim from '../ArrowAnim';
 
-import '../../css/customTheme.css';
-
 const DashboardPlayground = () => (
   <Link
     className="dashboard-playground-link add-left-margin-feat"
@@ -36,6 +34,8 @@ const DashboardPlayground = () => (
 );
 
 const FeatDesktop: FC = () => {
+  gsap.registerPlugin(ScrollTrigger);
+
   const dashboardDiv = useRef(null);
   const userfDiv = useRef(null);
   const pluginDiv = useRef(null);
@@ -74,7 +74,7 @@ const FeatDesktop: FC = () => {
       .to(img3.current, {
         opacity: 1,
       });
-  });
+  }, [triggerDiv.current, pinDiv.current, img1.current, img2.current, 
img3.current]);
   return (
     <div className="feat-container-d" ref={triggerDiv}>
       <div className="left-pane" style={{ width: '50%', height: '100%' }}>
@@ -175,8 +175,9 @@ const FeatDesktop: FC = () => {
 };
 
 const FeatMobile: FC = () => {
+  gsap.registerPlugin(ScrollTrigger);
+
   const observers = [];
-  const triggerDivCol = useRef(null);
   const img1col = useRef(null);
   const img2col = useRef(null);
   const img3col = useRef(null);
@@ -219,12 +220,11 @@ const FeatMobile: FC = () => {
     observers.forEach((it, index) => {
       it.observe(elems[index]);
     });
-  }, []);
+  }, [img1col.current, img2col.current, img3col.current]);
 
   return (
     <div
       className="feat-container-m"
-      ref={triggerDivCol}
       style={{ width: '100%' }}
     >
       <div
@@ -299,7 +299,6 @@ const FeatMobile: FC = () => {
 };
 
 const FeatContainer: FC = () => {
-  gsap.registerPlugin(ScrollTrigger);
   const windowType = useWindowType();
 
   if (windowType === 'desktop') {
@@ -308,31 +307,26 @@ const FeatContainer: FC = () => {
 
   return <FeatMobile />;
 };
-const FeatContainerMemo = memo(FeatContainer);
-
-const Features: FC = () => {
-  const featPin = useRef(null);
 
-  return (
-    <>
-      <div ref={featPin} className="feat-top" style={{ padding: '50px 0' }}>
-        <h3 className="feat-head-desc"><Translate 
id="features.component.why.title">Why APISIX Gateway?</Translate></h3>
-        <h2 className="feat-head add-left-margin">
-          <Translate id="features.component.why.subtitle">
-            Reduce time fighting bugs, focus on designing world-class systems 
with API Gateway
-          </Translate>
-        </h2>
-        <p className="feat-desc add-left-margin">
-          <Translate id="features.component.why.message">
-            Apache APISIX is the first open-source API Gateway
-            that includes a built-in low-code Dashboard,
-            which offers a powerful and flexible UI for developers to use.
-          </Translate>
-        </p>
-      </div>
-      <FeatContainerMemo />
-    </>
-  );
-};
+const Features: FC = () => (
+  <>
+    <div className="feat-top" style={{ padding: '50px 0' }}>
+      <h3 className="feat-head-desc"><Translate 
id="features.component.why.title">Why APISIX Gateway?</Translate></h3>
+      <h2 className="feat-head add-left-margin">
+        <Translate id="features.component.why.subtitle">
+          Reduce time fighting bugs, focus on designing world-class systems 
with API Gateway
+        </Translate>
+      </h2>
+      <p className="feat-desc add-left-margin">
+        <Translate id="features.component.why.message">
+          Apache APISIX is the first open-source API Gateway
+          that includes a built-in low-code Dashboard,
+          which offers a powerful and flexible UI for developers to use.
+        </Translate>
+      </p>
+    </div>
+    <FeatContainer />
+  </>
+);
 
 export default Features;
diff --git a/website/src/components/sections/HeroSection.tsx 
b/website/src/components/sections/HeroSection.tsx
index 9b98c405f1e..016774f8446 100644
--- a/website/src/components/sections/HeroSection.tsx
+++ b/website/src/components/sections/HeroSection.tsx
@@ -4,14 +4,13 @@ import Link from '@docusaurus/Link';
 import useBaseUrl from '@docusaurus/useBaseUrl';
 import Translate from '@docusaurus/Translate';
 
-import '../../css/customTheme.css';
 import BrowserOnly from '@docusaurus/BrowserOnly';
 import useWindowType from '@theme/hooks/useWindowSize';
 import ArrowAnim from '../ArrowAnim';
 
 const LazyLoadHeroCanvas = () => {
   const windowType = useWindowType();
-  if (windowType === 'mobile') return (null);
+  if (windowType === 'mobile') return null;
 
   return (
     <BrowserOnly>
diff --git a/website/src/components/sections/HomeEventsSection.tsx 
b/website/src/components/sections/HomeEventsSection.tsx
index fc83f701ec9..d793114dad3 100644
--- a/website/src/components/sections/HomeEventsSection.tsx
+++ b/website/src/components/sections/HomeEventsSection.tsx
@@ -4,7 +4,6 @@ import useDocusaurusContext from 
'@docusaurus/useDocusaurusContext';
 
 import Translate from '@docusaurus/Translate';
 
-import '../../css/customTheme.css';
 import ChevronRight from '../../assets/icons/chevron-right.svg';
 
 interface EventInfo {
diff --git a/website/src/css/customTheme.css b/website/src/css/customTheme.css
index 257b55283b7..3c81af56b43 100644
--- a/website/src/css/customTheme.css
+++ b/website/src/css/customTheme.css
@@ -512,6 +512,17 @@ a:hover {
   color: #615d5d;
 }
 
+.arch-card-caption > p {
+  width: 90%;
+  letter-spacing: 0.2px;
+  font-family: MaisonNeue-Light, sans-serif;
+  font-weight: 700;
+  text-align: center;
+  position: relative;
+  bottom: -15px;
+  font-size: 1rem;
+}
+
 .arch-card-border {
   z-index: -10;
   position: absolute;
@@ -549,16 +560,6 @@ a:hover {
   font-weight: 700;
 }
 
-.arch-card-caption > p {
-  letter-spacing: 0.2px;
-  font-family: MaisonNeue-Light, sans-serif;
-  font-weight: 700;
-  text-align: center;
-  position: relative;
-  bottom: -15px;
-  font-size: 1rem;
-}
-
 .add-left-margin {
   position: relative;
   left: 16.8%;
@@ -1596,6 +1597,10 @@ a:hover {
   .react-toggle {
     display: none;
   }
+
+  .arch-card-caption > p {
+    width: 50%;
+  }
 }
 
 .bottom-pos {
diff --git a/website/src/hooks/useWindowSize.ts 
b/website/src/hooks/useWindowSize.ts
new file mode 100644
index 00000000000..34cd3dc5fa6
--- /dev/null
+++ b/website/src/hooks/useWindowSize.ts
@@ -0,0 +1,21 @@
+import { useLayoutEffect, useState } from 'react';
+
+type WindowWidth = number
+type WindowHeight = number
+type UseWindowSize = () => [WindowWidth, WindowHeight];
+
+const useWindowSize: UseWindowSize = () => {
+  const [size, setSize] = useState<[WindowWidth, WindowWidth]>([0, 0]);
+
+  useLayoutEffect(() => {
+    function updateSize() {
+      setSize([window.innerWidth, window.innerHeight]);
+    }
+    window.addEventListener('resize', updateSize);
+    updateSize();
+    return () => window.removeEventListener('resize', updateSize);
+  }, []);
+  return size;
+};
+
+export default useWindowSize;
diff --git a/website/src/pages/docs.tsx b/website/src/pages/docs.tsx
index aca60b65749..50a73689703 100644
--- a/website/src/pages/docs.tsx
+++ b/website/src/pages/docs.tsx
@@ -1,7 +1,6 @@
 import type { FC } from 'react';
 import React from 'react';
 import styled from 'styled-components';
-import '../css/customTheme.css';
 import Layout from '@theme/Layout';
 import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
 
diff --git a/website/src/pages/help.tsx b/website/src/pages/help.tsx
index 746460db96d..f773eb8a3f5 100644
--- a/website/src/pages/help.tsx
+++ b/website/src/pages/help.tsx
@@ -5,10 +5,9 @@ import Layout from '@theme/Layout';
 
 import Translate from '@docusaurus/Translate';
 
+import { LazyLoadImage } from 'react-lazy-load-image-component';
 import ChevronRight from '../assets/icons/chevron-right.svg';
 
-import '../css/customTheme.css';
-
 const PageTitle = styled.h1`
   margin-top: 2rem;
   font-size: 3rem;
@@ -37,7 +36,7 @@ const Help: FC = () => (
         <div className="card">
           <div className="header">
             <h2>
-              <img
+              <LazyLoadImage
                 src="/img/documents.png"
                 id="documents-icon"
                 alt="documents icon"
@@ -60,7 +59,7 @@ const Help: FC = () => (
         <div className="card">
           <div className="header">
             <h2>
-              <img src="/img/community.png" alt="community icon" />
+              <LazyLoadImage src="/img/community.png" alt="community icon" />
               <Translate id="help.website.community.title">Join 
Community</Translate>
             </h2>
           </div>
diff --git a/website/src/pages/index.tsx b/website/src/pages/index.tsx
index 9299b1ce2d0..95e0af89345 100644
--- a/website/src/pages/index.tsx
+++ b/website/src/pages/index.tsx
@@ -1,5 +1,5 @@
 import type { FC } from 'react';
-import React, { useState, useEffect, useLayoutEffect } from 'react';
+import React, { useEffect } from 'react';
 import useThemeContext from '@theme/hooks/useThemeContext';
 import Layout from '@theme/Layout';
 import Head from '@docusaurus/Head';
@@ -15,19 +15,6 @@ import HomeEventsSection from 
'../components/sections/HomeEventsSection';
 import EndCTA from '../components/sections/Endcta';
 import EventPosterCard from '../components/EventPosterCard';
 
-const useWindowSize = () => {
-  const [size, setSize] = useState([0, 0]);
-  useLayoutEffect(() => {
-    function updateSize() {
-      setSize([window.innerWidth, window.innerHeight]);
-    }
-    window.addEventListener('resize', updateSize);
-    updateSize();
-    return () => window.removeEventListener('resize', updateSize);
-  }, []);
-  return size;
-};
-
 const ThemeResetComponent = () => {
   const { isDarkTheme, setLightTheme } = useThemeContext();
   const windowType = useWindowType();
@@ -57,41 +44,37 @@ const ThemeResetComponent = () => {
   return (null);
 };
 
-const Index: FC = () => {
-  const [screenWidth] = useWindowSize();
-
-  return (
-    <Layout>
-      <Head>
-        <meta
-          name="twitter:title"
-          content="Apache APISIX® - Cloud-Native API Gateway"
-        />
-        <meta
-          name="twitter:description"
-          content="Apache APISIX is a dynamic, real-time, high-performance 
Cloud-Native API gateway, based on the Nginx library and etcd."
-        />
-        <meta
-          name="twitter:site"
-          content="@apacheapisix"
-        />
-        <meta
-          name="og:description"
-          content="Apache APISIX is a dynamic, real-time, high-performance 
Cloud-Native API gateway, based on the Nginx library and etcd."
-        />
-      </Head>
-      <HeroSection />
-      <Architecture screenWidth={screenWidth} />
-      <Features />
-      <Benefits screenWidth={screenWidth} />
-      <Comparison />
-      <OpensourcePromo />
-      <HomeEventsSection />
-      <EndCTA />
-      <EventPosterCard />
-      <ThemeResetComponent />
-    </Layout>
-  );
-};
+const Index: FC = () => (
+  <Layout>
+    <ThemeResetComponent />
+    <Head>
+      <meta
+        name="twitter:title"
+        content="Apache APISIX® - Cloud-Native API Gateway"
+      />
+      <meta
+        name="twitter:description"
+        content="Apache APISIX is a dynamic, real-time, high-performance 
Cloud-Native API gateway, based on the Nginx library and etcd."
+      />
+      <meta
+        name="twitter:site"
+        content="@apacheapisix"
+      />
+      <meta
+        name="og:description"
+        content="Apache APISIX is a dynamic, real-time, high-performance 
Cloud-Native API gateway, based on the Nginx library and etcd."
+      />
+    </Head>
+    <HeroSection />
+    <Architecture />
+    <Features />
+    <Benefits />
+    <Comparison />
+    <OpensourcePromo />
+    <HomeEventsSection />
+    <EndCTA />
+    <EventPosterCard />
+  </Layout>
+);
 
 export default Index;
diff --git a/website/src/pages/team.tsx b/website/src/pages/team.tsx
index 873f932af0b..2fed0804c6e 100644
--- a/website/src/pages/team.tsx
+++ b/website/src/pages/team.tsx
@@ -15,8 +15,6 @@ import IconPuzzle from '../assets/icons/puzzle.svg';
 import IconEye from '../assets/icons/eye.svg';
 import IconDocumentText from '../assets/icons/document-text.svg';
 
-import '../css/customTheme.css';
-
 const PageTitle = styled.h1`
   margin-top: 2rem;
   font-size: 4rem;
@@ -248,7 +246,7 @@ const ContributeCardRightSide = styled.div`
 
 const Team: FC = () => {
   const { siteConfig } = useDocusaurusContext();
-  const memberSections = siteConfig.customFields.team.map((section) => {
+  const memberSections = (siteConfig.customFields.team as any).map((section) 
=> {
     const memberCards = section.members.map((member) => (
       <div key={member.username}>
         <MemberCard
@@ -273,7 +271,7 @@ const Team: FC = () => {
       </div>
     );
   });
-  const repoComponents = siteConfig.customFields.allRepos.map((repo) => (
+  const repoComponents = (siteConfig.customFields.allRepos as any).map((repo) 
=> (
     <RepoCard
       className="team-repocard"
       href={`https://github.com/${repo}/graphs/contributors`}
diff --git a/yarn.lock b/yarn.lock
index eebf1ab8885..9374364d5a9 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2033,6 +2033,14 @@
   dependencies:
     "@types/react" "*"
 
+"@types/react-lazy-load-image-component@^1.5.2":
+  version "1.5.2"
+  resolved 
"https://registry.yarnpkg.com/@types/react-lazy-load-image-component/-/react-lazy-load-image-component-1.5.2.tgz#b87e814b6b91853b802f04465364ff1e913dce6a";
+  integrity 
sha512-4NLJsMJVrMv18FuMIkUUBVj/PH9A+BvLKrZC75EWiEFn1IsMrZHgL1tVKw5QBfoa0Qjz6SkWIzEvwcyZ8PgnIg==
+  dependencies:
+    "@types/react" "*"
+    csstype "^3.0.2"
+
 "@types/react-router-config@*":
   version "5.0.6"
   resolved 
"https://registry.yarnpkg.com/@types/react-router-config/-/react-router-config-5.0.6.tgz#87c5c57e72d241db900d9734512c50ccec062451";
@@ -6727,6 +6735,11 @@ lodash.some@^4.4.0:
   resolved 
"https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d";
   integrity sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=
 
+lodash.throttle@^4.1.1:
+  version "4.1.1"
+  resolved 
"https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4";
+  integrity 
sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==
+
 lodash.truncate@^4.4.2:
   version "4.4.2"
   resolved 
"https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193";
@@ -8480,6 +8493,14 @@ react-json-view@^1.21.3:
     react-lifecycles-compat "^3.0.4"
     react-textarea-autosize "^8.3.2"
 
+react-lazy-load-image-component@^1.5.4:
+  version "1.5.4"
+  resolved 
"https://registry.yarnpkg.com/react-lazy-load-image-component/-/react-lazy-load-image-component-1.5.4.tgz#e75b6520c972b6278a9811876716cdab56e401fb";
+  integrity 
sha512-PSi9tckzZmiqfYZwS6ke2RoRbICsN5m0qsG6fEjUdQNe5STiJieXLlRuGD3uAASOQPFiKYFSLoueN07nk0uffw==
+  dependencies:
+    lodash.debounce "^4.0.8"
+    lodash.throttle "^4.1.1"
+
 react-lifecycles-compat@^3.0.4:
   version "3.0.4"
   resolved 
"https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362";
@@ -9817,7 +9838,7 @@ [email protected], style-to-object@^0.3.0:
   dependencies:
     inline-style-parser "0.1.1"
 
-styled-components@^5.3.3:
+styled-components@^5, styled-components@^5.3.3:
   version "5.3.5"
   resolved 
"https://registry.yarnpkg.com/styled-components/-/styled-components-5.3.5.tgz#a750a398d01f1ca73af16a241dec3da6deae5ec4";
   integrity 
sha512-ndETJ9RKaaL6q41B69WudeqLzOpY1A/ET/glXkNZ2T7dPjPqpPCXXQjDFYZWwNnE5co0wX+gTCqx9mfxTmSIPg==

Reply via email to