按需加载

随着 web 网页的流行,越来越多的人选择使用网页来代替传统的 APP,随之而来的就是网页越来越庞大,前端性能的问题尤其显现。一些大的项目都会做一些性能优化来提高访问速度,以提升用户的体验,比如:按需加载,资源优化等。

按需加载可以提高页面加载速度,如果当前页面只使用了某个功能,我们可以选择只加载这个功能,避免过于庞大的包加载进页面而需要等等过长的时间。

接下来我们先讨论一个问题:什么时候需要按需加载呢?

如果打包的产物是一个文件,这个文件又很大,一次性下载下来的速度就会比较慢,可能会造成刚进入页面时长时间的白屏的情况,这种体验非常不好;如果打包成多个文件,但是浏览器在同一时间内可以发出的请求数有限制,这也会导致用户等待。按需加载就可以很好的去解决这些问题。

那么我们如何按需加载呢?

简单有效的方式是使用 babel-plugin-import

什么是 babel-plugin-import?

babel-plugin-import 是阿里开源的一款 babel 插件,它会在编译过程中将 import 的写法自动转换为按需引入的方式,主要用于组件的按需引入。

如何在项目中添加 babel-plugin-import?

使用方法

安装

npm install babel-plugin-import --save-dev

配置

通过 .babelrc 配置文件或者 babel-loader 引入。

{
  "plugins": [["import", options]]
}

其中 options 为具体的配置项

如果使用 babel7,可以做如下的配置:

{
  "plugins": [["import", options, "antd"]]
}

接下来一起看看具体的配置项 options

{
  "libraryName": "antd",
  "style": true,   // or 'css' or 'function'
  "libraryDirectory": "components",  // default: lib
  "camel2DashComponentName": false,  // default: true
  "styleLibraryDirectory": "lib",
  "customName": (name: string, file: object) => {
        const filename = file.opts.filename;
        if (name === 'TimePicker'){
          return 'antd/lib/custom-time-picker';
        }
        if (filename.indexOf('/path/to/my/different.js') >= 0) {
          return 'antd/lib/custom-name';
        }
        return `antd/lib/${name}`;
      }
}
  • libraryName 代表库的名称

  • style 引入样式,可以指定 css、true 或者 function

  • libraryDirectory 组件所在目录,默认:lib

  • camel2DashComponentName 将引入的组件名转化为"-"连接的文件名

  • styleLibraryDirectory 样式文件路径

  • customName 自定义导入文件路径,也可以是一个文件,例如:require('path').resolve(__dirname, './customName.js')

customName.js 文件如下:

module.exports = function customName(name) {
  return `antd/lib/${name}`;
};

使用示例

上来讲述了使用方法,我们一起来看看配置后的结果吧!

{ "libraryName": "antd" }
import { Button } from 'antd';
import { TimePicker } from "antd"

ReactDOM.render(<Button>xxxx</Button>);

// 最后输出结果
var _button = require('antd/lib/button');
var TimePicker = require('antd/lib/time-picker');

ReactDOM.render(<_button>xxxx</_button>);

上面只配置了libraryNameantd,按照默认路径 lib 引入组件。

{ "libraryName": "antd", style: "css" }
import { Button } from 'antd';
ReactDOM.render(<Button>xxxx</Button>);

// 最后输出结果
var _button = require('antd/lib/button');
require('antd/lib/button/style/css');
ReactDOM.render(<_button>xxxx</_button>);

配置 style: "css",直接引入经过打包后的 antd 样式文件

{ "libraryName": "antd", style: true }
import { Button } from 'antd';
ReactDOM.render(<Button>xxxx</Button>);

// 最后输出结果
var _button = require('antd/lib/button');
require('antd/lib/button/style');
ReactDOM.render(<_button>xxxx</_button>);

配置 style: true,在项目编译阶段,可以对引入的 antd 样式文件进行编译,从而可以压缩打包尺寸

{
    "libraryName": "antd",
    "style": (name: string, file: Object) => {
       if(name === 'antd/lib/utils'){
         return false;
       }
     return `${name}/style/2x`;
   }
}

配置 style: (name) => ${name}/style/2x,引入 css 文件路径是 ComponentName/style/2x

{
  "libraryName": "element-ui",
  "styleLibraryDirectory": "lib/theme-chalk",
}
import { Button } from 'element-ui';

// 最后输出结果
var _button = require('element-ui/lib/button');
require('element-ui/lib/theme-chalk/button');

配置 "styleLibraryDirectory": "lib/theme-chalk",指定样式在 lib/theme-chalk 目录下。

{
  "libraryName": "element-ui",
  "camel2DashComponentName": false,
}
import { TimePicker } from "antd"

// 最后输出结果
var _button = require('antd/lib/TimePicker');

配置 camel2DashComponentName: false,不会将组件名转化为"-"连接的文件名

{
    "libraryName": "antd",
    "customName": (name: string, file: object) => {
      const filename = file.opts.filename;
      if (name === 'TimePicker'){
        return 'antd/lib/custom-time-picker';
      }
      if (filename.indexOf('/path/to/my/different.js') >= 0) {
        return 'antd/lib/custom-name';
      }
      return `antd/lib/${name}`;
    }
}
import { TimePicker } from "antd"

// 最后输出结果
var _button = require('antd/lib/custom-time-picker');

配置 customName,可以根据指定路径引入组件。

现在我们可以方便地使用按需加载了,不止是开源的组件库,或者是我们自研的组件库都可以使用这种方法。但是也需要我们的组件库支持,也就是说我们的组件库要符合一定的目录结构,export 导出也要符合规范才可以。

总结

有了 babel-plugin-import 后我们可以愉快地进行开发了,只需要在项目中配置一次就不需要关心了。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容