首页 >web前端 >js教程 >快速优化您的 ReactJS 应用程序的性能和大小

快速优化您的 ReactJS 应用程序的性能和大小

Linda Hamilton
Linda Hamilton原创
2024-12-10 20:13:10740浏览

React 被大量用于前端密集型应用程序,具有其独特的性能和尺寸优化方式。改进两者将对 React 包大小产生相当大的可衡量的影响。考虑到我们专注于客户端渲染的应用程序,包大小越小,加载时间越快。

服务器端渲染将进一步缩短加载时间。在服务器端渲染中,当用户请求网页时,React 组件将在服务器本身中渲染为 HTML 代码。然后这个预渲染的页面被发送到浏览器,让用户立即看到页面,而无需 JS 加载时间的开销。

但这完全是一个不同的故事。让我们主要关注通过在代码中进行调整来改善包包大小来尝试改进客户端呈现的站点。让我们深入探讨一下。

1. 代码分割和动态导入

React 代码的“捆绑”是跟踪所有导入和代码并将其组合成一个名为“Bundle”的单个文件的过程。 Webpack、Browserify 等已经为我们做到了这一点。

Webpack 有一个名为“代码分割”的功能,负责将单个包分割成更小的块,对块进行重复数据删除,并“按需”导入它们。这会显着影响应用程序的加载时间。

module.exports = {
  // Other webpack configuration options...
  optimization: {
    splitChunks: {
      chunks: 'all', // Options: 'initial', 'async', 'all'
      minSize: 10000, // Minimum size, in bytes, for a chunk to be generated
      maxSize: 0, // Maximum size, in bytes, for a chunk to be generated
      minChunks: 1, // Minimum number of chunks that must share a module before splitting
      maxAsyncRequests: 30, // Maximum number of parallel requests when on-demand loading
      maxInitialRequests: 30, // Maximum number of parallel requests at an entry point
      automaticNameDelimiter: '~', // Delimiter for generated names
      cacheGroups: {
        defaultVendors: {
          test: /[\/]node_modules[\/]/,
          priority: -10,
          reuseExistingChunk: true,
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true,
        },
      },
    },
  },
};

使用 React Suspense 延迟加载组件 (React 18):与动态导入相结合将显示组件加载时间的明显改进。

通常,当我们在父组件中导入子组件时,我们是静态导入的。为了防止在我们实际必须渲染它之前导入该组件,我们可以将动态导入与 React Suspense 结合使用。 React Suspense 可以按需加载组件。它显示了 Fallback UI,同时动态导入然后渲染相应的组件。

import { lazy } from 'react';

// The lazy loaded Component has to be exported as default
const BlogSection = lazy(() => import('./BlogSection.tsx'));

export default function HomePage() {
  return (
    <>
      <Suspense fallback={<Loading />}>
        <BlogSection />
      </Suspense>
    </>
  );
}

function Loading() {
  return <h2>Component is Loading...</h2>;
}

2. 摇树

这是 JavaScript 捆绑程序使用的一种技术,用于在创建捆绑包之前删除所有未使用的代码。 ES6代码可以进行tree-shaking;但是,基于 CommonJS 的代码(即使用“require”)不能进行 tree-shaken。

Webpack Bundle Analyzer 是一个插件,可帮助您通过交互式地图可视化 Webpack 的大小。

npm install --save-dev webpack-bundle-analyzer
npm install -g source-map-explorer

然后配置您的 webpack 以将上述内容添加为插件:

plugins: [
  new BundleAnalyzerPlugin(),
  new HtmlWebpackPlugin({
    template: './public/index.html', // Path to your HTML template
    filename: 'index.html', // Output HTML file name
    inject: true, // Inject all assets into the body
  }),
];

确保您的脚本配置为运行 Webpack:

"build": "webpack --config webpack.config.js --mode production"

运行yarn build来生成report.html,它将帮助您有效地可视化您的包大小。

它看起来像这样:

Quick Optimization for your ReactJS Application for Performance and Size

3. 并发渲染

让我们首先了解什么是阻塞渲染。阻塞渲染是指主线程(UX 更新)被阻塞,因为 React 在后台执行一些不太重要的任务。 React 16 之前都是这种情况。

React 18 引入了并发功能,这意味着它将:

  • 让您更好地控制后台更新的安排方式,并通过不阻塞主线程来创建流畅的最终用户体验。
  • 启动状态更新的自动批处理:批处理是指将由于多次状态更新而导致的多次重新渲染进行分组,使得状态只更新一次。

使用 startTransition() 钩子将 React 更新视为非紧急更新,帮助 React 优先考虑紧急更新,例如用户输入和用户与组件的交互。

module.exports = {
  // Other webpack configuration options...
  optimization: {
    splitChunks: {
      chunks: 'all', // Options: 'initial', 'async', 'all'
      minSize: 10000, // Minimum size, in bytes, for a chunk to be generated
      maxSize: 0, // Maximum size, in bytes, for a chunk to be generated
      minChunks: 1, // Minimum number of chunks that must share a module before splitting
      maxAsyncRequests: 30, // Maximum number of parallel requests when on-demand loading
      maxInitialRequests: 30, // Maximum number of parallel requests at an entry point
      automaticNameDelimiter: '~', // Delimiter for generated names
      cacheGroups: {
        defaultVendors: {
          test: /[\/]node_modules[\/]/,
          priority: -10,
          reuseExistingChunk: true,
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true,
        },
      },
    },
  },
};

在这个例子中,当输入值改变时,handleChange函数被调用。 startTransition 函数用于将对列表状态的更新标记为非紧急。这允许 React 优先更新值状态,确保即使列表很大时输入也能保持响应。

使用 useDeferredValue 钩子推迟一个值(通常是昂贵的计算),直到 UI 不那么繁忙。

import { lazy } from 'react';

// The lazy loaded Component has to be exported as default
const BlogSection = lazy(() => import('./BlogSection.tsx'));

export default function HomePage() {
  return (
    <>
      <Suspense fallback={<Loading />}>
        <BlogSection />
      </Suspense>
    </>
  );
}

function Loading() {
  return <h2>Component is Loading...</h2>;
}

在此示例中,useDeferredValue 挂钩用于推迟值状态,直到 UI 不那么繁忙。这有助于通过将大列表的渲染推迟到处理输入更新之后来保持输入响应。

并发渲染的主要优点

  • 改进的响应能力:通过允许 React 中断渲染工作,UI 仍然可以响应用户交互。
  • 优先级:React 可以优先考虑紧急更新而不是非紧急更新,确保更流畅的用户体验。
  • 更好的性能:可以推迟昂贵的更新,减少对主线程的影响并提高应用程序的整体性能。

4.支持资源预加载(React 19)

如果您知道应用程序在加载过程中会获取任何大量资源,那么预加载资源是一个好主意。这些资源可以是字体、图像、样式表等

预加载有益的场景

  • 子组件将使用资源。在这种情况下,您可以在父组件的渲染阶段预加载它。
  • 在事件处理程序中预加载它,该事件处理程序会重定向到将使用此资源的页面/组件。事实上,这是比在渲染期间预加载更好的选择。
module.exports = {
  // Other webpack configuration options...
  optimization: {
    splitChunks: {
      chunks: 'all', // Options: 'initial', 'async', 'all'
      minSize: 10000, // Minimum size, in bytes, for a chunk to be generated
      maxSize: 0, // Maximum size, in bytes, for a chunk to be generated
      minChunks: 1, // Minimum number of chunks that must share a module before splitting
      maxAsyncRequests: 30, // Maximum number of parallel requests when on-demand loading
      maxInitialRequests: 30, // Maximum number of parallel requests at an entry point
      automaticNameDelimiter: '~', // Delimiter for generated names
      cacheGroups: {
        defaultVendors: {
          test: /[\/]node_modules[\/]/,
          priority: -10,
          reuseExistingChunk: true,
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true,
        },
      },
    },
  },
};

有趣的事实:实施预加载后,包括 Shopify、Financial Times 和 Treebo 在内的许多网站都发现以用户为中心的指标(例如交互时间和用户感知延迟)提高了 1 秒。


Quick Optimization for your ReactJS Application for Performance and Size

请留下反馈

我希望您觉得这个博客有帮助!您的反馈对我来说非常宝贵 ,所以请在下面的评论中留下您的想法和建议。

请随时在 LinkedIn 上与我联系以获取更多见解和更新。让我们保持联系,继续共同学习和成长!

以上是快速优化您的 ReactJS 应用程序的性能和大小的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn