Bagaimana cara mengurangi ukuran bundel produk?

135

Saya punya aplikasi sederhana, diinisialisasi oleh angular-cli.

Ini menampilkan beberapa halaman relatif terhadap 3 rute. Saya memiliki 3 komponen. Pada salah satu halaman ini saya menggunakan lodashdan modul HTTP 2 Sudut untuk mendapatkan beberapa data (menggunakan RxJS Observable, mapdan subscribe). Saya menampilkan elemen-elemen ini menggunakan sederhana *ngFor.

Tapi, meskipun faktanya aplikasi saya sangat sederhana, saya mendapatkan paket dan peta paket besar (menurut saya). Saya tidak berbicara tentang versi gzip tetapi ukuran sebelum gzipping. Pertanyaan ini hanyalah penyelidikan rekomendasi umum.

Beberapa hasil tes:

ng membangun

Hash: 8efac7d6208adb8641c1 Waktu: 10129ms chunk {0} main.bundle.js, main.bundle.map (main) 18,7 kB {3} [awal] [diterjemahkan]

chunk {1} styles.bundle.css, styles.bundle.map, styles.bundle.map (styles) 155 kB {4} [awal] [dirender]

chunk {2} scripts.bundle.js, scripts.bundle.map (scripts) 128 kB {4} [awal] [diberikan]

chunk {3} vendor.bundle.js, vendor.bundle.map (vendor) 3.96 MB [awal] [dirender]

chunk {4} inline.bundle.js, inline.bundle.map (inline) 0 byte [entri] [diterjemahkan]

Tunggu: Paket bundel vendor 10Mb untuk aplikasi sederhana seperti itu?

ng build --prod

Hash: 09a5f095e33b2980e7cc Waktu: 23455ms chunk {0} main.6273b0f04a07a1c2ad6c.bundle.js, main.6273b0f04a07a1c2ad6c.bundle.map (utama) 18,3 kB {rangkuman awal]

chunk {1} styles.bfdaa4d8a4eb2d0cb019.bundle.css, styles.bfdaa4d8a4eb2d0cb019.bundle.map, styles.bfdaa4d8a4eb2d0cb019.bundle.map (styles) [rangkuman awal {rujukan] [rujukan} [rujukan] [rujukan} [rujukan] [rujukan} [rujukan] [rujukan}]

chunk {2} scripts.c5b720a078e5464ec211.bundle.js, scripts.c5b720a078e5464ec211.bundle.map (skrip) 128 kB {4} [awal] [diberikan]

chunk {3} vendor.07af2467307e17d85438.bundle.js, vendor.07af2467307e17d85438.bundle.map (vendor) 3,96 MB [awal] [diberikan]

chunk {4} inline.a345391d459797f81820.bundle.js, inline.a345391d459797f81820.bundle.map (inline) 0 byte [entri] [entri] [diterjemahkan]

Tunggu lagi: ukuran bundel vendor serupa untuk produk?

ng build --prod --aot

Hash: 517e4425ff872bbe3e5b Waktu: 22856ms chunk {0} main.95eadabace554e3c2b43.bundle.js, main.95eadabace554e3c2b43.bundle.map (main) 130 kB {3} [awal] [diterjemahkan]

chunk {1} styles.e53a388ae1dd2b7f5434.bundle.css, styles.e53a388ae1dd2b7f5434.bundle.map, styles.e53a388ae1dd2b7f5434.bundle.map (styles) 154 kB {4} [awal] [dirender] [dirender]

chunk {2} scripts.e5c2c90547f3168a7564.bundle.js, scripts.e5c2c90547f3168a7564.bundle.map (skrip) 128 kB {4} [awal] [diterjemahkan]

chunk {3} vendor.41a6c1f57136df286f14.bundle.js, vendor.41a6c1f57136df286f14.bundle.map (vendor) 2,75 MB [awal] [dirender]

chunk {4} inline.97c0403c57a46c6a7920.bundle.js, inline.97c0403c57a46c6a7920.bundle.map (inline) 0 byte [entri] [diterjemahkan]

ng build --aot

Hash: 040cc91df4df5ffc3c3f Waktu: 11011ms chunk {0} main.bundle.js, main.bundle.map (utama) 130 kB {3} [awal] [diterjemahkan]

chunk {1} styles.bundle.css, styles.bundle.map, styles.bundle.map (styles) 155 kB {4} [awal] [dirender]

chunk {2} scripts.bundle.js, scripts.bundle.map (scripts) 128 kB {4} [awal] [diberikan]

chunk {3} vendor.bundle.js, vendor.bundle.map (vendor) 2.75 MB [awal] [dirender]

chunk {4} inline.bundle.js, inline.bundle.map (inline) 0 byte [entri] [diterjemahkan]

Jadi beberapa pertanyaan untuk menggunakan aplikasi saya di prod:

  • Mengapa bundel vendor begitu besar?
  • Apakah pohon bergetar dengan benar digunakan oleh angular-cli?
  • Bagaimana cara meningkatkan ukuran bundel ini?
  • Apakah file .map diperlukan?
  • Apakah fitur pengujian termasuk dalam bundel? Saya tidak membutuhkan mereka di prod.
  • Pertanyaan umum: alat apa yang direkomendasikan untuk mengemas prod? Mungkin angular-cli(menggunakan Webpack di latar belakang) bukan pilihan terbaik? Bisakah kita berbuat lebih baik?

Saya mencari banyak diskusi tentang Stack Overflow, tetapi saya belum menemukan pertanyaan umum.

BlackHoleGalaxy
sumber
Untuk mempelajari lebih lanjut tentang pengoptimalan aplikasi sudut 2, periksa ini: github.com/mgechev/angular-performance-checklist#introduction #introduction
Timathon
1
Tapi saya tidak berpikir kita harus peduli sebanyak itu, angular-cli akan berkembang dan hal-hal akan dilakukan lebih baik dan lebih baik. Jika Anda memerlukan beberapa fitur yang tidak dimiliki oleh angular-cli, kirimkan saja masalah ke repo mereka: github.com/angular/angular-cli
Timathon
sementara saya pikir @Timathon benar dalam beberapa hal, jika ada yang mencoba untuk menyebarkan Angular2 ke dalam produksi mereka harus peduli tentang ukuran bundel karena ini secara langsung mempengaruhi kinerja aplikasi. Daftar periksa kinerja sudut adalah sumber yang bagus untuk melihat apa yang dapat ditingkatkan. tim sudut bekerja untuk mengurangi ukuran bundel. Senang melihat ke mana perginya!
Jack Clancy

Jawaban:

72

Perbarui Februari 2020

Karena jawaban ini mendapat banyak daya tarik, saya pikir akan lebih baik untuk memperbaruinya dengan optimasi sudut yang lebih baru:

  1. Seperti yang dikatakan penjawab lain, ng build --prod --build-optimizeradalah pilihan yang baik untuk orang yang menggunakan kurang dari Angular v5. Untuk versi yang lebih baru, ini dilakukan secara default denganng build --prod
  2. Pilihan lain adalah menggunakan modul chunking / lazy loading untuk membagi aplikasi Anda menjadi potongan yang lebih kecil
  3. Mesin rendering Ivy datang secara default di Angular 9, ia menawarkan ukuran bundel yang lebih baik
  4. Pastikan deps pihak ketiga Anda dapat diguncang pohon. Jika Anda belum menggunakan Rxjs v6, Anda seharusnya.
  5. Jika semuanya gagal, gunakan alat seperti webpack-bundle-analyzer untuk melihat apa yang menyebabkan mengasapi dalam modul Anda
  6. Periksa apakah file Anda di-gzip

Beberapa klaim bahwa menggunakan kompilasi AOT dapat mengurangi ukuran bundel vendor menjadi 250kb. Namun, dalam contoh BlackHoleGalaxy, ia menggunakan kompilasi AOT dan masih tersisa dengan ukuran bundel vendor 2,75MB dengan ng build --prod --aot, 10x lebih besar dari yang seharusnya 250kb. Ini tidak di luar norma untuk aplikasi angular2, bahkan jika Anda menggunakan v4.0. 2.75MB masih terlalu besar untuk siapa pun yang benar-benar peduli dengan kinerja, terutama pada perangkat seluler.

Ada beberapa hal yang dapat Anda lakukan untuk membantu kinerja aplikasi Anda:

1) AOT & Tree Shaking (angular-cli melakukan ini di luar kotak). Dengan Angular 9 AOT secara default pada lingkungan prod dan dev.

2) Menggunakan rendering sisi server AKular Universal AKA (tidak di cli)

3) Pekerja Web (sekali lagi, bukan di cli, tetapi fitur yang sangat diminta)
lihat: https://github.com/angular/angular-cli/issues/2305

4) Pekerja Layanan
lihat: https://github.com/angular/angular-cli/issues/4006

Anda mungkin tidak memerlukan semua ini dalam satu aplikasi, tetapi ini adalah beberapa opsi yang ada saat ini untuk mengoptimalkan kinerja Angular. Saya percaya / berharap Google menyadari kekurangan di luar kotak dalam hal kinerja dan rencana untuk meningkatkan ini di masa depan.

Berikut ini adalah referensi yang berbicara lebih mendalam tentang beberapa konsep yang saya sebutkan di atas:

https://medium.com/@areai51/the-4-stages-of-perf-tuning-for-your-angular2-app-922ce5c1b294

Jack Clancy
sumber
Proyek minimal saya adalah 384kB, lihat github.com/JCornat/min-angular Saya yakin ada cara mudah untuk mengoptimalkannya, tetapi hampir 250kB!
Jacques Cornat
2
@ JacquesCornat terlihat bagus! Tetapi aplikasi Anda hanya memiliki satu komponen. Pertanyaannya adalah bagaimana mengelola ukuran bundel atau aplikasi yang lebih besar. Seringkali AOT tidak cukup mengurangi ukuran bundel, dan orang-orang dipaksa untuk mencari cara lain untuk mengoptimalkan. Saya sangat menyarankan semua orang untuk memeriksa webpack-bundle-analyzer. Cara yang sangat membantu / mudah untuk melihat apa yang menyebabkan mengasapi
Jack Clancy
Sayangnya, utilitas seperti sw-precachemenolak untuk berurusan dengan bundel vendor yang lebih besar dari 2MB.
1
@JackClancy "Pertanyaannya adalah bagaimana mengelola ukuran bundel atau aplikasi yang lebih besar". Tidak pertanyaannya adalah "bagaimana cara meningkatkan ukuran bundel ini?" dan dia berbicara tentang aplikasi minimalnya dengan 3 komponen. Omong-omong, berbicara tentang bundel besar, menggunakan konfigurasi AngularClass / angular-starter, sama seperti di repo saya, ukuran bundel saya untuk aplikasi besar naik dari 8MB (4MB tanpa file peta) ke 580kB.
Jacques Cornat
1
Terima kasih, Anda menyelamatkan saya. --prod mengurangi ukuran aplikasi dari 6Mb menjadi 1,2Mb. Masih tidak sempurna, tetapi menerima karena hanya untuk penggunaan desktop.
Vyacheslav Tsivina
21

Gunakan versi cli sudut terbaru dan gunakan perintah ng build --prod --build-optimizer Ini pasti akan mengurangi ukuran build untuk prod env.

Inilah yang dilakukan build optimizer di bawah kap:

Pengoptimal build memiliki dua pekerjaan utama. Pertama, kami dapat menandai bagian dari aplikasi Anda sebagai murni, ini meningkatkan guncangan pohon yang disediakan oleh alat yang ada, menghapus bagian tambahan dari aplikasi Anda yang tidak diperlukan.

Hal kedua yang dilakukan build optimizer adalah menghapus dekorator Angular dari kode runtime aplikasi Anda. Dekorator digunakan oleh kompiler, dan tidak diperlukan saat runtime dan dapat dihapus. Masing-masing pekerjaan ini mengurangi ukuran bundel JavaScript Anda, dan meningkatkan kecepatan boot aplikasi Anda untuk pengguna Anda.

Catatan : Satu pembaruan untuk Angular 5 dan lebih tinggi, proses ng build --prodotomatis ditangani di atas :)

Shubhendu Vaid
sumber
1
Sedangkan untuk angular 6 sekarang, vendor masih 4MB untuk hanya memasang sudut / material dan firebase
FindOutIslamSekarang
Itu adalah masalah dengan sudut / material, bahkan saya telah menghadapi kesalahan itu. Mengguncang pohon tidak dilakukan dengan benar mungkin merupakan akar penyebabnya. Dengan mesin renderer baru IVY mungkin itu akan terpecahkan.
Shubhendu Vaid
13

Lodash dapat menyumbangkan potongan kode bug ke bundel Anda, tergantung pada cara Anda mengimpornya. Sebagai contoh:

// includes the entire package (very large)
import * as _ from 'lodash';

// depending on your buildchain, may still include the entire package
import { flatten } from 'lodash';

// imports only the code needed for `flatten`
import flatten from 'lodash-es/flatten'

Secara pribadi saya masih menginginkan jejak kaki yang lebih kecil dari fungsi utilitas saya. Misalnya flattendapat berkontribusi hingga ke 1.2Kbundel Anda, setelah minimalisasi. Jadi saya telah membangun koleksi fungsi-fungsi lodash yang disederhanakan. Implementasi flattenkontribusi saya sekitar 50 bytes. Anda dapat memeriksanya di sini untuk melihat apakah itu bekerja untuk Anda: https://github.com/simontonsoftware/micro-dash

Eric Simonton
sumber
1
2 / Saya mencoba tips "loadash-es" dari komentar di atas. Ini mengurangi ukuran bundel saya 0,08mb.
Stefdelec
Itu tidak banyak! Apakah Anda masih memiliki hal lain yang mengimpor Lodash dengan cara lama? Anda tidak akan mendapatkan bantuan apa pun kecuali semuanya diimpor dengan cara baru.
Eric Simonton
Saya pikir saya sudah mengganti semuanya. Jika tidak, ukuran tidak akan berubah. Saya memberi tip lain di bawah ini (hal gzip) yang sangat membantu kami.
Stefdelec
Menarik. Berapa banyak bundel Anda yang berkontribusi terhadap lodash? (Misalnya menggunakan source-map-explorer.)
Eric Simonton
11

Pertama, bundel vendor sangat besar hanya karena Angular 2 bergantung pada banyak perpustakaan. Ukuran minimum untuk aplikasi Angular 2 adalah sekitar 500KB (250KB dalam beberapa kasus, lihat posting bawah).
Pohon goyang benar digunakan oleh angular-cli.
Jangan tidak termasuk .mapfile, karena hanya digunakan untuk debugging. Selain itu, jika Anda menggunakan modul penggantian panas, lepaskan untuk meringankan vendor.

Untuk mengemas produksi, saya personnaly menggunakan Webpack (dan angular-cli juga bergantung pada itu ), karena Anda dapat benar configure everything- benar untuk optimasi atau debugging.
Jika Anda ingin menggunakan Webpack, saya setuju itu agak rumit pandangan pertama, tetapi melihat tutorial di internet, Anda tidak akan kecewa.
Lain, gunakan angular-cli, yang menyelesaikan pekerjaan dengan sangat baik.

Menggunakan kompilasi Ahead-of-time adalah wajib untuk mengoptimalkan aplikasi, dan menyusutkan aplikasi Angular 2 menjadi 250KB .

Berikut adalah repo yang saya buat ( github.com/JCornat/min-angular ) untuk menguji ukuran bundel Angular minimal, dan saya mendapatkan 384kB . Saya yakin ada cara mudah untuk mengoptimalkannya.

Berbicara tentang aplikasi besar, menggunakan konfigurasi AngularClass / angular-starter , sama seperti dalam repo di atas, ukuran bundel saya untuk aplikasi besar ( 150+ komponen ) naik dari 8MB (4MB tanpa file peta) ke 580kB .

Jacques Cornat
sumber
Konfigurasi sudut-starter spesifik apa yang membantu mengurangi ukuran bundel? Apakah ini webpack.config?
MartinJH
2
Ya, itu adalah konfigurasi webpack yang mengurangi ukuran bundel.
Jacques Cornat
Terima kasih atas klarifikasinya :)
MartinJH
8

Solusi berikut mengasumsikan Anda melayani dist / folder Anda menggunakan nodejs. Silakan gunakan app.js berikut di tingkat root

const express = require('express'),http = require('http'),path = require('path'),compression = require('compression');

const app = express();

app.use(express.static(path.join(__dirname, 'dist')));
app.use(compression()) //compressing dist folder 
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, 'dist/index.html'));
})

const port = process.env.PORT || '4201';
app.set('port', port);

const server = http.createServer(app);
server.listen(port, () => console.log('Running at port ' + port))

Pastikan Anda menginstal dependensi;

npm install compression --save
npm install express --save;

Sekarang bangun aplikasinya

ng build --prod --build-optimizer

Jika Anda ingin kompres lebih lanjut dari build, katakan kurangi 300kb (kira-kira) dari, lalu ikuti proses di bawah ini;

Buat folder bernama vendordi dalam srcfolder dan di dalam folder vendor buat file rxjs.ts dan tempel kode di bawah ini di dalamnya;

export {Subject} from 'rxjs/Subject';
export {Observable} from 'rxjs/Observable';
export {Subscription} from 'rxjs/Subscription';

Dan kemudian tambahkan follwing dalam tsconfig.jsonfile di aplikasi angular-cli Anda. Kemudian di compilerOptions, tambahkan json berikut;

"paths": {
      "rxjs": [
        "./vendor/rxjs.ts"
      ]
    }

Ini akan membuat ukuran build Anda terlalu kecil. Dalam proyek saya, saya mengurangi ukuran dari 11mb menjadi 1mb. Semoga ini bisa membantu

Renil Babu
sumber
5

Satu hal yang ingin saya bagikan adalah bagaimana perpustakaan yang diimpor meningkatkan ukuran dist. Saya memiliki paket angular2-moment yang diimpor, sedangkan saya bisa melakukan semua format waktu tanggal yang saya perlukan menggunakan DatePipe standar yang diekspor dari @ angular / common.

Dengan Angular2-Moment "angular2-moment": "^1.6.0",

chunk {0} polyfills.036982dc15bb5fc67cb8.bundle.js (polyfill) 191 kB {4} [awal] [diterjemahkan] chunk {1} main.e7496551a26816427b68.bundle.js (utama) 2.2 MB {3} [awal] [diterjemahkan] chunk {2} styles.056656ed596d26ba0192.bundle.css (styles) 69 bytes {4} [awal] [diterjemahkan] chunk {3} vendor.62c2cfe0ca794a5006d1.bundle.js (vendor) 3.84 MB [awal] [dirender] chunk {4] } inline.0b9c3de53405d705e757.bundle.js (inline) 0 byte [entri] [diberikan]

Setelah menghapus Angular2-saat dan menggunakan DatePipe sebagai gantinya

chunk {0} polyfills.036982dc15bb5fc67cb8.bundle.js (polyfill) 191 kB {4} [awal] [diterjemahkan] chunk {1} main.f2b62721788695a4655c.bundle.js (utama) 2.2 MB {3} [awal] [diterjemahkan] chunk {2} styles.056656ed596d26ba0192.bundle.css (styles) 69 bytes {4} [awal] [diterjemahkan] chunk {3} vendor.e1de06303258c58c9d01.bundle.js (vendor) 3.35 MB [awal] [dirender] chunk {4 } inline.3ae24861b3637391ba70.bundle.js (inline) 0 byte [entri] [diberikan]

Perhatikan bundel vendor telah berkurang setengah Megabyte!

Intinya adalah perlu memeriksa apa paket standar sudut dapat lakukan bahkan jika Anda sudah terbiasa dengan lib eksternal.

kwalski
sumber
1

Jika Anda telah menjalankan ng build --prod- Anda seharusnya tidak memiliki vendorfile sama sekali.

Jika saya jalankan saja ng build- saya mendapatkan file-file ini:

masukkan deskripsi gambar di sini

Ukuran total folder adalah ~ 14MB. Waat! : D

Tetapi jika saya menjalankan ng build --prod- saya mendapatkan file-file ini:

masukkan deskripsi gambar di sini

Ukuran total folder adalah 584K.

Satu dan kode yang sama. Saya telah mengaktifkan Ivy dalam kedua kasus. Angular adalah 8.2.13.

Jadi - saya kira Anda tidak menambah --prodperintah build Anda?

pesho hristov
sumber
1

Jika Anda menggunakan Angular 8+ dan Anda ingin mengurangi ukuran bundel, Anda bisa menggunakan Ivy. Ivy hadir sebagai mesin tampilan default di Angular 9 Cukup buka src / tsconfig.app.json dan tambahkan parameter angularCompilerOptions, misalnya:

{
  "extends": ...,
  "compilerOptions":...,
  "exclude": ...,

/* add this one */ 
  "angularCompilerOptions": {
    "enableIvy": true
  }
}
Rachel
sumber
1

Ini memang mengurangi ukuran dalam kasus saya:

ng build --prod --build-optimizer --optimization.

Untuk Angular 5+ ng-build --prod melakukan ini secara default. Ukuran setelah menjalankan perintah ini berkurang dari 1,7MB menjadi 1,2MB, tetapi tidak cukup untuk tujuan produksi saya.

Saya bekerja di platform messenger Facebook dan aplikasi messenger harus kurang dari 1MB untuk berjalan di platform messenger. Sudah mencoba mencari solusi untuk mengguncang pohon yang efektif tetapi masih belum berhasil.

Mahesh Sharma
sumber
1

Kerjanya 100% ng build --prod --aot --build-optimizer --vendor-chunk = true

AJAY AVHAD
sumber
0

Saya memiliki aplikasi booting sudut 5 + pegas (application.properties 1.3+) dengan bantuan kompresi (tautan terlampir di bawah) dapat mengurangi ukuran ukuran main.bundle.ts dari 2,7 MB menjadi 530 KB.

Juga secara default --aot dan --build-optimizer diaktifkan dengan mode --prod Anda tidak perlu menentukannya secara terpisah.

https://stackoverflow.com/a/28216983/9491345

sah1
sumber
0

Periksa Anda memiliki konfigurasi bernama "produksi" untuk ng build --prod, karena ini adalah singkatan untuk ng build --configuration = produksi Tidak ada jawaban yang menyelesaikan masalah saya, karena masalahnya terletak tepat di depan layar. Saya pikir ini mungkin sangat umum ... Saya telah menginternasionalkan aplikasi dengan i18n mengubah nama semua konfigurasi menjadi misalnya produksi-en. Kemudian saya membangun dengan ng build --prod dengan asumsi, bahwa optimasi default digunakan dan harus mendekati optimal, tetapi sebenarnya hanya build ng telah dieksekusi yang menghasilkan bundel 7mb bukannya 250kb.

penangkal
sumber
0

Diambil dari sudut dokumen v9 ( https://angular.io/guide/workspace-config#alternate-build-configurations ):

Secara default, konfigurasi produksi ditentukan, dan perintah ng build memiliki opsi --prod yang dibuat menggunakan konfigurasi ini. Konfigurasi produksi menetapkan default yang mengoptimalkan aplikasi dalam sejumlah cara, seperti bundling file , meminimalkan kelebihan ruang kosong , menghapus komentar dan kode mati , dan menulis ulang kode untuk menggunakan nama pendek dan samar ( "minifikasi" ).

Selain itu Anda dapat mengompres semua deployable Anda dengan @ angular-builders / custom-webpack: pembuat browser tempat webpack.config.js kustom Anda terlihat seperti itu:

module.exports = {
  entry: {
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[hash].js'
  },
  plugins: [
    new CompressionPlugin({
      deleteOriginalAssets: true,
    })
  ]
};

Setelah itu Anda harus mengkonfigurasi server web Anda untuk menyajikan konten terkompresi misalnya dengan nginx Anda harus menambahkan ke nginx.conf Anda:

server {
    gzip on;
    gzip_types      text/plain application/xml;
    gzip_proxied    no-cache no-store private expired auth;
    gzip_min_length 1000;
    ...
}

Dalam kasus saya folder dist menyusut dari 25 hingga 5 mb setelah hanya menggunakan --prod di ng build dan kemudian menyusut ke 1,5mb setelah kompresi.

Bat0u89
sumber