
ב-26 בספטמבר התחלנו לבנות ב-Flutter את Cliqer Remote, אפליקציית הטלפון שלנו למציגים. חמישה ימים אחר כך היא כבר הייתה ב-TestFlight ובמסלול הפנימי של Google Play, עם כל התכונות של גרסת הדפדפן למציגים: השלט למצגות, המסך החי, הדיו, הצ'אט, ההערות והשיחות. היא עבדה. ואז מדדנו אותה בטלפונים אמיתיים, ראינו אחד מהם מגיע לטמפרטורת מעטפת של 42 °C רק מהצגת מסך משותף, וזרקנו אותה.
אף אחד מחוץ לצוות שלנו לא ראה את האפליקציה הזו. מה שמקבלים במקומה הוא אפליקציה נייטיב בכל פלטפורמה: SwiftUI ב-iPhone, ב-iPad וב-Apple Watch, Kotlin ו-Jetpack Compose ב-Android וב-Wear OS, ומתחת לכולן מנוע אחד, שנכתב פעם אחת ב-Rust. זה הסיפור של הסיבה, עם המספרים שמדדנו בדרך.
- לשלט למצגות יש תפקיד מוזר לאפליקציית טלפון: לשבת ביד חמה במשך שעה, להציג וידאו חי של המסך, ולעולם לא לפספס הקשה. זמן פריים, חום וגודל חשובים כאן יותר מאשר ברוב האפליקציות.
- גרסת ה-Flutter שלנו נכתבה מהר ונראתה טוב, אבל אפקטי הזכוכית ונתיב הווידאו שלה גבו מחיר מה-GPU בכל פריים. ב-Galaxy S24+ הורדנו מסך אחד מ-19.8 ms ל-5.7 ms של עבודת GPU לפריים, ועדיין נלחמנו במנוע במקום לבנות את המוצר.
- אחר כך הצבנו שלוש גרסאות באותו טלפון, באותו חדר, מול אותו מסך משתנה, עשר דקות כל אחת. גרסת ה-Flutter הראשונה ציירה 47.6 פריימים בשנייה, חיממה את הטלפון ב-5.9 °C וצרכה 168 mAh. האפליקציה הנייטיב לא ציירה אף פריים של ממשק, חיממה אותו ב-0.2 °C וצרכה 86 mAh: חצי מהסוללה.
- האפליקציות הנייטיב קטנות יותר: 10.8 MB לאפליקציית ה-iPhone כולל אפליקציית ה-Apple Watch שבתוכה (גרסת ה-Flutter שקלה 27.6 MB), והורדה של 5.8 MB ב-Android (Flutter: 15.6 MB), שנמדדו באותה שיטה.
- באותו מאמץ גרמנו לאפליקציית המחשב להפוך לחיצה לשקופית מהר פי עשרה: 48 ms ב-PowerPoint ו-42 ms ב-Keynote ב-Mac, במקום כחצי שנייה קודם.

שלט למצגות הוא אפליקציה מוזרה לבנות
רוב האפליקציות משמשות לפרקי זמן קצרים. שלט למצגות לא. הוא יושב ביד אחת לאורך הרצאה שלמה, לרוב תחת אורות במה, המסך דולק והרדיו עמוס כל הזמן. ב-Cliqer הוא גם מציג תמונה חיה של מסך המציג, מצייר דיו על השקופיות, מעביר צ'אט והערות, ויכול להעלות את המציג למצלמה כשהמארח מזמין אותו.
הגדרת התפקיד הזו קובעת שלושה כללים:
- כל הקשה חייבת להגיע, עכשיו. לחיצה שמגיעה באיחור היא דובר שעומד בשתיקה מול קהל.
- הטלפון חייב להישאר קריר. טלפון חם מאט את עצמו, וטלפון מואט מאבד פריימים, מפענח וידאו באיחור ומרוקן את הסוללה מהר יותר. וגם לא נעים להחזיק אותו שעה.
- האפליקציה חייבת להיות קטנה ולהיפתח מהר. אנשים מתקינים אותה באולם, לרוב ברשת ה-Wi-Fi של הכנס, דקות לפני שהם עולים לבמה.
Flutter מסוגל לעמוד בשלושתם ברוב האפליקציות. שלנו התבררה כסוג האפליקציה שבו הוא עולה יותר ממה שהוא נותן.
מה ש-Flutter עשה נכון
כבוד למי שמגיע לו. Flutter לקח אותנו מתיקייה ריקה לאפליקציה מלאה בשתי החנויות בחמישה ימים, עם בסיס קוד אחד, hot reload, תמיכה מצוינת בבדיקות וממשק שנראה זהה בכל מקום. כתבנו לה 266 בדיקות. אם אתם בונים אפליקציה של טפסים ורשימות, דשבורד או חנות, עדיין נמליץ עליו בלי לחשוב פעמיים.
למדנו ממנו גם הרבה. כמעט כל ממצא בפוסט הזה הגיע ממעקב אחרי גרסת ה-Flutter הזו בטלפון אמיתי, וחלק מהתיקונים חיים היום בכל לקוח של Cliqer, כולל גרסת הדפדפן.
איפה זה כאב: זכוכית עולה מסך שלם לכל פריים
המראה של Cliqer הוא זכוכית חלבית: לוחות שקופים למחצה שמטשטשים את מה שמאחוריהם. ב-iPhone וב-iPad זה היה זול. בטלפון הבדיקה שלנו ב-Android, Galaxy S24+ עם מסך 120 Hz, זה לא היה. ב-120 Hz יש לפריים 8.3 ms כדי להצטייר, מתחילתו ועד סופו.
עקבנו אחרי ה-GPU במכשיר ומצאנו את הסיבה באופן שבו מנוע הרינדור קורא את הרקע: כל לוח זכוכית העתיק את המסך כולו, בכל פריים, ועוד עם multisampling. במסך ההצטרפות היו תשעה לוחות זכוכית, כלומר תשע העתקות של מסך מלא לכל פריים. ה-GPU בטלפון הזה הוא תכנון ברמת מחשב שולחני שאינו tiler: אין לו דרך זולה לקרוא בחזרה את מה שהוא צייר זה עתה, וכל גודל טקסטורה חדש פירושו הקצאת זיכרון חדשה שהקרנל מאפס קודם. במעקב אחד, 71% מזמן ה-raster thread הוקדשו להקצאת זיכרון גרפי.

תיקנו את זה, מסך אחר מסך. עברנו לגרסה מוקדמת של המנוע כדי שטשטוש יוגבל ללוח שלו (מ-41 ms ל-17 ms). קיבצנו את תשעת הלוחות במסך ההצטרפות לקריאה משותפת אחת (מ-19.8 ms ל-5.7 ms). הפסקנו להנפיש את הגודל של כל משטח זכוכית, כי כל גודל חדש היה הקצאה חדשה, וזייפנו את האנימציות עם שכבות בגודל קבוע במקום. הפריים הגרוע ביותר של סורק ה-QR ירד מ-285 ms ל-18 ms.
כל אחד מהתיקונים האלה היה עקיפה של המנוע, לא תכונה בשביל מציג. וכשזכוכית מהווה 80 עד 90% מזמן ה-GPU בחדר, תמיד היינו במרחק לוח חדש אחד מאובדן פריימים מחדש.
איפה זה ממש כאב: וידאו, והחום שהוא מייצר
המסך המשותף הוא הדבר הכבד ביותר שהאפליקציה מציגה. בגרסת ה-Flutter, כל פריים וידאו מפוענח הועבר לממשק כטקסטורה, כלומר הממשק צייר את עצמו מחדש עבור כל פריים וידאו: החדר, הזכוכית, הפקדים, הכול, 45 פעמים בשנייה, רק כדי להזיז את הפיקסלים בתוך מלבן אחד.
מדדנו את זה לראשונה ב-Galaxy עם מעקבי מערכת ב-1 באוקטובר. בזמן שהווידאו התנגן, ה-GPU עמד על כ-440 MHz. כשהשקופית התחלפה, פריימים לקחו 25 עד 33 ms וה-GPU הגיע לתקרת ה-800 MHz שלו ליותר ממחצית המעבר. הטלפון היה במצב התרמי "בינוני" של המערכת עם טמפרטורת מעטפת של 42 °C, והגביל את ה-GPU של עצמו כדי להתמודד. החום גם גרם למדידות שלנו לשקר: טלפון חם נמדד איטי בכ-20% מטלפון קריר, ולכן כל השוואה חייבה החלפה בין גרסאות באותה טמפרטורה.
אז ניסינו את הניסוי המתבקש: להעביר את הווידאו לשכבה נייטיב שמערכת ההפעלה מרכיבה בעצמה, מחוץ לממשק. אותו טלפון, אותה אפליקציה, אותו חדר: הממשק הפסיק להצטייר מחדש בגלל הווידאו, תדר ה-GPU ירד מ-440 ל-121 MHz, והפריים בזמן החלפת שקופית ירד מ-25 עד 33 ms ל-3 עד 7 ms. שחררנו את התיקון הזה בתוך אפליקציית ה-Flutter ב-1 באוקטובר. הוא גם הראה לנו איפה נמצאת התשובה האמיתית: באפליקציה נייטיב, הווידאו תמיד יושב על שכבת מערכת, ב-iPhone וב-Android, כך שכל סוג הבעיות הזה נעלם מעצם התכנון ולא בזכות עקיפה.
אותו טלפון, אותו חדר, עשר דקות
טענות על חום הן זולות, אז מדדנו. ב-5 באוקטובר הצבנו שלוש גרסאות באותו Galaxy S24+, אחת אחרי השנייה, כל אחת לעשר דקות, מנותק מהחשמל, באותו חדר, מול אותו מסך משותף משתנה. לפני כל הרצה הטלפון התקרר בחזרה.
- Flutter, גרסה ראשונה: האפליקציה כפי שבנינו אותה בהתחלה, הווידאו מצויר על ידי הממשק.
- Flutter, מכוונן: אותה אפליקציה אחרי תיקוני הזכוכית והווידאו שלמעלה.
- נייטיב: Cliqer Remote החדשה.

גרסת ה-Flutter הראשונה ציירה מחדש את כל הממשק שלה 47.6 פעמים בשנייה רק כדי להציג וידאו, החזיקה את ה-GPU בממוצע של 366 MHz וצרכה 1.47 שניות של זמן CPU בכל שנייה. האפליקציה הנייטיב לא ציירה אף פריים ממשק אחד בעשר דקות: רק שכבת הווידאו זזה. ה-GPU שלה עמד בממוצע על 129 MHz, ה-CPU על 0.69 שניות לשנייה, והיא צרכה 86 mAh מהסוללה לעומת 168 mAh. זה חצי מהסוללה לאותה עבודה.

ועכשיו החום. בעשר דקות גרסת ה-Flutter הראשונה לקחה את הסוללה מ-36.2 °C ל-42.1 °C, והטלפון התחיל להאט את עצמו. גרסת ה-Flutter המכווננת עלתה ב-1.9 °C. האפליקציה הנייטיב עלתה ב-0.2 °C. הרצאה נמשכת יותר מעשר דקות, וזה ההבדל שמרגישים ביד.
כדי להיות הוגנים כלפי גרסת ה-Flutter המכווננת: היא התקרבה. התיקונים שלנו בתוך Flutter הורידו את רוב העלות, והנייטיב ניצחה אותה בפער קטן יותר, 12% פחות CPU ו-25% פחות סוללה. העיקר הוא נקודת ההתחלה של כל אחת. הגרסה הראשונה היא איך שאפליקציית Flutter טובה נראית מהקופסה; נייטיב משיגה את התוצאה הקרירה בלי העקיפות.
איך מדדנו, כדי שתוכלו לחזור על זה: מעקבי Perfetto במכשיר (ציר זמן של פריימים, תדר GPU, מוני סוללה), זמן CPU של התהליך מהקרנל, וטמפרטורת הסוללה של הטלפון עצמו, עם אותה אנימציה של 60 fps על המסך המשותף בכל הרצה. טלפון אחד והרצה אחת לכל גרסה, אז התייחסו למספרים כאל בדיקת שטח זהירה, לא כאל בנצ'מרק מעבדה. ההרצה הנייטיב גם התחילה קרירה בכ-2 °C, ולכן אנחנו משווים את העלייה.
מה בנינו במקום
Cliqer Remote החדשה היא נייטיב בכל פלטפורמה, ובנויה על מנוע משותף אחד.
הממשק נייטיב בכל פלטפורמה. ב-iPhone וב-iPad זה SwiftUI עם Liquid Glass של המערכת עצמה. ב-Android זה Jetpack Compose, עם טשטוש רקע אמיתי היכן שהפלטפורמה מאפשרת. גם אפליקציות ה-Apple Watch וה-Wear OS הן נייטיב, קטנות מספיק כדי לשים את כפתורי הבא והקודם על פרק כף היד.
המנוע נכתב פעם אחת, ב-Rust. הצטרפות לחדר, התחברות מחדש והמשך אחרי שינוי רשת, קבלת וידאו המסך, שליחת לחיצות, לייזר ודיו, צ'אט, הערות, הטיימר, שיחות וצימוד טלפון למחשב, כולם חיים בספריית Rust אחת ששתי האפליקציות חולקות. כל אפליקציה רק מציירת את הממשק, מפענחת וידאו עם מפענח החומרה של המערכת ומדברת עם המצלמה והמיקרופון. תיקון בפרוטוקול נכנס פעם אחת ומגיע לשתי הפלטפורמות, ושתי האפליקציות לא יכולות להתרחק זו מזו.
Rust הייתה הבחירה הטבעית למנוע הזה: אין garbage collector שעוצר פריים, בטיחות זיכרון בלי runtime, והיא מתקמפלת לספרייה קטנה אחת גם ל-iOS וגם ל-Android. היא מהירה איפה שזה חשוב. ב-Mac, המנוע שלנו מחלק לפקטות פריים H.264 של 20 KB ב-31 µs, משלים לחיצת יד מאובטחת ב-198 µs לכל צד, ובבדיקות שלנו מעביר פריים וידאו של 100 KB לממשק ה-Android ב-46 µs (זה לקח 440 µs לפני שייעלנו את הגבול הזה). דרך ממסר, זמן הלוך ושוב נמדד בחציון של 13 עד 16 ms בבדיקות שלנו.
וגם קטנה יותר

מדדנו את שתי הגרסאות באותה שיטה. אפליקציית ה-iPhone כפי שהועלתה ל-Apple ירדה מ-27.6 MB ל-10.8 MB, וזה כולל את אפליקציית ה-Apple Watch (1.5 MB) שבתוכה. ההורדה לטלפון Android, שנמדדה עם כלי ה-bundle של Google עצמה עבור אותו טלפון 64 ביט, ירדה מ-15.6 MB ל-5.8 MB. בערך שליש מהגודל הקודם משנה הרבה כשמישהו מתקין את האפליקציה ב-Wi-Fi של האולם כשנותרו חמש דקות.
המרדף אחרי מילישניות לא נעצר בטלפון
אפליקציית טלפון מהירה יותר היא רק חצי מלחיצה. החצי השני הוא המחשב שמריץ את המצגת, ובזמן שהאפליקציות נבנו מחדש טיפלנו גם בצד הזה.
לחיצות: מחצי שנייה לעשירית
כשלחיצה מגיעה לאפליקציית המחשב של Cliqer, היא צריכה להזיז את המצגת ואז לעדכן את כל מי שבחדר איזו שקופית מוצגת. החלק השני הזה נהג לשאול את אפליקציית המצגות מה מספר השקופית אחרי כל לחיצה, והשאלה הזו הייתה איטית.

Cliqer 2.3 שומרת חיבור אחד פתוח ל-PowerPoint או ל-Keynote וקוראת את המיקום ישירות מהצעד שזה עתה בוצע. ב-Mac, על פני 20 הרצות, חציון הזמן מלחיצה לשקופית ירד מ-509 ms ל-48 ms ב-PowerPoint ומ-408 ms ל-42 ms ב-Keynote. עשר לחיצות מהירות, מהסוג שמציג עושה כדי לדלג על קטע, נהגו לקחת 5.3 שניות עד שהתייצבו. עכשיו הן מתמזגות לתנועה אחת ונוחתות תוך 254 ms.
וידאו שעומד בקצב גם ב-Wi-Fi גרוע
מוקדם יותר השנה גילינו למה מסך משותף יכול לקפוא לשניות ב-Wi-Fi. וידאו המסך ב-Cliqer עובר בערוץ נתונים אמין, והתקן שעליו הערוץ הזה בנוי ממתין לפחות שנייה שלמה לפני שליחה חוזרת של פקטה שאבדה, ומכפיל את ההמתנה בכל חזרה. Chrome משתמש ב-400 ms. כל פריים שאחרי הפריים שאבד חיכה בתור, המארח אז דחף רענון מלא לאותו תור בדיוק, ובקישור איטי הוא עשה את זה שוב ושוב.

כיווננו את טיימרי השליחה החוזרת לערכים של Chrome ומנענו מרענונים להיתקע בתור מאחורי העומס. בסימולציית רשת עם מודל אובדן של Wi-Fi, שיתוף ב-1080p ירד מ-15 עד 22 הקפאות של שנייה ומעלה בכל שתי דקות ל-0 עד 2, וחציון הפיגור מהשידור החי ירד מרמה של עד 2.3 שניות ל-12 ms. הגבלנו גם את הרענונים המלאים לאחד לכל זרם בכל חצי שנייה, כי כל אחד מהם נשלח לכל צופה: לפני ההגבלה הזו, צופה יכול היה לקבל 19 רענונים מלאים בשנייה, כ-40 Mbit/s.
בצד הטלפון, מפענח הווידאו בחומרה של ה-Galaxy עיכב פריים רגיל אחד לכ-60 ms, בערך פעם בשנייה. הוראה למפענח לרוץ במהירות מלאה הורידה את זה ל-אפס פריימים מאוחרים ב-50 שניות. התיקון הזה כלול באפליקציית ה-Android הנייטיב.
מה היינו אומרים לצוות אחר
אם אתם בונים משהו בזמן אמת לטלפונים, את הדברים האלה לקח לנו ימים ללמוד, ויישומם לוקח דקות:
- מדדו על המכשיר האמיתי הגרוע ביותר שלכם, לא על האמולטור. האמולטור שלנו רץ ב-60 Hz על backend גרפי אחר ולא הצליח להראות אף אחת מבעיות הזכוכית.
- החליפו בין גרסאות באותה טמפרטורה. טלפון חם נמדד איטי בכ-20%. השוואה בין הרצה קרה להרצה חמה תשקר לכם.
- ספרו את קריאות הטשטוש שלכם. כל טשטוש רקע יכול לעלות העתקה של מסך מלא לכל פריים. קבצו אותם, הגבילו אותם, ולעולם אל תנפישו את הגודל של משטח מטושטש.
- לעולם אל תציירו מחדש את הממשק בשביל וידאו. שימו את הווידאו בשכבה שהמערכת מרכיבה. זה היה השיפור הגדול ביותר שמדדנו ב-GPU, בסוללה ובחום.
- בקשו ממפענח החומרה מהירות של זמן אמת. ב-Android, הגדירו את ה-operating rate של המפענח. שורה אחת העלימה תקיעה של 60 ms בכל שנייה.
- בדקו את הטיימרים של שכבת התעבורה. ערוצי נתונים אמינים יורשים טיימרים של שליחה חוזרת מתקנים ישנים יותר. מינימום של שנייה הוא נצח עבור וידאו חי.
- התייחסו לרענונים מלאים כאל הפריימים היקרים שהם. הגבילו אותם לכל זרם, כי כל אחד מהם נשלח לכל צופה.
- מזגו פרצי קלט. עשר לחיצות צריכות להיות תנועה אחת של עשר, לא עשרה סבבי הלוך ושוב.
- קראו מה הכלים שלכם כותבים לתוך ה-build. שרשרת כלים (toolchain) בגרסה מוקדמת הפעילה דגל רינדור ב-manifest של Android שלנו בלי לשאול.
מה זה אומר בשבילכם
10x
לחיצה לשקופית מהירה יותר ב-PowerPoint וב-Keynote ב-Mac
5.8 MB
הורדה ל-Android, בערך שליש מהגודל הקודם
10.8 MB
אפליקציית iPhone כולל אפליקציית ה-Apple Watch שבתוכה
Half
מהסוללה של גרסת ה-Flutter הראשונה שלנו, אותו טלפון, אותן 10 דקות
Cliqer Remote היא נייטיב ב-iPhone, ב-iPad, ב-Android, ב-Apple Watch וב-Wear OS. הלחיצות מהירות יותר, הטלפון נשאר קריר וצורך חצי מהסוללה שצרכה הגרסה הראשונה שלנו, הווידאו מצויר כפי שהטלפון תוכנן לצייר אותו, והאפליקציה בערך שליש מגודלה הקודם. גרסת הדפדפן למציגים עדיין עובדת בכל דפדפן בלי שום התקנה, כך שאף אחד בחדר שלכם לא נשאר בחוץ.
שאלות נפוצות
Cliqer Remote מציגה וידאו חי, זכוכית חלבית ושלט למצגות בטלפון שיושב ביד של מציג במשך שעה. בגרסת ה-Flutter הממשק צויר מחדש עבור כל פריים וידאו וכל לוח זכוכית העתיק את המסך כולו בכל פריים, מה שעלה בזמן GPU ובחום ב-Android. אפליקציות נייטיב מציירות וידאו על שכבת מערכת מעצם התכנון, והן יצאו בערך בשליש מגודל ההורדה.
בבדיקה שלנו ב-Galaxy S24+, עשר דקות של וידאו מסך חי חיממו את הטלפון ב-0.2 °C עם האפליקציה הנייטיב, לעומת 5.9 °C עם גרסת ה-Flutter הראשונה שלנו. האפליקציה הנייטיב לא ציירה אף פריים ממשק בזמן שהווידאו התנגן, וצרכה 86 mAh מהסוללה לעומת 168 mAh.
לא. Flutter הביא אותנו לאפליקציה מלאה בשתי החנויות בחמישה ימים, ואחרי הכוונון שלנו האפליקציה הנייטיב צרכה רק 25% פחות סוללה ממנו. לרוב האפליקציות הוא בחירה מצוינת. האפליקציה שלנו משלבת וידאו חי רציף, משטחי זכוכית מטושטשים רבים וסשנים ארוכים בטלפון חם, וזה בדיוק המקרה שבו מודל הרינדור שלו עלה לנו הכי הרבה.
היא מריצה את כל מה שאינו ציור: הצטרפות לחדר והתחברות מחדש אליו, קבלת המסך המשותף, שליחת לחיצות, לייזר ודיו, צ'אט, הערות, הטיימר, שיחות וצימוד טלפון למחשב. אפליקציות ה-iPhone וה-Android חולקות אותה, כך שתיקון מגיע לשתיהן בבת אחת.
ב-Mac עם Cliqer 2.3, אפליקציית המחשב הופכת לחיצה להחלפת שקופית בחציון של 48 ms ב-PowerPoint ו-42 ms ב-Keynote, שנמדדו על פני 20 הרצות. הרשת מוסיפה מעל זה זמן הלוך ושוב משלה, שבבדיקות הממסר שלנו עמד בחציון על 13 עד 16 ms.
לא. גרסת הדפדפן למציגים עובדת בכל דפדפן מודרני בלי התקנה. האפליקציות מוסיפות סורק QR נייטיב, Face ID או זיהוי ביומטרי לשליטה במארח, מסך שנשאר דולק, ושלטים למצגות ב-Apple Watch וב-Wear OS.
למה העברנו את תשתית הזמן האמת של Cliqer אל מחוץ ל-Cloudflare (ולמה אנחנו עדיין מעריצים)
ארבעה חודשים על ה-edge של Cloudflare: מה נשבר, מה בנינו כדי להתמודד, ולמה Cliqer פועלת עכשיו על שרתים ייעודיים משלנו.
לשלוט במצגת מהטלפון: השוואה של כל האפליקציות
PowerPoint, Keynote, Canva, Unified Remote, PPTControl, Cliqer ועוד: אילו אפליקציות שלט בטלפון עובדות דרך האינטרנט, מציגות הערות ומתאימות לכם.
להריץ את ההפקה הבאה שלכם עם Cliqer
להמשיך לקרוא
עוד חדשות המוצר להפקה הבאה שלכם


למה העברנו את תשתית הזמן האמת של Cliqer אל מחוץ ל-Cloudflare (ולמה אנחנו עדיין מעריצים)

איך הפכנו את שיתוף המסך למהיר פי ארבעה
לקבל את המדריך הבא לפני ההפקה הבאה שלכם
מדריכים מעשיים למציגים, לצוותי AV ולצוותי אירועים, וגם עדכוני הגרסאות של Cliqer שבאמת חשובים. בלי ספאם, וביטול ההרשמה בלחיצה אחת.
