Skip to content

כל ה-JS של עמוד ההגדרות מרונדר פעמיים — כל מאזין רשום כפול וכל שמירה שולחת שתי בקשות #3295

Description

@amirbiron

הממצא

ב-webapp/templates/settings.html, בלוק ה-JS מקונן בתוך בלוק התוכן:

   9:  {% block content %}
1935:    {% block extra_js %}      ← כ-2300 שורות JS
4250:    {% endblock %}
4251:  {% endblock %}

ב-Jinja, בלוק שמוגדר בתוך בלוק אחר בתבנית-בת מרונדר פעמיים: פעם אחת במקומו בתוך content כשהתבנית-האם מרנדרת את {% block content %} (base.html:2172), ופעם שנייה בחריץ {% block extra_js %} שב-base.html:5175.

התוצאה: כל פונקציה, כל addEventListener וכל אתחול בבלוק הזה קיימים ורצים פעמיים.

הראיות

מדידה על העמוד המוגש בפועל (Flask מקומי, משתמש מחובר):

id="stickyFontsCard"          1     ← ה-markup מרונדר פעם אחת
id="noteFontsMsg"             1
── גופן הפתקים                2     ← ה-JS מרונדר פעמיים
function persist(             2
function notify(              2

והתוצאה המעשית, נמדדה בכרומיום עם יירוט בקשות — שינוי בורר אחד:

{ "posts_for_one_change": 2,
  "bodies": ["{\"note_fonts\":{...},\"note_fonts_scope\":\"global\"}",
             "{\"note_fonts\":{...},\"note_fonts_scope\":\"global\"}"] }

שתי בקשות POST /api/ui_prefs זהות, על שינוי אחד.

היקף — לא רק כרטיס אחד

הכפילות חלה על כל הבלוק. דוגמה חלקית מהפונקציות שמוגדרות פעמיים בעמוד המוגש:

exportBackup   handleRestoreFile   diskBackupNow   driveBackupNow
disconnectDrive   loadDriveStatus   loadDiskStatus   loadThemesList
persistThemeScope   openPopover   closePopover   markSeen   resetSeen

וספירת קריאות רשת בעמוד המוגש: fetch('/api/drive/backup ×4, fetch('/api/disk ×6, fetch('/api/backup/export ×2, fetch('/api/backup/restore ×2.

שמירת העדפות היא idempotent ולכן הנזק שם הוא בזבוז בלבד. מה שדורש בדיקה הוא הפעולות שאינן בהכרח כאלה — גיבוי לדיסק, גיבוי ל-Drive, ייצוא ושחזור. לא בדקתי אותן, ואיני טוען שהן שבורות; אני מדווח שהן יושבות באותו בלוק כפול ולכן צריך לבדוק כל אחת.

התיקון המוצע

הבלוק כבר יושב במקום סביר בתוך content. הדרך הקצרה היא להסיר את תגי הבלוק המקוננים (שורות 1935 ו-4250) ולהשאיר את ה-JS בדיוק היכן שהוא — אז הוא מרונדר פעם אחת, במיקום שבו הוא כבר רץ ראשון היום. החריץ {% block extra_js %} של base.html יישאר ריק, כפי שהוא בתבניות אחרות.

זה לא PR של שתי שורות. הסרת ההרצה השנייה משנה את ההתנהגות של כל מה שבבלוק: קוד שהסתמך בלי דעת על כך שהעותק השני דורס משתנה גלובלי, או שהמאזין הכפול "כיסה" משהו, ישתנה. זה דורש מעבר על הבלוק ובדיקה בדפדפן, ולכן סבב נפרד.

איך זה התגלה

בזמן אימות תיקון ב-#3293. מדידת ההנפשה בדפדפן הראתה שתי קריאות ל-ckToast על שינוי אחד, מה שלא הסתדר עם הקוד. המעקב הוביל לכפילות הרינדור.

בדרך התברר גם שהשרת המקומי מחזיק את התבנית מקומפלת בזיכרון, כך שעריכה על הדיסק אינה משפיעה על מה שמוגש בלי הפעלה מחדש — שווה לזכור בכל בדיקת תבנית ידנית.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions