Sebagai rangka kerja web yang sangat baik, AnglarJS boleh memudahkan beban pembangunan bahagian hadapan. Sebastian Fröstl baru-baru ini menyatakan dalam catatan blog "Penalaan Prestasi AngularJS untuk Senarai Panjang" bahawa AnglarJS berjalan sangat perlahan apabila memproses senarai besar yang mengandungi struktur data yang kompleks. Dia juga berkongsi penyelesaian dalam artikel itu. Di bawah ialah terjemahan artikel tersebut.
AnglarJS hebat, tetapi ia berjalan sangat perlahan apabila berurusan dengan senarai besar yang mengandungi struktur data yang kompleks. Ini ialah masalah yang kami hadapi semasa pemindahan halaman pentadbir teras ke AngularJS. Halaman ini harus berfungsi dengan lancar apabila memaparkan 500 baris data, tetapi masa pemaparan kaedah pertama mengambil masa 7 saat yang mengerikan.
Kemudian, kami mendapati terdapat dua isu prestasi utama semasa proses pelaksanaan. Satu berkaitan dengan arahan "ng-repeat" dan satu lagi berkaitan dengan penapis.
Di bawah ini kami akan berkongsi pengalaman kami dalam menyelesaikan masalah prestasi melalui kaedah yang berbeza, dengan harapan dapat memberi inspirasi kepada anda.
1. Mengapakah ng-repeat dalam AngularJS perlahan apabila memproses senarai besar?
ng-repeat dalam AngularJS akan menjadi perlahan apabila memproses lebih daripada 2500 pengikatan data dua hala. Ini disebabkan oleh AngularJS mengesan perubahan melalui fungsi "pemeriksaan kotor". Setiap semakan mengambil masa, jadi senarai besar yang mengandungi struktur data yang kompleks akan melambatkan aplikasi anda.
2. Prasyarat untuk meningkatkan prestasi
Arahan rakaman masa
Untuk mengukur masa yang diperlukan untuk membuat senarai, kami menulis program mudah untuk merekod masa dengan menggunakan atribut "$last" bagi "ng-repeat". Masa disimpan dalam perkhidmatan TimeTracker, supaya rakaman masa dipisahkan daripada pemuatan data pada bahagian pelayan.
// Siarkan arahan ulangan untuk mengelog masa pemaparan angular.module('siApp.services').directive('postRepeatDirective', ['$timeout', '$log', 'TimeTracker', function($timeout, $log, TimeTracker) { mengembalikan fungsi(skop, elemen, attrs) { jika (skop.$terakhir){ $masa tamat(fungsi(){ var timeFinishedLoadingList = TimeTracker.reviewListLoaded(); var ref = New Date(timeFinishedLoadingList);var end = new Date(); $log.debug("## DOM rendering list took: " (end - ref) " } } ]); >
Sifat Garis Masa Alat Pembangun ChromeDalam tab Garis Masa Alat Pembangun Chrome, anda boleh melihat peristiwa, bingkai penyemak imbas sesaat dan peruntukan memori. Alat "memori" digunakan untuk mengesan kebocoran memori dan memori yang diperlukan oleh halaman. Masalah kelipan halaman berlaku apabila kadar bingkai lebih rendah daripada 30 bingkai sesaat. Alat "bingkai" boleh membantu memahami prestasi pemaparan dan juga boleh menunjukkan masa CPU yang dibelanjakan oleh tugas JavaScript.
3. Penalaan asas dengan mengehadkan saiz senarai
Cara terbaik untuk mengurangkan masalah ini adalah dengan mengehadkan saiz senarai yang dipaparkan. Ini boleh dicapai dengan penomboran dan menambah bar skrol tak terhingga.Penomboran
Untuk penomboran, kita boleh menggunakan penapis "limitTo" AngularJS (AngularJS versi 1.1.4 dan lebih baru) dan penapis "startFrom". Anda boleh mengurangkan masa pemaparan dengan mengehadkan saiz senarai paparan. Ini adalah cara paling berkesan untuk mengurangkan masa pemaparan.
// Penomboran dalam pengawal $scope.currentPage = 0; $scope.pageSize = 75; $scope.numberOfPages = function() { return Math.ceil($scope.displayedItemsList.length/ $scope.pageSize } ; // Mulakan dari penapis angular.module('app').filter('startFrom', function() { return function(input, start) { return input.slice(start); }; // Gunakan dalam HTML // Butang penomboran{{$index 1}}
Jika anda tidak boleh/tidak mahu menggunakan paging, tetapi proses penapisan sangat perlahan, pastikan anda menyemak lima langkah pertama dan gunakan "ng-show" untuk menyembunyikan elemen senarai yang berlebihan.
Bar skrol tanpa had
Jika anda ingin mengetahui lebih lanjut tentang kaedah ini, anda boleh layari
http://binarymuse.github.io/ngInfiniteScroll/
4. Tujuh Peraturan Penalaan
1. Berikan senarai tanpa pengikatan dataIni adalah penyelesaian yang paling jelas memandangkan pengikatan data adalah sumber isu prestasi yang paling mungkin. Jika anda hanya mahu memaparkan senarai sekali sahaja dan tidak perlu mengemas kini atau menukar data, melepaskan pengikatan data adalah penyelesaian yang sangat baik. Malangnya, anda kehilangan kawalan ke atas data anda, tetapi kami tidak mempunyai pilihan selain menggunakan undang-undang ini. Ketahui lebih lanjut:
https://github.com/Pasvaz/bindonce.
2. Jangan gunakan kaedah sebaris untuk mengira dataUntuk menapis senarai terus dalam pengawal, jangan gunakan kaedah yang mendapatkan pautan penapis. "ng-repeat" menilai setiap ungkapan [$digest(
http://docs.angularjs.org/api/ng.$rootScope.Scope#$digest)]. Dalam kes kami, "filteredItems()" mengembalikan pautan yang ditapis. Jika proses penilaian lambat, ia akan melambatkan keseluruhan permohonan dengan cepat.
//Ini bukan kaedah yang baik kerana ia memerlukan penilaian yang kerap.
//Ini adalah kaedah yang akan digunakan
3. Gunakan dua senarai (satu untuk paparan paparan dan satu sebagai sumber data)
Mengasingkan senarai yang akan dipaparkan daripada senarai data keseluruhan ialah model yang sangat berguna. Anda boleh mempraproses beberapa penapis dan menggunakan pautan yang disimpan dalam cache pada paparan. Kes berikut menunjukkan proses pelaksanaan asas. Pembolehubah filteredLists memegang pautan dalam cache, dan kaedah applyFilter mengendalikan pemetaan.
/* Pengawal */ // Item senarai asas var = [{name:"John", active:true}, {name:"Adam"}, {name:"Chris"}, {name:"Heather" }]; // Init displayedList $scope.displayedItems = item; // Filter Cache var filteredLists['active'] = $filter('filter)(item, {"active" : true}); scope.applyFilter = function(type) { if (filteredLists.hasOwnProperty(type){ // Semak sama ada penapis dicache $scope.displayedItems = filteredLists[type]; } else { /* Penapisan bukan cache */ } } // Tetapkan semula tapis $scope.resetFilter = function() { $scope.displayedItems = item } /* Lihat */Pilih aktif
{{item.name}}
4. Gunakan ng-if dalam templat lain dan bukannya ng-show
Jika anda menggunakan arahan atau templat untuk memaparkan maklumat tambahan, seperti mengklik untuk memaparkan maklumat terperinci item senarai, pastikan anda menggunakan ng-if (AngularJSv. 1.1.5 dan lebih baru). ng-if menghalang rendering (berbanding dengan ng-show). Jadi pengikatan DOM dan data lain boleh dinilai mengikut keperluan.
Kandungan di atas memberi anda penjelasan terperinci tentang 7 cadangan untuk penalaan prestasi AngularJS saya harap anda menyukainya.