移除未使用的代码

在此 Codelab 中,您可以通过 移除任何不使用和不需要的依赖项。

应用屏幕截图

测量

建议您先衡量网站的效果 添加优化建议。

  • 如需预览网站,请按查看应用。然后按 全屏 全屏

继续操作,点击你最喜欢的小猫!Firebase Realtime Database 是 因此得分会实时更新, 与使用该应用的所有其他用户同步。🐈

  1. 按 `Ctrl+Shift+J`(在 Mac 上,按 `Command+Option+J`)打开开发者工具。
  2. 点击网络标签页。
  3. 选中停用缓存复选框。
  4. 重新加载应用。

原始 app bundle 大小为 992 KB

要加载这个简单的应用,需要大约 1 MB 的 JavaScript 代码!

查看开发者工具中的项目警告。

  • 点击 Console(控制台)标签页。
  • 确保已启用“Warnings”的 Filter 输入。

警告过滤条件

  • 查看显示的警告。

控制台警告

Firebase 是此应用中使用的库之一 通过提供警告让开发者知道不要导入自己的 整个软件包,但只包含所使用的组件。也就是说, 可以移除此应用以加载 。

在有些情况下,使用了特定的库 一个更简单的替代方案。移除不需要的库的概念是 详细介绍

分析软件包

该应用中有两个主要依赖项:

  • Firebase:此平台可提供许多 适用于 iOS、Android 或 Web 应用的实用服务。在这里,其实时 数据库用于 实时存储和同步每只小猫的信息。
  • Moment.js:一个实用程序库,可让您更轻松地 在 JavaScript 中处理日期。每只小猫的出生日期都存储在 Firebase 数据库,且 moment 用于以周为单位计算其存在时间。

为什么只有两个依赖项会合为将近 1 MB 的 bundle 大小? 其中一个原因是,任何依赖项都可以反过来 所以如果模型的每个深度/分支都存在依赖关系, 依赖项“tree”。应用很容易变大 如果包含许多依赖项,速度相对较快。

分析捆绑器以更好地了解执行情况。这里有许多 可以帮助实现此目的的各种社区工具,例如 webpack-bundle-analyzer

此工具的软件包已作为 devDependency 包含在应用中。

"devDependencies": {
  //...
  "webpack-bundle-analyzer": "^2.13.1"
},

这意味着,您可以直接在 webpack 配置文件中使用它。 在 webpack.config.js 的开头导入此文件:

const path = require("path");

//...
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
  .BundleAnalyzerPlugin;

现在,在 plugins 数组内的文件末尾将其作为插件添加:

module.exports = {
  //...
  plugins: [
    //...
    new BundleAnalyzerPlugin()
  ]
};

应用重新加载时,您应该会看到整个应用的 而非应用本身

Webpack 软件包分析器

这不像看到猫咪那样可爱 ⧫,但对它还是很有帮助的。 将鼠标悬停在任一软件包上,即可显示其大小(以 3 个为单位) 方法:

统计数据大小 进行任何缩减或压缩之前的大小。
解析后的大小 编译完成后,软件包中实际软件包的大小。 webpack 版本 4(在此应用中使用)缩减了 自动编译的文件,这就是它比统计信息 。
Gzip 压缩大小 使用 gzip 编码压缩的软件包的大小。这个 请参阅另一指南。

借助 webpack-bundle-analyzer 工具,您可以更轻松地识别 构成了软件包的很大一部分不需要的软件包。

移除未使用的软件包

可视化图表显示 firebase 软件包还包含许多其他内容 而不仅仅是数据库它包含其他软件包,例如:

  • firestore
  • auth
  • storage
  • messaging
  • functions

这些都是 Firebase 提供的出色服务(请参阅 文档 但在应用中并未使用任何技术 没有理由将其全部导入。

还原 webpack.config.js 中的更改以再次看到应用:

  • 移除插件列表中的 BundleAnalyzerPlugin
plugins: [
  //...
  new BundleAnalyzerPlugin()
];
  • 现在,从文件顶部移除未使用的导入内容:
const path = require("path");

//...
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

现在,应用应该可以正常加载了。修改 src/index.js 以更新 Firebase 导入。

import firebase from 'firebase';
import firebase from 'firebase/app';
import 'firebase/database';

现在,当应用重新加载时,DevTools 警告不会显示。打开 开发者工具的 Network 面板还显示了软件包大小的很好缩减:

捆绑包大小缩减到 480 KB

移除了超过一半的软件包大小。Firebase 提供了许多不同的 并允许开发者仅将实际应用 所需的资源。在此应用中,仅使用 firebase/database 来存储和同步 所有数据firebase/app 导入,用于为以下对象设置 API Surface: 都是必不可少的

许多其他热门库(如 lodash)也允许开发者 有选择地导入其软件包的不同部分。不必执行太多工作 更新应用中的库导入,使其仅包含正在使用的库 可以大幅提升性能。

虽然 bundle 大小已大幅缩减,但 要做的事!😈

移除不需要的软件包

与 Firebase 不同,moment 库的部分内容无法 而且或许能将其彻底删除呢?

每只可爱小猫的生日以 Unix 格式(以毫秒为单位)存储, Firebase 数据库。

以 Unix 格式存储出生日期

这是特定日期和时间的时间戳,以 自世界协调时间 (UTC) 1970 年 1 月 1 日 00:00 起经过的毫秒数。如果当前 日期和时间可以采用相同的格式进行计算, 我们可以构建每只小猫的年龄。

与往常一样,按照本文中的说明操作时,请尽量不要进行复制和粘贴。起始内容 从 src/index.js 的导入中移除了 moment

import firebase from 'firebase/app';
import 'firebase/database';
import * as moment from 'moment';

Firebase 事件监听器可处理数据库中的值更改:

favoritesRef.on("value", (snapshot) => { ... })

在此基础上,添加一个小函数,用于计算 指定日期:

const ageInWeeks = birthDate => {
  const WEEK_IN_MILLISECONDS = 1000 * 60 * 60 * 24 * 7;
  const diff = Math.abs((new Date).getTime() - birthDate);
  return Math.floor(diff / WEEK_IN_MILLISECONDS);
}

在此函数中,当前日期与 时间 (new Date).getTime() 和出生日期(birthDate 参数,已经 (以毫秒为单位)的计算方法, 一个星期。

最后,可以通过以下方式在事件监听器中移除 moment 的所有实例: 此函数:

favoritesRef.on("value", (snapshot) => {
  const { kitties, favorites, names, birthDates } = snapshot.val();
  favoritesScores = favorites;

  kittiesList.innerHTML = kitties.map((kittiePic, index) => {
    const birthday = moment(birthDates[index]);

    return `
      <li>
        <img src=${kittiePic} onclick="favKittie(${index})">
        <div class="extra">
          <div class="details">
            <p class="name">${names[index]}</p>
            <p class="age">${moment().diff(birthday, 'weeks')} weeks old</p>
            <p class="age">${ageInWeeks(birthDates[index])} weeks old</p>
          </div>
          <p class="score">${favorites[index]} ❤</p>
        </div>
      </li>
    `})
});

现在重新加载应用,然后再次查看 Network 面板。

捆绑包大小缩减到 225 KB

我们的套装又缩减了一半!

总结

在此 Codelab 中,您应该对如何分析 以及为什么移除未使用的或不需要的软件包 软件包在开始用这种方法优化应用之前,请先 需要注意的是,在大型企业中,这可能要复杂得多 应用

关于移除未使用的库,请尝试找出 哪些部分使用了,哪些没有。神秘主题 请退一步检查 哪些顶级依赖项可能需要它试着找到一种方法 使它们相互分离。

移除不需要的库方面,方法可能稍微复杂一些 复杂。一定要与团队密切合作,看看能否 有助于简化代码库的某些部分。正在移除此文件夹中的moment 可能看似每次都做正确的事, 是否有需要处理的时区和不同的语言区域?或 如果有更复杂的日期操作,该怎么办?事情可能 处理和解析日期/时间以及 moment 等库时比较棘手 和 date-fns 可以大大简化这一过程。

一切都需要权衡,因此评估是否值得 部署自定义解决方案,而不依赖于 第三方库