概要:
Safari とフルスクリーン Web アプリ (別名 Web アプリ対応) には、localStorage データの個別のインメモリ ライトスルー キャッシュがあります。フルスクリーン アプリがアクティブになるたびに、ディスクから localStorage をリロードします (Safari の変更を表示できるようにします)。ただし、Safari がアクティブになると、localStorage データがディスクからリロードされないため、Safari を強制終了して再起動しない限り、フルスクリーン アプリで行われた変更は表示されません。
完全な説明:
コンピュータ サイエンスの難しい問題は2 つだけです。
- キャッシュの無効化
- ものに名前を付ける
- オフバイワンエラー
localStorage のバグのある動作は、問題 #1 の結果です。理由は次のとおりです。
iOS ブラウザー エンジンがロードされると、localStorage のデータがディスクから読み取られ、メモリにキャッシュされます。次に、データを読み取るたびに (例: getItem
)、データはディスクからではなくメモリから読み取られます。書き込み時 (たとえばsetItem
)、データはメモリに書き込まれ、(非同期的に) ディスクにフラッシュされます。localStorage は同期であるため、この実装は完全に合理的です。すべての読み取りと書き込みのためにディスクに行った場合、高価なディスク IO を実行するために、すべての読み取り/書き込みで JavaScript がブロックされます。
問題は、フル スクリーン Web アプリ (FSWA と呼びましょう) が iOS ブラウザー エンジンの別のインスタンスを使用し、FSWA が localStorage データ用にディスク上の同じ場所を共有しているにもかかわらず、メモリ内キャッシュを共有していないことです。 Safari を使用した localStorage データの。
アクティブなアプリケーションになるたびに FSWA が完全にリロードされる (つまり、localStorage データがディスクからリロードされる) という事実を追加すると、見ている動作が得られます。
舞台裏はこちら…
- ユーザーは、Safari で localStorage にデータを書き込む変更を行います
- Safari はデータを Safari のメモリ内 localStorage キャッシュに書き込みます
- Safari は localStorage データをキャッシュからディスクにフラッシュします
- ユーザーがサファリを離れ、FSWA を起動する
- FSWA は、ローカル ストレージ データをディスクからインメモリ キャッシュにロードして読み取ります。
- ユーザーは、Safari で (手順 1 で) 変更されたデータを確認します。
- ユーザーが localStorage にデータを書き込む FSWA に変更を加える
- FSWA は localStorage キャッシュにデータを書き込みます (Safari のキャッシュは更新されません)。
- FSWA は localStorage キャッシュ データをディスクにフラッシュします
- ユーザーが Safari に戻る
- Safari はすでに実行されており、ディスクから localStorage データをリロードしません。
- Safari は既存のメモリ内キャッシュから古いデータを読み取ります
- 手順 7 で行った変更がユーザーに表示されない
これを証明するために、手順 4 と手順 10 の間でSafari を強制終了できます。その後、手順 11 で Safari を再起動すると、ディスクから localStorage がリロードされ、FSWA によって書き込まれたデータが表示されます。