モバイル&ワイヤレスブロードバンドでインターネットへ

gwaw.jp
 
verification / multi-cause

「直った」を、どう測るか
原因が3つ重なると、判定が壊れる

スマートフォンでだけ、ページの右に余白が出る。 それをスマートフォンだけで追いかけた記録です。 直したはずが再発し、また直しては再発する。 原因は3層に重なっていて、しかも1つは確率的に現れました。 直っていないのに直って見える——判定そのものが壊れていたという話です。

切り分け 複数原因 検証設計 モバイル

[ § 0 ] 導入

直したのに、直らない

自分のサイトを手元の端末で見ていて、気づきました。 ページを下へスクロールしていくと、途中から右側に余白ができる。 指を離すと戻ることもあれば、戻らないこともある。

CSS の問題だろうと見当をつけて、思い当たるところを直しました。直りました。 翌日また出ました。別のところを直しました。直りました。また出ました。

これを5回ほど繰り返して、ようやく気づきます。 「直った」という判定が、当てにならない

この記事で扱わないこと

個々の CSS 的な原因と対処は別の3本にまとめました。ここでは技術の中身ではなく、どうやって「直った」を判定するかだけを扱います。

[ § 1 ] 環境

スマートフォンだけで、追いかけた

症状が出るのはスマートフォンです。だから確認もスマートフォンで行いました。 手元にあったのは、この2つだけです。

手段できること
テキストエディタのプレビューコンソールが使える。JS を実行して要素を調べられる
サーバーにアップロードして表示本番と同じ状態を目で見る

いま振り返ると、この構成に決定的な穴がありました。 ただし、その穴に気づくのはかなり後になってからです。

画面幅の問題ではあります。 パソコンでもウィンドウを極端に狭めれば、同じ現象が出たかもしれません。 ただ普段の作業でその幅にすることはなく、 結果としてスマートフォンでしか遭遇しませんでした
[ § 2 ] 道具

測る道具を、自分で間違える

推測で直すのをやめて、計測することにしました。 画面幅を超えている要素を探す短いスクリプトを書き、コンソールで実行します。

最初に書いたもの
document.querySelectorAll('*').forEach(el => {
  const r = el.getBoundingClientRect();
  if (r.right > innerWidth) hits.push(el);
});

3件見つかりました。すべて span です。直しました。 結果は変わりませんでした

誤検出でした。 見つかった span は、横スクロールできる箱の中身でした。 枠からはみ出していますが、それはスクロールして読むためのもので、 ページ幅には影響しません。 祖先にスクロール容器があるかを見ていなかったのが原因です。
直したもの
// 祖先のどこかで横がクリップされていれば、ページ幅には響かない
function contained(el){
  for (let p = el.parentElement; p && p !== document.documentElement; p = p.parentElement)
    if (getComputedStyle(p).overflowX !== 'visible') return true;
  return false;
}

直したスクリプトを実行すると、今度は 0件。 ところが症状は出ています。

0件という結果は、正しかったのです。 要素の寸法を測っている限り、寸法を持たないものは見つかりません。 背景、影、変形——このときの原因は、そのどれかでした。 道具が間違っていた段階と、道具が正しく「無い」と答えていた段階が、 続けて起きていました。
[ § 3 ] 判定

効いたのか、たまたまか

対処を入れては確認する、を繰り返していました。 その判定はこうです——ページを開いて、余白が出なければ直った

これで問題ない、と思っていました。実際、 多くの不具合はこの判定で足ります。原因が1つで、常に同じ結果が出るなら

3層に重なっていた

最終的に分かった原因は、3つありました。

内容現れ方
① CSS の不備縮む余地が無い要素があった常に寄与
② 初回の計算読み込み直後の幅が確定しきらない読み込み直後だけ
③ 空の広告枠配信されなかった枠が幅を持って残る確率的

問題は③です。広告が配信されるかどうかはこちらでは決められません。 3箇所のうち全部埋まることもあれば、1つ空くこともある。 同じページを開いても、毎回条件が違う

だから「直った」に見えた

①を直した状態で開くと、こうなります。

空いた枠はみ出し量見え方
11個52 px出る
20個12 px出ない
30個12 px出ない
41個52 px出る
2回続けて出なければ、人は「直った」と判定します。 そして次に開いたときに再発すると、 「別の原因がある」と考えて、対処を積み増します。 実際にはまだ①しか直っていないのに、 ②や③に見当違いの手当てを重ねていくことになる。

私が5回繰り返したのは、これでした。 効いた対処と、たまたま出なかった回を、区別できていなかったのです。

[ § 4 ] 体感デモ

判定が壊れるところを、見る

3つの原因を個別に「直した」状態にして、 20回ページを開いたときの結果を並べます。 広告の配信率も変えられます。

Interactive · verification simulator
直したつもりで、20回開く
はみ出し量が15pxを超えると目視できる、というモデルです。数値は説明のための概算。
広告の配信率 72%

①だけを直した状態にして、何度か引き直してみてください。 連続して緑が並ぶことがあります。そこで確認をやめれば、「直った」と判定します。 直っていないのに

[ § 5 ] 転機

規則性が、見つかる

転機は、対処を思いつかなくなってから来ました。 ただリロードを繰り返して眺めていたら、広告の出方と症状が対応していることに気づきます。

広告の状態症状
3カ所すべて表示された出ない
2カ所だけ表示(1カ所が空白)出る
3カ所すべて削除した出ない

3つ目が効きました。広告があるから悪いのではない。 全部消しても症状は出ないのですから。 埋まらなかった枠だけが問題でした。

確率的な原因は、条件を固定すると見える。 「毎回違う」ことに困っていたのに、 その「違い」自体を観察対象にしたら答えが出ました。 症状の有無だけを見ていたときは、何も分からなかった。 何と対応して変わるのかを見る——それが判定を成り立たせる条件でした。
[ § 6 ] 環境の穴

見ていたものが、違った

原因が分かってから、§1 の構成に戻ります。 確認手段は2つありました。そのどちらにも、広告が無かったのです。

環境広告症状
エディタのプレビュー配信されない出ない
サーバーにアップロード配信される出る

コンソールが使えるのはプレビューだけ。つまり 計測できる環境には、原因が存在しなかった。 アップロードした先では症状が見えるけれど、そこでは細かく調べられない。

「同じCSSなのに結果が違う」と思っていました。 同じではありませんでした。片方には広告があり、片方には無かった。 その差を確かめずに、両方を同じものとして比べていたのが、 遠回りの一番の原因だったと思います。

ただし、この差は道具になる

逆に使えば、1回で層を切り分けられます。 プレビューで出ず、本番だけで出るなら、 広告のように本番にしか存在しないものを疑う。 両方で出るなら、ページ自体の問題。 環境が2つあることは、弱点ではなく比較の材料でした。
[ § 7 ] 引き算

真因が分かってから、対処を外す

③を潰したあと、それまでに入れた対処を1つずつ検証しました。 もう要らないものが混ざっているはずだからです。

入れた対処判定理由
未配信の広告枠を畳む必須真因
背景の描画範囲を限る必要別の症状に効いていた
要素に縮む余地を与える必要実在した不備
広告枠の高さを予約する必要確定までの揺れを抑える
ページ全体のはみ出しを隠す保険無くても平気だが残す
合成レイヤーへの昇格不要常時メモリを使う
読み込み後の再計算不要毎回走る。①で解決済み

2つ外せました。どちらも入れたときは効いたように見えたものです。

対処を足すのは簡単ですが、外すのは難しい。 効いているように見えるものを消すには、 真因が分かっている必要があります。 分からないまま外せば、再発したときに「外したせいだ」と考えてしまう。 足した対処は、真因が判明するまで外せません。 だから闇雲に積むほど、後が重くなります。
[ § 8 ] まとめ

測れる状態を、先に作る

振り返ると、順序が逆でした。 直し方を考える前に、「直った」をどう判定するかを決めるべきだった。

1回開いて出なければ直った——この判定は、 原因が1つで、結果が毎回同じという前提の上に立っています。 その前提が崩れているのに気づかず、判定だけを使い続けたのが今回でした。

この記事のまとめ

  • 原因が複数あると、部分的な対処が効いたり効かなかったりする。判定が成り立たなくなる。
  • とくに確率的に現れる原因が混ざると、同じ状態でも結果が変わる。
  • 2回続けて出なければ「直った」と判定してしまう。そこで確認をやめるのが危ない
  • 症状の有無だけを見ても分からない。何と対応して変わるかを見ると規則性が出る。
  • 計測の道具も間違える。0件という結果が正しいこともある——寸法を持たない原因なら。
  • 確認環境と本番環境の差を、先に確かめる。同じものを見ている保証は無い
  • その差は比較の材料にもなる。片方だけで出るなら、片方にしか無いものを疑う。
  • 真因が分かったら、途中の対処を外す。効いて見えただけのものが混ざっている。

関連記事

『「直った」を、どう測るか — 原因が3つ重なると、判定が壊れる』を公開しました。