当方、フリーの IT 技術者。ある Web ベースのシステムを開発しているのだが、プロジェクトのマネージャー、リーダーをはじめとするメンバーの無知と無理解のおかげで作業が進まずに困っています。
ブラウザーのキャッシュの仕組みを少しでも知っている人なら、非 IT 系の方でも読めるように書きました。ぜひ助言をお願いします。
私は発注元(A 社)に客先常駐している。私が契約しているのは A 社のグループ会社である B 社だ。
A 社内のチームメンバーは以下のとおり。
さて、今開発しているシステム(以下システム P)はもともとスタンドアローンで運用する形態だったが、最近クラウドバージョンの提供も始まり、現在はスタンドアローンバージョンとクラウドバージョンの並行開発となっている。X さん、Y さん、Z さんは主にクラウドサーバーの管理や、私や W さんが作った部分のテストを担当している。
クラウドバージョンの初めてのアップデートを控えた 6 月に問題が発覚した。コードをアップデートすると、ブラウザーのキャッシュが効いていて表示がおかしくなるというのだ。
プログラマー以外の 4 人は実は Web システムの案件は初めてで、ブラウザーのキャッシュの仕組みすら理解していない。X さんから相談を受け、「Web アプリケーションからブラウザーのキャッシュをクリアーすることはできない。代わりに、HTML から読み込まれる外部リソースの後ろに『?v=3.14』のようなダミーのクエリー文字列をつければよい。アップデートのたびに数字を変える。これは一般的に採用されている手法で、これ以外の解決策はない」ということを伝えた。具体的にコードエディター上で修正イメージを見せて、すべてに対応するのに 1 日あればできる、とも。
これで「そうですか、ではお願いします」となれば、テストを含めて 2、3 日で終わった話なのだが、ここから長い混乱が始まる。
X さんから、「変更箇所をなるべく少なくしたいので、前回リリース分と今回リリース分で変更のあったファイルのリストを出してほしい」と言われる。変更のないリソースにはクエリー文字列をつけたくないらしい。
内心呆れつつ、Git (ソースコード管理システム)でファイルの変更履歴を調べ、一覧表を提出した。X さんに「それぞれのページでソースコードを確認し、この一覧表に載っているファイルにはクエリー文字列がついていることをひとつひとつ確認するのですよね。却って手間が掛かりますよ。それよりも、すべてのファイルを対象にしたほうが作るほうもテストするほうも楽です」と伝えた。
6 月も残り 1 週間を切ったある日、Z さんから、「実際に問題になっているのはどのファイルのどの部分か、スタイルシートのどのクラス・ID 指定が効いていないのか、V さんが知りたがっている。原因解明に必要なので調べるように」と指示が出る。
私は「ブラウザーのキャッシュが効いているためで、キャッシュを消すか無効にすれば直る。今までも修正のたびにテストではキャッシュを消してもらっていたでしょう」と説明するが、調べろ調べろと繰り返すばかり。「そんなことを調べて何になるんですか。キャッシュの問題ですよ?」と言うと、Z さんは手をわなわな震わせて、「お客さまが知りたいと言っているのに、『そんなことを調べて何になるんですか』とはどういうことですか!」と声を荒らげる。しまいには「お客さまのご要望にお応えして私たちはお金をもらっている。お客さまからの依頼なら応えるのが当たり前」と言い出す。技術的に意味がないことをいくら説明するも理解されない。
非プログラマー 4 氏の知識の底上げをしないといつまで経っても平行線だと思い、Redmine (課題管理システム)にブラウザーのキャッシュの仕組みを解説する文書を投稿した。ほぼ同じものを以下に掲載する。非技術者にも分かりやすく書いたつもりだ。あまり細かいことを説明しても混乱させるだけだと思い、リクエストヘッダーの Cache-Control や Expires などは説明を省いた。
キャッシュとは
キャッシュ(cache) とは、一度読み込んだデータを内部に保存しておく機構のことです。2 回目以降の読み込み時はキャッシュを読み込むことで、処理時間の短縮を図ります。
ウェブブラウザーにおけるキャッシュは一般に、HTML ファイルおよび HTML から読み込まれる外部リソース(スタイルシートファイル、JavaScript ファイル、画像ファイルなど)に対して適用されます。
キャッシュが作られるタイミング
ブラウザーがあるファイルを読み込もうとする時、キャッシュがなければ実ファイルを読み込んだ上でそのファイルの内容をキャッシュします。
キャッシュが破棄されるタイミング
キャッシュがいつ破棄されるのかは完全にブラウザー依存です。異なるファイルのキャッシュが同じ期間だけ存在するかどうかも分かりません。
キャッシュはユーザーがブラウザーの操作で明示的に削除(クリアー)することはできますが、 サーバー側からクライアント(ブラウザー)のキャッシュをクリアーすることはできません。
ウェブアプリケーションのキャッシュ対策
ウェブアプリケーションをアップデートした際、クライアントのキャッシュを無効にするために、以下の手法がよく使われます。
< link rel="stylesheet" type="text/css" href="style.css" > < script type='text/javascript' src='script.js' >< /script > < img src="picture.jpg" alt="" width="640" height="480" >このような外部リソース読み込みについて、ファイル名の後ろにクエリー文字列を追加します。
< link rel="stylesheet" type="text/css" href="style.css?v=2.4.0" > < script type="text/javascript" src="script.js?v=2.4.0" >< /script > < img src="picture.jpg?v=2.4.0" alt="" width="640" height="480" >スクリプトでない静的ファイルにクエリー文字列を付加しても、読み込まれるファイルは同じです。つまり、
style.css
とstyle.css?v=2.4.0
は同じ style.css というファイルを指します。ブラウザーが style.css をキャッシュしている状態で、この行を読み込んだとします。
< link rel="stylesheet" type="text/css" href="style.css?v=2.4.0" >ブラウザーは「
style.css?v=2.4.0
というファイルはキャッシュにない」と判断し、style.css?v=2.4.0 というファイルを読み込みます。結果として、ディスク上の style.css が読み込まれてスタイルシートが更新されます。この HTML をまた読み込んだ時は、「
style.css?v=2.4.0
というファイルはキャッシュ済み」と判断し、ディスク上のファイルではなくキャッシュを利用します。ウェブアプリケーションをバージョン 2.5.0 にアップデートする時には、「
?v=2.4.0
」の部分を「?v=2.5.0
」に書き換えてリリースします。< link rel="stylesheet" type="text/css" href="style.css?v=2.5.0" > < script type="text/javascript" src="script.js?v=2.5.0" >< /script > < img src="picture.jpg?v=2.5.0" alt="" width="640" height="480" >同様の仕組みで、2.4.0 時代のキャッシュがあっても 2.5.0 用に書き換えられたファイルが読み込まれ、キャッシュの問題は起こりません。
この手法は、キャッシュ問題を解決する手段としては一般的に用いられているものです。俗に「キャッシュバスター (cachebuster)」とも呼ばれます。
数日経った日の午後。Y さんが A4 判数ページにもなる「調査報告書」を作成した。問題になっているスタイルシートについて前回リリース分と今回リリース予定分の差分を取り、それぞれの行について「新規」「変更」「削除」の印をつけ、「とりあえず、このクラス指定が効いていないだけなので、HTML 中にインラインスタイル(< div style="..." >)で指定すればよい」と結論づけていた。
報告書には「状況から見て、変更・削除されたスタイル指定は影響が出るらしい。新規に追加した部分については影響がないようだ」とも。私が書いた説明を読んでいないのか、理解できなかったのか。
この報告書を元に、X さんから「この行とこの行にインラインスタイルを指定してください。これで暫定対応とします」と指示が出た。
私は「この修正は何ら根本的な対策になっていないことは理解していますか。『現状で問題になっている箇所』は、この環境でたまたまそうなっているだけの話で、ほかのお客さまの環境では別の画面が崩れるかもしれないのです。それを承知の上で、これを暫定対応としてよいのですね」と X さんに確認。X さんは「はい」とだけ答えたので、黙って作業を完了した。Git のコミットメッセージに「この方法は何の効果もないこと、それでも作業をしてよいのかを X さんに確認の上、作業」と書いてコミットした。
しばらくすると X さんから「うまく表示されています。OK です」と報告があった。
夕方、私が帰ろうとすると、X さんが Y さんに「画面がおかしい」と言っている。横から覗くと、先ほど「暫定対応」とやらを入れた画面で、表示は正常だがボタンを押しても何の反応もない。私は静かに「JavaScript のキャッシュですね」。
聞けば、Y さんは「キャッシュはスタイルシートにだけ効く」と思い込んでいたらしい。やはり先の説明を読んでいないようだ。そして、Y さんの環境ではボタンは有効だったとも。
私は「Y さんの環境では(JavaScript の)古いキャッシュは効いていなかった。X さんのところではキャッシュが効いていた。これが、私が言っている『環境依存』の意味です。昼の暫定対応ではダメなんです。半月前から私が言っているように、すべての外部リソース読み込みにキャッシュバスターをつけないと解決にならないんです」と伝える。
Y さんは観念した様子で、「キャッシュバスターって、一部分にだけ適用することもできますか」と聞く。この人、理解してないなと思いつつ、「はい、できますよ」と返すと、「では、問題の発生している範囲を調査して、問題が起こっているファイルにだけキャッシュバスターを……」。やはり何も分かっていない。
私は繰り返し、ブラウザーのキャッシュは環境依存なのですべての外部リソース読み込みにキャッシュバスターを付加しないと無意味だと説明した上で、こう付け加えた。
「指示されたことだけを黙ってやっていれば、そりゃあそっちのほうがラクですよ。でも、喧嘩をしてでも、場の雰囲気を悪くしてでも自分の意見を主張するのは、技術者としてのちっぽけな良心からです。お願いですから、専門家の言うことを聞いてください。私の意見が信用ならないのでしたら、ほかの技術者に意見を聞いてください」
この数日後、本件の対応を先送りにすることが決まったと X さんから報告があった。
聞けば、リリースを急いでいるのは特定の顧客の要望によるものらしい。その顧客はスタンドアローンバージョンを利用しているので、アップデートの現地作業の際にブラウザーのキャッシュを消してくればいいとのこと。
リリースに間に合わない間に合わないとあれだけ騒いでいたのに。プロジェクト管理がまるでできていない。
そして今日の夕方、この件についてレビューを開きたいとプロジェクトマネージャーの V さんから言われる。レビューって、何をやればいいんだろう。何をすれば気が済むんだろう。Redmine に書いた説明を読んで理解してもらえれば、やるべきことはひとつしかないと分かろうものなのに。
X さんから質問を受ける。「例の件、ほかの方法はないんでしょうか。『こういう方法もあるけれど、工数が掛かるので採用しません』というのがもしあれば話が進めやすいかと」。残念ながらありません、せいぜいファイル名そのものを変更するくらいですが、本質的には同じことですし管理の手間が増大します、と伝えた。
ついでに、X さんに「あの説明を読んで、よく分からない部分があったら教えてください」と尋ねると、実は忙しくて斜め読みしかしていないと白状された。その状態で対応策を一生懸命協議していたのですな。
レビューの席でまた一悶着ありそうだ。どうやったら彼らを納得させられるのだろうか。信用できない技術者に説明してもらったって、信じないんだったら意味がないのにねえ。
相手はバカなんだから バカにはバカと気づかせないように、丁寧に尊敬しながらバカ用に説明しろ メールなんか送っても読むわけないバカなんだから
どこも同じだな、馬鹿が幅をきかせすぎ。元増が気の毒
この案件でB社との縁は切る。そもそも体制がおかしすぎる。 指示する人数の方が多いじゃん。 インラインスタイルでもhtmlにjs直書きでもしてこの案件だけ乗り切ってしまえ。 静的コ...
元増田です。 あと、テスタ共はブラウザのデバッグツール(F12)は使ってないの? 使ってますよ。キャッシュの消し方も知っています。それなのに、私の説明を理解できない、理解し...
お疲れ様。 ってことはhttpについては理解してないんだね。 そんな人材を当該案件にアサインするB社に責任があるな。 まぁ当座のみしのいで上手く逃げて。
PHPならJSもCSSもincludeで1ファイル内に展開しちゃえばいんじゃね?
無知と無理解にプロジェクトが殺されそうだ https://anond.hatelabo.jp/20170706120144 文字数制限に引っかかって下のほうが切れたので、こちらに追記します。 なんでそこまで信用されてないの?...
ああなるほどテスタ共とは利害関係が一致しないんだね。 それじゃテスタ共は自分の責任にならないように必死で立ち回ることしかしないよ。 元増田の人工が減らされないで案件から...
XとZはこれから学習するには年齢的に厳しいけど、仕事だから学んでほしいわ Yは若いから出来そうなのに、典型的な大手出身の無能システム担当臭するな ただ、A社とB社の力関係等が分...
ブラウザキャッシュの問題なんて、 ・お客さんにブラウザのキャッシュをクリアさせる(手順書を作成して送る。) ・ウェブサーバの設定で、キャッシュされないように設定する ・そ...
元増田です。 あと、テスタ共はブラウザのデバッグツール(F12)は使ってないの? 使ってますよ。キャッシュの消し方も知っています。それなのに、私の説明を理解できない、理解し...
「無知と無理解にプロジェクトが殺されそうだ」の元増田です。 みなさんのトラックバックを読みました。やはり「つける薬はない」「うまく逃げおおせるべし」ということですよね…...
Z氏はPLの素養は全くないね。 バグの内容によるけど、ふつうはバグが少なくなることをPG自身に期待するなんて PLとしておかしい。何のためにテスタがいるのか。 品質管理を分業して品...
元増田はほんと出来た人だなぁ。 家の庭で問題なく育つ種子でも北極や砂漠に埋めたら育たないって当たり前なのにな。 実行するのは客PCの環境って前提が非WEB系にはわからん感覚なの...