
Bagaimana cara menghindari masalah kinerja dengan preset Core Animation, apa yang harus digunakan untuk melacak fragmen kode dan dengan fungsi apa untuk mengurangi pangsa operasi komputasi dalam aplikasi dari 26% menjadi 0,6% - baca bagian kedua artikel berdasarkan bahan laporan Luke Parkham pada konferensi MBLT DEV tahun lalu di konferensi MBLT DEV tahun lalu . Bagian pertama artikel tersedia di sini .
Di bawah kucing, tidak hanya tips berguna, tetapi juga tiket burung awal terbaru untuk MBLT DEV 2018 - Anda dapat membelinya hanya hari ini.
Animasi inti
Core Animation (CA) adalah preset di profiler yang menggunakan pengukuran FPS (bingkai per detik) untuk melihat apakah animasi tertinggal atau tidak. Seringkali, bahkan jika bidang masalah aplikasi ditemukan, kesulitan kinerja tetap ada. Alasannya adalah bahwa ketika bekerja dengan kerangka kerja UI, UIView digunakan, tetapi turunan CATransaction dibuat di bawah tenda (atau sistem melakukan ini sendiri), dan semua instruksi ini dikirim ke server untuk diproses. Server untuk rendering bertanggung jawab untuk membuat animasi. Jika animasi dilakukan menggunakan UIView, misalnya, metode kelas animate(withDuration:animations:)
, ia diproses oleh server render, yang dianggap sebagai utas terpisah dan berfungsi dengan semua animasi dalam aplikasi.
Anda dapat membuat server render berfungsi lambat sehingga tidak muncul di Time Profiler, tetapi itu masih akan memperlambat aplikasi. Begini tampilannya:


Di bagian atas adalah sensor frame rate. Di bawah ini adalah bagian paling penting - opsi debugging. Ada dua kunci dan parameternya mudah dikonfigurasikan. Yang pertama adalah color blended layers
. Memperbaikinya cukup sederhana. Bahkan, masalah bahkan muncul di iMessage, aplikasi yang sangat disukai Apple.

Merah menunjukkan area dengan latar belakang putih. Mereka tumpang tindih dengan latar belakang putih lain, dan untuk beberapa alasan tampak transparan. Ternyata program ini mencampur warna-warna ini satu sama lain - putih dengan putih, dan hasilnya lagi putih. Akibatnya, untuk setiap piksel yang ditandai dengan warna merah, perhitungan ekstra dilakukan yang tidak membawa manfaat apa pun - latar belakang putih diperoleh.
Aturan # 3
Buatlah lapisan-lapisan itu buram sedapat mungkin - asalkan warnanya sama dengan yang tumpang tindih. Layer memiliki properti opacity
, yang harus diatur ke unity. Selalu periksa bahwa warna latar belakang diatur dan buram.

Render pada layar
Opsi selanjutnya adalah rendering di luar layar. Jika Anda mengaktifkan fungsi ini, bagian-bagian akan disorot dengan warna kuning.
Kemudahan Core Animation adalah kemampuan untuk melihat aplikasi lain. Anda dapat mengaktifkan opsi, meluncurkan aplikasi dan melihat apa yang salah. Di layar di Instagram di atas ada lingkaran kuning kecil di mana cerita pengguna ditampilkan.

Misalnya, pada iPhone 6s, mereka memuat agak lambat. Dan jika Anda melihatnya di iPhone 5 atau pada model iPod lama, unduhan akan semakin lambat. Ini disebabkan oleh fakta bahwa rendering intra-sistem jauh lebih buruk daripada alpha blending. Ini memuat GPU. Akibatnya, perangkat harus terus melakukan perhitungan tambahan antara prosesor grafis dan prosesor pusat, sehingga ada penundaan tambahan yang dapat dihindari dalam kebanyakan kasus.
Aturan # 4
Jangan gunakan parameter cornerRadius
. Menggunakan viewLayer.cornerRadius
menghasilkan rendering offscreen. Sebagai gantinya, Anda dapat menggunakan kelas UIBezierPath
, serta sesuatu yang mirip dengan bekerja dengan CGBitMap, seperti halnya dengan decoding JPEG sebelumnya. Dalam hal ini, UIGraphics context
.

Ini adalah metode instance lain dari kelas UIImage. Di sini Anda dapat mengatur ukuran dan membuat sudut membulat. Bezierpath
digunakan untuk menyorot area gambar. Kemudian fragmen dikembalikan dari UIImageContext. Dengan demikian, kita mendapatkan gambar yang sudah selesai dengan sudut-sudut bulat bukannya membulatkan bingkai ke mana gambar akan dimasukkan.

Di halaman GIF - Twitter. Gambar ditampilkan secara real time. Halaman seharusnya membuka dan memberikan informasi, tetapi teks dan elemen lain dari layar melewati rendering di luar layar, sehingga animasi bergerak sangat lambat.
Aturan # 5
Properti kelas shouldRasterize
dari set CALayer memungkinkan Anda untuk shouldRasterize
-cache tekstur yang telah dirender. Lebih baik menghindarinya. Jika shouldRasterize
belum digunakan selama beberapa milidetik, ia akan meninggalkan cache dan akan menawarkan rendering dari setiap frame. Jadi ini menciptakan lebih banyak masalah daripada yang baik.
Mempercepat
- Hindari rendering di luar layar dan pencampuran lapisan transparan.
- Gunakan hanya ketika Anda tidak bisa melakukannya tanpa mereka. Render di luar layar muncul karena adanya bayangan, sudut pembulatan, dan sebagainya.
- Buat gambar buram.
- Jangan gunakan cornerRadius, gunakan kurva Bezier.
- Saat bekerja dengan teks, jangan gunakan properti layer.shadow, ganti dengan NSShadow.
Jejak aktivitas
Penelusuran aktivitas mirip dengan yang dilakukan Time Profiler, tetapi dalam skala yang lebih kecil. Ini memungkinkan Anda untuk mempertimbangkan aliran dan interaksinya satu sama lain.
Aturan # 6
Gunakan Jejak Sistem untuk melacak periode waktu untuk peristiwa tertentu. Anda dapat menemukan cara untuk melacak peristiwa atau bagian kode dan melihat berapa banyak waktu yang diperlukan dalam pekerjaan nyata aplikasi. System Trace memberikan informasi tentang apa yang terjadi di sistem:
- "Sing Post" menandakan bahwa sesuatu yang penting sedang terjadi.
- Tanda adalah peristiwa tunggal yang layak ditonton, misalnya penampilan animasi.
- Pada interval acara, Anda dapat melacak berapa lama decoding.

Jadi, program menunjukkan bagaimana kode berinteraksi dengan bagian sistem yang lain.
Di layar adalah contoh membuat templat jejak sistem:
- 1 - unggahan gambar
- 2 - penguraian gambar
- 3 - animasi tilt.
Anda perlu menambahkan beberapa opsi untuk memahami warna apa yang akan berubah. Biasanya, mereka diberi nomor, seperti 1 atau 2, dan berubah menjadi merah atau hijau, tergantung pada pengaturannya. Pada Objective-C, Anda perlu menulis perintah #import
untuk kdebug_signpost
. Di Swift, mereka sudah tersedia.

Maka Anda perlu memanggil fungsi ini dengan kdebug_signpost
atau kdebug_signpost_start
dan kdebug_signpost_end
.

Kami menunjukkan 3 peristiwa bersama dengan angka yang ditulis dalam kode, dan elemen kunci untuk setiap peristiwa tertentu. Angka terakhir menunjukkan warna. Misalnya, 2 berwarna merah.
Berikutnya adalah peristiwa penting, objek khusus. Diagram disederhanakan dijelaskan dalam proyek uji Luke pada Swift.
Tangkapan layar memperlihatkan bagaimana tampilannya ketika Anda mulai melacak. Pada awalnya, ketika aplikasi diluncurkan, program tidak akan memberikan informasi, tetapi begitu aplikasi crash, kita akan melihat perhitungannya.

Mengunduh gambar membutuhkan sekitar 200 milidetik. Kemudian muncul decoding, yang memakan waktu sekitar 40 milidetik. Sangat berguna untuk melacak data ini jika ada banyak operasi dalam aplikasi. Anda dapat membuat daftar acara dalam program, dan kemudian mengamati dan menerima informasi tentang berapa banyak waktu yang diperlukan untuk implementasi mereka, dan bagaimana mereka berinteraksi satu sama lain.
Alat tambahan
Di layar - Proyek AR untuk pemotretan gerak lambat pada smartphone. Aplikasi ini mirip dengan Snapchat. Ini menggunakan efek retouching foto, dan untuk setiap frame 26,4% dari semua operasi komputasi dihabiskan untuk itu. Karena itu, kamera memotret dengan lambat, sekitar 10 frame per detik. Ketika belajar, kita melihat bahwa garis paling atas melakukan sebagian besar pekerjaan. Dia bertanggung jawab untuk secara aktif mengirim data. Jika Anda memeriksa penyebab penurunan kinerja, Anda akan melihat bahwa intinya adalah penggunaan NSDispatchData
.

Subkelas NSData
hanya menerima urutan byte menggunakan metode getBytes
dalam interval tertentu dan meneruskannya ke lokasi lain. Tampaknya sangat sederhana, namun segala sesuatu yang dilakukan metode ini secara internal membutuhkan 18% dari 26% perhitungan.

Aturan # 1
Gunakan
NSData
dan
getBytes
. Ini adalah operasi sederhana pada Objective-C, tetapi jika itu menyebabkan masalah dalam sistem, Anda harus beralih ke fungsi tingkat rendah di dataran C. Karena masalahnya adalah dengan mendapatkan nilai mengambang, Anda dapat menggunakan fungsi memori salinan. Dengannya, Anda dapat memindahkan sepotong data ke lokasi lain. Ini sangat menghemat daya komputasi perangkat.
NSData memiliki banyak operasi. Dalam contoh tersebut, kode sumber disorot dengan warna merah. Menggunakan fungsi
getBytes
,
getBytes
dapat menerjemahkan data menjadi angka floating point. Metode dengan menyalin memori hampir sama. Ini cukup sederhana dan melakukan urutan operasi yang lebih sedikit.

Jika Anda mengubah pendekatan dan memulai aplikasi lagi, dapat dilihat bahwa persentase operasi komputasi yang dihabiskan untuk mengubah foto menurun dari 26% menjadi 0,6%. Dan ini disebabkan oleh perubahan hanya satu baris kode tentang menyalin memori. Frame rate telah meningkat secara signifikan.

Aturan # 2
Hindari tumpang tindih piksel satu sama lain saat membuat aplikasi yang memiliki rendering.
Dalam kebanyakan kasus, ini akan terjadi pada frekuensi di atas 60 frame per detik. Menggunakan CADisplayLink
, Anda dapat memperlambat pembaruan UI. Ada parameter preferFramesPerSecond. Ini hanya berlaku untuk iOS 10 dan yang lebih baru. Untuk sistem yang lebih lama, Anda harus melakukan ini secara manual. Saat bekerja di versi baru iOS, Anda dapat mengatur jumlah frame yang diinginkan per detik. Dalam kebanyakan kasus, 15 frame per detik atau lebih, sehingga tidak menyia-nyiakan daya komputasi dan tidak menambah pekerjaan yang tidak perlu ke aplikasi.

Aturan # 3
Saat bekerja dengan Objective-C, penting untuk menggunakan caching dari pointer IMP (pointer ke implementasi metode). Ketika metode
under the hood
disebut dalam Objective-C, fungsi
objc_msgSend()
. Jika penelusuran menunjukkan bahwa panggilan membutuhkan waktu lama, Anda dapat menyingkirkannya. Bahkan, ini adalah repositori cache dengan pointer ke suatu fungsi, mereka dapat diberi nama beberapa metode. Karena itu, alih-alih melakukan pencarian ini setiap kali, ada baiknya melakukan caching sebagai berikut: letakkan pointer fungsi di cache dan panggil mereka secara langsung. Ini biasanya terjadi dua kali lebih cepat.

Jika tidak ada pointer, maka metode ini disebut menggunakan perintah methodForSelector. Untuk memanggil metode bantuan fungsi panggilan biasa ini, Anda harus memasukkan nama objek di pemilih, yang menghasilkan hasil pencarian. Mungkin ini bukan cara yang paling nyaman, tetapi cepat.
Aturan # 4
Jangan gunakan ARC (penghitungan referensi otomatis). ARC menambahkan banyak pekerjaan ekstra.
Ketika ARC diaktifkan, compiler itu sendiri mencerai-beraikan retain
/ release
di tempat yang tepat. Namun, jika ada tempat yang retain
dan release
terlalu banyak waktu, pertimbangkan untuk menjatuhkan ARC. Lakukan ini jika optimasi diperlukan, karena akan memakan banyak waktu.
Kadang-kadang layak ditinggalkan bahkan Swift, terutama jika kinerja aplikasi sensitif terhadap perubahan. Swift memiliki beberapa fitur yang sangat keren, tetapi untuk melakukan tugas-tugas kecil sekalipun, itu memerlukan penulisan banyak baris kode untuk mencapai fungsionalitas tingkat tinggi.
Bahan yang berguna
Bagian pertama artikel tersedia di sini . Untuk wawasan lebih lanjut tentang topik ini, Luke Parham merekomendasikan untuk membaca buku " iOS dan MacOS: Performance Tuning " dan menonton tutorialnya .
Rekaman video dari laporan Luke di MBLT DEV 2017 sekarang dalam domain publik:
Pengetahuan dan kiat lebih lanjut di MBLT DEV 2018
Pembicara pertama mengumumkan:
- Netflix's John C. Fox akan berbicara tentang lokalisasi berkualitas tinggi, bekerja dengan kondisi jaringan yang agresif dan pengujian A / B.
- Krzysztof Zabลocki, The New York Times, sedang menyiapkan laporan tentang pola di iOS.
- Laura Morinigo, Ahli Pengembang Google, berbicara tentang praktik Firebase terbaik.
Tiket early bird terbaru akan terbang hari ini.
