[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article:eight-web-renewal":3},{"meta":4,"markdown":139},{"type":5,"articleId":6,"slug":6,"title":7,"titleEn":8,"category":9,"summary":10,"publishedAt":11,"image":12,"vocabulary":13,"source":136},"article","eight-web-renewal","Web版Eightのリニューアルと、安全なリリースのための取り組み","Renewing Web Eight and our efforts toward a safe release","software\u002Fcompanies\u002Fsansan","How the Eight team renewed the web version with improved search UX, using Feature Toggles and CSS specificity tricks to manage a large-scale UI overhaul safely.","2026-04-26T00:00:00Z","https:\u002F\u002Fimages.yamiyomi.com\u002Feight-web-renewal.png",[14,19,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132],{"word":15,"reading":16,"meaning":17,"level":18},"障害","しょうがい","failure, incident","N2",{"word":20,"reading":21,"meaning":22,"level":23},"懸念","けねん","concern, worry","N1",{"word":25,"reading":26,"meaning":27,"level":18},"操作性","そうさせい","operability, usability",{"word":29,"reading":30,"meaning":31,"level":18},"機能性","きのうせい","functionality",{"word":33,"reading":34,"meaning":35,"level":23},"刷新","さっしん","overhaul, reform",{"word":37,"reading":38,"meaning":39,"level":18},"連絡先","れんらくさき","contact information",{"word":41,"reading":42,"meaning":43,"level":18},"絞り込み","しぼりこみ","narrowing down, filtering",{"word":45,"reading":46,"meaning":47,"level":18},"任意","にんい","arbitrary, optional",{"word":49,"reading":50,"meaning":51,"level":23},"一括","いっかつ","batch, all at once",{"word":53,"reading":54,"meaning":55,"level":23},"付与","ふよ","assignment, granting",{"word":57,"reading":58,"meaning":59,"level":18},"大規模","だいきぼ","large-scale",{"word":61,"reading":62,"meaning":63,"level":18},"課題","かだい","challenge, issue",{"word":65,"reading":66,"meaning":67,"level":18},"戦略","せんりゃく","strategy",{"word":69,"reading":70,"meaning":71,"level":18},"採用","さいよう","adoption, employment",{"word":73,"reading":74,"meaning":75,"level":18},"並行","へいこう","parallel, concurrent",{"word":77,"reading":78,"meaning":79,"level":18},"依存","いぞん","dependency",{"word":81,"reading":82,"meaning":83,"level":18},"考慮","こうりょ","consideration",{"word":85,"reading":86,"meaning":87,"level":23},"厄介","やっかい","troublesome, burdensome",{"word":89,"reading":90,"meaning":91,"level":18},"実装","じっそう","implementation",{"word":93,"reading":94,"meaning":95,"level":18},"制御","せいぎょ","control",{"word":97,"reading":98,"meaning":99,"level":23},"機密性","きみつせい","confidentiality",{"word":101,"reading":102,"meaning":103,"level":23},"踏襲","とうしゅう","following, inheriting (a practice)",{"word":105,"reading":106,"meaning":107,"level":18},"再利用","さいりよう","reuse",{"word":109,"reading":110,"meaning":111,"level":18},"方針","ほうしん","policy, approach",{"word":113,"reading":114,"meaning":115,"level":23},"詳細度","しょうさいど","specificity (CSS term)",{"word":117,"reading":118,"meaning":119,"level":18},"上書き","うわがき","overwrite",{"word":121,"reading":122,"meaning":123,"level":18},"削除","さくじょ","deletion, removal",{"word":125,"reading":126,"meaning":127,"level":18},"背景色","はいけいしょく","background color",{"word":129,"reading":130,"meaning":131,"level":18},"経由","けいゆ","via, through",{"word":133,"reading":134,"meaning":135,"level":18},"既存","きぞん","existing, pre-existing",{"name":137,"url":138},"Sansan Builders Box","https:\u002F\u002Fbuildersbox.corp-sansan.com\u002Fentry\u002F2024\u002F11\u002F11\u002F110000","\n::para\nこんにちは。Eightでエンジニアをしている[藤野]{ふじの:Fujino (surname):N1}です。さて[今回]{こんかい:this time:N3}は、Web[版]{ばん:version:N2}Eightをリニューアルした[話]{はなし:story:N5}と、リリースにあたって[障害]{しょうがい:failure, incident:N1}[懸念]{けねん:concern:N1}を[減らす]{へらす:to reduce:N2}ために[行った]{おこなった:carried out:N5}アプローチについて[話します]{はなします:to talk about:N5}.\n\n#en\nHello. I'm Fujino, an engineer at Eight. Today I'll talk about how we renewed the web version of Eight, and the approaches we took to reduce failure risks during the release.\n::\n\n::heading\nWeb[版]{ばん:version:N2}Eightリニューアル！\n\n#en\nWeb Eight renewal!\n::\n\n::para\nEightにはWeb[版]{ばん:version:N2}とモバイルのアプリ[版]{ばん:version:N2}がありますが、[今]{いま:now:N5}まではアプリ[版]{ばん:version:N2}を[中心]{ちゅうしん:center:N4}にリニューアルが[進められて]{すすめられて:to be advanced:N3}いきました。そのためWeb[版]{ばん:version:N2}のUIに[関して]{かんして:regarding:N3}は、[検索]{けんさく:search:N1}の[操作性]{そうさせい:operability:N1}や[機能性]{きのうせい:functionality:N3}のアップデートが[遅れ気味]{おくれぎみ:tending to be delayed:N3}でした。\n\n#en\nEight has both a web version and a mobile app, but until now renewals had been driven primarily around the app. As a result, updates to the web UI's search operability and functionality had been falling behind.\n::\n\n::para\n[今回]{こんかい:this time:N3}のリニューアルでは[特に]{とくに:especially:N4}[検索]{けんさく:search:N1}の[操作性]{そうさせい:operability:N1}[向上]{こうじょう:improvement:N3}に[力]{ちから:effort:N4}を[入れて]{いれて:to put in:N5}います。トップページをフィード[画面]{がめん:screen:N3}から[連絡先]{れんらくさき:contacts:N2}[画面]{がめん:screen:N3}に[刷新]{さっしん:overhaul:N2}し、ログインしてすぐに[検索]{けんさく:search:N1}をすることが[可能]{かのう:possible:N3}になりました。また[新たに]{あらたに:newly:N4}[名刺]{めいし:business card:N2}[交換]{こうかん:exchange:N2}[日]{び:date:N5}での[絞り込み]{しぼりこみ:filtering, narrowing down:N1}が[可能]{かのう:possible:N3}になったり、[任意]{にんい:arbitrary:N3}の[条件]{じょうけん:condition:N1}で[検索]{けんさく:search:N1}した[名刺]{めいし:business card:N2}の[情報]{じょうほう:information:N3}に[一括]{いっかつ:batch, all at once:N1}でタグを[付与]{ふよ:to assign:N3}できるようになったりと、アプリ[版]{ばん:version:N2}では[手]{て:hand:N4}が[届きにくい]{とどきにくい:hard to reach:N2}Web[版]{ばん:version:N2}ならではの[操作性]{そうさせい:operability:N1}を[実現]{じつげん:realize:N3}しました。\n\n#en\nThis renewal focused especially on improving search operability. We overhauled the top page from a feed screen to a contacts screen, making it possible to search immediately after logging in. We also added filtering by business card exchange date and batch-tagging of cards matching any search criteria — delivering web-specific operability that the app version struggles to match.\n::\n\n::heading\nリリースに[向けて]{むけて:toward:N3}の[動き]{うごき:movement:N4}\n\n#en\nEfforts toward the release\n::\n\n::heading\nFeature Toggle\n\n#en\nFeature Toggle\n::\n\n::para\n[大規模]{だいきぼ:large-scale:N1}なリリースにおいて、[課題]{かだい:challenge:N2}となるのがブランチ[戦略]{せんりゃく:strategy:N2}です。[特に]{とくに:especially:N4}UI[部分]{ぶぶん:part:N3}が[変わる]{かわる:to change:N3}ような[変更]{へんこう:change:N3}の[場合]{ばあい:case:N3}、[間違って]{まちがって:mistakenly:N3}リリースされてはいけないのでmainブランチにマージするかを[判断]{はんだん:judgment:N3}する[必要]{ひつよう:necessity:N3}が[出て]{でて:to arise:N5}きます。Web[版]{ばん:version:N2}Eightの[開発]{かいはつ:development:N4}チームではブランチ[戦略]{せんりゃく:strategy:N2}にgit flowを[採用]{さいよう:adopt:N2}しているのですが、[複数]{ふくすう:multiple:N2}チームが[並行]{へいこう:parallel:N2}して[開発]{かいはつ:development:N4}するとなった[場合]{ばあい:case:N3}には[大きな]{おおきな:large:N5}featureブランチからブランチを[切って]{きって:to cut:N4}いくことになります。そうなるとブランチ[間]{かん:between:N5}の[依存]{いぞん:dependency:N2}[関係]{かんけい:relation:N3}などを[考慮]{こうりょ:consider:N1}しながら[開発]{かいはつ:development:N4}を[進める]{すすめる:to advance:N3}[必要]{ひつよう:necessity:N3}があるため、[非常に]{ひじょうに:extremely:N3}[厄介]{やっかい:troublesome:N1}です。\n\n#en\nIn a large-scale release, branching strategy becomes a real challenge. Especially when UI changes are involved, you need to decide whether to merge into main since accidental releases must be avoided. The Web Eight dev team uses git flow, but when multiple teams develop in parallel, they end up branching off a large feature branch. That means you have to develop while considering inter-branch dependencies, which is extremely troublesome.\n::\n\n::para\nそこで[打ち手]{うちて:countermeasure:N3}としてFeature Toggleを[実装]{じっそう:implement:N2}しました。Feature Toggleとは、[任意]{にんい:arbitrary:N3}の[環境]{かんきょう:environment:N1}・[任意]{にんい:arbitrary:N3}のユーザにおいてのみ[特定]{とくてい:specific:N3}のフラグ（[状態]{じょうたい:state:N1}）を[持たせる]{もたせる:to make hold:N4}ように[制御]{せいぎょ:control:N3}するものです。ただし、[注意]{ちゅうい:caution:N4}が[必要]{ひつよう:necessary:N3}で[機密性]{きみつせい:confidentiality:N1}の[高い]{たかい:high:N5}リリースには[適さない]{てきさない:not suitable:N3}ということです。なぜならJavaScript[側]{がわ:side:N3}でUIを[切り替える]{きりかえる:to switch:N2}[戦略]{せんりゃく:strategy:N2}は、コードから[内容]{ないよう:content:N3}が[読み取れて]{よみとれて:can be read:N3}しまう[可能性]{かのうせい:possibility:N3}があるからです。しかし、[今回]{こんかい:this time:N3}の[刷新]{さっしん:overhaul:N2}においては[機能]{きのう:function:N3}の[整理]{せいり:reorganization:N1}が[主]{しゅ:main:N4}[目的]{もくてき:purpose:N4}であり、[機密性]{きみつせい:confidentiality:N1}はそれほど[重要]{じゅうよう:important:N3}ではありませんでした。\n\n#en\nSo we implemented Feature Toggle as a countermeasure. A Feature Toggle controls specific flags (states) only for certain environments and certain users. However, be aware that it is not suitable for confidential releases, since a strategy of switching UI on the JavaScript side means the content could potentially be read from the code. But in this renewal, the main purpose was reorganizing features, so confidentiality was not that important.\n::\n\n::heading\nCSSでの[画面]{がめん:screen:N3}[切り替え]{きりかえ:switching:N2}\n\n#en\nSwitching screens with CSS\n::\n\n::para\n[今回]{こんかい:this time:N3}のWeb[版]{ばん:version:N2}の[刷新]{さっしん:overhaul:N2}では、[主に]{おもに:mainly:N4}トップページの[検索]{けんさく:search:N1}[画面]{がめん:screen:N3}に[関して]{かんして:regarding:N3}のみ[手]{て:hand:N4}を[加えて]{くわえて:to add:N3}おり、[他]{ほか:other:N3}の[画面]{がめん:screen:N3}に[関して]{かんして:regarding:N3}はヘッダーや[背景色]{はいけいしょく:background color:N3}をのぞいて[既存]{きぞん:existing:N1}を[踏襲]{とうしゅう:follow, inherit:N1}したものになっています。そのため[既存]{きぞん:existing:N1}のコンポーネントを[再利用]{さいりよう:reuse:N2}して[刷新]{さっしん:overhaul:N2}を[進めて]{すすめて:to advance:N3}いったのですが、Feature Toggleを[使って]{つかって:to use:N4}コンポーネントを[出し分けて]{だしわけて:to show selectively:N5}いく[方針]{ほうしん:approach:N2}にはデメリットがありました。それは、[単に]{たんに:simply:N3}[出し分ける]{だしわける:to show selectively:N5}だけではファイル[数]{すう:number:N3}やコード[量]{りょう:quantity:N2}が[増えて]{ふえて:to increase:N3}いく[一方]{いっぽう:one direction, only:N4}だということです。\n\n#en\nIn this web renewal, we only touched the top page search screen; other screens inherited the existing design aside from headers and background colors. So we reused existing components to drive the overhaul, but the approach of selectively rendering components via Feature Toggle had a drawback: simply switching between old and new would only keep increasing file count and code volume.\n::\n\n::para\nそこで[今回]{こんかい:this time:N3}、body[要素]{ようそ:element:N1}に[対して]{たいして:toward:N3}Feature ToggleがONになっている[場合]{ばあい:case:N3}にのみ[特別]{とくべつ:special:N4}なクラス[名]{めい:name:N5}を[付与]{ふよ:assign:N3}することでCSS[経由]{けいゆ:via:N3}でUIを[変更]{へんこう:change:N3}する[方法]{ほうほう:method:N3}でアプローチしました。このmixinはCSSの[詳細度]{しょうさいど:specificity:N1}を[利用]{りよう:use:N3}することで[既存]{きぞん:existing:N1}のスタイルを[上書き]{うわがき:overwrite:N5}するためのものです。[刷新]{さっしん:overhaul:N2}[後]{ご:after:N5}のリファクタリングでは、mixinの[呼び出し]{よびだし:invocation:N3}[部分]{ぶぶん:part:N3}を[削除]{さくじょ:delete:N1}してmixinの[中身]{なかみ:content:N4}だけを[残す]{のこす:to leave:N3}だけで[済む]{すむ:to suffice:N3}ようにしました。\n\n#en\nSo this time, we approached it by assigning a special class name to the body element only when the Feature Toggle is ON, and changing the UI via CSS. This mixin uses CSS specificity to override existing styles. After the overhaul, refactoring only requires removing the mixin invocations and keeping just their inner content.\n::\n"]