# 按需加载

引用 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

react 文档 (opens new window)

# 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

我把他们详细地写了一遍,可以查看下一篇图片懒加载