Chào mọi người, thư viện Antd được sử dụng phổ biến trong tất cả các project hiện tại của công ty và đôi khi tích hợp nó vào trong các bộ source code và khởi chạy sẽ dẫn đến những xung đột về giao diện, làm giảm trải nghiệm người dùng đi khá nhiều và ngay cả đến khi mình dev và nhìn thấy cũng khá là ngứa mắt nên ngày hôm nay mình sẽ chỉ mọi người một tips để khắc phục được vấn đề này.
1. Hiện tượng Flickering là gì?
Hiện tượng “flickering” trong giao diện người dùng (UI) là khi các thành phần của giao diện xuất hiện và biến mất nhanh chóng hoặc không ổn định, gây ra sự khó chịu hoặc làm giảm trải nghiệm người dùng.
Khi tích hợp thư viện Ant Design (antd) vào dự án, flickering có thể xuất hiện do một số nguyên nhân sau:
- Xung đột CSS: Khi các quy tắc CSS trong Ant Design xung đột với quy tắc CSS hiện có trong dự án của bạn, có thể dẫn đến xung đột và hiện tượng flickering.
- Thời gian tải và hiển thị component: Nếu component của Ant Design mất thời gian để tải hoặc hiển thị, điều này có thể dẫn đến flickering khi giao diện chuyển từ trạng thái không có component này sang trạng thái có nó.
- Sự không ổn định của JavaScript: Nếu có lỗi JavaScript hoặc mã không ổn định trong dự án của bạn, đặc biệt là liên quan đến việc tương tác với các component của Ant Design, có thể gây ra flickering.
Hình 1: Hiện tượng flickering giao diện
Nhìn hình ảnh trên, chúng ta có thể thấy được mỗi lần reload lại trang thì giao diện đăng nhập khi sử dụng Antd sẽ bị nhấp nháy hay gọi là “flickering”, gây ra cảm giác trải nghiệm UX khá khó chịu.
Và sau đây, chúng ta sẽ cùng đến với cách khắc phục vấn đề nêu trên.
2. Cách khắc phục hiện tượng flickering trong Project nextJS
Trong dự án NextJs, tạo một file provider antd.registry.tsx với nội dung như sau:
'use client'; //Nếu dùng Nextjs14
import React from 'react';
import { createCache, extractStyle, StyleProvider } from '@ant-design/cssinjs';
import type Entity from '@ant-design/cssinjs/es/Cache';
import { useServerInsertedHTML } from 'next/navigation';
const StyledComponentsRegistry = ({ children }: React.PropsWithChildren) => {
const cache = React.useMemo<Entity>(() => createCache(), []);
const isServerInserted = React.useRef<boolean>(false);
useServerInsertedHTML(() => {
// avoid duplicate css insert
if (isServerInserted.current) {
return;
}
isServerInserted.current = true;
return <style id="antd" dangerouslySetInnerHTML={{ __html: extractStyle(cache, true) }} />;
});
return <StyleProvider cache={cache}>{children}</StyleProvider>;
};
export default StyledComponentsRegistry;
Chúng ta sẽ cùng đọc hiểu phần code ở trên xem chức năng của nó là gì nhé.
Thư viện @ant-design/cssinjs sử dụng phương pháp CSS-in-JS để tích hợp các kiểu CSS cho các thành phần của Ant Design vào dự án của mình thông qua mã Javascript thay vì phải tạo các tệp CSS riêng biệt. Có thể đọc thêm tại đây.
Bản chất của provider trên là tạo ra một cache các giá trị style của các thành phần trong Ant Design và chèn nó vào phần <Head> của HTML ngay khi mà server đang được render. Khi đó mỗi lần reload giao diện thì các thành phần của Ant Design được load ra ở phía client với style đã có sẵn trước đó (do được insert khi server rendering) nên tình trạng flickering sẽ không thể xảy ra nữa.
Bước cuối cùng, chúng ta cần bọc các thành phần giao diện của chúng ta vào provider trên như sau:
Với phiên bản NextJs 14, ta sẽ sử dụng provider trên trong file layout.tsx:
//Nextjs 14
import StyledComponentsRegistry from "@/providers/antd.registry";
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body>
<StyledComponentsRegistry>{children}</StyledComponentsRegistry>
</body>
</html>
);
}
Với phiên bản NextJs 13 trở về, ta sẽ sử dụng provider trên trong file pages/_app.tsx:
//NextJs 13
import React from 'react';
import StyledComponentsRegistry from "@providers/antd.registry";
import type { AppProps } from 'next/app';
const App = ({ Component, pageProps }: AppProps) => (
<StyledComponentsRegistry>
<Component {...pageProps} />
</StyledComponentsRegistry>
);
export default App;
Và kết quả nhận được:
Hình 2: Hiện tượng flickering giao diện đã không còn
Và bài viết của mình cũng xin kết thúc ở đây, hy vọng bài viết sẽ giúp ích được cho mọi người khi gặp tình huống tương tự như này. Cám ơn mọi người đã theo dõi ^^