Procházet zdrojové kódy

perf: 主页优化

BaiLuoYan před 3 týdny
rodič
revize
ba5415901e

+ 22 - 2
src/pages/home/components/Features.tsx

@@ -1,3 +1,4 @@
+import { useEffect, useRef } from 'react';
 import { useTranslation } from 'react-i18next';
 
 import { Icon } from '@iconify/react';
@@ -9,6 +10,22 @@ import Wrapper from './Wrapper';
 
 export function Features() {
     const { t } = useTranslation();
+    const scrollRef = useRef<HTMLDivElement>(null);
+
+    useEffect(() => {
+        const el = scrollRef.current;
+        if (!el) return;
+        const scrollToCenter = () => {
+            const { scrollWidth, clientWidth } = el;
+            if (scrollWidth > clientWidth) {
+                el.scrollLeft = (scrollWidth - clientWidth) / 2;
+            }
+        };
+        scrollToCenter();
+        const observer = new ResizeObserver(scrollToCenter);
+        observer.observe(el);
+        return () => observer.disconnect();
+    }, []);
 
     const items = [
         {
@@ -40,12 +57,15 @@ export function Features() {
                     </p>
                 </div>
             </Wrapper>
-            <div className="w-full sm:max-w-full sm:overflow-x-scroll sm:no-scrollbar">
+            <div
+                ref={scrollRef}
+                className="w-full sm:max-w-full sm:overflow-x-auto sm:overflow-y-hidden sm:no-scrollbar"
+            >
                 <Wrapper className="w-fit min-w-full flex flex-wrap sm:flex-nowrap items-stretch gap-8">
                     {items.map(({ titleKey, descKey, icon }, index) => (
                         <div
                             key={index}
-                            className="rounded-2xl border border-white/10 bg-white/5 sm:min-h-[246px] w-full sm:w-[406px] p-5 sm:p-8 shrink-0 flex flex-col"
+                            className="transition-all rounded-2xl border border-white/10 bg-white/5 sm:min-h-[246px] w-full sm:w-[406px] p-5 sm:p-8 shrink-0 flex flex-col"
                         >
                             <Icon
                                 icon={icon}

+ 21 - 1
src/pages/home/components/Pricing/index.tsx

@@ -1,3 +1,4 @@
+import { useEffect, useRef } from 'react';
 import { useTranslation } from 'react-i18next';
 import { useNavigate } from 'react-router-dom';
 
@@ -9,6 +10,22 @@ export function Pricing() {
     const { t } = useTranslation();
     const navigate = useNavigate();
     const { plans, selectedPlanId, setSelectedPlanId } = useService();
+    const scrollRef = useRef<HTMLDivElement>(null);
+
+    useEffect(() => {
+        const el = scrollRef.current;
+        if (!el) return;
+        const scrollToCenter = () => {
+            const { scrollWidth, clientWidth } = el;
+            if (scrollWidth > clientWidth) {
+                el.scrollLeft = (scrollWidth - clientWidth) / 2;
+            }
+        };
+        scrollToCenter();
+        const observer = new ResizeObserver(scrollToCenter);
+        observer.observe(el);
+        return () => observer.disconnect();
+    }, []);
 
     return (
         <section className="w-full pt-7 sm:pt-16 lg:pt-[176px]">
@@ -22,7 +39,10 @@ export function Pricing() {
                     </p>
                 </div>
             </Wrapper>
-            <div className="w-full sm:max-w-full sm:overflow-x-scroll sm:no-scrollbar py-4">
+            <div
+                ref={scrollRef}
+                className="w-full sm:max-w-full sm:overflow-x-auto sm:overflow-y-hidden sm:no-scrollbar py-4"
+            >
                 <Wrapper className="w-fit min-w-full flex flex-wrap sm:flex-nowrap items-stretch gap-8">
                     {plans.map((plan) => (
                         <PlanCard