Xây dựng các ứng dụng canvas lớn và phức tạp
Hầu hết các bài viết trong phần tài liệu này đều đề cập đến hiệu suất thời gian chạy của ứng dụng theo trải nghiệm của người dùng. Bài viết này đề cập đến hiệu suất của ứng dụng theo kinh nghiệm của những người tạo ra chúng.
Khi các ứng dụng ngày càng lớn hơn và phức tạp hơn, Power Apps Studio cần phải tải và quản lý số lượng lớn các điều khiển, công thức và nguồn dữ liệu, tất cả đều có mối quan hệ phụ thuộc lẫn nhau tăng theo cấp số nhân. Power Apps Studio có thể mất nhiều thời gian hơn để tải và các tính năng như IntelliSense và mã hóa màu có thể bị chậm. Sử dụng các khuyến nghị sau để làm việc tốt hơn với các ứng dụng lớn và phức tạp Power Apps Studio. Chúng cũng có thể giúp cải thiện hiệu suất thời gian chạy của ứng dụng.
Các ví dụ trong bài viết này sử dụng giải pháp mẫu Cấp cứu bệnh viện phản hồi.
Sử dụng App.Formulas thay vì App.OnStart
Mẹo
Bạn có thể sử dụng với hàm và các thuộc tính đầu ra tùy chỉnh của thành phần canvas làm giải pháp thay thế cho các công thức được đặt tên.
Cách tốt nhất để giảm thời gian tải cho cả Power Apps Studio và ứng dụng của bạn là thay thế khởi tạo biến và bộ sưu tập trong App.OnStart bằng các công thức được đặt tên trong App.Formulas.
Hãy cùng xem ví dụ sau đây sử dụng App.OnStart.
// Get the color of text on a dark background.
Set(varColorOnDark,RGBA(0, 0, 0, 1));
// Get the color of the menu icons.
Set(varColorMenuIcon,"#0070a9");
// Get the styles for a form.
Set(varFormStyle,
{
DataCard: { Height: 50 },
Title: { Height: 50, Size: 21, Color: varColorOnDark },
Control: { Height: 50, Size: 18 },
Label: { Size: 18, Color: varColorOnDark }
}
);
ClearCollect(
FacilitiesList,
ForAll(
Facilities,
{ Name: 'Facility Name', Id: Facility }
)
);
If(
Not IsBlank(Param("FacilityID")),
Set(ParamFacility,
LookUp(
FacilitiesList,
Id = GUID(Param("FacilityID"))
).Name
);
);
Vì chúng là một chuỗi các câu lệnh nên ứng dụng của bạn phải đánh giá các lệnh gọi Set và Collect này theo thứ tự trước khi có thể hiển thị màn hình đầu tiên, điều này khiến ứng dụng tải chậm hơn. Và vì toàn bộ App.OnStart phải được xem xét như một tổng thể, thứ tự được giữ nguyên và lỗi được tổng hợp trước khi trả về kết quả cuối cùng, nên công thức này rất phức tạp để Power Apps Studio phân tích.
Có một cách tốt hơn. Thay vào đó, hãy sử dụng App.Formulas và định nghĩa các biến và bộ sưu tập này dưới dạng các công thức được đặt tên, như trong ví dụ sau.
// Get the color of text on a dark background.
varColorOnDark = RGBA(0, 0, 0, 1);
// Get the color of the menu icons.
varColorMenuIcon = "#0070a9";
// Get the styles for a form.
varFormStyle =
{
DataCard: { Height: 50 },
Title: { Height: 50, Size: 21, Color: varColorOnDark },
Control: { Height: 50, Size: 18 },
Label: { Size: 18, Color: varColorOnDark }
};
FacilitiesList =
ForAll(
Facilities,
{ Name: 'Facility Name', Id: Facility }
);
ParamFacility =
If( Not IsBlank(Param("FacilityID")),
LookUp(
FacilitiesList,
Id = GUID(Param("FacilityID"))
).Name,
Blank()
);
Sự thay đổi này có vẻ nhỏ nhưng có thể mang lại tác động rất lớn. Vì mỗi công thức được đặt tên đều độc lập với các công thức khác, Power Apps Studio có thể phân tích chúng một cách độc lập, do đó có thể chia một App.OnStart lớn thành các phần nhỏ hơn. Chúng tôi đã thấy thời gian tải giảm tới 80% chỉ với thay đổi này. Power Apps Studio
Ứng dụng của bạn cũng tải nhanh hơn vì không phải đánh giá các công thức này cho đến khi cần kết quả. Màn hình đầu tiên của ứng dụng sẽ hiển thị ngay lập tức.
Không thể sử dụng công thức được đặt tên trong mọi trường hợp vì bạn không thể sửa đổi chúng hoặc sử dụng chúng với Set. Một số tình huống đòi hỏi phải sử dụng biến trạng thái có thể sửa đổi được. Bộ hoàn hảo cho những tình huống này và bạn nên tiếp tục sử dụng nó. Tuy nhiên, thông thường, bạn sẽ sử dụng biến toàn cục trong OnStart để thiết lập các giá trị tĩnh không thay đổi. Trong những trường hợp đó, công thức có tên là lựa chọn tốt hơn.
Vì các công thức được đặt tên là bất biến nên tiền tố var
(viết tắt của "biến") làm quy ước đặt tên không còn phù hợp nữa. Chúng tôi không thay đổi tên trong ví dụ này vì điều này đòi hỏi phải thay đổi phần còn lại của ứng dụng cho phù hợp.
Thật hấp dẫn khi đặt một công thức được đặt tên trong App.OnStart, nhưng đừng làm vậy. Họ không thuộc về nơi đó. Là một thuộc tính hành vi On, App.OnStart đánh giá từng câu lệnh theo thứ tự, tạo các biến toàn cục và chỉ trao đổi với cơ sở dữ liệu một lần khi ứng dụng được tải. Công thức được đặt tên là công thức xác định cách tính toán một cái gì đó bất cứ khi nào cần và luôn đúng. Bản chất công thức này cho phép chúng độc lập và cho phép ứng dụng hoàn tất việc tải trước khi chúng được đánh giá.
Chia nhỏ các công thức dài
App.OnStart là một trong những ứng dụng tệ nhất đối với các công thức dài và chắc chắn là nơi bạn nên bắt đầu, nhưng đây không phải là trường hợp duy nhất.
Nghiên cứu của chúng tôi đã chỉ ra rằng hầu hết các ứng dụng có thời gian tải lâu đều có ít nhất một công thức dài hơn 256.000 ký tự. Power Apps Studio Một số ứng dụng có thời gian tải lâu nhất có công thức dài hơn 1 triệu ký tự. Các công thức từ lâu đã gây áp lực đáng kể lên Power Apps Studio.
Tệ hơn nữa, việc sao chép và dán một điều khiển có công thức dài sẽ làm công thức đó trùng lặp trong thuộc tính của điều khiển mà không hề được thực hiện. Power Apps được mô phỏng theo Excel, trong đó nhiều bản sao của một công thức là phổ biến. Tuy nhiên, trong Excel, công thức bị giới hạn ở một biểu thức và tối đa là 8.000 ký tự. Power Apps công thức có thể dài hơn nhiều khi sử dụng logic mệnh lệnh và toán tử nối (;
hoặc ;;
, tùy thuộc vào địa phương).
Giải pháp chung là chia các công thức dài thành các phần nhỏ hơn và sử dụng lại các phần đó, như chúng ta đã làm trong phần trước khi thay đổi các câu lệnh Set/Collect trong App.OnStart thành các công thức được đặt tên trong App.Formulas. Trong các ngôn ngữ lập trình khác, các phần có thể tái sử dụng thường được gọi là chương trình con hoặc hàm do người dùng định nghĩa. Bạn có thể coi công thức được đặt tên như một dạng hàm đơn giản do người dùng định nghĩa, không có tham số hoặc tác dụng phụ.
Sử dụng công thức được đặt tên ở mọi nơi
Trong ví dụ trước, chúng tôi đã sử dụng các công thức được đặt tên để thay thế cho App.OnStart. Tuy nhiên, bạn có thể sử dụng chúng để thay thế phép tính ở bất kỳ đâu trong ứng dụng.
Ví dụ, một trong các màn hình trong giải pháp mẫu phản hồi của Bệnh viện cấp cứu bao gồm logic này trong Screen.OnVisible:
ClearCollect(
MySplashSelectionsCollection,
{
MySystemCol: First(
Filter(
Regions,
Region = MyParamRegion
)
).System.'System Name',
MyRegionCol: First(
Filter(
Regions,
Region = MyParamRegion
)
).'Region Name',
MyFacilityCol: ParamFacility,
MyFacilityColID: LookUp(
FacilitiesList,
Id = GUID(Param("FacilityID"))
).Id
}
);
Công thức này có thể được chia thành một tập hợp các công thức được đặt tên. Nó cũng làm cho công thức dễ đọc hơn.
MyRegion = LookUp(
Regions,
Region = MyParamRegion
);
MyFacility = LookUp(
FacilitiesList,
Id = GUID(Param("FacilityID")
);
MySplashSelectionsCollection =
{
MySystemCol: MyRegion.System.'System Name',
MyRegionCol: MyRegion.'Region Name',
MyFacilityCol: ParamFacility,
MyFacilityColID: MyFacility.Id
};
Chúng tôi đã trích xuất ParamFacility dưới dạng công thức được đặt tên trước đó khi chúng tôi di chuyển hầu hết các lệnh gọi Set từ App.OnStart đến các công thức được đặt tên trong App.Formulas.
Các công thức được đặt tên chỉ được đánh giá khi cần đến giá trị của chúng. Nếu mục đích ban đầu khi sử dụng Screen.OnVisible là trì hoãn công việc cho đến khi màn hình hiển thị, thì công việc vẫn được trì hoãn dưới dạng các công thức có tên toàn cục trong App.Formulas.
Sử dụng hàm With
Bạn cũng có thể sử dụng hàm With trong công thức để phân tách logic. Tạo một bản ghi trong tham số đầu tiên với các giá trị bạn muốn sử dụng làm trường, sau đó sử dụng các trường đó trong tham số thứ hai để tính giá trị trả về từ Với. Ví dụ, ví dụ trước có thể được viết chỉ bằng một công thức có tên:
MySplashSelectionsCollection =
With( { MyRegion: LookUp(
Regions,
Region = MyParamRegion
),
MyFacility: LookUp(
FacilitiesList,
Id = GUID(Param("FacilityID")
)
},
{
MySystemCol: MyRegion.System.'System Name',
MyRegionCol: MyRegion.'Region Name',
MyFacilityCol: ParamFacility,
MyFacilityColID: MyFacility.Id
}
)
Một nhược điểm khi sử dụng With theo cách này là MyFacility
không thể sử dụng MyRegion
vì chúng được định nghĩa trong cùng một hàm With, một vấn đề không có ở các công thức được đặt tên. Một giải pháp là lồng các hàm With và sử dụng từ khóa As để đặt tên cho bản ghi của từng hàm nhằm dễ dàng truy cập vào tất cả các biến With .
Sử dụng các thành phần canvas
Các thành phần canvas thường được sử dụng để tạo ra một điều khiển UI có thể được đặt trên canvas giống như một điều khiển thông thường. Bạn cũng có thể sử dụng chúng mà không cần đặt chúng trong UI để thực hiện các phép tính với các thuộc tính đầu ra tùy chỉnh thay cho các công thức được đặt tên. Các thành phần Canvas dễ dàng chia sẻ giữa các ứng dụng với các thư viện thành phần và được hỗ trợ đầy đủ, không giống như các công thức được đặt tên. Tuy nhiên, chúng khó cấu hình và sử dụng hơn các công thức được đặt tên.
Để phân tách logic:
- Trong Power Apps Studio, chuyển sang tab Thành phần trong Chế độ xem cây.
- Tạo thành phần mới.
- Trong ngăn Thuộc tính, bật Phạm vi ứng dụng truy cập.
- Thêm thuộc tính tùy chỉnh.
- Đặt Loại thuộc tính thành Đầu ra và Loại dữ liệu cho phù hợp.
- Chọn Tạo.
- Trong công cụ chọn thuộc tính bên cạnh thanh công thức ở đầu màn hình, hãy chọn thuộc tính mới.
- Viết công thức logic để phân tách và tái sử dụng.
Để sử dụng logic:
- Chuyển sang tab Màn hình trong chế độ xem Cây.
- Trong ngăn Chèn, hãy mở rộng Tùy chỉnh và chèn thành phần của bạn.
- Để tính toán giá trị bằng thuộc tính, hãy sử dụng ComponentName.PropertyName.
Sử dụng Select với điều khiển ẩn cho logic bắt buộc
Logic bắt buộc được sử dụng để sửa đổi trạng thái bằng Đặt và Thu thập, thông báo cho người dùng bằng Thông báo, điều hướng đến màn hình hoặc ứng dụng khác bằng Điều hướng và Khởi chạy và ghi giá trị vào cơ sở dữ liệu bằng Bản vá, Gửi biểu mẫu hoặc Xóa nếu.
Các công thức được đặt tên và thuộc tính đầu ra tùy chỉnh của thành phần canvas không hỗ trợ logic bắt buộc. Một cách phổ biến để phân chia logic mệnh lệnh là sử dụng thuộc tính OnSelect của một điều khiển ẩn.
- Thêm một nút điều khiển vào màn hình.
- Đặt thuộc tính OnSelect thành logic bắt buộc mà bạn muốn thực thi.
- Đặt thuộc tính Có thể nhìn thấy thành false vì người dùng không cần phải nhìn thấy hoặc tương tác với nó.
- Gọi
Select( Button )
khi bạn muốn thực hiện logic mệnh lệnh.
Ví dụ, một trong các màn hình trong mẫu của chúng tôi có thuộc tính OnSelect sau trên một điều khiển Nút . (Ví dụ đơn giản này chỉ mang tính chất minh họa. Thông thường, bạn chỉ sử dụng kỹ thuật này cho các công thức dài hơn.)
btnAction_17.OnSelect =
Trace("Feedback Screen: Submit Button",TraceSeverity.Information);
If(
// Proceed if all forms are validated.
And(
FormFeedback.Valid
),
// Set the updates to static variables.
Set(updatesFeedback,Patch(Defaults('App Feedbacks'), FormFeedback.Updates));
// Submit the first form. Subsequent actions can be found in the OnSuccess.
SubmitForm(FormFeedback);
,
Notify("Please complete all fields before proceeding",
NotificationType.Warning,2000)
);
Để chia logic này thành nhiều phần, chúng ta có thể đặt các phần vào các nút điều khiển Nút riêng biệt và Chọn chúng từ bản gốc:
btnTrace.OnSelect =
Trace("Feedback Screen: Submit Button",TraceSeverity.Information);
btnSubmit.OnSelect =
If(
// Proceed if all forms are validated.
And(
FormFeedback.Valid
),
// Set the updates to static variables.
Set(updatesFeedback,Patch(Defaults('App Feedbacks'), FormFeedback.Updates));
// Submit the first form. Subsequent actions can be found in OnSuccess.
SubmitForm(FormFeedback);
,
Notify("Please complete all fields before proceeding",
NotificationType.Warning,2000)
);
btnAction_17.OnSelect =
Select( btnTrace );
Select( btnSubmit );
Kỹ thuật này chỉ có tác dụng trên cùng một màn hình. Các kỹ thuật khác phức tạp hơn một chút có thể hoạt động trên nhiều màn hình, chẳng hạn như sử dụng điều khiển Toggle, đặt OnCheck thành logic bạn muốn chạy và đặt Default thành biến toàn cục, sau đó chuyển đổi biến toàn cục với Set( global, true ); Set( global, false )
tại điểm bạn muốn chạy logic.
Trong ví dụ này, một số phân tách logic đã được thực hiện. Bình luận đề cập rằng "Những hành động tiếp theo có thể được tìm thấy trong OnSuccess". Sự kiện này chạy logic bắt buộc sau khi bản ghi đã được gửi thành công, một giải pháp cụ thể cho hàm SubmitForm .
Phân vùng ứng dụng
Một số ứng dụng có tới hàng nghìn quyền kiểm soát và hàng trăm nguồn dữ liệu, làm chậm Power Apps Studio. Tương tự như các công thức dài, các ứng dụng lớn có thể được chia thành các phần nhỏ hơn hoạt động cùng nhau để tạo ra một trải nghiệm người dùng duy nhất.
Ứng dụng canvas riêng biệt
Một cách tiếp cận là triển khai các phần trong các ứng dụng canvas riêng biệt và sử dụng chức năng Khởi chạy để điều hướng giữa các ứng dụng riêng biệt và truyền ngữ cảnh cần thiết.
Phương pháp này đã được sử dụng trong giải pháp mẫu Cấp cứu bệnh viện phản hồi. Mỗi ứng dụng riêng biệt quản lý từng khu vực chính của toàn bộ ứng dụng. Các ứng dụng chia sẻ một thành phần tổng đài chung thông qua thư viện thành phần mà mỗi ứng dụng hiển thị trên màn hình khởi động:
Khi người dùng chọn một khu vực, thành phần sẽ sử dụng siêu dữ liệu về các ứng dụng có sẵn và ứng dụng nào đang lưu trữ thành phần đó. Nếu màn hình mong muốn nằm trong ứng dụng này (tức là ThisItem.Screen không trống), thì lệnh Điều hướng sẽ được thực hiện. Nhưng nếu màn hình mong muốn nằm trong một ứng dụng khác (tức là ThisItem.PowerAppID không trống), thì hàm Launch sẽ được sử dụng với App ID của mục tiêu và ngữ cảnh FacilityID:
If(
IsBlank(ThisItem.Screen),
If(IsBlank(ThisItem.PowerAppID),
Launch(ThisItem.URL),
Launch("/providers/Microsoft.PowerApps/apps/" & ThisItem.PowerAppID,
"FacilityID", Home_Facility_DD.Selected.Id)
),
Navigate(
ThisItem.Screen,
Fade
)
);
Trạng thái trong ứng dụng gốc sẽ bị mất khi một ứng dụng khác được khởi chạy. Hãy chắc chắn lưu bất kỳ trạng thái nào trước khi bạn gọi hàm Khởi chạy . Ghi vào cơ sở dữ liệu, gọi SaveData hoặc truyền trạng thái cho ứng dụng mục tiêu với các tham số được đọc bằng hàm Param .
Ứng dụng dựa trên mô hình với các trang tùy chỉnh
Các phần cũng có thể được triển khai dưới dạng các trang tùy chỉnh. Các trang tùy chỉnh hoạt động như một ứng dụng canvas nhỏ với bộ chứa ứng dụng dựa trên mô hình để điều hướng.
Lưu ý
Bạn có thể cho chúng tôi biết bạn thích dùng ngôn ngữ nào cho tài liệu không? Làm một cuộc khảo sát ngắn. (xin lưu ý, khảo sát này bằng tiếng Anh)
Cuộc khảo sát sẽ mất khoảng bảy phút. Không có dữ liệu cá nhân nào được thu thập (điều khoản về quyền riêng tư).