Thiết kế biểu mẫu cho hiệu suất trong ứng dụng hướng mô hình

Xây dựng trải nghiệm trong đó các nhiệm vụ có thể được hoàn thành nhanh chóng và hiệu quả là rất quan trọng đối với sự hài lòng của người dùng. Ứng dụng theo hướng mô hình có thể được tùy chỉnh cao để tạo ra trải nghiệm đáp ứng nhu cầu của người dùng, nhưng điều quan trọng là phải biết cách viết mã, xây dựng và chạy các ứng dụng theo hướng mô hình một cách hiệu quả, tải nhanh khi người dùng mở và điều hướng trong ứng dụng của bạn trong khi làm các công việc hàng ngày. Hiệu suất đã được chứng minh là nguyên nhân chính dẫn đến sự không hài lòng về một ứng dụng khi nó không được tối ưu hóa cho hiệu suất.

Các tùy chỉnh thông minh và các biểu mẫu hoạt động hiệu quả những khía cạnh quan trọng để xây dựng các biểu mẫu hiệu quả và năng suất cao. Điều quan trọng nữa là đảm bảo rằng bạn đang xây dựng các biểu mẫu có năng suất cao bằng các phương pháp hay nhất trong thiết kế và bố cục giao diện người dùng. Để biết thông tin về cách thiết kế biểu mẫu cho hiệu quả và năng suất, hãy xem Thiết kế các biểu mẫu chính hiệu quả trong các ứng dụng hướng mô hình.

Điều quan trọng nữa là đảm bảo người dùng sử dụng các thiết bị được khuyến nghị và hỗ trợ cũng như các thông số kỹ thuật bắt buộc tối thiểu. Thêm thông tin: Trình duyệt web được hỗ trợ và các thiết bị di động

Làm việc với dữ liệu và tab

Phần này trình bày cách các điều khiển hiển thị dữ liệu và tab tác động đến hiệu suất biểu mẫu.

Tầm quan trọng của tab mặc định

Tab mặc định là tab được mở rộng đầu tiên trên một biểu mẫu. Nó đóng một vai trò đặc biệt trong việc tải một trang biểu mẫu. Theo thiết kế, các điều khiển của tab mặc định luôn được hiển thị khi mở bản ghi. Cụ thể, logic khởi tạo điều khiển, chẳng hạn như truy xuất dữ liệu, được gọi cho mọi điều khiển trên tab.

Ngược lại, tab phụ không thực hiện việc khởi tạo này trên các điều khiển của nó khi biểu mẫu được tải ban đầu. Thay vào đó, quá trình khởi tạo điều khiển xảy ra tại thời điểm mở tab phụ thông qua tương tác của người dùng hoặc lệnh gọi phương thức API máy khách setFocus. Điều này tạo cơ hội để tránh cho tải biểu mẫu ban đầu khỏi quá trình xử lý điều khiển quá mức bằng cách đặt một số điều khiển nhất định trong các tab phụ thay vì tab mặc định. Do đó, chiến lược vị trí điều khiển có thể có ảnh hưởng đáng kể đến khả năng đáp ứng của tải biểu mẫu ban đầu. Tab mặc định đáp ứng tốt hơn cung cấp trải nghiệm tổng thể tốt hơn để sửa đổi các trường quan trọng, tương tác với thanh lệnh và khám phá các tab và phần khác.

Luôn đặt các điều khiển được sử dụng nhiều nhất ở đầu tab mặc định của bạn. Bố cục và kiến trúc thông tin không chỉ quan trọng đối với hiệu suất mà còn để cải thiện năng suất khi người dùng tương tác với dữ liệu trên biểu mẫu. Thêm thông tin: Thiết kế các biểu mẫu chính hiệu quả trong các ứng dụng hướng mô hình

Kiểm soát theo hướng dữ liệu

Các điều khiển yêu cầu dữ liệu bổ sung ngoài bản ghi chính gây ra sự căng thẳng nhất về khả năng phản hồi biểu mẫu và tốc độ tải. Các điều khiển này tìm nạp dữ liệu qua mạng và thường kéo theo khoảng thời gian chờ (được coi là chỉ báo tiến độ) vì có thể mất thời gian để truyền dữ liệu.

Một số điều khiển theo hướng dữ liệu bao gồm:

Chỉ giữ lại các điều khiển được sử dụng thường xuyên nhất trong số các điều khiển này trên tab mặc định. Các điều khiển theo hướng dữ liệu còn lại nên được phân phối thành các tab phụ để cho phép tải nhanh tab mặc định. Hơn nữa, chiến lược bố cục này làm giảm cơ hội tìm nạp dữ liệu cuối cùng không được sử dụng.

Có các kiểm soát khác ít tác động hơn các kiểm soát theo hướng dữ liệu nhưng vẫn có thể tham gia vào chiến lược bố trí ở trên để đạt được hiệu suất tốt nhất. Các kiểm soát này bao gồm:

Trình duyệt web

Phần này bao gồm các phương pháp hay để sử dụng với các trình duyệt web.

Không mở cửa sổ mới

Phương thức API máy khách openForm cho phép tùy chọn tham số hiển thị biểu mẫu trong cửa sổ mới. Không sử dụng tham số này hoặc đặt nó thành false. Đặt nó thành false sẽ đảm bảo phương thức openForm thực hiện hành vi mặc định là hiển thị biểu mẫu bằng cửa sổ hiện có. Nó cũng có thể trực tiếp gọi chức năng JavaScript window.open từ một tập lệnh tùy chỉnh hoặc một ứng dụng khác; tuy nhiên, điều này cũng nên tránh. Mở một cửa sổ mới có nghĩa là tất cả các tài nguyên của trang cần được tìm nạp và tải từ đầu vì trang không thể tận dụng khả năng lưu trữ dữ liệu trong bộ nhớ giữa một biểu mẫu đã tải trước đó và biểu mẫu trong một cửa sổ mới. Để thay thế cho việc mở các cửa sổ mới, hãy cân nhắc sử dụng trải nghiệm đa phiên cho phép các bản ghi được mở trong nhiều tab trong khi vẫn tối đa hóa lợi ích về hiệu suất của bộ nhớ đệm máy khách.

Sử dụng các trình duyệt hiện đại

Sử dụng trình duyệt web cập nhật nhất là chìa khóa để đảm bảo ứng dụng chạy theo mô hình của bạn chạy nhanh nhất có thể. Lý do cho điều này là nhiều cải tiến hiệu suất chỉ có thể được sử dụng trong các trình duyệt hiện đại mới hơn.

Ví dụ: nếu tổ chức của bạn có các phiên bản cũ hơn của Firefox, các trình duyệt không dựa trên Chromium, v.v., nhiều tính năng tăng hiệu suất được tích hợp vào ứng dụng theo hướng mô hình sẽ không khả dụng trong các phiên bản trình duyệt cũ hơn vì chúng không hỗ trợ các tính năng mà ứng dụng phụ thuộc vào để chạy nhanh và suôn sẻ.

Trong hầu hết các trường hợp, bạn có thể thấy tốc độ tải trang được cải thiện bằng cách chuyển sang Microsoft Edge, cập nhật lên phiên bản trình duyệt hiện tại mới nhất từ phiên bản cũ hơn hoặc chuyển sang trình duyệt dựa trên Chromium hiện đại.

Tùy chỉnh JavaScript

Phần này trình bày cách thực hiện các tùy chỉnh thông minh khi bạn sử dụng JavaScript để giúp bạn tạo các biểu mẫu và trang hiệu quả trong một ứng dụng theo hướng mô hình.

Sử dụng JavaScript với các biểu mẫu

Khả năng tùy chỉnh biểu mẫu bằng JavaScript cung cấp cho các nhà phát triển chuyên nghiệp sự linh hoạt tuyệt vời về hình thức cũng như cách thức biểu mẫu hoạt động. Việc sử dụng không đúng cách tính linh hoạt này có thể tác động tiêu cực đến hiệu suất của biểu mẫu. Các nhà phát triển nên sử dụng các chiến lược sau để tối đa hóa hiệu suất biểu mẫu khi triển khai các tùy chỉnh JavaScript.

Sử dụng các yêu cầu mạng không đồng bộ khi yêu cầu dữ liệu

Yêu cầu dữ liệu không đồng bộ thay vì đồng bộ khi dữ liệu bổ sung là cần thiết cho các tùy chỉnh. Đối với các sự kiện hỗ trợ chờ mã không đồng bộ như OnLoad biểu mẫu và sự kiện OnSave biểu mẫu, trình xử lý sự kiện phải trả về Promise để nền tảng đợi cho đến khi Promise được giải quyết. Nền tảng sẽ hiển thị một giao diện người dùng thích hợp trong khi người dùng đợi sự kiện hoàn tất.

Đối với các sự kiện không hỗ trợ chờ mã không đồng bộ, như sự kiện OnChange biểu mẫu, bạn có thể sử dụng giải pháp thay thế để ngừng tương tác với biểu mẫu trong khi mã đang thực hiện yêu cầu không đồng bộ bằng cách sử dụng showProgressIndicator. Điều này tốt hơn so với việc sử dụng các yêu cầu đồng bộ vì người dùng sẽ vẫn có thể tương tác với các phần khác của ứng dụng khi chỉ báo tiến trình được hiển thị.

Đây là một ví dụ sử dụng mã không đồng bộ trong các điểm mở rộng đồng bộ.

//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);

Bạn nên cẩn thận khi sử dụng mã không đồng bộ trong trình xử lý sự kiện không hỗ trợ chờ mã không đồng bộ. Điều này đặc biệt đúng đối với mã cần một hành động được thực hiện hoặc xử lý để giải quyết mã không đồng bộ. Mã không đồng bộ có thể gây ra sự cố nếu trình xử lý giải pháp mong muốn ngữ cảnh ứng dụng vẫn giống như khi mã không đồng bộ được khởi động. Mã của bạn nên kiểm tra xem người dùng có ở trong cùng một ngữ cảnh sau mỗi điểm tiếp tục không đồng bộ hay không.

Ví dụ: có thể có mã trong trình xử lý sự kiện để thực hiện yêu cầu mạng và thay đổi điều khiển bị vô hiệu hóa dựa trên dữ liệu phản hồi. Trước khi nhận được phản hồi từ yêu cầu, người dùng có thể đã tương tác với điều khiển hoặc điều hướng đến một trang khác. Bởi vì người dùng đang ở trên một trang khác, ngữ cảnh biểu mẫu có thể không có sẵn, điều này có thể dẫn đến lỗi hoặc có thể có hành vi không mong muốn khác.

Hỗ trợ không đồng bộ trong các sự kiện OnLoad và biểu mẫu OnSave

Biểu mẫu OnLoad và sự kiện OnSave hỗ trợ các trình xử lý trả về các lời hứa. Các sự kiện sẽ đợi bất kỳ lời hứa nào do một trình xử lý trả về để giải quyết, tối đa là một khoảng thời gian chờ. Hỗ trợ này có thể được kích hoạt thông qua cài đặt ứng dụng.

Thông tin khác:

Giới hạn số lượng dữ liệu được yêu cầu trong quá trình tải biểu mẫu

Chỉ yêu cầu lượng dữ liệu tối thiểu cần thiết để thực hiện logic nghiệp vụ trên một biểu mẫu. Lưu vào bộ nhớ đệm dữ liệu được yêu cầu càng nhiều càng tốt, đặc biệt đối với dữ liệu không thay đổi thường xuyên hoặc không cần làm mới. Ví dụ: hãy tưởng tượng có một biểu mẫu yêu cầu dữ liệu từ bảng thiết lập. Dựa trên dữ liệu trong bảng cài đặt, biểu mẫu có thể chọn ẩn một phần của biểu mẫu. Trong trường hợp này, JavaScript có thể lưu dữ liệu vào bộ nhớ cache trong sessionStorage để dữ liệu chỉ được yêu cầu một lần mỗi phiên (onLoad1). Chiến lược cũ trong khi xác thực lại cũng có thể được sử dụng khi JavaScript sử dụng dữ liệu từ sessionStorage trong khi yêu cầu dữ liệu cho điều hướng tiếp theo đến biểu mẫu (onLoad2). Cuối cùng, một chiến lược khử trùng lặp có thể được sử dụng trong trường hợp một trình xử lý được gọi nhiều lần liên tiếp (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   
    }
}

Sử dụng thông tin có sẵn trong API ứng dụng khách thay vì đưa ra yêu cầu. Ví dụ: thay vì yêu cầu vai trò bảo mật của người dùng khi tải biểu mẫu, bạn có thể sử dụng getGlobalContext.userSettings.roles.

Chỉ tải mã khi cần

Tải mã theo nhu cầu nếu cần cho các sự kiện cho một biểu mẫu cụ thể. Nếu bạn có mã chỉ dành cho biểu mẫu Abiểu mẫu B, nó không nên được đưa vào thư viện được tải cho biểu mẫu C. Nó phải nằm trong thư viện riêng của nó.

Tránh tải các thư viện trong sự kiện OnLoad nếu chúng chỉ được sử dụng cho sự kiện OnChange hoặc OnSave. Thay vào đó, hãy tải chúng trong các sự kiện đó. Bằng cách này, nền tảng có thể trì hoãn việc tải chúng cho đến khi tải biểu mẫu. Thêm thông tin: Tối ưu hóa hiệu suất biểu mẫu

Xóa việc sử dụng API bảng điều khiển trong mã sản xuất

Không sử dụng các phương thức API bảng điều khiển như console.log trong mã sản xuất. Việc ghi dữ liệu vào bảng điều khiển có thể làm tăng đáng kể nhu cầu bộ nhớ và có thể ngăn không cho dữ liệu bị dọn sạch trong bộ nhớ. Điều này có thể dẫn đến ứng dụng trở nên chậm hơn theo thời gian và cuối cùng là bị lỗi.

Tránh rò rỉ bộ nhớ

Rò rỉ bộ nhớ trong mã của bạn có thể dẫn đến hiệu suất chậm hơn theo thời gian và cuối cùng khiến ứng dụng của bạn gặp sự cố. Rò rỉ bộ nhớ xảy ra khi ứng dụng không giải phóng bộ nhớ khi không còn cần thiết. Với tất cả các tùy chỉnh và thành phần mã trên biểu mẫu của bạn, bạn nên:

  • Xem xét kỹ lưỡng và kiểm tra các kịch bản cho bất kỳ thứ gì chịu trách nhiệm dọn dẹp bộ nhớ, chẳng hạn như các lớp chịu trách nhiệm quản lý vòng đời của các đối tượng.
  • Dọn dẹp tất cả người nghe và đăng ký sự kiện, đặc biệt nếu xuất hiện trong đối tượng window.
  • Dọn dẹp tất cả các bộ đếm thời gian như setInterval.
  • Tránh, hạn chế và dọn dẹp các tham chiếu đến các đối tượng toàn cục hoặc tĩnh.

Đối với các thành phần điều khiển tùy chỉnh, việc dọn dẹp có thể được thực hiện trong phương pháp phá hủy.

Để biết thêm thông tin về cách khắc phục sự cố bộ nhớ, hãy truy cập tài liệu dành cho nhà phát triển Edge này.

Các công cụ bạn có thể sử dụng để giúp ứng dụng hoạt động hiệu quả

Phần này mô tả các công cụ có thể giúp bạn hiểu các vấn đề về hiệu suất và đưa ra các đề xuất về cách tối ưu hóa các tùy chỉnh của bạn trong các ứng dụng theo mô hình.

Thông tin chuyên sâu về hiệu suất

Thông tin chi tiết về hiệu suất là một công cụ tự phục vụ dành cho người tạo ứng dụng doanh nghiệp, phân tích dữ liệu đo từ xa thời gian chạy và cung cấp danh sách đề xuất được ưu tiên để giúp cải thiện hiệu suất của các ứng dụng theo mô hình. Tính năng này cung cấp một tập hợp thông tin chuyên sâu phân tích hàng ngày liên quan đến hiệu suất của ứng dụng Customer Engagement hoặc ứng dụng dựa trên mô hình Power Apps, chẳng hạn như Dynamics 365 Sales hoặc Dynamics 365 Service, với các đề xuất và các mục có thể hành động. Người tạo ứng dụng doanh nghiệp có thể xem thông tin chi tiết về hiệu suất ở cấp ứng dụng trong Power Apps. Thêm thông tin: Thông tin chi tiết về hiệu suất là gì? (xem trước)

Bộ kiểm tra giải pháp

Trình kiểm tra giải pháp là một công cụ mạnh mẽ có thể phân tích các tùy chỉnh của máy khách và máy chủ cho các vấn đề về hiệu suất hoặc độ tin cậy. Nó có thể phân tích cú pháp JavaScript phía máy khách, biểu mẫu XML và phần bổ trợ phía máy chủ .NET và cung cấp thông tin chi tiết được nhắm mục tiêu về những gì có thể làm chậm người dùng cuối. Chúng tôi khuyên bạn nên chạy trình kiểm tra giải pháp mỗi khi bạn xuất bản các thay đổi trong môi trường phát triển, để mọi lo ngại về hiệu suất được hiển thị trước khi đến tay người dùng cuối. Thông tin thêm: Sử dụng công cụ kiểm tra giải pháp để xác thực ứng dụng dựa trên mô hình của bạn trong Power Apps

Một số ví dụ về các vấn đề liên quan đến hiệu suất được tìm thấy với trình kiểm tra giải pháp:

  • il-specify-column. Tránh chọn tất cả các cột thông qua API truy vấn Dataverse.
  • web-use-async. Tương tác với tài nguyên HTTP và HTTPS không đồng thời.
  • web-avoid-ui-refreshribbon. Tránh sử dụng refreshRibbon trong biểu mẫu OnLoadEnableRule.

Bộ kiểm tra đối tượng

Trình kiểm tra đối tượng chạy chẩn đoán thời gian thực trên các đối tượng thành phần trong giải pháp của bạn. Nếu sự cố được phát hiện, một đề xuất sẽ được trả về mô tả cách khắc phục sự cố. Thêm thông tin: Sử dụng trình kiểm tra đối tượng để chẩn đoán thành phần giải pháp (xem trước)

Các bước tiếp theo

Thiết kế biểu mẫu chính hiệu quả trong ứng dụng dựa trên mô hình