使用していないコードを削除する

この Codelab では、次のアプリのパフォーマンスを改善します。 未使用の依存関係と不要な依存関係を削除します

アプリのスクリーンショット

測定

まず最初にウェブサイトのパフォーマンスを測定し、 最適化の追加

  • サイトをプレビューするには、[アプリを表示] を押します。[ 全画面表示 全画面表示

お気に入りの子猫をクリックしてね!Firebase の Realtime Database は スコアがリアルタイムで更新され、 アプリケーションを使用するすべての人と同期されます。🐈

  1. Ctrl+Shift+J キー(Mac の場合は Command+Option+J キー)を押して DevTools を開きます。
  2. [ネットワーク] タブをクリックします。
  3. [キャッシュを無効にする] チェックボックスをオンにします。
  4. アプリを再読み込みします。

元のバンドル サイズは 992 KB

このシンプルなアプリケーションを読み込むために、約 1 MB 相当の JavaScript が配布されます。

DevTools でプロジェクトの警告を確認します。

  • [Console] タブをクリックします。
  • 横にあるレベルのプルダウンで Warnings が有効になっていることを確認します。 Filter 入力。

警告フィルタ

  • 表示された警告を確認します。

コンソールの警告

このアプリケーションで使用されているライブラリの一つである Firebase は、 インポートしないようデベロッパーに知らせる 使用されるコンポーネントのみに適用されます。言い換えると、 このアプリケーションで削除して読み込むことができる、未使用のライブラリ 迅速に進めることができます。

特定のライブラリが使用されている場合でも、 よりシンプルな代替手段となります。不要なライブラリを削除するというコンセプトは、 後ほど説明します。

バンドルの分析

このアプリケーションには主に 2 つの依存関係があります。

  • Firebase: さまざまな iOS、Android、ウェブ アプリケーション用の便利なサービスです。ここでは [リアルタイム Database は、 各子猫の情報をリアルタイムで保存、同期できます。
  • Moment.js: 以下のタスクを簡単に実行するユーティリティ ライブラリです。 日付を処理する方法を紹介します各子猫の生年月日は Firebase データベースです。moment は年齢(週数)を計算するために使用されます。

2 つの依存関係だけでもバンドルサイズが 1 MB 近くになるのはなぜですか?まず 理由の 1 つは、どの依存関係にも独自のものが存在できることです。 階層の深さ/ブランチごとに、2 つだけでなく、 依存関係「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 Bundle Analyzer

子どもたちの子猫 NDK ほどキュートではありませんが、とっても頼りになる存在です。 いずれかのパッケージにカーソルを合わせると、そのパッケージのサイズが 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 の警告が表示されなくなります。[ DevTools の [Network] パネルでは、バンドルサイズが大幅に削減されています。

バンドルサイズを 480 KB に縮小しました

バンドルサイズの半分以上が削除されています。Firebase では、さまざまな種類の デベロッパーは、実際に利用されているもののみを 必要ありません。このアプリケーションでの保存と同期には firebase/database のみが使用されました すべてのデータが含まれます。firebase/app インポート。次の API サーフェスを設定します。 必ず指定する必要があります。

他の多くの一般的なライブラリ(lodash など)では、デベロッパーが次のことを行えます。 パッケージのさまざまな部分を選択的にインポートできます。あまり手間をかけずに アプリケーションのライブラリ インポートを更新して、使用されているものだけが含まれるようにする パフォーマンスを大幅に改善できます

バンドルサイズはかなり小さくなりましたが やらなければならないのか!😈

不要なパッケージの削除

Firebase とは異なり、moment ライブラリの一部は、 完全に削除できるでしょうか?

それぞれのかわいい子猫の誕生日は Unix 形式(ミリ秒)で Firebase データベース。

Unix 形式で保存された生年月日

これは特定の日時のタイムスタンプで、 1970 年 1 月 1 日 00:00(UTC)から経過したミリ秒。現在の 同じ形式で日時を計算できます。これは、 各子猫の年齢(週)はおそらく構築できます。

いつものように、手順どおりにコピーして貼り付けないようにしてください。開始: 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 引数は、すでに (ミリ秒単位)が計算されて、1 秒あたりのミリ秒数で 1 週間に及びます

最後に、イベント リスナー内の 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 を使用すると、この処理が大幅に簡素化されます。

何事もトレードオフの関係であり、その価値を測ることが重要です。 カスタム ソリューションをロールアウトするための複雑さと労力が 使用できます。