Tối ưu hóa Next.js App Bundle và cải thiện hiệu suất của nó

Tối ưu hóa Next.js App Bundle và cải thiện hiệu suất của nó

Trong bài viết này, chúng ta sẽ tìm hiểu cách tối ưu hóa ứng dụng Next.js ( liên kết đến ứng dụng ) bằng cách giảm 43% kích thước gói và tăng điểm số lên 73 từ 36 trong Thông tin chi tiết về tốc độ trang của Google .

Hãy bắt đầu với việc phân tích bản dựng sản xuất của Next.js. Khi chúng tôi thực thi  npm run build , Next.js cung cấp cho chúng tôi thống kê về bản dựng sản xuất. Nó chỉ định kích thước của các trang và khối sẽ được gửi tới trình duyệt.

Next.js tạo các tệp phổ biến và sẽ được chia sẻ trên các trang. Các tệp này được gọi là JS tải đầu tiên. Các tệp JS tải đầu tiên chứa mã khung và mã được nhiều trang sử dụng.

Nếu thành phần này sử dụng lại hơn 50% số tệp, thì Next.js sẽ bao gồm thành phần đó trong JS tải đầu tiên. Chúng tôi không thể thay đổi hành vi này, nhưng chúng tôi có thể tối ưu hóa mã của mình.

Sau đây là đầu ra của lệnh  npm run build  và điểm Google PageSpeed ​​Insights. Như bạn có thể thấy, kích thước của các tệp có màu đỏ và vàng. Mục tiêu của chúng tôi là làm cho chúng có màu xanh.

Optimize Next JS

Next js và Google DEV

Đi nào.

Phân tích JS tải đầu tiên

Chúng tôi bắt đầu bằng cách phân tích và xác định các gói có trong First Load JS. Để tìm thấy điều đó, chúng ta cần cài đặt các phụ thuộc dev sau.

npm install save-dev @next/bundle-analyzer cross-env

Sau khi cài đặt, hãy thêm đoạn mã sau vào  package.json  bên dưới  scripts .

"scripts" : { "analyze" : "cross-env ANALYZE=true next build" , "analyze:server" : "cross-env BUNDLE_ANALYZE=server next build" , "analyze:browser" : "cross-env BUNDLE_ANALYZE=browser bản dựng tiếp theo" }, 
     
     
     
  

Thêm đoạn mã sau vào next.config.js. Nếu bạn không có tệp này, thì hãy tạo nó trong thư mục gốc của dự án của bạn.

const withBundleAnalyzer = yêu cầu ( '@next/bundle-analyzer' )({ 
    enable : process . env . ANALYZE === 'true' })  

  
mô-đun . export = withBundleAnalyzer ({ 
    env : { 
        NEXT_PUBLIC_ENV : 'PRODUCTION' , //cấu hình tiếp theo của bạn ở đây }, })   
    

Tiếp theo, thực hiện lệnh này  npm run analytics , lệnh này sẽ mở hai tab mới trong trình duyệt của bạn bằng các biểu đồ. Tập trung vào  biểu đồ client.html  .

Sau đó, thay thế các thư viện lớn hơn bằng các thư viện nhỏ hơn, tương đương và xóa các thư viện không liên quan. Để thay thế bất kỳ thư viện nào, hãy truy cập  https://bundlephobia.com/ , xem kích thước thư viện của bạn và kiểm tra xem bạn có bất kỳ lựa chọn thay thế nào với kích thước nhỏ hơn không. Nếu không, hãy thử viết mã tùy chỉnh của riêng bạn. Trong bản trình diễn này:

  • Chúng tôi đã xóa thư viện js-cookie  dùng để đọc và ghi cookie và thay thế bằng mã tùy chỉnh.
  • Chúng tôi đã thay thế thư viện framer-motion  bằng react-transition-group vì nó nhỏ hơn 10 lần.
  • Thay vì sử dụng  react-gpt , được sử dụng để hiển thị quảng cáo của Google, chúng tôi đã tạo thành phần quảng cáo tùy chỉnh của riêng mình (thông tin chi tiết sau).
  • Chúng tôi đã chuyển  tệp khoảnh khắc  sang phía máy chủ từ máy khách, vì kích thước của khoảnh khắc  lớn. Bằng cách này, chúng tôi có thể gửi ngày được định dạng từ API hoặc định dạng ngày ở phía máy chủ, như sau.
xuất chức năng không đồng bộ getServerSideProps ( ngữ cảnh ) { const moment = ( đang chờ nhập ( 'khoảnh khắc' )). mặc định (); // phương pháp mặc định là truy cập xuất khẩu mặc định return { 
    date : moment . định dạng ( 'dddd D MMMM YYYY' ), } }   
     
   
  

Bây giờ ngày này sẽ được gửi dưới dạng chỗ dựa cho thành phần, có thể được sử dụng (getServerSideProps chỉ có thể được sử dụng trong các trang không nằm trong thành phần) . Bây giờ,  momentjs  sẽ không được gửi tới trình duyệt.

Nhập động

Các thành phần không hiển thị trong lần tải đầu tiên của trang và các thành phần được hiển thị dựa trên các điều kiện nhất định phải được nhập động thay vì thông thường. Điều này đảm bảo rằng các thành phần này chỉ được gửi đến trình duyệt khi cần thiết. Tham khảo ví dụ mã sau đây.

nhập động từ 'tiếp theo/động'   

const Modal = dynamic (() => import ( '../components/header' ));     

xuất hàm mặc định Home () { return ( { showModal && < Modal />} ) }    
   
      
  

Mở tab Mạng. Khi điều kiện được đáp ứng, bạn sẽ thấy một yêu cầu mạng mới được thực hiện để tìm nạp thành phần động (nhấp vào nút để mở phương thức).

Lazy load ảnh sử dụng next/image

Next.js có một thành phần tích hợp có tên  next/image . Nó chỉ tải hình ảnh khi chúng ở trong chế độ xem.

nhập Hình ảnh từ "tiếp theo/hình ảnh" ;   

const Index = () => { return ( <> <p> Tên miền bên ngoài phải được định cấu hình trong < Code > next . config . js </ Code > bằng 
        thuộc tính < Code > tên miền </ Code > . < / p > < Hình ảnh 
        alt = "Logo Next.js" 
        src =     
   
    
      
           
      
      "https://assets.vercel.com/image/upload/v1538361091/repositories/next-js/next-js-bg.png" 
        width ={ 1200 } 
        height ={ 400 } /> </> ); };
      
    
  

Quảng cáo Google lười tải

Tập lệnh Google Ads thường chặn chuỗi chính, vì vậy chúng tôi sẽ tải tập lệnh tám giây sau khi tải trang. Ban đầu, chúng tôi sử dụng  gói react-gpt  để tải tập lệnh Google Ads. Chúng tôi sẽ thay thế điều đó bằng mã tùy chỉnh được tối ưu hóa của chúng tôi.

Đối với điều này, chúng tôi đã tạo một hook tùy chỉnh để chèn bất kỳ tập lệnh nào. Nó sẽ trả về trạng thái tùy thuộc vào trạng thái tiêm khi tập lệnh Google Ads được đưa vào. Khi nó  sẵn sàng trở lại , chúng tôi sẽ chạy mã Quảng cáo.

nhập Phản ứng từ "phản ứng" ;   

const useScript = ( src , delay = null ) => { const [ status , setStatus ] = React . useState ( src ? "đang tải" : "nhàn rỗi" );    
        

  Phản ứng . useEffect (() => { if (! src ) { 
      setStatus ( "idle" ); return "idle" ; }  
      
       
    

    hãy để tập lệnh = tài liệu . querySelector ( `script[src="${src}"]` ); để hết thời gian = null ;
     

    if (! script ) { if ( delay ) { 
        timeout = setTimeout (() => { 
          injectScript (); // Thêm trình xử lý sự kiện sau khi script được thêm 
          script . addEventListener ( "load" , setStateStatus ); 
          script . addEventListener ( " lỗi" , setStateStatus ); }, chậm trễ ); } khác { 
        tiêmScript ();  
          
          
        
        
      } } 
      other { setStatus ( script . getAttribute ( "data-status" )); }
      
    

    const setStateStatus = ( event ) => { 
      setStatus ( event . type === "load" ? "ready" : "error" ); };        
    

    // mã để tiêm script function injectScript () { 
      script = document . createElement ( "tập lệnh" ); 
      kịch bản . src = src ; 
      kịch bản . không đồng bộ = đúng ; 
      kịch bản . setAttribute ( "trạng thái dữ liệu" , "đang tải" ); 
      tài liệu . cơ thể . appendChild ( tập lệnh );
        

      const setDataStatus = ( sự kiện ) => { 
        tập lệnh . setAttribute ( "data-status" , event . type === "load" ? "ready" : "error" ); };   
          
               
        
      

      kịch bản . addEventListener ( "tải" , setDataStatus ); 
      kịch bản . addEventListener ( "lỗi" , setDataStatus ); }
    

    if ( script ) { //script sẽ không được xác định có sẵn khi nó bị trì hoãn do đó hãy kiểm tra nó trước khi thêm 
      tập lệnh nghe . addEventListener ( "tải" , setStateStatus ); 
      kịch bản . addEventListener ( "lỗi" , setStateStatus ); }  
      
    

    return () => { if ( script ) { 
        script . removeEventListener ( "tải" , setStateStatus ); 
        kịch bản . removeEventListener ( "lỗi" , setStateStatus ); } nếu ( hết thời gian ) { 
        clearTimeout ( hết thời gian ); } }; }, [ src ]);   
        
      
        
      
    
   

  trả lại trạng thái ; };
xuất useScript mặc định ; 

Sử dụng hook này trong  pages/index.js .

const MyApp = () => { const status = useScript ( script , 8000 ); trả về ( <> <p> Trạng thái chính : { trạng thái }</ p > { trạng thái === ' nhàn rỗi ' && < Quảng cáo />} </> ); };     
   
   
    
       
          
    
  

Nếu bạn muốn tạo một thành phần quảng cáo tùy chỉnh như thế này thì hãy làm theo  bài viết này .

Bạn cũng có thể lười tải các tập lệnh khác như tập lệnh Google Analytics.

Nhập khẩu cụ thể

Nếu bạn đang sử dụng các thư viện như  lodash  và  date-fn , chúng ta có thể dễ dàng giảm kích thước gói bằng cách chỉ nhập các chức năng cụ thể thay vì nhập đầy đủ, như thế này.

// Nhập cũ _get từ ' lodash '
 

// Nhập mới _get từ ' lodash / get '
 

Chúng tôi có thể tối ưu hóa việc sử dụng nhiều thư viện khác. Để biết thêm chi tiết,  hãy xem bài viết này . Đừng quên xóa các mục nhập không sử dụng khỏi dự án.

Tối ưu hóa tiếp theo/liên kết

Nếu bạn đang sử dụng  next/link  trong dự án của mình, hãy thêm chỗ dựa tìm nạp trước vào nó và đặt thành false. Next.js theo mặc định tìm nạp trước các trang có liên kết trong chế độ xem. Giả sử bạn có một tiêu đề với hai liên kết  ‘/home’  và  ‘/about’ . Ngay cả khi người dùng đang ở trên trang chủ, nội dung của trang giới thiệu cũng sẽ được tải vì liên kết giới thiệu có thể được nhìn thấy trong chế độ xem.

Khi tìm nạp trước được đặt thành  false , quá trình tìm nạp trước sẽ vẫn diễn ra nhưng chỉ khi liên kết được di chuột qua.

<li> <Link href = "/about" prefetch = {false} > <a> Giới thiệu về chúng tôi </a> </Link> </li> <li> <Link href = "/blog/hello-world" prefetch = {false} > >
		 <a> Bài đăng blog </a> </Link> </li>
	  
		
    


	  
    

Tối ưu hóa phông chữ

Khi chúng tôi sử dụng các thư viện biểu tượng như  font-awesome , chúng tôi chỉ sử dụng tối đa 15 biểu tượng nhưng toàn bộ thư viện đã được tải. Vấn đề là nó là tài nguyên chặn hiển thị. Vì vậy, thay vì tải toàn bộ thư viện, bạn chỉ cần tải xuống các biểu tượng cần thiết dưới dạng tệp SVG và sử dụng chúng. Bạn cũng có thể lười tải những hình ảnh SVG này.

Bạn cũng có thể sử dụng  font-display: swap;  cho phông chữ của bạn vì nó không chặn kết xuất. Thay vào đó, mặt phông chữ được cung cấp một khoảng thời gian hoán đổi vô hạn và một khoảng thời gian khối tối thiểu.

@ phông chữ - mặt { 
  phông chữ - gia đình : Ví dụFont ; 
  src : url ( /path/ đến / fonts / examplefont . woff ) định dạng ( 'woff' ), 
       url ( /path/ đến / fonts / examplefont . eot ) định dạng ( 'eot' ); 
  phông chữ - trọng lượng : 400 ; kiểu 
  chữ _  : bình thường ; 
  phông chữ - hiển thị : trao đổi ; }

Nếu bạn đang sử dụng Google Fonts trực tiếp từ liên kết, thì hãy tải xuống phông chữ và tự lưu trữ chúng.

Các thành phần React tải chậm (tùy chọn)

Chúng tôi cũng chỉ có thể tải một thành phần khi nó ở trong chế độ xem bằng cách sử dụng  thư viện react-lazyload  , thư viện này cũng hỗ trợ SSR. Chúng tôi cũng có thể cung cấp phần bù, vì vậy người dùng sẽ không biết về hành vi tải chậm này.

nhập LazyLoad từ 'Reac-lazyload' ;   

< LazyLoad offset ={ 100 }> < Footer /> </ LazyLoad >
     

Loại trừ các thư viện lớn khỏi gói

Như tôi đã thảo luận trước đó, các thư viện được thêm vào First Load JS. Trong dự án của chúng tôi, chúng tôi đang sử dụng  thư viện Biểu đồ đồng bộ hóa  trên nhiều trang, do đó,  thư viện biểu đồ đồng bộ  hóa được gộp vào lần tải đầu tiên.

Các trang không sử dụng  biểu đồ  Đồng bộ hóa cũng đang tải thư viện biểu đồ Đồng bộ hóa  , vì nó đã được thêm vào First Load JS hoặc gói chính. Để tối ưu hóa nó, chúng tôi đã theo dõi bài viết tuyệt vời này của Robert S về  cách loại trừ các thư viện lớn .

Nguồn: https://www.syncfusion.com/blogs/post/optimize-next-js-app-bundle-improve-its-performance.aspx

Bài viết liên quan

2023.02.08
Quảng cáo trong game trong game trên mobile: Lợi ích, chiến lược và các ví dụ điển hình

GIỚI THIỆU Quảng cáo trong Game trong Game di động là gì? Quảng cáo trong Game là chiến lược doanh […]

2023.02.01
Các phương pháp hàng đầu để phát triển phần mềm năm 2023

Phát triển phần mềm là một ngành công nghiệp không ngừng phát triển. Cách bạn phát triển phần mềm vào năm […]

2023.01.16
Xu hướng phát triển game mobile năm 2023

Khi bước sang năm 2023, chúng tôi mong đợi những xu hướng và đổi mới mới trong lĩnh vực phát […]

2022.12.23
13 xu hướng phát triển web cho năm 2023

Các nhà phát triển web chịu trách nhiệm phát triển mã cho các trang web biết cách hoạt động. Điều này […]

2022.12.21
Có gì mới trong Strapi V4 – Tính năng, Cải tiến và Migration

Strapi phiên bản 4 mang đến nhiều cải tiến hơn nữa cho danh sách giao diện người dùng và chức […]

2022.12.06
Trí tuệ nhân tạo (AI) để hỗ trợ khách hàng và tại sao bạn cần nó

Sự phát triển của Trí tuệ nhân tạo (AI) đang tạo tiền đề cho việc tăng hiệu quả giữa các […]

Giới thiệu

Chúng tôi có kinh nghiệm trong phát triển các dự án E-commerce, phần mềm quản lý, Mobi app, các dự án outsource. Với những công nghệ mới nhất hiện nay.

Tìm kiếm