Formulir desain untuk performa dalam aplikasi berdasarkan model

Membangun pengalaman di mana tugas dapat diselesaikan secara cepat dan efisien sangat penting untuk kepuasan pengguna. Aplikasi berdasarkan model dapat sangat disesuaikan untuk membuat pengalaman yang sesuai dengan kebutuhan pengguna, namun penting untuk mengetahui cara membuat kode, membangun, dan menjalankan aplikasi berdasarkan model secara efektif yang dimuat dengan cepat saat pengguna membuka dan menavigasi dalam aplikasi Anda saat melakukan tugas harian. Performa telah terbukti menjadi pendorong utama ketidakpuasan atas aplikasi saat tidak dioptimalkan untuk performa.

Penyesuaian cerdas dan formulir performa adalah aspek penting untuk membangun formulir yang sangat efisien dan produktif. Penting juga untuk memastikan Bahwa Anda membangun formulir yang sangat produktif dengan praktik terbaik dalam desain dan tata letak antarmuka pengguna. Untuk informasi tentang merancang formulir untuk efisiensi dan produktivitas, lihat Merancang formulir utama yang produktif dalam aplikasi berdasarkan model.

Penting juga untuk memastikan pengguna berada di perangkat yang direkomendasikan dan didukung serta spesifikasi minimum yang diperlukan. Informasi lebih lanjut: Browser web dan perangkat seluler yang didukung

Menggunakan data dan tab

Bagian ini mencakup cara mengontrol yang menampilkan data dan tab yang mempengaruhi kinerja formulir.

Signifikansi tab default

Tab default adalah tab diperluas pertama pada formulir. Ia memainkan peran khusus dalam pemuatan halaman formulir. Secara desain, kontrol tab default akan selalu ditampilkan saat membuka rekaman. Secara khusus, logika inisialisasi kontrol, seperti pengambilan data, diaktifkan untuk setiap kontrol pada tab.

Sebaliknya, tab kedua tidak melakukan inisialisasi pada kontrolnya saat formulir awalnya dimuat. Sebagai gantinya, inisialisasi kontrol terjadi pada saat tab kedua dibuka melalui interaksi pengguna atau memanggil metode API klien setFocus. Hal ini memberikan peluang untuk melindungi beban formulir awal dari pemrosesan kontrol yang berlebihan dengan menempatkan kontrol tertentu di tab kedua, bukan tab default. Oleh karena itu, strategi penempatan kontrol dapat memiliki efek yang signifikan pada respons beban formulir awal. Tab default yang lebih responsif memberikan pengalaman keseluruhan yang lebih baik untuk memodifikasi bidang penting, berinteraksi dengan bilah perintah, serta menjelajahi tab dan bagian lainnya.

Selalu letakkan kontrol yang paling sering digunakan di bagian atas tab default. Arsitektur tata letak dan informasi tidak hanya penting bagi kinerja, tetapi juga untuk meningkatkan produktivitas saat pengguna berinteraksi dengan data pada formulir. Informasi selengkapnya: Merancang formulir utama produktif dalam aplikasi berdasarkan model

Kontrol berdasarkan data

Kontrol yang memerlukan data ekstra selain rekaman utama menghasilkan tekanan paling besar pada responsivitas formulir dan kecepatan pemuatan. Kontrol ini mengambil data melalui jaringan dan sering melibatkan periode tunggu (terlihat sebagai indikator progres) karena dapat makan waktu untuk mentransmisikan data.

Beberapa kontrol berdasarkan data mencakup:

Simpan hanya yang paling sering digunakan dari kontrol ini di tab default. Kontrol berdasarkan data lainnya harus didistribusikan ke tab kedua agar tab default dapat dimuat dengan cepat. Selain itu, strategi tata letak ini mengurangi peluang mengambil data yang akhirnya tidak digunakan.

Ada kontrol lain yang kurang berpengaruh daripada kontrol berdasarkan data tetapi tetap dapat berpartisipasi dalam strategi tata letak di atas untuk mencapai kinerja terbaik. Kontrol tersebut mencakup:

Browser web

Bagian ini mencakup praktik yang baik untuk digunakan dengan browser web.

Jangan buka jendela baru

Metode API klien openForm memungkinkan pilihan parameter untuk menampilkan formulir di jendela baru. Jangan gunakan parameter ini atau atur ke salah. Mengaturnya ke salah akan memastikan metode openForm melakukan perilaku default dalam menampilkan formulir menggunakan jendela yang ada. Anda juga dapat secara langsung memanggil fungsi JavaScript window.open dari skrip kustom atau aplikasi lain; namun, hal ini juga harus dihindari. Membuka jendela baru berarti semua sumber daya halaman harus diambil dan dimuat dari awal karena halaman tidak dapat memanfaatkan kemampuan cache data dalam memori antara formulir yang dimuat sebelumnya dan formulir di jendela baru. Sebagai alternatif untuk membuka jendela baru, pertimbangkan menggunakan pengalaman multisesi yang memungkinkan rekaman dibuka di beberapa tab sambil tetap memaksimalkan manfaat performa cache klien.

Gunakan browser modern

Menggunakan browser web terbaru adalah kunci untuk memastikan aplikasi berdasarkan model Anda berjalan secepat mungkin. Alasannya, banyak peningkatan performa hanya dapat digunakan pada browser modern yang lebih baru.

Misalnya, jika organisasi Anda memiliki versi browser Firefox non-Chromium yang lebih lama, dan sebagainya, banyak keuntungan performa yang terpasang pada aplikasi berdasarkan model tidak akan tersedia di versi browser lama karena tidak mendukung fitur yang tergantung pada aplikasi untuk berjalan dengan cepat dan lancar.

Kebanyakan kasus, Anda dapat mengharapkan untuk melihat peningkatan beban halaman hanya dengan beralih ke Microsoft Edge, memperbarui ke versi browser terbaru dari versi yang lebih lama, atau beralih ke browser berbasis Chromium modern.

Penyesuaian JavaScript

Bagian ini mencakup cara membuat penyesuaian cerdas saat Anda menggunakan JavaScript yang membantu Anda membuat formulir dan halaman performa dalam aplikasi berdasarkan model.

Menggunakan JavaScript dengan formulir

Kemampuan untuk formulir yang akan disesuaikan oleh JavaScript memberikan fleksibilitas yang luar biasa bagi pengembang profesional atas tampilan dan perilaku formulir. Penggunaan fleksibilitas ini dengan tidak tepat dapat mempengaruhi kinerja formulir secara negatif. Pengembang harus menggunakan strategi berikut untuk memaksimalkan performa formulir saat menerapkan penyesuaian JavaScript.

Menggunakan permintaan jaringan asinkron saat meminta data

Minta data secara asinkron daripada secara asinkron bila data tambahan diperlukan untuk penyesuaian. Untuk aktivitas yang mendukung menunggu kode asinkron seperti aktivitas OnLoad dan OnSave formulir, penanganan aktivitas harus mengembalikan Promise agar platform dapat menunggu hingga Promise diselesaikan. Platform akan menampilkan UI yang sesuai saat pengguna menunggu aktivitas selesai.

Untuk aktivitas yang tidak mendukung menunggu kode asinkron, seperti aktivitas OnChange formulir, Anda dapat menggunakan solusi untuk menghentikan interaksi dengan formulir saat kode melakukan permintaan asinkron menggunakan showProgressIndicator. Hal ini lebih baik daripada menggunakan permintaan sinkron karena pengguna tetap dapat berinteraksi dengan bagian lain dari aplikasi saat indikator progres ditampilkan.

Berikut adalah contoh menggunakan kode asinkron dalam poin ekstensi sinkron.

//Only do this if an extension point does not yet support asynchronous code
try {
    await Xrm.WebApi.retrieveRecord("settings_entity", "7333e80e-9b0f-49b5-92c8-9b48d621c37c");
    //do other logic with data here
} catch (error) {
    //do other logic with error here
} finally {
    Xrm.Utility.closeProgressIndicator();
}

// Or using .then/.finally
Xrm.Utility.showProgressIndicator("Checking settings...");
Xrm.WebApi.retrieveRecord("settings_entity", "7333e80e-9b0f-49b5-92c8-9b48d621c37c")
    .then(
        (data) => {
            //do other logic with data here
        },
        (error) => {
            //do other logic with error here
        }
    )
    .finally(Xrm.Utility.closeProgressIndicator);

Anda harus hati-hati saat menggunakan kode asinkron pada penanganan aktivitas yang tidak mendukung menunggu kode asinkron. Hal ini sangat berlaku untuk kode yang memerlukan tindakan yang harus diambil atau ditangani pada resolusi kode asinkron. Kode asinkron dapat menyebabkan masalah jika penanganan resolusi mengharapkan konteks aplikasi tetap sama seperti saat kode asinkron dimulai. Kode Anda harus memastikan bahwa pengguna berada dalam konteks yang sama setelah setiap titik kontinuasi asinkron.

Contohnya, mungkin ada kode pada penanganan aktivitas untuk membuat permintaan jaringan dan mengubah kontrol untuk dinonaktifkan berdasarkan data respons. Sebelum respons dari permintaan diterima, pengguna mungkin telah berinteraksi dengan kontrol atau menavigasi ke halaman yang berbeda. Karena pengguna berada di halaman yang berbeda, konteks formulir mungkin tidak tersedia, yang dapat menyebabkan kesalahan atau mungkin ada perilaku lain yang tidak diinginkan.

Dukungan asinkron di aktivitas OnLoad dan OnSave formulir

Formulir OnLoad dan aktivitas OnSave mendukung penanganan yang mengembalikan janji. Aktivitas akan menunggu janji yang dikembalikan oleh penanganan untuk ditangani, hingga periode waktu habis. Dukungan ini dapat diaktifkan melalui pengaturan aplikasi.

Informasi selengkapnya:

Batasi jumlah data yang diminta selama pemuatan formulir

Cukup minta jumlah data minimum yang diperlukan untuk melakukan logika bisnis pada formulir. Cache data yang diminta sebanyak mungkin, terutama untuk data yang tidak sering berubah atau tidak perlu baru. Misalnya, misalkan ada formulir yang meminta data dari tabel pengaturan. Berdasarkan data dalam tabel pengaturan, formulir dapat memilih untuk menyembunyikan bagian formulir. Dalam kasus ini, JavaScript dapat membuat cache data di sessionStorage sehingga data hanya diminta satu kali per sesi (onLoad1). Strategi kedaluwarsa saat melakukan validasi ulang juga dapat digunakan dengan JavaScript menggunakan data dari sessionStorage saat meminta data untuk navigasi berikutnya ke formulir (onLoad2). Terakhir, strategi deduplikasi dapat digunakan dalam kasus penanganan dipanggil beberapa kali berturut-turut (onLoad3).

const SETTING_ENTITY_NAME = "settings_entity";
const SETTING_FIELD_NAME = "settingField1";
const SETTING_VALUE_SESSION_STORAGE_KEY = `${SETTING_ENTITY_NAME}_${SETTING_FIELD_NAME}`;

// Retrieve setting value once per session
async function onLoad1(executionContext) {
    let settingValue = sessionStorage.getItem(SETTING_VALUE_SESSION_STORAGE_KEY);

    // Ensure there is a stored setting value to use
    if (settingValue === null || settingValue === undefined) {
        settingValue = await requestSettingValue();
    }

    // Do logic with setting value here
}

// Retrieve setting value with stale-while-revalidate strategy
async function onLoad2(executionContext) {
    let settingValue = sessionStorage.getItem(SETTING_VALUE_SESSION_STORAGE_KEY);

    // Revalidate, but only await if session storage value is not present
    const requestPromise = requestSettingValue();

    // Ensure there is a stored setting value to use the first time in a session
    if (settingValue === null || settingValue === undefined) {
        settingValue = await requestPromise;
    }
    
    // Do logic with setting value here
}

// Retrieve setting value with stale-while-revalidate and deduplication strategy
let requestPromise;
async function onLoad3(executionContext) {
    let settingValue = sessionStorage.getItem(SETTING_VALUE_SESSION_STORAGE_KEY);

    // Request setting value again but don't wait on it
    // In case this handler fires twice, don’t make the same request again if it is already in flight
    // Additional logic can be added so that this is done less than once per page
    if (!requestPromise) {
        requestPromise = requestSettingValue().finally(() => {
            requestPromise = undefined;
        });
    }

    // Ensure there is a stored setting value to use the first time in a session
    if (settingValue === null || settingValue === undefined) {
        settingValue = await requestPromise;
    }
    
    // Do logic with setting value here
}

async function requestSettingValue() {
    try {
        const data = await Xrm.WebApi.retrieveRecord(
            SETTING_ENTITY_NAME,
            "7333e80e-9b0f-49b5-92c8-9b48d621c37c",
            `?$select=${SETTING_FIELD_NAME}`);
        try {
            sessionStorage.setItem(SETTING_VALUE_SESSION_STORAGE_KEY, data[SETTING_FIELD_NAME]);
        } catch (error) {
            // Handle sessionStorage error
        } finally {
            return data[SETTING_FIELD_NAME];
        }
    } catch (error) {
        // Handle retrieveRecord error   
    }
}

Gunakan informasi yang tersedia dalam API klien daripada membuat permintaan. Contohnya, daripada meminta peran keamanan pengguna pada beban formulir, Anda dapat menggunakan getGlobalContext.userSettings.roles.

Muatkan kode hanya bila diperlukan

Muat kode sebanyak yang diperlukan untuk aktivitas untuk formulir tertentu. Jika Anda memiliki kode yang hanya untuk formulir A dan formulir B, kode tersebut tidak boleh disertakan dalam pustaka yang dimuat untuk formulir C. Harus di pustaka sendiri.

Hindari pemuatan pustaka dalam aktivitas OnLoad jika hanya digunakan untuk aktivitas OnChange atau OnSave. Melainkan, muat dalam aktivitas tersebut. Dengan cara ini platform dapat menunda pemuatannya hingga setelah formulir dimuat. Informasi selengkapnya: Mengoptimalkan performa formulir

Menghilangkan penggunaan API konsol dalam kode produksi

Jangan gunakan metode API konsol seperti console.log dalam kode produksi. pengelogan data ke konsol dapat secara signifikan meningkatkan permintaan memori dan dapat mencegah data dibersihkan dalam memori. Hal ini dapat mengakibatkan aplikasi menjadi lebih lambat seiring waktu dan akhirnya macet.

Hindari kebocoran memori

Kebocorkan memori pada kode dapat menyebabkan kinerja lebih lambat seiring waktu dan mengakibatkan aplikasi macet. Kebocoran memori terjadi saat aplikasi gagal melepas memori ketika tidak lagi diperlukan. Dengan semua penyesuaian dan komponen kode di formulir, Anda harus:

  • Pertimbangkan secara menyeluruh dan uji skenario untuk apa pun yang bertanggung jawab untuk membersihkan memori, seperti kelas yang bertanggung jawab untuk mengelola siklus hidup objek.
  • Bersihkan semua mendengarkan aktivitas dan langganan, terutama jika ada pada objek window.
  • Bersihkan semua timer seperti setInterval.
  • Hindari, batasi, dan bersihkan referensi ke objek global atau statis.

Untuk komponen kontrol kustom, membersihkan dapat dilakukan dengan metode hancurkan.

Untuk informasi lebih lanjut tentang cara memperbaiki masalah memori, buka dokumentasi pengembang Edge.

Alat yang dapat Anda gunakan untuk membantu membuat aplikasi berkinerja

Bagian ini menjelaskan alat yang dapat membantu Anda memahami masalah performa dan menawarkan rekomendasi cara mengoptimalkan penyesuaian dalam aplikasi berdasarkan model.

Wawasan performa

Wawasan performa adalah alat layanan mandiri untuk pembuat aplikasi enterprise yang menganalisis data telemetri runtime dan memberikan daftar rekomendasi prioritas untuk membantu meningkatkan kinerja aplikasi berdasarkan model. Fitur ini menyediakan rangkaian wawasan analitik harian terkait kinerja aplikasi berbasis model Power Apps atau keterlibatan pelanggan, seperti Dynamics 365 Sales atau Dynamics 365 Service, dengan rekomendasi dan item yang dapat ditindaklanjuti. Pembuat aplikasi Enterprise dapat melihat wawasan performa terperinci pada tingkat aplikasi dalam Power Apps. Informasi lebih lanjut: Apa itu wawasan kinerja? (pratinjau)

Pemeriksa solusi

Pemeriksa solusi adalah alat bantu canggih yang dapat menganalisis penyesuaian klien dan server untuk masalah performa atau keandalan. Plug-in sisi klien dapat mengurai JavaScript sisi klien, xml formulir, dan plug-in sisi server .NET, serta memberikan wawasan yang ditargetkan tentang hal yang dapat memperlambat pengguna akhir. Sebaiknya jalankan pemeriksa solusi setiap kali Anda mempublikasikan perubahan dalam lingkungan pengembangan, sehingga masalah performa muncul sebelum menjangkau pengguna akhir. Informasi lebih lanjut: Gunakan pemeriksa solusi untuk memvalidasi aplikasi berbasis model Anda di Power Apps

Beberapa contoh masalah yang terkait dengan performa yang ditemukan dengan pemeriksa solusi:

Pemeriksa objek

Pemeriksa objek menjalankan diagnostik real-time pada objek komponen dalam solusi Anda. Jika masalah terdeteksi, maka rekomendasi akan dihasilkan yang menjelaskan cara memperbaiki masalah. Informasi lebih lanjut: Menggunakan pemeriksa objek untuk mendiagnosis komponen solusi (pratinjau)

Langkah berikutnya

Desain formulir utama produktif dalam aplikasi yang diarahkan model