Material-ui: Bisakah pengetikan disederhanakan untuk meningkatkan kinerja?

Dibuat pada 7 Jan 2020  ·  70Komentar  ·  Sumber: mui-org/material-ui

Seperti yang disarankan oleh @eps1lon di #18128, saya membuat masalah ini sebagai tempat untuk mendiskusikan pengetikan Material-UI dan apakah mereka dapat disederhanakan untuk mengurangi jumlah waktu yang dihabiskan untuk memeriksanya, terutama selama pengeditan.

Selalu ada ketegangan antara memiliki tipe yang paling tepat (yang memberikan kesalahan terbaik dan penyelesaian editor) dan memiliki pemeriksaan tipe yang cepat (ujung spektrum adalah any ).
Masalah seperti https://github.com/microsoft/TypeScript/issues/34801 menunjukkan bahwa Material-UI mungkin mendapat manfaat dari melonggarkan ketepatan untuk mendapatkan kembali beberapa perf.

Dari repro yang saya selidiki sejauh ini, banyak kelambatan tampaknya berasal dari sejumlah besar nama properti CSS (lihat https://github.com/mui-org/material-ui/blob/master/packages/ material-ui-styles/src/withStyles/withStyles.d.ts). Saya sendiri bukan pengguna CSS aktif, saya punya beberapa pertanyaan naif:

1) Apakah saya benar dalam berasumsi bahwa memiliki nama dan tipe untuk setiap properti CSS yang terkenal sangat berharga dan bukan sesuatu yang bisa kita lepaskan?
2) Jenis CSSProperties tampaknya ada untuk mendukung "pemilih semu dan kueri media", yang - menurut bacaan saya yang terbatas - tampaknya dinamai tas properti CSS tambahan.
a) Apakah tas ini sendiri rekursif atau hanya ada satu lapisan tambahan? Yaitu, apakah Anda beralih dari width ke foo.width atau ke foo.bar.width , dll? Jika hanya satu level, penyederhanaan jenis akan memotong repro lokal saya dari 4,6 detik menjadi 3,6 detik (yaitu kemenangan besar).
b) Saya bermain-main dengan tipenya sendiri dan tidak dapat menemukan yang lebih baik dari BaseCSSProperties[keyof BaseCSSProperties] , tetapi - seperti yang saya kira Anda ketahui - itu bukan tipe yang sangat berguna. Pada dasarnya dikatakan bahwa setiap properti CSS dapat memiliki jenis properti CSS (lainnya) - itu hanya sedikit lebih baik dari any .
3) Dalam StyleRules , jika tidak ada properti, Anda mendapatkan CSSProperties atau () => CSSProperties (yang dengan sembarangan akan saya sebut "Properties CSS thunked"), yang masuk akal - CSSProperties mungkin malas. Jika ada properti, Anda mendapatkan CreateCSSProperties<Props> , yang masuk akal - Props mungkin diperlukan untuk menghitung CSSProperties - atau (props: Props) => CreateCSSProperties<Props> , yang tidak saya lakukan 't mengerti karena secara efektif malas ganda - Anda telah melewati Props sekali untuk mendapatkan CreateCSSProperties dan sekali lagi untuk mendapatkan properti individual. Mengapa "berduri ganda"?

Secara terpisah, saya menduga, tetapi belum menunjukkan bahwa IsEmptyInterface terlalu mahal untuk manfaat yang diberikannya. Namun, mungkin saja saya tidak sepenuhnya memahami manfaatnya, jadi akan sangat membantu untuk mendengar lebih banyak.

Bisakah kita bekerja sama untuk menemukan keseimbangan yang tepat antara akurasi dan kinerja? (Catatan: "buat kompiler lebih cepat" jelas merupakan strategi yang layak, tetapi saya ingin mengetik di tempat yang baik sebelum kami mengoptimalkannya.) Terima kasih!

performance typescript

Komentar yang paling membantu

Saya mulai menambahkan Material UI ( 4.9.4 ) ke proyek saya hari ini, dan pelambatannya sangat signifikan sehingga saya rasa saya bahkan tidak dapat menggunakannya dalam proyek saya. Baru saja menambahkan komponen <Slider/> , dikustomisasi menggunakan withStyles() .

Kita berbicara tentang umpan balik TypeScript instan di IDE saya ke apa yang terasa seperti 5-10 detik (untuk bagian dari kode saya yang bahkan tidak berinteraksi dengan Material UI sekarang - ini hanya perlambatan TypeScript lengkap dalam file yang menggunakan komponen). Pasti ada yang salah dengan tipe ini (atau ya, terlalu rumit), sepertinya @amcasey sedang melakukan penyelidikan yang bagus - saya harap Anda bisa menyelesaikannya!

Mencoba menemukan cara agar saya setidaknya dapat mengecualikan semua hal TypeScript untuk @material-ui untuk saat ini (pada dasarnya membuat seluruh modul any ) - tetapi TypeScript tampaknya tidak membuatnya cukup mudah.

Semua 70 komentar

Saya tidak terbiasa dengan tipe material-ui tetapi cobalah untuk menjawab pertanyaan-pertanyaan ini.

  1. Ya, dukungan penuh untuk semua properti css yang dideklarasikan dalam standar web sebenarnya berguna.
  2. a) Dalam kasus kami, kami tidak pernah menggunakan kedalaman lebih dari 2, tetapi kasus seperti ini sangat mungkin terjadi
    ``` naskah
    const styles = (tema: Tema) =>
    buatGaya({
    suatu tempat: {
    '&:arahkan tombol': {
    visibilitas: 'terlihat',
    opasitas: 1,
                ':after': {
                    content: 'x',

                    [theme.breakpoints.up('lg')]: {
                        content: 'close',
                    },
                }
            },
        }
    });
```
b) I do not understand why `BaseCSSProperties[keyof BaseCSSProperties]` is needed there

  1. Saya pikir (props: Props) => CreateCSSProperties<Props> tidak diperlukan, kami mengecualikan jenis ini dalam versi jenis material-ui kami, dan tidak ada hal buruk yang terjadi.

Mungkin ada baiknya melihat implementasi tipe di versi 3.9.3, karena di versi ini, pengecekan tipe cukup cepat dan pengetikan bagus.

Pertama-tama saya ingin mengucapkan terima kasih karena telah menjangkau dan menyelidiki hal ini. Sangat membantu untuk memiliki seseorang yang membandingkan bagian mana dari jenisnya yang lambat atau tidak.

  1. Apakah saya benar dalam berasumsi bahwa memiliki nama dan tipe untuk setiap properti CSS yang terkenal sangat berharga dan bukan sesuatu yang bisa kita lepaskan?

Tidak mungkin untuk tidak memihak di sini. Saya tidak berpikir kita bisa menyerah meskipun melihat ekosistem yang lebih luas. Chrome devtools memiliki fitur ini, bereaksi sendiri ketik prop style dengan CSSProperties dll. Saya tidak dapat melihat diri saya beralih dari IDE ke browser dan memeriksa apakah itu dekorasi teks atau dekorasi font atau transformasi teks.

  1. [...]
    Apakah tas ini sendiri rekursif atau hanya ada satu lapisan tambahan?

Saya perlu memeriksa solusi CSS-in-JS yang kami gunakan. Secara teknis kueri media dalam CSS dapat bersifat rekursif. Saya akan bersedia untuk memotong rekursif ini dan melihat apakah kami mendapatkan laporan. Kueri media yang disarangkan secara teknis dapat diratakan dengan operator and . Kita harus membatasinya pada dua level: Satu untuk kueri media dan satu untuk penyeleksi semu. Ini masih harus diketik IMO:

const styles = {
  root: {
    '<strong i="18">@media</strong> (max-width: 12cm)': {
      ':hover': {}
    }    
  }
}

Apakah ini sesuatu yang Anda lihat sendiri tulis @oliviertassinari?

  1. [...]
    CSSProperties - atau (alat peraga: Alat Peraga) => CreateCSSProperties, yang saya tidak mengerti karena secara efektif malas ganda - Anda telah melewati Props sekali untuk mendapatkan CreateCSSProperties dan sekali lagi untuk mendapatkan properti individual. Mengapa "berduri ganda"?

Jika argumen itu sendiri bukan tas properti tetapi fungsi, maka itu membutuhkan tema. Gaya dapat bergantung pada dua jenis tas properti yang berbeda: Tema (tersedia melalui API konteks React) atau props (langsung diteruskan ke komponen):

makeStyles({ root: { color: 'blue' }}); // A
makeStyles(theme => ({ root: { color: theme.color } })); // B
makeStyles({ root: props => ({ color: props.color})}); // C
makeStyles({ root: { color: props => props.color } }); // D: same as C, only exists for dev ergonomics
makeStyles(theme => ({ root: props => ({ color: props.color || theme.color }) })); // E: what you called "double-lazy"

Ini bukan tentang evaluasi malas untuk meningkatkan kinerja tetapi lebih tentang harus menunggu konteks dan alat peraga tersedia.

Secara terpisah, saya kira, tetapi belum menunjukkan bahwa IsEmptyInterface terlalu mahal untuk manfaat yang diberikannya. Namun, mungkin saja saya tidak sepenuhnya memahami manfaatnya, jadi akan sangat membantu untuk mendengar lebih banyak.

Ada satu kasus di mana ini digunakan:

Mempertimbangkan

const useStaticStyles = makeStyles({ root: { color: 'blue' } });
const useDynamicStyles= makeStyles({ root: { color: props =>  props.color } })
function Component() {
  const staticClasses = useStaticStyles(); // No error
  const throwingClasses = useDynamicStyles(); // $ExpectError
  const dynamicClasses = useDynamicStyles({ color: 'blue' });
}

Untuk menyimpulkan tanda tangan panggilan dari fungsi yang dikembalikan dari makeStyles (yaitu kait bernama sesuatu seperti useSomeStyles ). Kita perlu memeriksa jenis tas gaya apa yang diteruskan ke makeStyles . Kami sudah memiliki pembantu untuk menyimpulkan jenis alat peraga yang digunakan dalam tas gaya . Jika tas gaya statis yaitu TS menyimpulkan tipe {} . Kemudian kita cek tipe inferred dari Props dengan IsEmptyInterface dan untuk satu branch kita gunakan call signature dengan parameter 0 dan untuk branch lainnya kita gunakan call signature dengan 1 parameter yang sama dengan tipe inferred props ( lihat StylesRequireProps dan StylesHook .

Singkatnya: Kami menghindari keharusan untuk menulis useStaticStyles({}) atau useStaticStyles(null as any) . Itu diperkenalkan di https://github.com/mui-org/material-ui/pull/14019 untuk menutup https://github.com/mui-org/material-ui/issues/14018. Saya kira kita bisa melakukan hubungan pendek menentukan tanda tangan panggilan. Mungkin membebani tanda tangan panggilan alih-alih menggunakan tipe bersyarat?

Masalah dengan "fitur" ini adalah bahwa pengguna tingkat lanjut tidak memiliki masalah dalam menggunakan null as any jika mereka memahami alasannya. Bahkan mungkin melewati objek kosong tidak apa-apa meskipun tidak diperlukan. Namun, ini sangat membingungkan/frustrasi ketika tidak terbiasa dengan Material-UI atau TypeScript. Terutama karena sebagian besar penataannya tidak didasarkan pada alat peraga.

Sepertinya sebagian besar waktu pemeriksa tipe sibuk dengan solusi penataan? Saya akan mengharapkan tanda tangan panggilan untuk komponen kami yaitu alat peraga apa yang mungkin paling sering digunakan.

Saya dapat merayapi lebih banyak repositori untuk melihat secara khusus penggunaan withStyles atau makeStyles . Sejauh ini saya hanya melihat penggunaan alat peraga.

Apakah ini sesuatu yang Anda lihat sendiri tulis @oliviertassinari?

@eps1lon Kami memiliki beberapa kemunculan ini bersarang di basis kode (misalnya dengan <strong i="8">@media</strong> (hover: none) ). Tapi itu tidak terlalu sering untuk komponen inti. Saya membayangkan itu adalah userland yang sama. Itu pasti bisa menjadi bagian dari tradeoff.

@beholderrk

  1. Saya pikir sebanyak itu, tetapi saya pikir saya mungkin juga bertanya.
  2. a) Kedalaman dua harus dapat diekspresikan - hanya akan ada sedikit lebih banyak duplikasi daripada kedalaman satu.
    b) Butuh waktu cukup lama bagi saya untuk memahami hal ini dan saya berharap dapat menjelaskannya secara langsung, bukan melalui teks. Pada dasarnya, tanda tangan indeks mengatakan bahwa semua properti memiliki tipe yang sama. Itu hanya bisa berfungsi jika itu menentukan tipe yang berfungsi untuk semuanya. Salah satu cara untuk melakukannya adalah dengan membuat gabungan semua tipe properti, BaseCSSProperties[keyof BaseCSSProperties] - maka akan benar bahwa setiap properti memiliki tipe yang kompatibel. Misalnya, satu-satunya properti yang dapat Anda miliki di CSS adalah name: string dan width: number . Salah satu cara untuk menentukan tanda tangan indeks yang berfungsi dengan kedua properti adalah dengan mengatakan bahwa setiap properti adalah string | number . Itu tidak bagus - name tidak akan pernah menjadi number dan width tidak akan pernah menjadi string - tetapi berhasil. Masalah sebenarnya adalah bahwa hal yang Anda inginkan sebenarnya tidak dapat diungkapkan (setidaknya, sejauh yang dapat kami tentukan - mungkin ada peretasan "pintar" yang melakukannya). Anda sebenarnya ingin mengatakan bahwa tipe Anda berisi name: string , width: number atau x: CSSProperties , di mana x adalah name atau width - "apa pun kecuali" yang hilang. Saya harap itu sedikit lebih jelas.
  3. Kedengarannya seperti @eps1lon ingin mengatakan sesuatu tentang ini, tetapi saya masih menguraikan tanggapannya.

Garis dasar yang dikenal baik akan sangat membantu. Apakah Anda kebetulan memiliki tautan?
Sunting: menemukannya.

@eps1lon Senang menjadi bagian dari percakapan. Cepat, jenis yang benar baik untuk semua orang. 😄

  1. Tidak ada argumen di sini - saya pikir saya akan bertanya lebih awal karena itu akan membuat seluruh percakapan terputus.
  2. Dua lapisan tampaknya bisa dilakukan (dengan peringatan penting bahwa jenisnya sebagian besar masih tidak berguna). Saya akan melihat apakah saya dapat menyusun sesuatu.
  3. Dengan kurangnya konteks saya, tidak jelas bahwa tema dan alat peraga berbeda. Jika ya, maka strukturnya masuk akal. Terima kasih telah mengklarifikasi.

Mengenai isEmptyInterface , bisakah Anda membuat parameter properti menjadi (misalnya) useStaticStyles opsional? Itu akan kurang tepat, dalam arti bahwa penelepon dapat menghilangkannya ketika mereka diharapkan, tetapi akan jauh lebih murah untuk mengetik cek. Seperti yang saya katakan, saya tidak punya angka atau apa pun untuk Anda - itu hanya spekulasi di pihak saya.

Apa pendapat Anda tentang 2(b)? Sepertinya tipe itu tidak memberikan banyak nilai karena pada dasarnya mengatakan bahwa nama properti apa pun akan diterima dan tipe pengembalian bisa menjadi salah satu dari banyak hal.

Mengenai isEmptyInterface, bisakah Anda membuat parameter properti menjadi (misalnya) useStaticStyles opsional?

Saya ingin bereksperimen dengan membebani tanda tangan panggilan terlebih dahulu dan melihat apakah ini berdampak. Kemudian kami akan mencoba membuatnya lebih sedikit suara dengan membuatnya selalu opsional. Tampaknya lebih aman dari biasanya untuk membuatnya lebih sedikit suara karena hampir semua kasus penggunaan hanya memanggilnya sekali sehingga Anda mungkin hanya akan membuat kesalahan sekali dan itu muncul dengan cukup cepat. Akan sulit untuk menjualnya meskipun jika itu tidak memberi kami banyak kinerja. Saya akan menggunakan repositori yang dibuat untuk masalah asli (https://github.com/microsoft/TypeScript/issues/34801#issue-514055289).

Apa pendapat Anda tentang 2(b)? Sepertinya tipe itu tidak memberikan banyak nilai karena pada dasarnya mengatakan bahwa nama properti apa pun akan diterima dan tipe pengembalian bisa menjadi salah satu dari banyak hal.

Melewatkan itu secara tidak sengaja. Saya akan melihatnya setelah eksperimen IsEmptyInterface.

@eps1lon Setuju sekali - pertahankan isEmptyInterface jika menghilangkannya bukan kemenangan perf yang substansial.

Dengan #19320 kami menyingkirkan beberapa tipe kondisional kompleks di mana fungsi yang berlebihan mencapai hal yang sama (menghapus IsEmptyInterface dan semua tipe logika boolean). Meskipun tampaknya itu tidak memberi kami banyak keuntungan selain memiliki lebih sedikit kode.

Saya ingin menambahkan bahwa saya sedang beralih antara TS 3.2.4 dan 3.7.4. Rangkaian pengujian tipe kami berjalan 50% lebih lambat di 3.7.4 dibandingkan dengan 3.2.4 (~ 90-an vs 50-an).

Saya akan terus menyelidiki apakah kami dapat membatasi kedalaman CSSProperties dan menghapus dukungan untuk kueri media dan penyeleksi semu sepenuhnya. Memiliki yang tidak diketik sebenarnya bukan pilihan. Pemeriksa tipe harus dapat memeriksanya dalam waktu yang wajar.

Mungkin pemeriksa tipe adalah hambatan yang sebenarnya. Mungkin kita bisa menyelidiki di mana versi perf yang terkena.

Jika Anda mengirimi saya perintah yang Anda jalankan di 3.2.4 dan 3.7.4, saya dapat membuat profil secara lokal. Namun, pengalaman menunjukkan bahwa penyebabnya mungkin akan menjadi tambahan, pemeriksaan yang diinginkan ditambahkan sejak 3.2.4. (Dan saya berasumsi "0s" adalah salah ketik - mungkin "40-an" atau "50-an"?)

Mengenai CSSProperties, saya setuju bahwa menjaga nama dan tipe properti sangat berharga. Namun, saya pikir ada lebih dari sekadar memeriksanya dalam waktu yang wajar - masalah pertama adalah sistem tipe tidak dapat benar-benar mengekspresikan bentuk yang Anda inginkan. Saya pikir kita mungkin akan meluangkan waktu untuk mengerjakan solusi umum untuk masalah tersebut - dapatkah saya berasumsi bahwa Anda tertarik untuk berpartisipasi dalam diskusi itu?

Kami memiliki skrip untuk membandingkan beberapa versi kompiler jadi, jika Anda dapat mengidentifikasi tes yang cukup stabil yang Anda ingin kami jalankan, kami dapat memperkirakan grafik perlambatan dari waktu ke waktu.

(Dan saya berasumsi "0s" adalah salah ketik - mungkin "40-an" atau "50-an"?)

Maaf, ini adalah 50-an.

Jika Anda mengirimi saya perintah yang Anda jalankan di 3.2.4 dan 3.7.4, saya dapat membuat profil secara lokal.

Itu hanya yarn typescript di root yang menjalankan perintah yang sama di setiap ruang kerja yang mengimplementasikannya. Misalnya yarn workspace @material-ui/styles run typescript menguji tipe kita dengan tslint dan dtslint 's $ExpectError . Dalam 3.7.4 kami menemukan beberapa kegagalan dan harus menyesuaikan pengujian kami (lihat #19242)

masalah pertama adalah bahwa sistem tipe tidak dapat benar-benar mengekspresikan bentuk yang Anda inginkan.

Saya curiga sebanyak itu. Sepertinya cara kita mencampur bentuk "konkret" dengan objek dengan tanda tangan indeks hanyalah solusi.

dapatkah saya berasumsi bahwa Anda tertarik untuk berpartisipasi dalam diskusi itu?

Pastinya. Saya akan menghabiskan sedikit lebih banyak waktu dengan CSSProperties non-rekursif dan kemudian menulis lebih banyak tes untuk mengilustrasikan apa yang kita cari dalam tipe tersebut. Saya menduga bahwa solusi penataan css-in-js lainnya mengalami kemacetan kinerja yang serupa.

Saya akan mencoba perintah-perintah itu besok (saya kira saya harus menyebutkan bahwa saya sedang dalam waktu pasifik dan mengamati hari libur AS).

Sepertinya cara kita mencampur bentuk "konkret" dengan objek dengan tanda tangan indeks hanyalah solusi.

Terima kasih, saya telah berjuang dengan cara terbaik untuk mengungkapkannya. Ya, Anda benar bahwa tanda tangan indeks tidak melakukan apa yang Anda inginkan. Kami memiliki beberapa pemikiran tentang varian yang mungkin, tetapi kami perlu mengeksplorasi implikasi kinerjanya.

Saya menduga bahwa solusi penataan css-in-js lainnya mengalami kemacetan kinerja yang serupa.

Sangat banyak sehingga. Kami berharap apa pun yang kami lakukan untuk Anda dapat digeneralisasi untuk meningkatkan keseluruhan ekosistem.

Saya merasa seperti kehilangan sesuatu yang jelas, tetapi saat ini saya terjebak. Pertama, saya menyerah pada Windows - semuanya tampak bekerja lebih baik di Linux. Beri tahu saya jika Anda ingin mempelajarinya. Kedua, saya bisa menjalankan yarn typescript - dengan bersih, sejauh yang saya tahu - tetapi tampaknya menjalankan tslint, daripada tsc murni. Ketika saya menjalankan tsc pada tsconfig.json yang sama (saya secara khusus menguji dengan gaya), saya mendapatkan ~40 kesalahan. Apa yang saya lakukan salah? Untuk tujuan pembuatan profil, menurunkan repro menjadi satu permintaan tsc akan sangat membantu.

@amcasey yarn typescript bukan tentang kompilasi tetapi menguji tipe kami. Kami menggunakan pengaturan yang mirip dengan yang digunakan dalam repo PastiTyped. File TypeScript di packages/* hampir selalu hanya sekumpulan pernyataan yang harus lulus atau gagal yang kita tangkap dengan $ExpectError .

Saya pikir kasus uji "dunia nyata" terbaik adalah menggunakan tsc pada dokumen kami melalui yarn workspace docs run tsc -p tsconfig.json setelah Anda menambahkan skipLibCheck: true dan noEmit: true ke ./docs/tsconfig.json :

--- a/docs/tsconfig.json
+++ b/docs/tsconfig.json
@@ -3,6 +3,8 @@
   "include": ["types", "src/pages/**/*"],
   "compilerOptions": {
     "allowJs": false,
-    "noUnusedLocals": true
+    "noUnusedLocals": true,
+    "noEmit": true,
+    "skipLibCheck": true
   }
 }

@eps1lon Terima kasih telah mengklarifikasi. Saya tidak senang tslint menjadi lebih lambat, tetapi saya ingin fokus pada satu variabel pada satu waktu. Saya akan menjalankan docs build yang Anda sarankan dengan berbagai versi TypeScript dan melihat apakah ada yang keluar. Terima kasih!

Pengaturan ini sempurna. Saya melihat waktu pemeriksaan berlipat ganda antara 3,3 dan 3,4.

| Versi | Periksa Waktu |
|-|-|
| 3.2 | 16,71 detik |
| 3.3 | 16,79 detik |
| 3.4 | 35,25 detik |
| 3.5 | 21.40-an |
| 3.6 | 23.10 |
| 3.7 | 27,39 detik |

Saya akan menggali lebih dalam, tetapi saya diberitahu bahwa implementasi 3.3 tipe kondisional tidak lengkap, implementasi 3.4 lambat, dan implementasi 3.5 bagus. Jadi, sayangnya, ini mungkin diharapkan.

Secara khusus, saya menduga perubahan ini menyebabkan pelambatan seperti yang dijelaskan dalam bug ini .

Saya menemukan bahwa antara 3,5 dan 3,7 ada peningkatan 6 detik dalam waktu yang diperlukan untuk menjalankan pemeriksaan. Itu terlihat cukup substansial.

@embeddedt Angka-angka itu berasal dari single run dengan setiap versi, jadi mungkin ada sedikit noise. Namun, saya akan menggali dan melihat apakah saya dapat menemukan sesuatu.

Saya mengulangnya di VM Linux dan 3.7 secara konsisten 20-25% lebih lambat dari 3.5.

Ini terbukti cukup sulit untuk membagi dua karena run berturut-turut dari build yang sama bervariasi ~5% dan perbedaan antara 3,5 dan 3,6 atau antara 3,6 dan 3,7 hanya ~10%.

Satu hal mencurigakan yang saya perhatikan adalah bahwa styled-components menyediakan file .d.ts terpisah untuk TS >= 3.7, jadi perbandingannya mungkin bukan apple to apple.

Sangat mengejutkan saya, tipe styled-components tampak lebih cepat. Membandingkan apel dengan apel masih akan membuat penyelidikan lebih mudah.

Saya tidak bisa memikirkan solusi yang cerdas, jadi saya akan merencanakan waktu kompilasi digabungkan dengan menggabungkan dan mencari paku. Saya berharap untuk memiliki nomor besok.

@amcasey Terima kasih atas upaya Anda dalam menyelidiki ini! Sangat rapi melihat anggota tim TS dan Material UI bekerja sama. Saya menemukan masalah Github ini mencoba mencari tahu mengapa pengalaman editor kami dengan Material UI sangat lambat (kami menggunakannya dalam dua proyek di tempat kerja). Dapat dipastikan bahwa kami melihat dampak yang cukup signifikan dalam intellisense dan kegunaan di dalam VsCode.

Pada titik ini kami akan dengan senang hati menukar sedikit keamanan tipe di JSS kami untuk umpan balik yang cepat untuk sisa perpustakaan. Terkadang butuh 8-10 detik menunggu sebelum server TypeScript mengejar perubahan kode

Bahkan dengan rata-rata tiga putaran, datanya sangat bising. Namun, tampaknya ada penurunan runtime yang nyata di https://github.com/microsoft/TypeScript/commit/ad322a561a301ae357da051b9221b2222c13be36 peningkatan yang nyata (kembali ke kira-kira level sebelumnya) di https://github.com/microsoft/TypeScript /commit/480b73915fdd805952fd355e4cf3e1bc803e0878 dan tren kenaikan umum setelah itu (meskipun terlihat terlalu seragam bagi saya dan saya menduga faktor lingkungan) termasuk lonjakan tertentu di https://github.com/microsoft/TypeScript/commit/c5e6d95e930048a033868d72440a9296904a33ec. Saya akan fokus pada dua yang pertama sampai saya menjalankan beberapa tes lagi untuk mengkonfirmasi tren kenaikan umum (bagaimana bisa menjadi lebih buruk secara seragam setiap komit?).

Tren kenaikan berdiri untuk pengawasan dan saya tidak tahu apa yang bisa menyebabkan itu. Mungkin pelambatan diskrit sangat berdekatan sehingga kebisingan membuatnya terlihat seperti kurva tunggal.

Saya menemukan hingga 10 run per komit dan sekarang ada empat regresi berbeda di area miring. :senyum:

https://github.com/microsoft/TypeScript/commit/26caa3793e310e271ddee8adc1804486e5b0749f (~700ms)
https://github.com/microsoft/TypeScript/commit/250d5a8229e17342f36fe52545bb68140db96a2e (~500ms)
https://github.com/microsoft/TypeScript/commit/7ce793c5b8c621af5ce50af0ca3958c7bd6541bf (~1300ms)
https://github.com/microsoft/TypeScript/commit/28050d5c47c6cd7627555f12cf13b1062f80322a (~400ms)

(Total waktu sebelum regresi dimulai adalah ~33 detik.)

Hanya untuk sedikit meredam ekspektasi: kemungkinan besar beberapa dari regresi ini akan berubah menjadi cek tambahan yang berharga dan, bahkan jika kami berhasil mendapatkan semua cek itu secara gratis, kami masih akan mengambil diskon 20% "terlalu lama ".

Sunting: Saya telah memperbarui tautan. Karena saya berjalan mundur sepanjang waktu, saya menjadi bingung dan menandai penggabungan _before_ setiap regresi.

@eps1lon Seseorang di ujung ini menyarankan agar menghapus @ts-ignore dapat membantu. Pada dasarnya, ketika kesalahan terdeteksi, diasumsikan bahwa prioritas utama pengguna adalah mendapatkan informasi yang baik tentang kesalahan tersebut, jadi ada kemungkinan banyak pekerjaan tambahan akan dilakukan. Jika informasi itu kemudian dibuang (karena @ts-ignore ), maka waktu itu akan terbuang sia-sia. (Sayangnya, tidak mudah untuk mendeteksi bahwa kesalahan tidak perlu dideteksi.) Strategi alternatif adalah menambahkan pernyataan tipe eksplisit (termasuk ke any ) hingga kompilator berhenti mengeluh.

@eps1lon Seseorang di ujung ini menyarankan agar menghapus @ts-ignore dapat membantu.

Kami hanya memiliki satu penggunaan di docs/ . Saya tetap menghapusnya untuk berjaga-jaga: #19504

Sejujurnya kedengarannya seperti @ts-ignore adalah anti-pola dalam kasus itu. Tidak hanya tidak memberi Anda informasi yang berguna yaitu jenis kesalahan apa yang kami miliki tetapi juga merupakan hambatan kinerja.

Sejauh yang saya tahu @ts-ignore hanya berguna dalam file .js yang sedang diperiksa jenisnya.

Hmm, itu hampir pasti tidak menjelaskan mengapa PR meningkatkan pesan kesalahan menurunkan kinerja. Jelas terlihat seperti peningkatan. 😄

Saya cukup baru di dunia TypeScript, terutama dalam hal solusi styling-in-JS, tapi saya diam-diam mengikuti utas ini selama sebulan terakhir dan saya ingin tahu pendapat orang tentang solusi potensial, di setidaknya dalam jangka pendek.

Saya berasumsi bahwa beberapa pengguna (saya sendiri) tidak terlalu banyak menggunakan sistem penataan gaya bawaan, atau menghindarinya sama sekali. Saya melakukan itu terutama karena saya jauh lebih akrab dengan CSS biasa atau Sass dan saya belum benar-benar punya waktu untuk menggali cara efektif menggunakan sistem penataan JS. Saya lebih suka membuat nama kelas saya sendiri, menulis file stylesheet terpisah, menggunakan nama kelas di dalam komponen React saya dan melanjutkan. Pada dasarnya, saya bergaya seolah-olah saya sedang menulis HTML biasa.

Karena itu, apakah mungkin/praktis untuk menambahkan tanda yang mematikan pemeriksaan tipe untuk bagian mahal dari sistem penataan (mungkin dengan melakukan hal-hal seperti type CSSProperties = any )? Saya tidak tahu statistik untuk jumlah orang yang menggunakan sistem gaya vs. tidak menggunakannya, tetapi saya pikir itu tidak akan banyak merugikan (asalkan cek ditambahkan untuk menguji pengetikan dengan set bendera itu) , dan ini akan menjadi cara cepat untuk meningkatkan kinerja setidaknya untuk satu segmen pengguna.

Hanya ingin menyebutkan ide umum; merasa bebas untuk menembak jatuh. :slightly_smiling_face:

@embeddedt Secara umum, secara eksplisit menandai sesuatu sebagai any adalah cara yang baik untuk menonaktifkan pemeriksaan tipe untuk simbol itu. Karena itu, saya tidak dapat mengingat apakah Anda dapat menghancurkan deklarasi sebelumnya atau lebih tepatnya, seperti yang Anda sarankan, Anda memerlukan dukungan kompiler untuk menghindari masalah deklarasi duplikat.

Nomor baru (mesin berbeda, metrik waktu berbeda):

| Versi | Total Waktu |
|-|-|
| 3.5.3 | 32,5 detik |
| 3.7.5 | 35.9s |
| tuan | 29,9 detik |

Beberapa masalah yang saya posting di atas masih terbuka, tetapi pada dasarnya kami kembali ke 3,5 perf (untuk benchmark ini). Jelas, ini masih jauh lebih lambat dari yang kita inginkan, tetapi kumpulan perubahan berikutnya kemungkinan berada di sisi material-ui.

Diuji 3.8.1 pada rangkaian pengujian kami dan sepertinya mereka secepat yang sebelumnya menggunakan 3.2.4 (3.7 secara signifikan lebih lambat).

Terus terang, saya tidak percaya seberapa banyak kinerja yang dapat kami peroleh kembali tanpa melepaskan fungsionalitas baru. :smile: Saya pikir mungkin ada sedikit kelonggaran (misalnya https://github.com/microsoft/TypeScript/pull/36754), tapi saya masih curiga bahwa perubahan yang paling berdampak adalah penyederhanaan jenis CSSProperties. Apakah Anda memiliki kesempatan untuk bermain-main dengan mereka sama sekali? Sepertinya setidaknya sebagian pengguna (misalnya @embeddedt) akan dengan senang hati menyerahkan beberapa jenis pengecekan sebagai ganti kemenangan perf.

Sepertinya setidaknya sebagian pengguna (misalnya @embeddedt) akan dengan senang hati menyerahkan beberapa jenis pemeriksaan sebagai ganti kemenangan perf

Bukankah seseorang dari tim TS baru saja men-tweet baru-baru ini bahwa untuk setiap pengguna yang menginginkan tipe yang lebih ketat ada satu yang menginginkan yang lebih longgar? :senyum:

Bagi saya ini bukan tentang pengecekan tipe (browser devtools memiliki kemampuan yang jauh lebih baik untuk memeriksa CSS Anda). Ini lebih tentang memiliki pelengkapan otomatis yang tersedia.

Saya akan bermain-main dengan "versi" yang berbeda dan melihat bagaimana mereka melakukannya.

@amcasey Saya tidak berpikir sifat rekursif dari CSSProperties (disebut CSSObject dalam gaya-komponen) adalah masalah utama. Kalau tidak, kinerja mereka akan seburuk milik kita. Lihat https://github.com/eps1lon/mui-types-perf/pull/6 dan log benchmark .

Ini mungkin lebih merupakan masalah dengan jumlah "kelebihan beban" yang kita lakukan. styled-components hanya mengizinkan objek statis sementara kami mengizinkan versi thunked serta setiap properti menjadi thunk. Aku tidak yakin.

Saya ingin menyederhanakan tanda tangan tipe (karena ini IMO juga lebih mudah dipahami oleh para pengembang) tetapi saya secara eksplisit diminta untuk mencocokkan implementasi JSS. Sekarang kami mendukungnya, kami tidak dapat dengan mudah mundur. Apalagi jika keuntungannya berada di wilayah 20%. Saya tidak berpikir itu membenarkan kerusakan.

Bisakah tipe secara kondisional dibuat kurang akurat (berdasarkan pengaturan pengguna)? Itu seharusnya tidak merusak kode yang ada (karena pengaturan dapat dimatikan secara default), dan akan memungkinkan pengguna seperti saya yang tidak memerlukan tipe kompleks untuk melihat peningkatan kinerja dengan cepat.

akan memungkinkan pengguna seperti saya yang tidak memerlukan tipe kompleks untuk melihat peningkatan kinerja dengan cepat.

Bahkan tidak dikonfirmasi bahwa Anda akan mendapatkan perbedaan yang nyata. Saya telah melihat 15% perf menang tetapi dipertanyakan apakah ini dapat dikenali.

"Pengaturan pengguna" yang saya lihat adalah menambal paket saat diinstal. Kami tidak memiliki bandwidth untuk mempertahankan beberapa versi pengetikan.

@eps1lon Maaf, saya pikir pertanyaan saya mungkin tidak jelas. Saya pikir CSSProperties baik-baik saja (meskipun, jelas, jika akan lebih cepat jika lebih kecil) - Saya sebenarnya berharap mungkin ada ruang untuk menyederhanakan subtipe di https://github.com/mui-org /material-ui/blob/master/packages/material-ui-styles/src/withStyles/withStyles.d.ts. Misalnya, apakah Anda akan mendapatkan penyelesaian yang lebih sedikit jika Anda mengubah jenis ini menjadi any ?

Sunting: di kotak saya, ini membuat kompilasi proyek docs 15% lebih cepat (29,7 detik menjadi 25,5 detik), tetapi saya tidak tahu efeknya pada pengalaman pengeditan.
Sunting 2: Sebenarnya, setelah Anda menyerah untuk melipat di bagian rekursif dari tipe, Anda bisa menggunakan BaseCreateCSSProperties dan properti lainnya akan memiliki tipe any (yaitu Anda dapat menyimpan tipe sebenarnya dari properti CSS).
Sunting 3: Sunting 2 tidak berfungsi karena pemeriksaan properti berlebih (yaitu nama properti sewenang-wenang tidak diizinkan dalam literal objek).

Poin Anda tentang penyelesaian vs pengecekan tipe sangat menarik karena saya memiliki hipotesis bahwa beberapa penulis tipe mungkin merasa seperti itu. @DanielRosenwasser Saya pikir kami ingin melakukan sesuatu seperti ini untuk mengakomodasi pola "a" | "b" | string - apakah itu berhasil?

Perhatikan juga bahwa styled-components mengalami (kami yakin) masalah kinerja pemeriksa yang terkait erat.

Mengenai kemampuan untuk menentukan jenisnya dengan lebih tepat, saya telah mengajukan https://github.com/microsoft/TypeScript/issues/36782 .

Sepertinya emotion mungkin berada di kapal yang sama.

Saya mulai menambahkan Material UI ( 4.9.4 ) ke proyek saya hari ini, dan pelambatannya sangat signifikan sehingga saya rasa saya bahkan tidak dapat menggunakannya dalam proyek saya. Baru saja menambahkan komponen <Slider/> , dikustomisasi menggunakan withStyles() .

Kita berbicara tentang umpan balik TypeScript instan di IDE saya ke apa yang terasa seperti 5-10 detik (untuk bagian dari kode saya yang bahkan tidak berinteraksi dengan Material UI sekarang - ini hanya perlambatan TypeScript lengkap dalam file yang menggunakan komponen). Pasti ada yang salah dengan tipe ini (atau ya, terlalu rumit), sepertinya @amcasey sedang melakukan penyelidikan yang bagus - saya harap Anda bisa menyelesaikannya!

Mencoba menemukan cara agar saya setidaknya dapat mengecualikan semua hal TypeScript untuk @material-ui untuk saat ini (pada dasarnya membuat seluruh modul any ) - tetapi TypeScript tampaknya tidak membuatnya cukup mudah.

@lostpebble Apakah hal yang sama terjadi dengan menggunakan sesuatu selain withStyles untuk menyesuaikan slider, katakanlah modul CSS?

@lostpebble Saat ini kami tidak memiliki cara yang didukung untuk mengecualikan kumpulan jenis tertentu. Jika Anda benar-benar menginginkannya, hal yang perlu dicoba adalah pemetaan jalur. Anda dapat mencoba pemetaan jalur seperti "@material-ui/*": ["simplemui"] dan kemudian membuat simplemui.d.ts berisi

declare const x: any;
export = x;

Itu akan secara efektif membuat semua tipe material-ui any . Ini jelas merupakan peretasan dan bukan sesuatu yang dapat saya rekomendasikan, tetapi mungkin membuka blokir pengalaman mengedit Anda.

Saya pikir kami telah membuat beberapa peningkatan yang baik (di suatu tempat di area 30%) tetapi sepertinya yang bisa kami lakukan sekarang adalah membuat pengetikan lebih longgar.

Ini benar-benar membutuhkan proposal konkret, misalnya kode salah mana yang akan Anda setujui agar dapat diterima oleh pemeriksa tipe. Kemudian kita perlu membuat tolok ukur dan melihat apakah ini membuat penyok yang berarti.

Anda harus memahami bahwa regresi yang sengaja diperkenalkan menambah banyak pekerjaan bagi pengelola karena kami harus menjelaskan hal ini kepada konsumen perpustakaan dan secara keseluruhan cukup membuat stres.

Jadi ini bukan prioritas bagi saya saat ini kecuali seseorang memiliki kecerdasan yang dapat ditindaklanjuti. Kalau tidak, saya harus menghabiskan terlalu banyak waktu untuk pengembalian yang sangat sedikit.

Dalam kasus saya untuk makeStyles(theme => createStyles(...)) , mengembalikan Record<ClassKey, any> dari createStyles(...) hampir ~setengah~ (dalam kode dan komputer saya, sekitar ~1200ms -> 750ms~ 1400ms → 1100ms) encodedSemanticClassifications-full: elapsed time ditampilkan di log tsserver (tampaknya bukan pekerjaan yang mahal, tetapi mungkin menunggu pemeriksaan tipe selesai).

export default function createStyles<ClassKey extends string, Props extends {}>(
  styles: StyleRules<Props, ClassKey>,
): Record<ClassKey, any>;

createStyles(...) memeriksa struktur gaya sehingga kita dapat melewati pemeriksaan tipe untuk argumen-jenis-serikat-masif-dari makeStyles vs.-jenis-pengembalian-serikat-massif dari createStyles.

~(Dan mengomentari seluruh kode makeStyles: 650ms)~

@ypresto createStyles hanya diperlukan untuk versi TypeScript tanpa const pernyataan. Jika Anda dapat menggunakan { display: 'block' as const } dalam basis kode Anda (ts >= 3.4) maka gunakan itu lebih dari createStyles .

@eps1lon Kami menyadarinya dan mencoba beralih di docs tetapi hasilnya tidak mengesankan.

@eps1lon dengan const dan tanpa createStyles , IntelliSense tidak menampilkan kandidat yang sadar konteks lagi :cry:

@ypresto Seharusnya. Apakah Anda memiliki contoh cuplikan kode?

@amcasey

Menambahkan as const ke objek luar atau properti secara efektif membunuhnya. Saya tidak ingin menempatkannya di setiap properti.

const useStyles = makeStyles(theme => ({
  root: {
    // no IntelliSense
  }
} as const))

Juga tanpa createStyles memiliki batasan kecil untuk penyelesaian string.

const useStyles = makeStyles(theme => ({
  root: {
    direction: '|', // no IntelliSense at | (works with createStyles)
    direction: | // IntelliSense works at |
  }
}))

@ypresto Dengan "membunuhnya", maksud Anda "menyebabkannya bekerja dengan cara yang sama seperti yang dilakukan createStyles "?

Ini adalah hambatan untuk meletakkannya di mana-mana, tetapi tidak lebih dari hambatan daripada meletakkan createStyles mana-mana.

@amacleay maksud saya kills IntelliSense : berdoa:.

Maaf, saya melewatkan komentar Anda. Aku akan mencobanya.

Saya tidak tahu mengapa tetapi ini 1100ms → 750ms, menariknya:

 export const DropArea: React.FC<CardProps & {
   active?: boolean
   description: string
   icon?: React.ReactNode
-}> = ({ active, description, icon, children, ...props }) => {
+}> = ({ children, ...props }) => {
   const classes = useStyles()
+  const active = false
+  const icon: React.ReactNode = null
+  const description = ''
   return (
     <Card {...props} className={clsx(classes.root)} variant="outlined">

Menghapus CardProps & dari FC hampir sama hasilnya. Mungkin karena CardProps memperluas PaperProps, yang memperluas Atribut HTML yang besar.

UPDATE & PENTING: Ternyata mengganti CardProps dengan HTMLAttributes<HTMLDivElement> juga mengurangi waktu (tidak terukur).

Akhirnya, saya menemukan yang terbesar, 750ms → 130ms:

Menghapus style={...} dari dua Tipografi.

-<Typography variant="subtitle2" component="div" noWrap style={{ width: '26ch' }}>...</Typography>
+<Typography variant="subtitle2" component="div" noWrap>...</Typography>
-<Typography variant="caption" component="div" noWrap style={{ width: '20ch' }}>...</Typography>
+<Typography variant="caption" component="div" noWrap>...</Typography>

Tapi kenapa? Menambahkan gaya yang sama ke <div> tidak mencapai kinerja. Mungkin OverridableComponent terlalu rumit..?

(Saya menggunakan TypeScript 3.8.3, @material-ui/core 4.9.1)

AFAIK cara Material-UI menangani gaya lokal pada komponen berbeda dari cara React menanganinya untuk elemen HTML.

@embeddedt Di level tipe, itu React.CSSProperties yang sama dengan prop gaya div.

@ypresto saya berdiri dikoreksi. Maaf.

Hai teman-teman, tidak yakin apakah layak membuka masalah baru untuk ini, jadi saya akan mempostingnya di sini karena ini terkait dengan kebenaran jenis/kinerja. Beri tahu saya jika saya harus membuka masalah sebagai gantinya.
Saat mengikuti dokumentasi untuk menambahkan font khusus , saya berakhir dengan kesalahan pengetikan berikut:
Type 'string' is not assignable to type 'FontFaceFontDisplayProperty'

Aneh, karena pengetikan csstype 2.6.9 tampaknya valid dan atribut lainnya baik-baik saja (menggunakan MUI 4.9.5).

const sourceSansPro = {
  fontFamily: "'Source Sans Pro'",
  fontStyle: "normal",
  fontDisplay: "swap", // won't work
  fontWeight: 400,
  src: `
    url('/static/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf') format("truetype")
  `
};

Properti tema:

  overrides: {
    MuiCssBaseline: {
      "@global": {
        "@font-face": [sourceSansPro]
      }
    }

Jenisnya adalah type FontFaceFontDisplayProperty = "auto" | "block" | "fallback" | "optional" | "swap";

@eric-burel Ini adalah masalah dengan pelebaran tipe otomatis TypeScripts. Mencoba

- fontDisplay: "swap", // won't work
+ fontDisplay: "swap" as "swap",

Terima kasih berhasil, dan saya telah mempelajari konsep baru "jenis pelebaran" :) Aneh bahwa fontStyle tidak terpengaruh misalnya, ini bukan satu-satunya properti CSS yang didefinisikan sebagai enum tetapi pertama kali saya menekan ini .

Sunting: ok saya buruk itu didokumentasikan dengan baik: https://material-ui.com/guides/typescript/#using -createstyles-to-defeat-type-widening

Akhirnya, saya menemukan yang terbesar, 750ms → 130ms:

Menghapus style={...} dari dua Tipografi.

-<Typography variant="subtitle2" component="div" noWrap style={{ width: '26ch' }}>...</Typography>
+<Typography variant="subtitle2" component="div" noWrap>...</Typography>
-<Typography variant="caption" component="div" noWrap style={{ width: '20ch' }}>...</Typography>
+<Typography variant="caption" component="div" noWrap>...</Typography>

Tapi kenapa? Menambahkan gaya yang sama ke <div> tidak mencapai kinerja. Mungkin OverridableComponent terlalu rumit..?

(Saya menggunakan TypeScript 3.8.3, @material-ui/core 4.9.1)

Apakah menurut Anda ini memengaruhi waktu pembuatan, atau hanya waktu yang diperlukan agar intellisense berguna? Saya mendapatkan masalah build (kehabisan memori) dan beberapa kode TS kami memiliki banyak style={someStyle} disetel pada komponen. Ingin tahu apakah itu bagian dari masalah kita.

@yatrix7 , secara umum, saya berharap waktu pemeriksaan yang lama ini memengaruhi waktu respons build dan editor.

Saya ada yang sedang mencari ini? Saya tahu ada beberapa peningkatan dalam hal waktu pemeriksaan tipe TypeScript di pemutakhiran versi sebelumnya. Namun, masih lambat.
Tidak keberatan melihat ke dalam ini sendiri.

Tidak keberatan melihat ke dalam ini sendiri.

Itu akan luar biasa. Saat ini kami tidak mengetahui item yang dapat ditindaklanjuti untuk kami kerjakan. Jadi setiap petunjuk untuk kemacetan akan dihargai.

Menambahkan beberapa pembandingan untuk saat ini, untuk membantu menyelidiki: https://github.com/mui-org/material-ui/pull/22110

@FabianKielmann Di akhir TS, saya telah mengerjakan alat investigasi kinerja yang saya harap akan segera cukup matang untuk diterapkan pada material-ui.

Jika Anda memiliki waktu untuk dihabiskan untuk ini, Anda juga dapat mencoba sesuatu seperti https://github.com/microsoft/TypeScript/issues/38583.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat