refactor: optimize component rendering with memoization and improve state management
- Added memoization to ChatHistoryPanel, ChatMessageList, and TaskBoard components to prevent unnecessary re-renders. - Refactored HomePage to utilize useMemo for derived state calculations, enhancing performance. - Updated main.tsx to conditionally render React.StrictMode based on the environment. - Improved chat and channel store hooks to allow for selector functions, enhancing flexibility in state selection. - Enhanced streaming message handling in chat store to manage pending deltas more effectively. - Refactored LoginPage to include animated decorations for improved user experience. - Implemented lazy loading for routes in the router to optimize initial load time.
This commit is contained in:
@@ -43,6 +43,7 @@ export default function LoginPage() {
|
||||
const [form, setForm] = useState<LoginFormValues>(INITIAL_FORM);
|
||||
const [errors, setErrors] = useState<FormErrors>({});
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
const [showDecorations, setShowDecorations] = useState(false);
|
||||
|
||||
const captchaUrl = useMemo(
|
||||
() => (form.randomStr ? getCaptchaImageUrl(form.randomStr) : ''),
|
||||
@@ -50,7 +51,14 @@ export default function LoginPage() {
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setForm((current) => ({ ...current, ...createCaptchaState() }));
|
||||
const frameId = window.requestAnimationFrame(() => {
|
||||
setShowDecorations(true);
|
||||
setForm((current) => ({ ...current, ...createCaptchaState() }));
|
||||
});
|
||||
|
||||
return () => {
|
||||
window.cancelAnimationFrame(frameId);
|
||||
};
|
||||
}, []);
|
||||
|
||||
function refreshCaptcha(clearSubmitError = true): void {
|
||||
@@ -123,20 +131,25 @@ export default function LoginPage() {
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex h-screen flex-col"
|
||||
style={{
|
||||
backgroundImage: `url(${loginBackground})`,
|
||||
backgroundSize: '100% 100%',
|
||||
backgroundPosition: '0 0',
|
||||
backgroundRepeat: 'no-repeat',
|
||||
}}
|
||||
className="relative flex h-screen flex-col overflow-hidden bg-[linear-gradient(135deg,#eef5ff_0%,#f8fbff_42%,#ffffff_100%)] dark:bg-[#111214]"
|
||||
>
|
||||
{showDecorations ? (
|
||||
<img
|
||||
aria-hidden="true"
|
||||
alt=""
|
||||
className="pointer-events-none absolute inset-0 h-full w-full object-cover"
|
||||
decoding="async"
|
||||
fetchPriority="low"
|
||||
src={loginBackground}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
<TitleBar variant="light" />
|
||||
|
||||
<main
|
||||
className={['box-border flex flex-auto pl-2 pr-2 pb-2', platform !== 'linux' ? 'pt-2' : 'pt-11'].join(' ')}
|
||||
className={['relative z-10 box-border flex flex-auto pl-2 pr-2 pb-2', platform !== 'linux' ? 'pt-2' : 'pt-11'].join(' ')}
|
||||
>
|
||||
<div className="box-border w-[836px] rounded-2xl border border-black/5 bg-white p-8 shadow-[0_18px_50px_rgba(15,23,42,0.12)] dark:border-[#2a2a2d] dark:bg-[#1b1b1d]">
|
||||
<div className="box-border w-[836px] rounded-2xl border border-black/5 bg-white/95 p-8 shadow-[0_18px_50px_rgba(15,23,42,0.12)] backdrop-blur-sm dark:border-[#2a2a2d] dark:bg-[#1b1b1d]/95">
|
||||
<div className="flex items-center">
|
||||
<img className="h-12 w-12" src={blueLogo} alt="zn-ai" />
|
||||
</div>
|
||||
@@ -241,7 +254,17 @@ export default function LoginPage() {
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<img className="ml-2 w-[540px] max-w-[48vw] self-center object-contain" src={loginIllustration} alt="" />
|
||||
{showDecorations ? (
|
||||
<img
|
||||
aria-hidden="true"
|
||||
alt=""
|
||||
className="ml-2 w-[540px] max-w-[48vw] self-center object-contain"
|
||||
decoding="async"
|
||||
fetchPriority="low"
|
||||
loading="eager"
|
||||
src={loginIllustration}
|
||||
/>
|
||||
) : null}
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user