Pohon JavaScript bergetar, seperti pro

Ini adalah terjemahan dari artikel tentang mengoptimalkan dan mengurangi ukuran bundel aplikasi. Ini bagus karena praktik terbaik dijelaskan di sini, kiat yang harus Anda ikuti untuk membuat trishhing berfungsi dan membuang kode yang tidak digunakan dari majelis. Ini akan bermanfaat bagi banyak orang, karena sekarang semua orang menggunakan sistem perakitan di mana ada trishashing di luar kotak. Tetapi agar itu berfungsi dengan benar, Anda harus mematuhi prinsip-prinsip yang diuraikan di bawah ini.

gambar

Trichashing menjadi teknik utama ketika Anda perlu mengurangi ukuran bundel dan meningkatkan kinerja aplikasi di JS.

Cara kerja trichashing:

  1. Anda mendeklarasikan impor dan ekspor di setiap modul.
  2. Kolektor (Webpack, Rollup, atau lainnya) menganalisis pohon dependensi selama perakitan.
  3. Kode yang tidak digunakan dikecualikan dari bundel terakhir.

gambar
File utilitas mengekspor dua fungsi,

gambar
tetapi hanya initializeName yang digunakan, formatName dapat dihapus.

Sayangnya, untuk pengoperasian trishaking yang benar, satu pengaturan kolektor tidak cukup. Untuk mencapai hasil yang lebih baik, perlu memperhitungkan banyak detail, serta memastikan bahwa modul tidak dilewati selama optimasi.

Di mana untuk memulai?


Ada sejumlah besar pedoman untuk menyiapkan trishaking. Lebih baik mulai terjun ke topik dengan dokumentasi Webpack resmi .

Perlu disebutkan bahwa beberapa tahun yang lalu saya membuat pelat dengan perakitan dan trichashing yang sudah dikonfigurasi. Jadi, jika Anda memerlukan titik awal untuk sebuah proyek, repositori saya bisa menjadi contoh yang bagus dari krakenjs / grumbler .

Artikel ini membahas cara kerja dengan Webpack, Babel, dan Terser. Namun, sebagian besar prinsip yang disajikan akan berfungsi baik jika Anda menggunakan Webpack, Rollup, atau yang lainnya.

Gunakan sintaks ES6 untuk impor dan ekspor


Menggunakan impor dan ekspor ES6 adalah langkah pertama dan paling penting untuk melakukan trichashing.

Sebagian besar implementasi lain dari pola "modul", termasuk commonjs dan require.js, adalah non-deterministik selama proses pembangunan. Fitur ini tidak memungkinkan pengumpul seperti Webpack untuk menentukan dengan tepat apa yang diimpor, apa yang diekspor, dan, sebagai hasilnya, kode apa yang dapat dihapus dengan aman.

gambar
Opsi yang dimungkinkan saat menggunakan commonjs.

Saat menggunakan modul ES6, opsi impor dan ekspor lebih terbatas:

  • Anda dapat mengimpor dan mengekspor hanya pada tingkat modul, dan tidak di dalam fungsi;
  • nama modul hanya bisa berupa string statis, bukan variabel;
  • semua yang Anda impor harus diekspor ke suatu tempat.

gambar
Modul ES6 memiliki semantik dan aturan penggunaan yang lebih sederhana.

Aturan yang disederhanakan memungkinkan perakit memahami dengan tepat apa yang diimpor dan diekspor, dan, sebagai hasilnya, menentukan kode mana yang tidak digunakan sama sekali.

Jangan izinkan Babel untuk mengangkut impor dan ekspor


Masalah pertama yang mungkin Anda temui ketika menggunakan Babel untuk menerjemahkan kode adalah konversi default modul ES6 ke commonjs. Ini mencegah kolektor dari mengoptimalkan kode dan membuang terlalu banyak.

Untungnya, dalam konfigurasi Babel ada cara mudah untuk menonaktifkan transpilasi modul .

Setelah Anda melakukan ini, pengumpul akan dapat melakukan pengalihan impor dan ekspor.

Buat ekspor atom Anda


Webpack biasanya membiarkan ekspor tetap utuh dalam kasus berikut:

  • ;
  • ;
  • .

Ekspor semacam itu akan sepenuhnya dimasukkan dalam bundel, atau sepenuhnya dihapus. Jadi, pada akhirnya, Anda mungkin berakhir dengan bundel berisi kode yang tidak akan pernah digunakan.

gambar
Kedua fungsi akan dimasukkan dalam bundel, meskipun hanya satu yang digunakan.

gambar
Dan di sini kelas akan sepenuhnya ditambahkan ke majelis.

Cobalah untuk menjaga ekspor Anda sekecil dan sesederhana mungkin.

gambar
Hanya fungsi yang akan digunakan yang akan masuk ke bundel akhir.

Penerapan saran ini memungkinkan kolektor untuk mengeluarkan lebih banyak kode karena sekarang selama proses perakitan Anda dapat melacak fungsi mana yang diimpor dan digunakan, dan mana yang tidak.

Kiat ini juga membantu untuk menulis kode dengan gaya yang lebih fungsional dan dapat digunakan kembali, dan untuk menghindari penggunaan kelas yang tidak dibenarkan.

Jika Anda tertarik pada pemrograman fungsional, lihat artikel ini .

Hindari efek samping pada tingkat modul


Saat menulis modul, banyak orang kehilangan faktor penting, tetapi sangat berbahaya - pengaruh efek samping.

gambar
Webpack tidak mengerti apa fungsi window.memoize, dan karenanya tidak dapat membuang fungsi ini.

Perhatikan contoh di atas window.memoizeakan dipanggil pada saat impor modul.

Seperti yang dilihat Webpack:

  • ok, fungsi add murni dibuat dan diekspor di sini - mungkin saya bisa menghapusnya jika tidak akan digunakan nanti;
  • kemudian window.memoize dipanggil, yang ditambahkan add;
  • Saya tidak tahu apa yang dia lakukan window.memoize, tetapi saya tahu bahwa dia mungkin akan menelepon add dan membuat efek samping.
  • jadi untuk keamanan saya akan meninggalkan fungsi add dalam bundel, bahkan jika tidak ada orang lain yang menggunakannya .

Pada kenyataannya, kami yakin itu window.memoizeadalah fungsi murni yang tidak membuat efek samping dan penambahan panggilan jika seseorang menggunakannya memoizedAdd.

Tetapi Webpack tidak mengetahui hal ini dan, demi perdamaian, menambahkan fungsi add pada bundel terakhir.

Sejujurnya: versi terbaru dari Webpack dan Terser sangat bagus dalam mendeteksi efek samping.

gambar
Kami memberi Webpack lebih banyak informasi dan mendapatkan bundel yang dioptimalkan.

Sekarang pengumpul memiliki informasi yang cukup untuk analisis:

  • dipanggil di sini memoizedi tingkat modul, ini bisa penuh dengan masalah;
  • tetapi fungsinya memoizeberasal dari impor ES6, Anda perlu melihat fungsinya di util.js;
  • memang, memoize terlihat seperti fungsi murni, tidak ada efek samping;
  • jika tidak ada yang menggunakan fungsi ini add, kita dapat dengan aman mengecualikannya dari bundel terakhir.

Ketika Webpack tidak menerima informasi yang cukup untuk membuat keputusan, itu akan mengambil jalan yang aman dan meninggalkan fungsinya.

Gunakan alat-alat untuk mengidentifikasi potensi masalah pembolosan


Saya menemukan dua alat untuk mengidentifikasi masalah.

Alat pertama adalah penggabungan modul , sebuah plugin untuk Webpack, yang memungkinkan Anda untuk mencapai peningkatan kinerja yang signifikan. Ini memiliki opsi debugging. Perlu dicatat bahwa faktor-faktor yang mencegah penggabungan dan trichashing adalah sama: misalnya, efek samping pada tingkat modul. Perhatikan peringatan plugin dengan serius, karena masalah apa pun berpotensi meningkatkan ukuran bundel.

Yang kedua adalah plugin untuk linter https://www.npmjs.com/package/eslint-plugin-tree-shaking . Saya belum mengintegrasikannya ke dalam boilerplate saya, karena itu tidak mendukung aliran ketika saya bereksperimen dengannya. Namun, dia cukup mengidentifikasi masalah dengan trichashing.

Hati-hati dengan perpustakaan


Cobalah menggunakan perpustakaan yang dioptimalkan untuk trichashing. Jika Anda mengimpor bundel besar kode yang diperkecil, misalnya jquery.min.js, ada kemungkinan modul ini tidak akan dioptimalkan. Lebih baik mencari modul dari mana fungsi atom dapat diimpor, dan untuk perakitan dan minifikasi menggunakan Webpack atau Rollup.

Terkadang Anda dapat mengimpor seluruh perpustakaan. Misalnya, ketika menggunakan membangun produksi Bereaksi, Anda tidak perlu membuang apa pun - semua yang ada di dalamnya sudah dioptimalkan.

Jika Anda menggunakan pustaka yang mengekspor fungsi individual, misalnya, lodash, coba impor hanya fungsi yang diperlukan dan pastikan yang lain dikecualikan dari bundel terakhir.

Gunakan bendera bangun


Plugin DefinePlugin untuk Webpack memiliki fitur yang luar biasa, tetapi bukan yang paling terkenal - kemampuan untuk mempengaruhi kode apa yang akan dikecualikan selama proses pembuatan.

gambar

Jika kita meneruskannya __PRODUCTION__: trueke plugin, tidak hanya pemanggilan fungsi validateOptions, tetapi juga definisinya akan dikecualikan dari bundel terakhir .
Ini menyederhanakan pembuatan bundel berbeda untuk pengembangan dan produksi, dan juga membantu memastikan bahwa kode yang dimaksudkan untuk debugging tidak masuk ke dalam produksi.

Mulai perakitan


Sangat sulit untuk menentukan bagaimana Webpack akan mengoptimalkan modul tertentu.

Jadi jalankan build, periksa bundel terakhir dan lihat apa yang terjadi. Lihatlah kode JavaScript dan pastikan tidak ada yang tersisa di dalamnya yang seharusnya dibuang dengan cara trichashing.

Sesuatu yang lain


Jika Anda tahu tips berguna lainnya, silakan tulis tentang ini di komentar.

All Articles