# 按需加载
引用 webpack 对按需加载的解释 (opens new window):
按需加载或者懒加载,是一种很好的优化网页或应用的方式。这种方式实际上是先把你的代码在一些逻辑断点处分离开,然后在一些代码块中完成某些操作后,立即引用或即将引用另外一些新的代码块。这样加快了应用的初始加载速度,减轻了它的总体体积,因为某些代码块可能永远不会被加载。
# 框架中的懒加载
# vue
# vue 异步组件 (opens new window)
在大型应用中,我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块。为了简化,Vue 允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。Vue 只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染。
# vue 路由懒加载 (opens new window)
当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。
结合 Vue 的异步组件和 Webpack 的代码分割功能,轻松实现路由组件的懒加载。
首先,可以将异步组件定义为返回一个 Promise 的工厂函数 (该函数返回的 Promise 应该 resolve 组件本身):
const Foo = () =>
Promise.resolve({
/* 组件定义对象 */
});
第二,在 Webpack 2 中,我们可以使用动态 import 语法来定义代码分块点 (split point):
import('./Foo.vue'); // 返回 Promise
注意
如果您使用的是 Babel,你将需要添加 syntax-dynamic-import 插件,才能使 Babel 可以正确地解析语法。
结合这两者,这就是如何定义一个能够被 Webpack 自动代码分割的异步组件。
const Foo = () => import('./Foo.vue');
在路由配置中什么都不需要改变,只需要像往常一样使用 Foo:
const router = new VueRouter({
routes: [{ path: '/foo', component: Foo }]
});
# react
# import()
在你的应用中引入代码分割的最佳方式是通过动态 import()
语法。
import('./math').then(math => {
console.log(math.add(16, 26));
});
当 Webpack 解析到该语法时,会自动进行代码分割。
当使用 Babel 时,你要确保 Babel 能够解析动态 import 语法而不是将其进行转换。对于这一要求你需要
babel-plugin-syntax-dynamic-import
插件。
# React.lazy
React.lazy 函数能让你像渲染常规组件一样处理动态引入(的组件)。
// 使用之前:
// import OtherComponent from './OtherComponent';
// 使用之后:
const OtherComponent = React.lazy(() => import('./OtherComponent'));
此代码将会在组件首次渲染时,自动导入包含 OtherComponent 组件的包。
React.lazy 接受一个函数,这个函数需要动态调用 import()。它必须返回一个 Promise,该 Promise 需要 resolve 一个 defalut export 的 React 组件。
然后应在 Suspense 组件中渲染 lazy 组件,如此使得我们可以使用在等待加载 lazy 组件时做优雅降级(如 loading 指示器等)。
import React, { Suspense } from 'react';
const OtherComponent = React.lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
</div>
);
}
fallback 属性接受任何在组件加载过程中你想展示的 React 元素。你可以将 Suspense 组件置于懒加载组件之上的任何位置。你甚至可以用一个 Suspense 组件包裹多个懒加载组件。
# 基于路由的代码分割
这里是一个例子,展示如何在你的应用中使用 React.lazy 和 React Router 这类的第三方库,来配置基于路由的代码分割。
import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
const Home = lazy(() => import('./routes/Home'));
const About = lazy(() => import('./routes/About'));
const App = () => (
<Router>
<Suspense fallback={<div>Loading...</div>}>
<Switch>
<Route exact path='/' component={Home} />
<Route path='/about' component={About} />
</Switch>
</Suspense>
</Router>
);
# webpack 的按需加载
按需加载或者懒加载,是一种很好的优化网页或应用的方式。这种方式实际上是先把你的代码在一些逻辑断点处分离开,然后在一些代码块中完成某些操作后,立即引用或即将引用另外一些新的代码块。这样加快了应用的初始加载速度,减轻了它的总体体积,因为某些代码块可能永远不会被加载。
总结来说就是通过代码分割和动态导入后,然后在事件响应时「按需」请求/加载「动态分割」的 chunk。
相关文章你可以阅读:
# 图片懒加载
图片懒加载的实现有多种方法,参考神三元的 blog (opens new window) 有一下三种方法:
- 方案一: clientHeight、scrollTop 和 offsetTop
- 方案二: getBoundingClientRect
- 方案三: IntersectionObserver
我把他们详细地写了一遍,可以查看下一篇图片懒加载