แชร์ผ่าน


สร้างแอปแคนวาสที่มีขนาดใหญ่และซับซ้อน

บทความส่วนใหญ่ในส่วนของเอกสารนี้ครอบคลุมประสิทธิภาพการทํางานรันไทม์ของแอปตามประสบการณ์ของผู้ใช้งาน บทความนี้ครอบคลุมประสิทธิภาพการทํางานของแอปตามที่ผู้ที่สร้างแอปนั้นมีประสบการณ์

เมื่อแอปมีขนาดใหญ่ขึ้นและซับซ้อนมากขึ้น Power Apps Studio จําเป็นต้องโหลดและจัดการตัวควบคุม สูตร และแหล่งข้อมูลที่มีขนาดใหญ่ขึ้น ด้วยการอ้างอิงที่เพิ่มขึ้นแบบทวีคูณ Power Apps Studio สามารถใช้เวลานานในการโหลดและคุณลักษณะต่างๆ เช่น IntelliSense และการเข้ารหัสสีอาจล่าช้า ใช้คําแนะนําที่ตามมาเพื่อทํางานได้ดียิ่งขึ้นกับแอปขนาดใหญ่ และแอปที่ซับซ้อนใน Power Apps Studio นอกจากนี้ยังสามารถช่วยปรับปรุงประสิทธิภาพรันไทม์ของแอปของคุณได้

ตัวอย่างในบทความนี้ใช้โซลูชันตัวอย่างการตอบสนองฉุกเฉินของโรงพยาบาล

ใช้ App.Formulas แทน App.OnStart

เคล็ดลับ

คุณสามารถใช้ ฟังก์ชัน With และคุณสมบัติผลลัพธ์แบบกําหนดเองของคอมโพเนนต์พื้นที่ทํางานเป็นทางเลือกสําหรับสูตรที่มีชื่อ

วิธีที่ดีที่สุดในการลดเวลาการโหลดสําหรับทั้ง Power Apps Studio และแอปของคุณคือการแทนที่ตัวแปรและการเตรียมใช้งานคอลเลกชันใน App.OnStart ด้วยสูตรที่มีชื่อใน App.Formulas

มาดูตัวอย่างต่อไปนี้ ซึ่งใช้ 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
    );
);

เนื่องจากเป็นลําดับของคําสั่ง แอปของคุณต้องประเมินการเรียก Set และ Collect เหล่านี้ก่อนที่จะสามารถแสดงหน้าจอแรก ซึ่งทําให้แอปโหลดช้าลง และเนื่องจากทั้ง App.OnStart ต้องได้รับการพิจารณาทั้งหมด ลําดับที่เก็บรักษาและข้อผิดพลาดรวมก่อนที่จะส่งกลับผลลัพธ์สุดท้าย สูตรจะซับซ้อนสําหรับ Power Apps Studio ในการวิเคราะห์

มีวิธีที่ดีกว่า ใช้ App.Formulas แทนและกําหนดตัวแปรและคอลเลกชันเหล่านี้เป็นสูตรที่มีชื่อดังในตัวอย่างต่อไปนี้

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

การเปลี่ยนแปลงนี้อาจดูมีขนาดเล็ก แต่อาจมีผลกระทบอย่างมาก เนื่องจากแต่ละสูตรที่มีชื่อเป็นอิสระจากสูตรอื่น ๆ Power Apps Studio สามารถวิเคราะห์สูตรเหล่านั้นได้อย่างอิสระ มีประสิทธิภาพในการแยก App.OnStart ขนาดใหญ่ออกเป็นชิ้นเล็ก ๆ เราได้เห็นเวลาการโหลดของ Power Apps Studio ลดลงมากถึง 80% ด้วยการเปลี่ยนแปลงนี้เท่านั้น

แอปของคุณยังโหลดได้เร็วขึ้นเนื่องจากไม่จําเป็นต้องประเมินสูตรเหล่านี้จนกว่าจะต้องการผลลัพธ์ หน้าจอแรกของแอปจะแสดงทันที

สูตรที่มีชื่อไม่สามารถใช้ได้ในทุกสถานการณ์เนื่องจากคุณไม่สามารถปรับเปลี่ยนสูตรดังกล่าวหรือใช้กับ Set ได้ ในบางสถานการณ์จําเป็นต้องใช้ตัวแปรสถานะที่สามารถปรับเปลี่ยนได้ ตั้งค่า เหมาะสมสําหรับสถานการณ์เหล่านี้ และคุณควรใช้งานต่อไป แต่บ่อยครั้งที่คุณไม่ได้ใช้ตัวแปรส่วนกลางใน OnStart เพื่อตั้งค่าคงที่ที่ไม่เปลี่ยนแปลง ในกรณีเหล่านั้น สูตรที่มีชื่อเป็นตัวเลือกที่ดีกว่า

เนื่องจากสูตรที่มีชื่อไม่สามารถเปลี่ยนแปลงได้ คํานําหน้า var (สั้นสําหรับ "ตัวแปร") ตามแบบแผนการตั้งชื่อจึงไม่เหมาะสมอีกต่อไป เราไม่ได้เปลี่ยนชื่อในตัวอย่างนี้ เนื่องจากต้องเปลี่ยนแปลงส่วนที่เหลือของแอปให้ตรงกัน

น่าสนใจที่จะใส่สูตรที่มีชื่อใน App.OnStart แต่ไม่ควรทำ. พวกเขาไม่ได้อยู่ในนั้น ในฐานะที่เป็นคุณสมบัติ On behavior App.OnStart จะประเมินแต่ละคําสั่งตามลําดับ สร้างตัวแปรส่วนกลาง และพูดคุยกับฐานข้อมูลเพียงครั้งเดียว เมื่อโหลดแอป สูตรที่มีชื่อเป็นสูตรที่กําหนดวิธีการคํานวณบางอย่าง เมื่อใดก็ตามที่ต้องการ และเป็นจริงเสมอ นี่คือธรรมชาติของสูตรนี้ที่ช่วยให้พวกเขาสามารถแยกออกเป็นอิสระได้และอนุญาตให้แอปเสร็จสิ้นการโหลดก่อนที่จะได้รับการประเมิน

แยกสูตรที่ยาวออก

App.OnStart เป็นหนึ่งในผู้กระทําผิดที่แย่ที่สุดสําหรับสูตรยาว และแน่นอนที่คุณควรเริ่มต้น แต่ไม่ใช่เพียงกรณีเดียว

การศึกษาของเราได้แสดงให้เห็นว่าแอปเกือบทั้งหมดที่มีเวลาการโหลดนานสําหรับ Power Apps Studio มีสูตรอย่างน้อยหนึ่งสูตรมากกว่า 256,000 ตัวอักขระ แอปบางตัวที่มีเวลาการโหลดนานที่สุดมีสูตรมากกว่า 1 ล้านตัวอักษร สูตรที่ใช้เวลานานทําให้ Power Apps Studio ล้ามาก

ยิ่งไปกว่านั้น การคัดลอกและวางตัวควบคุมที่มีสูตรยาว จะทำให้สูตรนั้นถูกคัดลอกไปยังคุณสมบัติของตัวควบคุมโดยไม่ทันได้สังเกต Power Apps ถูกสร้างขึ้นตามแบบของ Excel ที่ซึ่งการมีสำเนาของสูตรหลายชุดเป็นเรื่องปกติ อย่างไรก็ตาม ในสูตร Excel จะถูกจํากัดให้เป็นหนึ่งนิพจน์และสูงสุดที่ 8,000 อักขระ สูตร Power Apps สามารถขยายได้นานขึ้นโดยใช้ตรรกะเชิงกําหนดและตัวดําเนินการเกี่ยวโยง (; หรือ ;;ขึ้นอยู่กับตําแหน่งที่ตั้ง)

โซลูชันทั่วไปคือการแยกสูตรที่ยาวออกเป็นส่วนที่เล็กลง และนําส่วนกลับมาใช้ใหม่ดังที่เราทําในส่วนก่อนหน้าเมื่อเราเปลี่ยนคําสั่ง Set/Collect ใน App.OnStart เป็นสูตรที่มีชื่อใน App.Formulas ในภาษาการเขียนโปรแกรมอื่น ส่วนที่สามารถนํามาใช้ใหม่ได้มักจะเรียกว่าฟังก์ชันย่อยหรือฟังก์ชันที่ผู้ใช้กําหนดเอง คุณสามารถนึกภาพสูตรที่มีชื่อเป็นรูปแบบง่ายๆ ของฟังก์ชันที่ผู้ใช้กําหนดเอง โดยไม่มีพารามิเตอร์หรือผลข้างเคียง

ใช้สูตรที่มีชื่อทุกที่

ในตัวอย่างก่อนหน้านี้ เราใช้สูตรที่มีชื่อเป็นตัวแทนสําหรับ App.OnStart อย่างไรก็ตาม คุณสามารถใช้เพื่อแทนที่การคํานวณที่ใดก็ได้ในแอป

ตัวอย่างเช่น หนึ่งในหน้าจอในโซลูชันตัวอย่างการตอบสนองฉุกเฉินของโรงพยาบาลมีตรรกะนี้ใน 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
    }
); 

สูตรนี้สามารถแยกออกเป็นชุดของสูตรที่มีชื่อได้ นอกจากนี้ยังทําให้สูตรอ่านง่ายขึ้นอีกด้วย

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
    };

เราได้แยก ParamFacility เป็นสูตรที่มีชื่อก่อนหน้าเมื่อเราย้ายการเรียก Set ส่วนใหญ่จาก App.OnStart ไปยังสูตรที่มีชื่อใน App.Formulas

สูตรที่มีชื่อจะถูกประเมินเมื่อจําเป็นต้องมีค่าเท่านั้น ถ้าเป้าหมายเดิมของการใช้ Screen.OnVisible คือการทํางานเลื่อนออกไปจนกว่าหน้าจอจะแสดงขึ้นมา งานจะยังคงเลื่อนออกไปเป็นสูตรที่ชื่อส่วนกลางใน App.Formulas

ใช้ฟังก์ชัน With

คุณยังสามารถใช้ฟังก์ชัน With ในสูตรเพื่อแยกตรรกะได้ สร้างระเบียนในพารามิเตอร์แรกที่มีค่าที่คุณต้องการใช้เป็นเขตข้อมูล จากนั้นใช้เขตข้อมูลเหล่านั้นในพารามิเตอร์ที่สองเพื่อคํานวณค่าที่ส่งกลับจาก ด้วย ตัวอย่างเช่น สามารถเขียนตัวอย่างก่อนหน้านี้เป็นสูตรที่มีชื่อเพียงสูตรเดียว:

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
           }
    )

ข้อเสียอย่างหนึ่งของการใช้ ด้วย วิธีนี้คือ MyFacility ไม่สามารถใช้ MyRegion ได้เนื่องจากถูกกําหนดไว้ในฟังก์ชัน With เดียวกัน ซึ่งเป็นปัญหาที่ไม่มีอยู่ในสูตรที่มีชื่อ โซลูชันหนึ่งคือการซ้อน ฟังก์ชัน ด้วย และใช้คําสําคัญ เป็น เพื่อตั้งชื่อระเบียนสําหรับแต่ละรายการเพื่อให้เข้าถึงตัวแปร กับ ทั้งหมดได้อย่างง่ายดาย

ใช้คอมโพเนนต์แคนวาส

คอมโพเนนต์พื้นที่ทํางานมักใช้ในการสร้างตัวควบคุม UI ที่สามารถวางบนพื้นที่ทํางานได้เช่นเดียวกับตัวควบคุม คุณยังสามารถใช้ได้โดยไม่ต้องวางไว้ใน UI เพื่อทําการคํานวณด้วยคุณสมบัติเอาต์พุตแบบกําหนดเอง เป็นทางเลือกแทนสูตรที่มีชื่อ คอมโพเนนต์แคนวาสจะง่ายต่อการแชร์ในแอปต่าง ๆ ด้วยไลบรารีคอมโพเนนต์ และได้รับการสนับสนุนอย่างเต็มที่ แตกต่างจากสูตรที่มีชื่อ อย่างไรก็ตาม จะยากกว่าในการกําหนดค่าและใช้งานสูตรที่มีชื่อ

เพื่อแยกตรรกะ:

  1. ใน Power Apps Studio สลับไปยังแท็บ คอมโพเนนต์ในมุมมอง ทรี
  2. สร้างคอมโพเนนต์ใหม่
  3. ในบานหน้าต่างคุณสมบัติ ให้เปิดใช้งานขอบเขตแอป Access
  4. เพิ่มคุณสมบัติแบบกําหนดเอง
  5. ตั้งค่า ชนิดคุณสมบัติ เป็น เอาต์พุต และ ชนิดข้อมูล ตามความเหมาะสม
  6. เลือก สร้าง
  7. ในตัวเลือกคุณสมบัติที่อยู่ถัดจากแถบสูตรที่ด้านบนของหน้าจอ ให้เลือกคุณสมบัติใหม่
  8. เขียนสูตรสําหรับตรรกะเพื่อแยกและนํามาใช้ใหม่

ในการใช้ตรรกะ:

  1. สลับไปยังแท็บ หน้าจอในมุมมอง ทรี
  2. ในบานหน้าต่าง แทรก ให้ขยาย แบบกําหนดเอง และแทรกคอมโพเนนต์ของคุณ
  3. เมื่อต้องการคํานวณค่าที่มีคุณสมบัติ ให้ใช้ ComponentName.PropertyName

ใช้ Select กับตัวควบคุมที่ซ่อนอยู่สําหรับตรรกะเชิงคําสั่ง

ตรรกะเชิงวัตถุถูกใช้เพื่อปรับเปลี่ยนสถานะด้วย Set และ Collect แจ้งผู้ใช้ด้วย Notify นําทางไปยังหน้าจอหรือแอปอื่นด้วย Navigate และ Launch และเขียนค่าลงในฐานข้อมูลด้วย Patch, SubmitForm หรือ RemoveIf

สูตรที่มีชื่อและคุณสมบัติผลลัพธ์แบบกําหนดเองของคอมโพเนนต์พื้นที่ทํางานไม่สนับสนุนตรรกะเชิงกําหนด วิธีทั่วไปในการแยกตรรกะเชิงคําสั่งคือการใช้คุณสมบัติ OnSelect ของตัวควบคุมที่ซ่อนอยู่

  1. เพิ่มตัวควบคุม ปุ่ม ไปยังหน้าจอ
  2. ตั้งค่าคุณสมบัติ OnSelect เป็นตรรกะเชิงคําสั่งที่คุณต้องการดําเนินการ
  3. ตั้งค่าคุณสมบัติ ที่มองเห็นได้ เป็น เท็จ เนื่องจากผู้ใช้ไม่จําเป็นต้องดูหรือโต้ตอบกับคุณสมบัติดังกล่าว
  4. เรียกใช้ Select( Button ) เมื่อคุณต้องการดําเนินการตรรกะเชิงคําสั่ง

ตัวอย่างเช่น หนึ่งในหน้าจอในตัวอย่างของเรามีคุณสมบัติ OnSelect ต่อไปนี้บนตัวควบคุม ปุ่ม (ตัวอย่างอย่างง่ายนี้มีไว้เพื่อวัตถุประสงค์ในการแสดงภาพประกอบเท่านั้น โดยปกติแล้ว คุณจะใช้เทคนิคนี้สําหรับสูตรที่ยาวขึ้นเท่านั้น)

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

ในการแยกตรรกะนี้ออกเป็นส่วน ๆ เราสามารถใส่ส่วนต่างๆ ลงบนตัวควบคุม ปุ่มแยกต่างหาก และเลือกจาก ต้นฉบับ:

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

เทคนิคนี้ทํางานบนหน้าจอเดียวกันเท่านั้น เทคนิคอื่น ๆ ที่มีความซับซ้อนมากขึ้นระหว่างหน้าจอ เช่น ใช้ตัวควบคุม สลับ ตั้งค่า OnCheck เป็นตรรกะที่คุณต้องการเรียกใช้ และตั้งค่า Default เป็นตัวแปรส่วนกลาง แล้วสลับตัวแปรส่วนกลางใน Set( global, true ); Set( global, false ) จุดที่คุณต้องการเรียกใช้ตรรกะ

ในตัวอย่างนี้ มีการแยกตรรกะบางอย่างเรียบร้อยแล้ว ข้อคิดเห็นจะระบุว่า "สามารถพบการดําเนินการที่ตามมาได้ใน OnSuccess" เหตุการณ์นี้เรียกใช้ตรรกะเชิงอ้อมหลังจากส่งระเบียนเรียบร้อยแล้ว โซลูชันเฉพาะสําหรับฟังก์ชัน SubmitForm

แบ่งพาร์ติชันของแอป

แอปบางตัวมีตัวควบคุมเพิ่มขึ้นเป็นหลายพันและแหล่งข้อมูลหลายร้อยแหล่ง ซึ่งทําให้ Power Apps Studio ช้าลง เช่นเดียวกับสูตรที่ยาว แอปขนาดใหญ่สามารถแยกออกเป็นส่วนเล็ก ๆ ที่ทํางานร่วมกันเพื่อสร้างประสบการณ์ผู้ใช้หนึ่งราย

แยกแอป Canvas

วิธีหนึ่งคือการใช้ส่วนในแอปพื้นที่ทํางานแยกต่างหาก และใช้ฟังก์ชัน เปิดใช้ เพื่อนําทางระหว่างแอปที่แยกต่างหากและบริบทที่จําเป็น

วิธีการนี้ถูกใช้ในโซลูชันตัวอย่างการตอบสนองฉุกเฉินของโรงพยาบาล แยกแอปจัดการแต่ละพื้นที่หลักของแอปโดยรวม แอปแชร์คอมโพเนนต์สวิตช์บอร์ดทั่วไปผ่านไลบรารีคอมโพเนนต์ที่แต่ละแอปแสดงบนหน้าจอเริ่มต้น:

ภาพหน้าจอของแอปพื้นที่ทํางานตัวอย่างการตอบสนองเหตุฉุกเฉินของโรงพยาบาลที่ทํางานบนโทรศัพท์ ที่แสดงคอมโพเนนต์พื้นที่ทํางานของสวิตช์บอร์ด

เมื่อผู้ใช้เลือกพื้นที่ คอมโพเนนต์จะใช้เมตาดาต้าเกี่ยวกับแอปที่พร้อมใช้งานและแอปที่กําลังโฮสต์คอมโพเนนต์ ถ้าหน้าจอที่ต้องการอยู่ในแอปนี้ (นั่นคือ ThisItem.Screen ไม่ว่างเปล่า) จะมีการเรียกใช้นําทาง แต่ถ้าหน้าจอที่ต้องการอยู่ในแอปอื่น (นั่นคือ ThisItem.PowerAppID ไม่ว่างเปล่า) จะมีการใช้ฟังก์ชัน Launch กับ ID แอปของเป้าหมายและบริบท 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
    )
);

สถานะในแอปต้นฉบับจะหายไปเมื่อมีการเปิดใช้งานแอปอื่น ตรวจสอบให้แน่ใจว่าได้บันทึกสถานะใด ๆ ก่อนที่คุณจะเรียกใช้ฟังก์ชัน เปิดใช้ เขียนไปยังฐานข้อมูล เรียกใช้ SaveData หรือส่งผ่านสถานะไปยังแอปเป้าหมายด้วยพารามิเตอร์ที่อ่านด้วยฟังก์ชัน Param

แอปแบบจําลองข้อมูลที่มีหน้าแบบกําหนดเอง

ส่วนยังสามารถนํามาใช้เป็น หน้าแบบกําหนดเองได้ หน้าแบบกําหนดเองทําหน้าที่เป็นแอปพื้นที่ทํางานขนาดเล็กที่มีคอนเทนเนอร์แอปแบบจําลองข้อมูลสําหรับการนําทาง