From 286daac6503a8a8543f7e2e596bb5dd2c48500e1 Mon Sep 17 00:00:00 2001 From: Luc Mcgrady Date: Mon, 29 Dec 2025 23:19:07 +0000 Subject: [PATCH] Perf: Prevent partial template being sent to frontend --- proto/anki/scheduler.proto | 13 ++++++------- qt/aqt/mediasrv.py | 7 +++++-- rslib/src/scheduler/service/mod.rs | 7 +++++-- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/proto/anki/scheduler.proto b/proto/anki/scheduler.proto index e865af132..bd06ecd02 100644 --- a/proto/anki/scheduler.proto +++ b/proto/anki/scheduler.proto @@ -307,6 +307,11 @@ message NextCardDataResponse { bool stop_on_answer = 2; } + message PartialTemplate { + repeated card_rendering.RenderedTemplateNode front = 1; + repeated card_rendering.RenderedTemplateNode back = 2; + } + message NextCardData { QueuedCards queue = 1; repeated AnswerButton answer_buttons = 2; @@ -334,13 +339,7 @@ message NextCardDataResponse { deck_config.DeckConfig.Config.QuestionAction autoAdvanceQuestionAction = 18; deck_config.DeckConfig.Config.AnswerAction autoAdvanceAnswerAction = 19; - // TODO: We can probably make this a little faster by using oneof and - // preventing the partial_front and back being sent to svelte where it isn't - // used. Alternatively we can use a completely different message for both - // Rust -> Python and the Python -> Svelte though this would be more - // complicated to implement. - repeated card_rendering.RenderedTemplateNode partial_front = 10; - repeated card_rendering.RenderedTemplateNode partial_back = 11; + optional PartialTemplate partialTemplate = 11; } optional NextCardData next_card = 1; diff --git a/qt/aqt/mediasrv.py b/qt/aqt/mediasrv.py index 72a858fe8..c7ebef28b 100644 --- a/qt/aqt/mediasrv.py +++ b/qt/aqt/mediasrv.py @@ -711,16 +711,19 @@ def next_card_data() -> bytes: ctx = TemplateRenderContext.from_existing_card(card, False) qside = apply_custom_filters( - PartiallyRenderedCard.nodes_from_proto(data.next_card.partial_front), + PartiallyRenderedCard.nodes_from_proto(data.next_card.partialTemplate.front), ctx, None, ) aside = apply_custom_filters( - PartiallyRenderedCard.nodes_from_proto(data.next_card.partial_back), + PartiallyRenderedCard.nodes_from_proto(data.next_card.partialTemplate.back), ctx, qside, ) + # Dont send the partialy rendered template to the frontend to save bandwidth + data.next_card.ClearField("partialTemplate") + q_avtags = ctx.col()._backend.extract_av_tags(text=qside, question_side=True) a_avtags = ctx.col()._backend.extract_av_tags(text=aside, question_side=False) diff --git a/rslib/src/scheduler/service/mod.rs b/rslib/src/scheduler/service/mod.rs index e073236e7..ce3021f1e 100644 --- a/rslib/src/scheduler/service/mod.rs +++ b/rslib/src/scheduler/service/mod.rs @@ -11,6 +11,7 @@ use anki_proto::generic; use anki_proto::scheduler; use anki_proto::scheduler::next_card_data_response::AnswerButton; use anki_proto::scheduler::next_card_data_response::NextCardData; +use anki_proto::scheduler::next_card_data_response::PartialTemplate; use anki_proto::scheduler::next_card_data_response::TimerPreferences; use anki_proto::scheduler::next_card_data_response::TypedAnswer; use anki_proto::scheduler::ComputeFsrsParamsResponse; @@ -499,8 +500,10 @@ impl crate::services::SchedulerService for Collection { queue: Some(queue.into()), css: render.css.clone(), - partial_front: rendered_nodes_to_proto(q_nodes), - partial_back: rendered_nodes_to_proto(render.anodes), + partial_template: Some(PartialTemplate { + front: rendered_nodes_to_proto(q_nodes), + back: rendered_nodes_to_proto(render.anodes), + }), answer_buttons, autoplay: !deck_config.disable_autoplay,