Menggunakan xhprof saya perhatikan bahwa file_scan_directory()
membutuhkan lebih dari 10 detik untuk mengeksekusi ketika halaman depan dimuat. Mengapa harus begitu lama?
Ini adalah output dari xhprofile:
7
performance
hknik
sumber
sumber
Jawaban:
Sepertinya Anda terpengaruh oleh masalah yang diketahui di Drupal 7 .
Melihat fungsi-fungsi itu, sepertinya tidak ada modul atau mungkin satu file modul. Lihatlah drupal_get_filename () , ia memanggil drupal_system_listing (), yang memanggil fungsi ini jika tidak dapat menemukan file yang diminta. Tambahkan dpm (func_get_args ()) tepat sebelum memanggil drupal_system_listing (), yang akan memberi tahu Anda file mana yang tidak ditemukannya.
sumber
Ada beberapa alasan mengapa masalah ini muncul, dan saya sangat cemas, sekarang saya merasa agak berpengetahuan tentang alasan-alasan itu. Frustasi, jika Anda baru saja melihat masalah ini setelah memutakhirkan Drupal core ke 7.33+, ini bisa menjadi kesalahan ketik pada modul apa pun, bahkan jika Anda belum memutakhirkan modul itu.
Modul dihapus dari basis kode
Anda mungkin ingin memeriksa bug yang dikenal oleh @Berdir, terutama jika Anda baru saja menghapus modul "tidak terpakai" dari basis kode. Untuk mengetahui apakah Anda memiliki modul yang diaktifkan tetapi telah dihapus dari sistem file, Anda dapat menjalankan skrip seperti yang disebutkan di sini - atau menggunakan milik saya, ditulis untuk instalasi multi-situs pada sistem dengan drush, untuk dijalankan dari direktori basis Drupal:
atau yang berikut ini:
Jika Anda menemukan modul yang telah dihapus dari basis kode, ikuti petunjuk dalam masalah yang disebutkan oleh @Berdir.
Kesalahan pengkodean
Jika bukan itu, situasi Anda kemungkinan disebabkan oleh kesalahan pengkodean, seperti file yang telah dihapus tetapi masih ditambahkan oleh panggilan drupal_add_js (dari komentar 19 dalam edisi # 1082892) atau salah ketik yang salah dalam modul atau tema , mis.
imagecache_actions
(lihat https://drupal.org/node/2381357 ).Bagaimanapun, untuk mencari tahu persis mengapa ini terjadi, Anda perlu tahu persis file mana yang tidak ditemukan oleh Drupal. Jadi, sesuai komentar Berdir, Anda dapat sementara hack
drupal_get_filename
dibootstrap.inc
dengan menambahkan log atau pesan panggilan sebelum panggilan untukdrupal_system_listing()
. Jika Anda memiliki modul Devel diinstal makadpm
akan berfungsi; jika tidak, Anda bisa menggunakandrupal_set_message
atau syslog. Contoh:Setelah Anda tahu apa yang dicari Drupal, itu adalah taruhan yang bagus bahwa Anda akan dapat mengetahui ke mana harus pergi dari sana. Masalah saya disebabkan oleh panggilan untuk memasukkan file dari modul yang tidak ada
imagcache_actions
(perhatikan salah ketik). Jadi, saya mencariimagecache_actions
di basis kode saya (misalnyagrep -r imagcache_actions .
), dan menemukan bahwa versi 1.4imagecache_canvasactions.module
menggunakan module_load_include di luar semua panggilan fungsi, dalam lingkup file, dengan kesalahan ketik. Sekali lagi, kesalahan ini hanya terekspos setelah memperbarui ke Drupal 7.33+. Saya menemukan bahwa masalah telah dibuat untukimagecache_actions
, menerapkan tambalan, dan kembali berbisnis.sumber
Saya memiliki masalah yang sangat mirip -
file_scan_directory()
membunuh situs. Ternyatanode_modules
folder huuge yang tertanam di dalam tema khusus sayagulp
sedang dipindai setiap flush cache. Memindahkan file-file ini dari folder tema (dan memperbarui beberapa jalur di gulpfile saya) sepertinya memperbaikinya untuk saya. Atau: Saya pikir Anda bisa meretasfile.inc
:'nomask' => '/(\.\.?|CVS|node_modules)$/', // https://www.drupal.org/node/2329453#comment-9360519
sumber
Ini
file_scan_directory()
adalah fungsi rekursif yang semua file cocok dengan direktori yang diberikan. Penggunaanis_dir()
danopendir()
panggilan PHP yang mungkin paling mahal dalam hal panggilan sistem I / O. Bootstrap Drupal sederhana (mis.time drush ev ""
) Dapat memanggilfile_scan_directory
beberapa ribu kali (tergantung pada kompleksitas hierarki folder Drupal Anda, mis. Jumlah modul dan foldernya).Dalam kasus saya, saya memiliki ~ 1500 panggilan ke
file_scan_directory
(total 24 detik terdiri dari 2 panggilan daridrupal_system_listing
dalamcommon.inc
, kemudian panggilan lain dibagi dengan panggilan rekursif kefile_scan_directory
dirinya sendiri.Untuk meningkatkan kinerja panggilan I / O, Anda perlu menerapkan caching file. Ini dapat dicapai dengan menginstal dan mengaktifkan OPCache (
opcache.enable=1
) dan mengubah pengaturannya (lihat: Cara menggunakan PHP OPCache? ). Menggunakan caching berbasis memori seperti memcached / redis juga disarankan.Saat menggunakan antarmuka baris perintah (seperti
drush
), Anda juga harus mengaktifkanopcache.enable_cli=1
.Setelah perubahan, Anda dapat memeriksa syscalls yang lebih banyak menggunakan beberapa debugger yang tersedia.
Misalnya
Di Linux menggunakan
strace
(tekan Ctrl- Cuntuk menyelesaikan):On Unix using
dtrace
(menggunakan probe statis DTrace PHP ), misAnda selanjutnya dapat mempertimbangkan untuk mengoptimalkan
drupal_system_listing()
ataufile_scan_directory()
dengan menerapkan cache statis, misalnyaAtau untuk caching
file_scan_directory
panggilan daridrupal_system_listing()
, kemudian periksa tambalan berikut tersedia di: file_scan_directory harus di-cache .sumber