
エンジニアリング · 研究ノート
一つのテキストは、どのように信頼できるウェブページの訳文になるのか?
DOM の抽出、共通スケジューリング、出力検証、安全な書き戻しまで。18 点の図解で Browser Script Manager 翻訳システムのアーキテクチャ、データフロー、設計上の選択を理解する。
この記事の目次
この翻訳システムの設計の核は、絶えず変化するウェブページを、スケジュール可能で、再利用でき、識別情報を照合してから書き戻せる作業に整理することです。翻訳サービスは文章を生成し、拡張機能はその結果を正しいタイミングで正しい位置に表示します。
原文をたどり、システム全体のデータの流れを見る
Browser Script Manager は、翻訳とその他の機能をひとつの Manifest V3 拡張機能にまとめています。以下では、通常のウェブページ段落の翻訳フローを追います。各矢印は受け渡す内容を示し、ボックスのスイムレーンは実行境界を表します。選択テキストと翻訳センターの入口の違いは、次の節で説明します。
バージョンデータ
候補
または原文/
ブロック状態
更新
アダプターから戻った後に終了を確認
失敗状態は別途報告
ポリシーに適合する場合のみ再キュー投入
訳文の内容
再照合
表示可能な訳文
通常モードでは保存キューへ
状態更新
メモリに書き込み
各データフローをテキストで読む
- 01 原文を抽出し、セグメントを宣言 → 02 受信して翻訳需要の識別情報を作成:原文セグメント;バージョンデータ
- 02 受信して翻訳需要の識別情報を作成 → 03 ルール、共有ジョブ、ローカル検索:ページバインディング+原文
- C 文書コンテキストの候補を固定 → 03 ルール、共有ジョブ、ローカル検索:コンテキスト;候補
- C 文書コンテキストの候補を固定 → 01 原文を抽出し、セグメントを宣言:固定と接続確認の後に最初のセグメント群を送出
- 03 ルール、共有ジョブ、ローカル検索 → 07 状態と結果を通知:ローカル結果;または原文/;ブロック状態
- 03 ルール、共有ジョブ、ローカル検索 → 04 スケジュール、バッチ化、クォータの事前差し引き:ローカルで見つからず、外部送信が許可されている
- V 閲覧位置を更新 → 04 スケジュール、バッチ化、クォータの事前差し引き:閲覧位置;更新
- 04 スケジュール、バッチ化、クォータの事前差し引き → 05 翻訳サービスを呼び出す:API リクエスト
- 05 翻訳サービスを呼び出す → 06 終了確認と結果検証:生の応答/使用量;アダプターから戻った後に終了を確認
- 06 終了確認と結果検証 → 07 状態と結果を通知:有効なセグメント → 訳文を利用可能;失敗状態は別途報告
- 06 終了確認と結果検証 → 04 スケジュール、バッチ化、クォータの事前差し引き:失敗した項目/修復が必要な項目;ポリシーに適合する場合のみ再キュー投入
- 07 状態と結果を通知 → 08 バージョンを照合し、段落全体を組み立てる:バージョン状態;訳文の内容
- 08 バージョンを照合し、段落全体を組み立てる → 09 DOM 更新をスケジュールしてコミット:段落全体のテキスト結果
- G 現在の原文の識別情報を保持 → 09 DOM 更新をスケジュールしてコミット:現在の原文;再照合
- 06 終了確認と結果検証 → 10 ローカル翻訳メモリと保存状態:有効かつ現在も適用可能な;表示可能な訳文;通常モードでは保存キューへ
- 10 ローカル翻訳メモリと保存状態 → 07 状態と結果を通知:ローカル保存処理;状態更新
- 10 ローカル翻訳メモリと保存状態 → 11 クラウド同期ストレージ:暗号化してアップロード
- 11 クラウド同期ストレージ → 10 ローカル翻訳メモリと保存状態:復号して統合;メモリに書き込み
図 01B を展開|ローカル判定、検索失敗、外部送信ゲートを分岐ごとにたどる
またはディスク書き込み失敗
再判定
各データフローをテキストで読む
- D1 まずルールと固定した訳文を適用 → P ローカル状態/結果を返す:ローカル処理
- D1 まずルールと固定した訳文を適用 → D2 同じセマンティックキーの共有ジョブは存在するか?:翻訳が必要
- D2 同じセマンティックキーの共有ジョブは存在するか? → P 既存の共有ジョブを購読:既存
- D2 同じセマンティックキーの共有ジョブは存在するか? → D3 保存済み翻訳メモリを検索:新しい共有ジョブ:登録してから検索
- D3 保存済み翻訳メモリを検索 → P 永続保存された訳文が存在:ヒット
- D3 保存済み翻訳メモリを検索 → E 保存済み訳文の読み取りに失敗:読み取り失敗
- E 保存済み訳文の読み取りに失敗 → D3 保存済み翻訳メモリを検索:読み取りを再試行
- D3 保存済み翻訳メモリを検索 → D4 旧版の翻訳キャッシュを検索:ミスを確認済み
- D4 旧版の翻訳キャッシュを検索 → P 旧訳文を再利用し、保存形式を更新:ヒット
- D4 旧版の翻訳キャッシュを検索 → D5 見つからないことを確認して初めて外部送信を判断:ミス/読み取り失敗/旧版キーなし
- D5 見つからないことを確認して初めて外部送信を判断 → P ディスパッチしない 3 つの出口:ディスパッチしない
- D5 見つからないことを確認して初めて外部送信を判断 → D6 優先順位付けとバッチ化の後、リクエスト試行を承認:外部送信を許可し、ディスパッチキューへ
- D6 優先順位付けとバッチ化の後、リクエスト試行を承認 → W 待機/ブロックし、API には送信しない:準備未完了;またはディスク書き込み失敗
- W 待機/ブロックし、API には送信しない → D6 優先順位付けとバッチ化の後、リクエスト試行を承認:条件が回復;再判定
- D6 優先順位付けとバッチ化の後、リクエスト試行を承認 → T 翻訳サービスアダプターを開始:保守的な差し引きをコミット済み
なぜ service worker の再起動を考慮するのか?
Chrome の extension service worker はイベント駆動で、アイドル時に終了することがあります。通常の JavaScript グローバル変数は自動保存されません。そのため、このプロジェクトでは翻訳メモリとクォータを IndexedDB に保存し、再接続後にページからアクティブな需要を再宣言できるようにしています。これはライフサイクル設計であり、worker が決して中断しないという意味ではありません。
プラットフォームの根拠:Chrome 公式:service worker lifecycle(2026-10-25 参照)。
入口によって共有する部分も異なる
各翻訳入口は、バックグラウンドのリソースとディスパッチ承認の仕組みを共有します。ページのバッチ処理、選択テキストのストリーミング、翻訳センターは、それぞれ固有の出力方法を維持します。
| 入口 | システムへの入力方法 | 現在の表示方法 |
|---|---|---|
| ウェブページの段落 | 段落 → 文単位 → 共有翻訳フロー | 最終結果を待ち、現在も適用可能なことを確認してから画面を更新。一時プレビューを順次表示しない |
| 文書タイトル | 独立したテキスト単位として扱い、表示範囲付近の優先度に分類 | 最上位の文書のみを管理。リクエストのバージョンで、古い結果が新しいタイトルを上書きするのを防止 |
| 字幕 | 独立したテキスト単位として扱い、表示中コンテンツの優先度に分類 | セグメント完了後、字幕表示フローへ返す |
| 選択テキスト · LLM | バックグラウンドでテキストをストリーミング。リソースとクォータの承認を共有 | 蓄積したプレーンテキストで画面を継続更新できる。ページのバッチ応答解析とは異なる |
| 翻訳センター | 翻訳メモリを検索し、必要に応じて翻訳リクエストを送信 | 応答全体の受信後にカードを更新。リクエスト識別情報でキャンセルと古い応答を分離 |
まず、位置・ジョブ・リクエストを区別する
ページバインディングは画面上の需要を記録し、共有ジョブは再利用可能な翻訳タスクを表し、リクエスト試行は特定の翻訳リソースに対する 1 回の操作です。
横長の図は横方向にスクロールでき、テキストは選択できます。
同時に届く 2 つの同じ需要の重複送信を、どう防ぐのか?
バックグラウンドスケジューラーは、最初の非同期メモリ検索を始める前に、「検索中」のジョブをインデックスへ登録します。後から届くページの需要は同じジョブを購読し、先の検索がまだ戻っていなくても、同じタスクを別途作りません。そのため、非同期検索中の重複需要も統合できます。
抽出するのは識別可能な原文であり、HTML 全体ではない
横長の図は横方向にスクロールできます。
まず段落を識別
DOM、表示タイプ、除外ルールに基づいて走査し、自身の出力、非表示コンテンツ、発音注釈を飛ばします。
次に文へ分割
ブラウザーのテキスト分割機能を使い、2000 UTF-16 単位を超えたら、まず節を区切る句読点、次に書記素の境界を探します。
最後に識別情報を保持
各セグメントは元の範囲、分割順序、原文バージョンを保持し、原文が変わったらテキスト単位を再構築します。
UTF-16、字形、token を混同してはいけない理由
UTF-16 コード単位は JavaScript の文字列長に使う単位です。emoji は複数の単位を占める場合があり、複数の Unicode コードポイントが、ユーザーに見えるひとつの字形を構成することもあります。書記素(grapheme)は、このような可視のテキスト単位のまとまりを表し、token はモデルのトークナイザーによって決まります。
既定値の 2000 は、各テキスト単位の文字列長の上限です。ひとつの書記素だけで上限を超えたら、入力が大きすぎると報告します。ブラウザーがテキスト分割をサポートしない場合、フォールバックはコードポイント単位で処理するだけなので、複合字形を完全にまとめることは保証できません。
短いセグメントにはローカルのヒューリスティックもあります。URL などのノイズを除いた後、ラテン文字の単語 1 つだけなら省略することがあり、中国語・日本語・韓国語の文字を含む短いセグメントは保持できます。細切れのリクエストを減らす一方、意味のある単語を見落とす可能性もあります。選択テキストの翻訳には、ページ翻訳と同じ短文のしきい値を適用しません。
関連情報:ブラウザーのテキスト分割機能。
読んでいる場所を優先し、その先をプリロード
ページ側は「原文がどこにあるか」を把握し、バックグラウンドは「今どの文章を翻訳すべきか」を判断します。プリロード範囲は読む方向と速度で変わり、スケジューリングの優先順位はページをまたいで統一的に比較します。
範囲の模式図。長さは画面のピクセルに比例して描画していません
閲覧中:前方 3 画面分。段落登録は翻訳よりさらに 0.5 画面分先まで行います。
JavaScript が無効です。上には「閲覧中、下向き、高さ 800px、余白 1000px」の静的な例を残しています。
プリロードの数式とスクロールアルゴリズムを展開
設定余白が ≤0 の場合、両側とも 0 を返します。上向きに読む場合は上下の範囲を入れ替えます。スクロール速度は EMA で平滑化します:α=1−exp(−dt/200)、新速度=旧速度+(瞬間速度−旧速度)×α。dt の単位は ms、瞬間速度の単位は px/s です。間隔が 400ms に達したら、新しいサンプルをそのまま採用します。
方向転換には、逆方向への移動が累積で max(120px, 0.35H) に達する必要があります。前方向の速度が 2.5 viewport/s に達すると、高速スクロール状態に入り、2 秒間維持できます。これらのしきい値は、わずかな引き戻しによる監視範囲の再構築を減らすものです。設計上のヒューリスティックであり、読む意図を認識するモデルではありません。
スケジューリング例:同時実行枠 1、単項目リクエスト。P1 がフォーカス中で、3 ページにそれぞれ 3 つの表示中の文章がある
ルールで翻訳可否を決めてから重要語を保護
複数の語句を一度に検索
互いに重なる一致も含める
次にルールの具体性と識別番号を比較
安定した選択順序を得る
⟦n⟧ プレースホルダーに変換
置換済みの内容は再走査しない
用語保護の例。モデルの応答は模式的な文章です
モデルに送信
応答して復元
→ ラストベルトで使われるのは Rust 言語。
ルールの優先順序と Aho–Corasick の厳密な役割分担
まずページ全体の無効化を処理し、次に文全体の原文保持/指定訳文、ユーザーが固定した訳文、外部送信禁止を確認し、最後に語句をプレースホルダーへ置換します。外部送信を禁止しても、ローカルに保存された訳文は表示できます。
Aho–Corasick は複数の語句の検索を担当します。「最左・最長」は、その後の並べ替えとカーソルによる選択が共同で決める結果です。走査は UTF-16 コード単位で行われ、自然言語の単語境界は理解しません。全体の処理には一致候補の展開と並べ替えも含まれるため、全コストを単純に O(n) とは書けません。
照合範囲には任意のテキスト、文全体の厳密一致、リテラルの語句が含まれますが、任意の正規表現には対応していません。コンパイルまたは照合に失敗した場合は、より直接的な参照走査方式にフォールバックできます。
コンテキストは安定させ、同じ外部送信ルールに従わせる
文書コンテキストを有効にした翻訳設定では、最初のバッチを送る前に候補テキストを固定します。バックグラウンド側が現在のポリシーに従って適格な内容を選び、「翻訳してはいけない段落」が他の文のコンテキストを通じて間接的に送信されるのを防ぎます。
本文ブロックは最大 16 個
候補の合計 ≤6000 UTF-16 単位
全長は最大 1500 UTF-16 単位
コンテキストのフィンガープリントを計算
翻訳対象の文とは分離
コンテキストは背景情報だけを提供し、それ自体の訳文を出力する必要はありません。コンテキストが異なれば、セマンティックキーも異なる場合があります。
制約は残る
文書の前半の限られた範囲では、全文を網羅できるとは限りません。各翻訳入口で使うコンテキストにも違いがあります。
まずローカルに問う:この意味上の契約は、すでに翻訳済みか?
セマンティックキー:どの翻訳か?
ページキー:ページを開き直すときに何を復元するか?
ページキーは復元の意図とページの関連付けを管理し、セマンティックキーは原文の文と訳文の対応を決めます。
| データ層 | 保存戦略 | 設計上のトレードオフ |
|---|---|---|
| 翻訳メモリ | 有効期限なし、自動削除なし。既定値は内容の集計で 512 MiB/20 万件/1 件あたり 1 MiB | 容量がいっぱいになったら新たな書き込みを拒否し、既存の記録を保護します。数値には IndexedDB 全体のインデックスや追加のストレージコストは含まれません。 |
| 旧版キャッシュ | 既定値は 30 日/128 MiB。LRU 方式で削除 | 再構築可能なキャッシュであり、保存済み訳文とは異なる保持戦略を採用します。 |
| ルール/固定した訳文 | 永続化するポリシーデータ | ユーザーが指定した動作であり、一般的な LRU キャッシュではありません。 |
モデルやページが変わっても再利用できる結果はどれか?
ページ翻訳の意味上の識別情報には、プロバイダーやモデルを直接含めません。他の意味条件が同じなら、モデルを変えても既存の結果にヒットする可能性があります。「強制再翻訳」の場合に初めて翻訳メモリと旧版キャッシュを飛ばし、結果の検証に成功した後、同じセマンティックキーのメモリを置き換えます。
選択テキスト翻訳と翻訳センターは、それぞれ固有の入口の取り決めを使い、翻訳設定にもプロバイダー識別子を含めます。そのため、翻訳センターの A プロバイダーのカードが B プロバイダーのカードの結果を使うことはありません。同じプロバイダー設定でモデルを変更した場合は、元の識別情報を維持します。
コンテキスト、ルール、バージョンも意味上の契約に含め、ハッシュの厳密一致で訳文を探します。異なるページの同じ文でも、他の意味条件まで一致して初めて共有できます。似ているだけの文章が自動的にヒットすることはありません。
バッチ化でリクエストを節約し、ディスパッチ承認でリソースとクォータを守る
候補ジョブをまず閲覧需要に従って並べ、次に利用可能な翻訳リソースを選び、最後にバッチへの統合を試みます。大きなバッチはジョブをまとめられますが、表示中のコンテンツには小さな基準を使い、最初の結果が多くの文を待たずに済むようにします。
ユーザー設定と表示中コンテンツの基準の小さい方を採用
翻訳フローのバッチ設定に従って統合
同じバッチ内では互換性が必要
T1/T3 の候補窓に複数のページが現れた場合は、単項目のディスパッチを維持し、あるページのバッチを埋めるために別のページを飛ばさないようにします。個別修復が必要なジョブもバッチ化しません。
横長の図は横方向にスクロールできます。
同時実行数
システム全体、単一の翻訳リソース、関連するすべてのクォータグループを同時に確認します。初期既定の上限は、それぞれ同時実行枠 16、12、16 です。
送信レート
各翻訳リソースのトークンバケットは、既定で毎秒 8 リクエスト分の容量を補充し、最大 16 回分を蓄積します。これは開始のペースを管理するもので、毎秒 8 回の完了を保証するものではありません。
時間窓クォータ
設定に従って、毎分のリクエスト数、毎分の token 数、1 日のリクエスト数を確認します。実使用量が多ければ追加計上しますが、少ない場合や報告されない場合に事前差し引きを自動返却することはありません。
アルゴリズム:いつ時間を待ち、いつイベントを待つのか?
| 条件 | ディスパッチ判断 | 意味 |
|---|---|---|
| a > L | 需要をブロック | この需要自体が上限を超えており、設定を変えない限り、待っても収まりません。 |
| D ≤ 0 | このクォータ確認を通過 | 同時実行枠、送信レート、その他のクォータ確認も通過する必要があります。 |
| 0 < D ≤ S | 指定時刻まで待機 | 時間バケットを走査し、十分な差し引きが期限切れになる時刻を探します。 |
| D > S | 状態変更を待機 | コミット済みの差し引きがすべて期限切れになっても、コミット待ちの予約量と新しい需要の合計が上限を超えます。 |
同じ翻訳リソースの時間条件には最も遅いしきい値を採用し、枠の解放や書き込み完了も必要なら、対応するイベントを待ちます。異なる候補ジョブの間では、最も早く起動できる可能性のある時刻を探します。固定容量のリング状時間バケットにより、過去のリクエスト数に応じてメモリが無制限に増えるのを防ぎます。分の窓は 62 バケットで各 1 秒、日の窓は 1442 バケットで各 60 秒です。
差し引きが属する時間バケットの番号は ceil(帰属時刻 ÷ 各バケットの長さ)、つまり切り上げで求めます。永続化スナップショットの作成時には、コミット待ちの差し引きの帰属時刻を、少なくとも現在時刻+1000ms に設定します。トランザクション完了後にも現在時刻より前でないことを確保し、保守的に期限を決めます。リクエストのトークンバケットは整数で計数し、1 回のリクエストは 1,000,000 マイクロ単位に相当します。これはモデルが文章を分割する token とは無関係です。
アルゴリズム:リソース選択、token 推定、任意の適応制御
複数の翻訳リソースが使える場合、まず「候補窓内の互換性のある需要量 ÷ 利用可能な同時実行数」を比較し、分母は少なくとも 1 とします。次に負荷、ルーティング優先度、安定したリソース識別子順を比較します。これは目の前の候補からリソースを選ぶヒューリスティックであり、グローバルな最適配分を求めるものではありません。
これはローカルでディスパッチ可否を決めるための推定です。プロバイダーの実際の token 分割とは異なる場合があり、アカウントの残り枠の代わりにもなりません。ページのバッチでは翻訳指示とコンテキストも推定に加えるため、原文の文字数だけを毎分の token 使用量とみなすことはできません。
適応的な同時実行数の調整は既定で無効です。有効にすると、同時実行上限はハード上限の半分を切り上げた値から始まります。成功応答が届き、統計窓が 20 秒に達していれば、前の窓で成功が少なくとも 10 回あり、未処理ジョブが残り、輻輳がなかったかを確認します。すべて満たした場合にのみ枠を 1 つ増やします。容量の輻輳時は半減し、同じ調整周期内の減少は最大 1 回です。自動フォールバック切り替えも既定で無効であり、明示的に有効にした場合のみ、条件に合えば別のリソースへ切り替えます。
モデルが返すのはデータプロトコル。検証を通過して初めて訳文になる
既定のページバッチ翻訳では、短い識別番号で各結果を対応付けます。出力順は異なっても構いませんが、識別番号、訳文、プレースホルダーのすべてが検証に通る必要があります。これにより、「応答全体が壊れている」と「一部の項目だけ修復が必要」を分けて扱えます。
合成データの例です。原文の言語は自動判定し、翻訳先は台湾の繁体字中国語で、追加のコンテキストは付けません。応答順を意図的に入れ替えていますが、項目の識別番号で 1 対 1 に対応します。
送信した翻訳項目
| 項目の識別番号 | 原文 |
|---|---|
| 1 | Hello. |
| 2 | Goodbye. |
受信した翻訳結果
| 項目の識別番号 | 訳文 |
|---|---|
| 2 | 再見。 |
| 1 | 你好。 |
→ 表示可能な訳文 → 最終結果
空の訳文/長すぎる訳文/プレースホルダーの不一致
→ 後で個別に再試行
バージョン誤り、不正な JSON、余分な文章
→ 応答全体を拒否
| 翻訳サービス | 実際のネットワーク動作 | 応答の要件 |
|---|---|---|
| DeepSeek/OpenAI/Google | 下位層の自動再送は無効で、各操作のネットワークリクエストは最大 1 回です。再試行は上位のスケジューラーが管理します。カスタムサービス URL も、対応するサービスの接続ルールに従う必要があります。 | ストリーミングテキストは応答パーサーへ渡し、構造化データ形式に適合する必要があります。 |
| Microsoft | ひとつの操作内で、まず Edge の認証を取得し、その後翻訳を送信します。各段階のネットワークリクエストは 1 回まで、合計で最大 2 回です。 | 返された件数を確認し、元の位置に従って同じ項目識別番号を補い、統一形式へ変換します。 |
何を許容するのか? token の上限ではない数値はどれか?
パーサーは、指定マーカーで囲まれた先頭の思考部分、および応答全体を囲み、言語指定がないか JSON と指定された Markdown フェンスを許容します。正しい空白やデータフィールドの順序変更も受け入れます。任意の文章から JSON を推測して抜き出すことはしません。大きなストリーミング増分は 32,768 UTF-16 単位のチャンクに分けて処理し、チャンクをまたいでテキスト、エスケープ、Unicode の解析状態を保持します。
| 境界 | 既定値 | 計量方法 |
|---|---|---|
| テキスト応答全体 | 262,144 | 2 × UTF-16 長。外枠のテキストを含む |
| モデル応答のネットワークデータ量 | 16 MiB | テキスト応答の予算 × 64。SSE と JSON の外枠を含む |
| 単一項目の訳文 | 24,000 | UTF-16 コード単位 |
製品の方向性は「原文を自動判定 → 台湾の繁体字中国語」です。ページ翻訳と共有設定では異なる繁体字中国語の言語タグを使い、Microsoft ではさらに ISO 言語対応表で変換し、対応が見つからなければ繁体字中国語のタグを使います。サービス間の連携では、この言語表現の違いを処理する必要があります。
システムプロンプトは、原文とコンテキスト内の指示を無視し、訳文にはプレーンテキストを使うよう求めます。これは期待する動作を表しますが、プロンプトインジェクションや誤訳を完全に排除できる保証はありません。DeepSeek の思考モードは既定で無効で、ユーザーが変更することもできます。
どれだけ速く結果が戻っても、まずページが同じ状態かを確認
翻訳中に動的なウェブページの文章や段落が変わったり、ページを離れたりすることがあり、ユーザーがテキストを選択中のこともあります。バックグラウンドの完了は候補結果を得たことを意味するだけです。ウェブページのノードを実際に更新する前に、その時点の原文と操作状態を照合する必要があります。
横長の図は横方向にスクロールできます。
このフレームの予算に余裕あり
→ 今すぐ更新
この段落の最新の更新計画だけを保持
→ 保護条件の解除を待つ
更新計画をいったん保持
→ 次のフレームで再確認
時間はブロックの更新が完了するたびに確認します。予算を超えても一括更新が必要な最初のブロックは、単独でコミットできます。したがって 4ms は制御を譲るための予算であり、各ウェブページ更新の厳密な最大時間ではありません。
| 表示モード | 原文の扱い | 訳文の書き込み方 |
|---|---|---|
| 対訳 | 原文は元の位置に残します。旧訳文がある場合は、新しい更新計画のコミットを待って置き換えます。 | 訳文を入れるノードを作成し、表示キューへ渡して更新します。 |
| 訳文のみ | 元のノードオブジェクトを一時保持してからページから外し、復元時には同じノードを戻します。 | 主経路ではテキストノードと改行ノードで訳文を組み立て、モデルの文章を HTML として実行しません。 |
より細かな表示戦略:統合、延期、不要な書き換えの回避
表示タイミングの制御器は、順次届く結果を統合し、直近の処理時間でタイミングを調整します。新コスト推定値 = 0.6 × 旧コスト推定値 + 0.4 × 今回の所要時間。次の間隔は min(1000ms,2 × 新コスト推定値)です。ブラウザーのアニメーションフレーム通知がまだ届かない場合は、250ms のタイマーが補います。ここで追跡するのは処理時間であり、ブラウザーのレイアウトと描画の全コストを表すものではありません。
同じブロックには最新の更新待ち計画だけを保持し、延期する計画は最大 128 件です。超えた場合は「再更新が必要」の印に切り替えられ、この印の上限は 4096 です。ページ変更後の再照合は、段落ごとに実行中のジョブ 1 つと再実行待ちの印 1 つにまとめます。
表示用の要約値は「テキスト長+32 ビット FNV-1a ハッシュ」で書き換えを省略できるかを判断し、バックグラウンドの SHA-256 による意味上の識別とは異なります。内容が異なっても同じ要約値になる可能性があります。複数文の訳文は元の翻訳単位の順番で組み合わせ、接合部は中国語・日本語・韓国語の空白規則から推定します。元の空白を一文字ずつ復元するわけではありません。
同じ元ノードを保持することは、既存のオブジェクト関係の維持に役立ちます。ただしイベントのバインディング、レイアウト、操作の動作は、サイト自体の構造や更新方法の影響を受けます。
訳文が読めることと、保存済みであることは別
横長の図は横方向にスクロールできます。
保存キューはどうメモリを制限するのか?
| 領域 | 件数上限 | 推定バイト数の上限 |
|---|---|---|
| 主要保存キュー | 32 | 16 MiB |
| 追加待機領域 | 64 | 8 MiB |
| 保存失敗後に保持する内容 | 64 | 8 MiB |
待機中または保存失敗後の内容の保持期間は 10 分で、後続のキュー操作や再試行時に確認してクリーンアップします。容量は「原文の UTF-8 バイト数+訳文の UTF-8 バイト数 × 2+1024」で推定し、実際のメモリ使用量とは異なる場合があります。キューが満杯になると新たなページ翻訳のディスパッチを一時停止しますが、送信済みのリクエストは完了できます。
このキューは実行中のメモリにのみ存在します。バックグラウンドサービスが終了すると、書き込み未完了の内容は再起動しても自動復元されません。図はページ翻訳の保存状態を示しています。対話型の入口は内容を保存ジョブに入れるだけで、同じ完全な画面状態フローを待つことはありません。
キャンセルはコミット権限の撤回。再試行には明確な理由が必要
横長の図は横方向にスクロールできます。
以上は調整可能な既定値です。通常のページ再試行ポリシーは、初回を含む実送信 4 回を既定の基準とし、累積実行時間の予算は 180 秒です。大きすぎる複数項目のバッチには、単項目に分割して再キュー投入する修復経路もあります。一度も試行せず画面外で待っているだけの需要には、通常の 30 分の需要期限を適用しません。
| 失敗 | 処理方針 | 区別する理由 |
|---|---|---|
| HTTP 401/通常の 403/404 | 認証、権限、モデル設定の問題として扱い、該当する翻訳リソースをブロックします。 | むやみに再送しても設定は直りません。 |
| HTTP 429 · 容量関連 | 制限されたリソースまたはクォータ範囲にクールダウンを設定し、再利用可能になるまでジョブをキューに残します。 | 負荷が下がってから再試行します。 |
| HTTP 402/429 · 支払いまたは残り枠の不足 | 既定では再試行しません。枠不足に関する 403 もこの分類です。フォールバック切り替えを明示的に有効にし、独立したフォールバックの条件を満たす利用可能なリソースがあれば、別のリソースへ転送できます。 | 支払い/アカウントの枠の問題は、一時的な輻輳ではありません。 |
| HTTP 408/409/425/5xx | 一時的なサーバー障害として扱い、再試行できます。 | 時間の経過で回復する可能性がありますが、回数と予算の制限は受けます。 |
| HTTP 413/大きすぎる入力 | 複数項目のバッチを単項目に分けて再試行し、単項目でも大きすぎる場合はそのジョブをブロックします。 | バッチが大きすぎることは、各項目を個別にも翻訳できないことを意味しません。 |
再試行の時刻、起動、時計のジャンプ
通常のジョブの遅延再試行にはフルジッターを使い、毎回ゼロから待機上限までのランダムな遅延を選びます。容量関連の HTTP 429 では、制限されたリソースまたはクォータ範囲にクールダウンを設定し、サーバー指定の待機時間を使います。指定がなければ基本遅延を使い、ランダムジッターは適用しません。
ジッターは再試行の時刻を分散させます。応答ヘッダー Retry-After が指定する時刻は追加の下限であり、秒数または HTTP 日付を受け付け、サーバーとの時刻差も考慮します。サーバーが要求する待機時間は最大 7 日まで保持します。
起動スケジュールは、最も早い期限のタイマー 1 つにまとめます。予想待機時間が 30 秒以上なら、ブラウザーのバックグラウンドアラームで起動を補います。時計の確認では、システム時計と単調時計の経過時間を比較します。ずれが 5 秒を超える、またはシステム時刻が 5 秒を超えて戻った場合、新たなディスパッチを一時停止します。新たな異常がなく安定期間が 2 秒に達して初めて、保守的な方針で再開します。
キャンセル図が示すのは送信済みのネットワーク試行です。枠を予約済みでも未送信の試行は、先に終了して枠を解放できます。ただし、進行中の差し引きトランザクションがその後コミットに成功した場合、実際にサービスを呼び出していなくても保守的な差し引きは残ります。終了を確認できないネットワーク操作では関連リソースを隔離し、遅れて終了通知を受け取るまで枠を保持します。バックグラウンドサービスの再起動では新しい実行世代を作り、旧リクエストは同時実行枠を占有しなくなりますが、既知のクォータ台帳は保持し続けます。
「ローカル優先」でもデータの行き先を明確にする
原文単位/文書コンテキストをバックグラウンドへ送信
バージョン付きの状態・結果通知を受信
同じレコードにページの関連付けを含む
ページ復元の意図は別途保存
ページ側から見える設定と分離
ローカルでは追加のアプリケーション層暗号化なし
LLM は適格なコンテキストも受信可能
各サービスのプロトコルに従って返す
共有同期サービスが暗号化してからアップロード
同期の戻り経路はローカルメモリに書き込む
ページ側に渡す設定からは、API キー、リクエストヘッダー、プロバイダーオプションを除去します。設定の同期でもこれらのフィールドを除外し、同期を許可した設定のみを送信します。
| 仕組み | 実際の動作 | 維持すべき境界 |
|---|---|---|
| 外部送信禁止 | そのジョブの翻訳サービスへの送信を禁止します。ローカルに保存済みの訳文は引き続き検索できます。 | コンテキスト候補もポリシー確認を通る必要があります。翻訳メモリの同期は、ユーザーが同期に参加したかに従って別途処理します。 |
| シークレットモード | そのシークレットモードのジョブで使う翻訳メモリの検索と、生成した翻訳メモリの保存・同期を行いません。 | 文章内容を含まないディスパッチとクォータのメタデータは保存します。 |
| 翻訳ネットワークリクエスト | ブラウザーの認証情報を付けず、リダイレクトを拒否し、宛先オリジンを制限します。リモート接続には HTTPS を使います。 | 明示的に指定したローカル/プライベートネットワークのホストには HTTP を使用できます。 |
| 同期の暗号化 | HKDF-SHA-256 でキーを導出し、AES-256-GCM で同期データオブジェクトを暗号化します。 | 暗号化は同期内容を保護しますが、ローカル設定の分離は別の責務です。 |

コメントと議論
コメントサービスに接続しています…