代码拆分是一种技术,用于通过将捆绑的JavaScript文件分解为较小,更可管理的块来优化Web应用程序的加载性能。通过仅加载特定路由或页面所需的代码,基于路由的代码分裂大大减少了初始加载时间并改善了整体用户体验。
在本文中,我们将解释如何实现基于路由的代码分裂以及一些代码示例的某些方面。
为什么要基于路由的代码分裂?
开发大规模应用程序时,加载所有JavaScript代码的前期会导致初始加载时间增加,并对用户体验产生负面影响。相比之下,基于路由的代码拆分使您可以根据不同的路线或功能将应用程序分为较小的块。仅加载了与当前路线相关的代码,从而为特定页面提供更快的加载时间和更好的总体应用程序性能。
通过使用基于路由的代码拆分,您可以优先为每个路由的最关键代码,优化初始加载体验并减少交互时间(TTI)。
我们需要什么?
为了实际实现基于路由的代码拆分,我们需要使用两件事:
让我们更详细地看一下这些。
动态导入
动态导入是一种ECMAScript feature,它使我们可以即时导入模块。这确实很强大,除非您不幸足以支持IE,否则可以在所有major browsers中使用。
这是语法的样子:
import('./path-to-my-module.js');
import
将返回诺言,因此您将像应用程序中的任何其他承诺一样处理它。
import('./carModule.js')
.then(module => {
module.startEngine();
})
.catch(error => {
console.error('Error loading carModule:', error);
});
// or you can use async/await
const carModule = await import('./carModule.js');
carModule.startEngine();
一个很好的用例是,当您仅在应用程序的特定部分中使用重模块时。
<button onClick={onSortCarsClick}>Sort cars<button/>
function onSortCarsClick() {
// Load in the heavy module
const carModule = await import('./carModule.js');
carModule.sortCars();
}
react.lazy()
React.lazy()
是React中的一个函数,使您能够执行组件的“懒惰”或“按需”加载。它可以确保只有在实际渲染时才加载该组件。
在引入React.lazy()
之前,您可能需要设置更复杂的构建工具配置以实现相似的代码分配行为。使用React.lazy()
,此过程被简化并直接集成到React的核心中。
const MyLazyComponent = React.lazy(() => import('./MyComponent'));
悬念
由于该组件不再静态导入,因此我们需要在动态加载时显示某些内容。为此,我们使用React的<Suspense>
边界。
在下面的示例中,您会看到我们正在加载组件时显示一些后备UI。
<Suspense fallback={<div>Loading...</div>}>
<MyLazyComponent/>
</Suspense>
告诉我代码
这是一个完整的示例,说明我们如何使用动态导入,React.lazy()
和React路由器的组合来实现基于路由的代码分裂。
import { lazy, Suspense } from 'react';
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
// These components will only be loaded when they're actually rendered.
const Home = lazy(() => import('./components/Home'));
const About = lazy(() => import('./components/About'));
const Contact = lazy(() => import('./components/Contact'));
function App() {
return (
<Router>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/contact">Contact</Link>
</li>
</ul>
</nav>
<Suspense fallback={<div>Loading...</div>}>
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/contact">
<Contact />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</Suspense>
</Router>
);
}
export default App;
使用捆绑机分割代码
现代捆绑器对代码拆分具有内置支持,以实现有效的模块加载。经常发生的事情是,当Bundler在您的应用程序中遇到动态导入时,它会自动创建一个单独的块(JavaScript文件),稍后可以加载。这样,它就不会捆绑在主捆绑文件中,从而改善了应用程序的初始加载时间。
最后的想法
您可以看到,代码分裂有可能为我们提供重大的性能改进。但是,重要的是不要像大多数与性能相关的功能一样过于痴迷它,也会增加复杂性,因此只能在有意义的地方使用它。这就是为什么它通常是仅将其用于路线并从那里乘坐的重要第一步。
想看更多?
我主要撰写有关我作为前端开发人员日常生活中我所面临的真正技术主题的文章。如果这吸引您,那么随时可以在Twitter上关注我:https://twitter.com/cmacdonnacha
现在。 ð