IBM Security MaaS360

 View Only

Webpack Wizardry: Unraveling React Optimization Magic

By B S Sachin posted 17 days ago

  

What is Webpack?

Webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.

Why to use Webpack?

Webpack addresses several challenges in modern web development. The problem includes managing numerous interdependent JavaScript modules, dealing with diverse assets like CSS and images, optimizing code for production, and ensuring efficient development workflows. Webpack's solutions involve bundling modules into optimised bundles, enabling code splitting for on-demand loading, using loaders to process various assets, providing a development server for live reloading, optimising and minifying code for production, and seamlessly integrating with the broader front-end ecosystem. Overall, webpack streamlines the complexities of managing, optimising, and deploying front-end code in large and sophisticated web applications.

Core Concepts of Webpack

To get started you only need to understand the following Core Concepts:

  • Entry
  • Output
  • Loaders
  • Plugins
  • Mode

Entry

The entry point in Webpack serves as the starting point for constructing its internal dependency graph. It guides Webpack in determining the modules and libraries that the specified entry module relies on, both directly and indirectly. While the default entry point is typically set to ./src/index.js, developers have the flexibility to designate an alternative or multiple entry points by configuring the entry property within the webpack configuration.

What does this do? We are telling webpack that we would like 2 separate dependency graphs.

Output

The output property in webpack directs the bundling tool on where to place the generated bundles and how to name these files. By default, it assigns ./dist/main.js for the primary output file and utilises the ./dist folder for any additional generated files. This behaviour can be customised to meet specific requirements by defining an "output" field within your webpack configuration.

What does this do? With this configuration, webpack will generate two separate bundles: app.js and search.js. Each bundle corresponds to a specific entry point, allowing you to control and manage different parts of your application separately. This is particularly useful for optimizing code splitting and improving performance by loading only what's necessary for a given part of your application.

Loaders

Loaders serve as transformations applied to a module's source code, allowing preprocessing of files during import or loading. Comparable to tasks in other build tools, loaders provide an effective mechanism for handling front-end build steps. They can convert files from diverse languages, like TypeScript, to JavaScript, or load inline images as data URLs. Additionally, loaders enable tasks such as importing CSS files directly from JavaScript modules, enhancing flexibility in managing different types of assets in a web development workflow.

What does this do? We are instructing webpack to utilise the specified loaders in sequence for processing css files, ultimately bundling and dynamically injecting the resulting styles into the DOM during runtime.

Plugins

A plugin is a JavaScript object that can be applied to the entire build process to perform a wide range of tasks. Plugins enhance and extend the capabilities of Webpack by executing actions or transformations on the bundled code at different stages of the build lifecycle. They can be used to optimise code, inject environment variables, generate HTML files, extract and minify CSS, and perform various other tasks.

What does this do? The ProgressPlugin allows customisation of the progress reporting during compilation, while HtmlWebpackPlugin is employed to generate an HTML file. This HTML file includes the app.js file via a script tag.

Mode

The mode configuration option in Webpack, set to either 'development or production, tailors the build process, optimising for features like enhanced debugging and faster builds in development, and code minification and performance improvements for production.

Advanced Features

Having delved into the core concepts of webpack, let's now explore the transformative capabilities of code splitting and lazy loading. These advanced features open doors to dynamic performance enhancements, allowing your application to load and prioritise resources intelligently, resulting in a faster and more efficient user experience.

Code Splitting

Webpack's code splitting, a standout feature, enables the division of code into distinct bundles that can be loaded on demand or concurrently. This functionality not only facilitates the creation of smaller bundles but also provides control over the prioritisation of resource loading, offering a significant potential impact on overall load times when implemented effectively.

In the above project, where distinct components app and search cater to different workflows, we can leverage webpack's configurability to bundle them separately.
What does it do? This webpack configuration ensures that the app and search components are bundled independently, optimizing the load size for their respective workflows.

Lazy Loading

Lazy loading, also known as "on-demand" loading, proves to be a valuable strategy for optimizing websites or applications. The fundamental idea revolves around breaking down your code into logical segments and deferring their loading until a user action necessitates, or is anticipated to necessitate, a specific block of code. By adopting this approach, the initial application load is expedited, and the overall payload is reduced. This is particularly beneficial as certain code blocks may never be loaded unless explicitly required, contributing to a more streamlined and responsive user experience.

The before code directly imports Search, while the after code uses React's lazy function and dynamic import to asynchronously load Search only when it's needed.
What does it do? Suspense component is utilised to handle the asynchronous loading of lazy components, with the specified fallback content <div>Loading...</div> displayed while the Search component, a lazy-loaded component, is being loaded.

Outcomes from Applied Strategies

Our React library's bundle size and performance became unwieldy as we incorporated new workflows. Addressing this concern, we devised a plan to optimize the bundle and reduce its size. The image below illustrates our bundle size, which was approximately 9MB.

We have been proactively optimising the performance of our bundles, undertaking significant refactoring and restructuring of the entire React repository. This along with the introduction of code splitting and other optimisation techniques significantly reduced bundle sizes, decreasing them from 9MB to around 1MB per bundle. Cut down browser load times from 2 seconds to a swift 150 milliseconds. The optimisation efforts resulted in an outstanding 90% reduction in both bundle size and browser load time for the workflows.

0 comments
60 views

Permalink