This post is simultaneously posted on my Github personal blog

preface

If your project is using React-Toastify, check out this article. A problem I recently discovered with WebPack-bundle-Analyzer is that there are only certain pages where pop-ups can be used, such as when you click on favorites. But by packaging the results and running them, every page, whether used or not, starts with React-Toastify.

The use of the react – toastify

If you open it up at Github, here’s how it works:

import React from 'react';

import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';

function App(){
    const notify = () = > toast("Wow so easy!");

    return (
      <div>
        <button onClick={notify}>Notify!</button>
        <ToastContainer />
      </div>
    );
}
Copy the code

If the data flow is used in multiple places or needs to be controlled throughout the project, one approach is often to pull it over to Redux management, which in our case becomes

app.tsx

// Encapsulates logic and returns 
      
import Toast from "src/containers/Toast";

const { noToast } = this.props

return (
    / *... * /{! noToast &&<Toast />})Copy the code

The project uses next.js

Each of our pages/ pages has introduced the app. TSX public file. In the above code, Toast is a Toast component encapsulated by Redux, etc. It can be seen roughly from the above code that if noToast attributes are passed into the app. TSX component of each page, Then
will not be loaded and no pop-ups will appear when calling the Toast method.

This code was several years ago, presumably with the intention of importing it by default. Assuming that you really don’t need popup boxes on your page, you will upload the noToast attribute. However, I searched the whole project, and only one place used the noToast attribute, so this attribute is not known by the person who takes over later, so it will not be manually passed in the noToast attribute. React-toasify was introduced on every page

To use the toast method, the page must have
mounted before the pop-up box can be displayed

Existing problems

  1. We only click “Favorites” on the page details page, there will be a popbox (usereact-toastify), none of the other pages. But each page loads the chunk package
  2. The toast method used in the project is triggered by Redux, throughuseUpdateEffectListen globally

src/containers/Toast.tsx

useUpdateEffect(() = > {
  // toastProp is obtained from redux
  if (toastProp.message || toastProp.errors) notify(toastProp); // call toast in notify
}, [notify, toastProp]);
Copy the code

To optimize the

  1. Not every page, but the pages you use
  2. It is best to use the page, did not click when loading, such as only click favorites, to letreact-toasifyLoad.

This brings to mind dynamic imports, where react-Toastify is no longer needed in app.tsx judgment, as it encapsulates a component

import { ToastContent, ToastOptions } from "react-toastify";
		
// Dynamic import./Toastify is packaged Toastify
export const toastify = () = > import("./Toastify");
				
export const toast = (message: ToastContent, toastOptions? : ToastOptions) = > {	
  return toastify().then((toast) = > {	
    toast.showToast(message, toastOptions);	
  });		
};
Copy the code

The above effect is:

// before
import { toast } from "./toastify";
toast("Hello World");

// after
import("./toastify").then(module= > {
  module.toast("Hello World");
});
Copy the code

Now look at this file./Toastify. TSX (omits a lot of code…)


const setupToastContainer = () = > {
  if(! hasToastContainer) { hasToastContainer =true;
    // Add a div to the root HTML with the id root-toastify
    ReactDOM.render(
      <>
        <ToastGlobalStyle />
        <ToastWrapper/>
      </>.document.getElementById("root-toastify")); }};export const showToast = (message, toastOptions = {}) = > {
  setupToastContainer();
  toast(message, toastOptions);
};
Copy the code

The Redux dependency is eliminated, and the React-Toastify chunk package only loads when you click, not when you start loading, so the optimized result is that each page is packaged with 15-20K+ less compression.

This time I am a little lazy to write this article, because this is only one of the small points of the project optimization, I did not record the optimization point before, this time I will immediately review, the above code may look a little confused, did not release the complete code and do a Demo.

But that’s okay, because I found a complete PR example on Github for enhancement: Move React-Toastify to its own bundle, which is the same dynamic import of React-Toastify.


  • Ps:
    • Personal tech blog Github repository