| @WWW

以前、以下の記事でこのウェブサイトへのアクセス元 User Agent について書いた。

そのとき Hatena::Russia::Crawler というのが謎だということを書いた。最近のアクセスログを見ても相変わらずこの User Agent からのアクセスが多い。またアクセス頻度も高く、同一の URL に対して何度もアクセスしている。

これはやはりはてなの名を騙った怪しいクローラーなのではないかと思い調べてみた。

まず Hatena::Russia::Crawler という User Agent からのアクセスの IP アドレスを調べてみたところ以下だった。

cat log/access.log | grep 'useragent:Hatena::Russia::Crawler/0.01' | cut -f2 | sort | uniq -c | sort -nr
    434 remote_addr:52.68.0.227
    419 remote_addr:54.249.85.140
    417 remote_addr:54.92.97.59
    379 remote_addr:54.250.227.185

whois してみると AWS で運用されているものであることがわかるが、はてなのものかは断定できない。

もしこの IP からはてなブックマークやはてなアンテナなどの User Agent でのアクセスもあれば Hatena::Russia::Crawler ははてなのクローラーであると断定できるだろう。ということで調べてみたところこんな感じだった。

zcat -f log/access.log* | grep -E 'remote_addr:(52\.68\.0\.227|54\.249\.85\.140|54\.92\.97\.59|54\.250\.227\.185)' | cut -f13,2 | sort | uniq -c | sort -nr
  16687 remote_addr:54.250.227.185      useragent:Hatena::Russia::Crawler/0.01
  16448 remote_addr:54.92.97.59 useragent:Hatena::Russia::Crawler/0.01
  16370 remote_addr:54.249.85.140       useragent:Hatena::Russia::Crawler/0.01
  16272 remote_addr:52.68.0.227 useragent:Hatena::Russia::Crawler/0.01
     73 remote_addr:54.249.85.140       useragent:HatenaBookmark/4.0 (Hatena::Bookmark; Scissors)
     60 remote_addr:54.250.227.185      useragent:HatenaBookmark/4.0 (Hatena::Bookmark; Scissors)
     56 remote_addr:52.68.0.227 useragent:HatenaBookmark/4.0 (Hatena::Bookmark; Scissors)
     50 remote_addr:54.92.97.59 useragent:HatenaBookmark/4.0 (Hatena::Bookmark; Scissors)
     31 remote_addr:54.92.97.59 useragent:Hatena::Fetcher/0.01 (master) Furl/3.13
     31 remote_addr:54.250.227.185      useragent:Hatena::Fetcher/0.01 (master) Furl/3.13
     31 remote_addr:54.249.85.140       useragent:Hatena::Fetcher/0.01 (master) Furl/3.13
     26 remote_addr:52.68.0.227 useragent:Hatena::Fetcher/0.01 (master) Furl/3.13
     19 remote_addr:54.92.97.59 useragent:Hatena::Scissors/0.01
     19 remote_addr:54.250.227.185      useragent:Hatena::Scissors/0.01
     16 remote_addr:52.68.0.227 useragent:Hatena::Scissors/0.01
      9 remote_addr:54.249.85.140       useragent:Hatena::Scissors/0.01

なんと、 IP アドレスで検索してはてなのその他のクローラーもヒットしてしまった。つまり Hatena::Russia::Crawler ははてなのクローラーということだ。

ただしググっても一切情報が出てこない。 Hatena::Russia::Crawler で検索してトップヒットするのは自分のブログだ。

改めて Hatena::Russia::Crawler による直近 30 日間のアクセス状況を調べてみるとこんな感じだ。

zcat -f log/access.log* | grep 'useragent:Hatena::Russia::Crawler/0.01' | cut -f5 | sort | uniq -c | sort -nr
  15697 request_uri:/index.atom
   9913 request_uri:/2022/04/20/integrate-charts-category-with-select-boxs
   9373 request_uri:/2022/05/04/reputation-and-interpretation
   8422 request_uri:/2022/05/11/fly-to-kamikochi-from-fukuoka
   7716 request_uri:/2022/05/16/using-tantivy-over-tantiny
   5906 request_uri:/2022/04/17/quit-using-hey
   5139 request_uri:/2021/12/29/thoughts-on-manga-subscription
   1308 request_uri:/2021/12/13/keep-a-stack-books-whether-reading-them-or-not
    787 request_uri:/2022/06/23/each-entry-title-should-be-marked-up-with-h1
    741 request_uri:/2021/12/13/keep-stack-books-whether-reading-them-or-not
    456 request_uri:/2022/06/24/if-you-feel-apple-musics-recommendation-is-awful
    100 request_uri:/2022/06/14/thoughts-on-hatena-bookmark
     46 request_uri:/2015/12/07/thoughts-on-rural-life
     46 request_uri:/2015/12/02/thoughts-on-t-on-t
     46 request_uri:/2015/12/02/thoughts-on-christmas-song
     45 request_uri:/2019/12/02/stop-drinking-outside-frequently
     16 request_uri:/2020/11/08/where-i-went-in-2019
     11 request_uri:/2015/12/05/omm-writer-music-is-nice-to-listen-to-while-writing
      5 request_uri:/2022/05/04/the-golden-maintenance-week
      2 request_uri:/2022/06/24/
      2 request_uri:/2022/06/24

index.atom はフィードの URL なので除外するとして、特定の記事に対して数千回もアクセスがある。 30 日間で 9000 回ということは一日あたり 300 回だ。 1 時間あたり 12.5 回である。何のためにこんなに高頻度でクローリングしているのだろうか。

とここまで調べたところほかの Bot 系アクセスはどうなのかと改めて User Agent 毎のアクセス数を調べてみたらこんな感じだった。

zcat -f log/access.log* | cut -f13 | sort | uniq -c | sort -nr | head -10
 124894 useragent:Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)
  65794 useragent:Hatena::Russia::Crawler/0.01
  58274 useragent:Ruby
  31493 useragent:Mozilla/5.0 (iPhone; CPU iPhone OS 15_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Mobile/15E148 Safari/604.1
  29454 useragent:Mozilla/5.0 (compatible; AhrefsBot/7.0; +http://ahrefs.com/robot/)
  21492 useragent:Tiny Tiny RSS/21.11-7cfc30a (https://tt-rss.org/)
  20351 useragent:Slackbot 1.0 (+https://api.slack.com/robots)
  18765 useragent:Mozilla/5.0 (compatible; SemrushBot/7~bl; +http://www.semrush.com/bot.html)
  18395 useragent:Mozilla/5.0 (compatible; MJ12bot/v1.4.8; http://mj12bot.com/)
  17942 useragent:Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)

bingbot からのアクセスの方が Hatena::Russia::Crawler からのアクセスの 2 倍近くあった。ただし bingbot は検索エンジンのクローラーらしく、サイト全体をまんべんなくクローリングするような挙動で、特定の URL に一ヶ月間で数千回アクセスするような感じではない。

zcat -f log/access.log* | grep 'useragent:Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)' | cut -f5 | sort | uniq -c | sort -nr | head -25
    571 request_uri:/robots.txt
    352 request_uri:/
    205 request_uri:/category/misc
    160 request_uri:/2007/01/13/732
    156 request_uri:/2005/10/28/129
    150 request_uri:/2009/03/23/1010
    148 request_uri:/category/music
    146 request_uri:/archives
    144 request_uri:/category/www
    143 request_uri:/2016/07/
    143 request_uri:/2009/08/31/1074
    139 request_uri:/2010/07/05/1140
    138 request_uri:/category/photo
    138 request_uri:/2009/02/
    137 request_uri:/2006/09/09/658
    136 request_uri:/tags/netatmo
    136 request_uri:/2010/07/17/1145
    136 request_uri:/2006/07/23/611
    135 request_uri:/2014/03/
    134 request_uri:/?page=32
    134 request_uri:/2007/02/09/747
    133 request_uri:/category/shopping
    133 request_uri:/2021/07/26/how-to-get-to-kamikochi-from-fukuoka
    133 request_uri:/2011/11/03/finally-got-hhkpro2
    132 request_uri:/2006/01/

Hatena::Russia::Crawler は同一 URL に数千回もアクセスして何をしているのだろう? 謎は深まるばかりだ。

| @WWW

登山道上のケルン

はてなブックマークがユーザーインタビューをするということで、はてブに対する思いをネットに発露している人達が散見された。

自分はコロナ禍になって気がつくとはてなブックマークばかり見ていてヘビーユーザーになっていた(ブックマークはあまりしてなくて見る専)。会社の人との雑談がなくなり、息抜きしたいときにははてブを見る暮らしをしている。

なのでインタビューに応募してみたのだが、どうも落選してしまったみたいなので、はてブについての考えを書いてみることにする。

はてブのバリュープロポジション

まずはじめに、はてブとは何なのか、どんなメリットがあって使っているのかを整理したい。はてブには以下の三つのバリュープロポジション(価値訴求)があると思う。

  • インターネットで何が話題になっているかがわかる
  • ほかの人がコンテンツにどのような評価をしているか確認できる
  • 見かけた情報をあとで参照するために保存しておける

インターネットで何が話題になっているかがわかる

そこを訪れればいま何がインターネットで話題になっているかがわかる。ニュースサイトに張り付いてくまなく記事を読まなくても、はてブを訪れれば話題になっている情報だけを効率的に摂取することができる。

ほかの人がコンテンツにどのような評価をしているか確認できる

SNS ・掲示板サービス的な側面であり、ほかのユーザーと交流することができる。また、ほかの人のコメントによって大まかなコンテンツの概要を把握することもでき、コンテンツの要約機能も提供している。

見かけた情報をあとで参照するために保存しておける

そのまんまブックマークサービス的側面のことだ。当初オンラインブックマークサービスはこの側面をウリにして始まったと思うが、今日、この部分よりも何が話題になっているかの確認や、他の人のコメントを読みたくて利用している人がほとんどだと思う。

はてブの中の人もその辺は認識済みのようで、はてブのウェブサイトを未ログインで訪れるとサインアップを促すダイアログが表示され、「同じページを読んだ人の感想が集まります」とメッセージが記されている。「ブックマークしておいてあとから確認できます」とか「異なるパソコン間でブックマークを共有できます」みたいなことは言ってない。正しいと思う。

はてブ未ログインダイアログ

プラットフォームとしてのはてブ

プラットフォームとしてはてブをとらえたとき、ユーザーはコンテンツ(ブックマークコメント)の生産者と消費者に二分される。コンテンツの最初のブックマーカーになること、面白いコメントを書いてスターを獲得することをモチベーションとし、公開でブックマークするのが生産者で、消費者は生産者がブックマークしたコンテンツや、生産者によるブックマークコメントを読むことを目的にはてブを訪れる。ブックマークコメントが面白ければはてなスターを送る。はてブのような CGM では生産者と消費者はスパッと二分できなくて、あるときには生産者でありあるときには消費者であるというのが特徴だ。書籍『プラットフォーム革命』ではこの生産者と消費者の価値交換のことを「コア取引」と定義している。

はてブ考(コア取引).svg

はてブというプラットフォームを成長させるためには、プラットフォーム内で価値交換の回数を増やすことが超重要だ。

なお、はてブの外にインターネットを置いてみると、はてブというのはコンテンツ消費プラットフォームという側面が見えてくる。はてブ内の生産者も消費者も、インターネット上に存在する様々なコンテンツを閲覧する立場には変わりがない。

はてブ考(プラットフォーム).svg

はてブに集まっている人は、コメントする人もしない人も、インターネット上の情報をみんなで消費しているのだ。

高い生産者率

少し前、インターネット利用者の行動がだんだん見えなくなってきているということについても記事を書いた。

あとの方になってからインターネットを使い始めた人々にとっては、インターネットとは自分から情報を差し出す場ではなく、情報を摂取する場なのだ。買い物をしたり、動画を見たり、音楽を聞いたりしているだけだ。自分でウェブサイトを持ってブログを作ったりしている我々は、今日のインターネットにおいて決してマジョリティではない。

受動的にインターネットを使うだけの人に、 1990 年代の終わりに我々インターネット老人が感じたのと同じような興奮や感動を与えられるのだろうか。多分、発想を転換しないと難しいだろう。我々が面白がったインターネットと彼らが欲しているインターネットは別のものなのだ。ただ受動的に使っているだけでより便利になり、快適になっていくインターネットをどうやって作っていくかが見えないインターネットの時代のテーマになると思う。

スマートフォン全盛時代になってインターネットを使い始めたユーザーは生産者側に回ることが少なく、ひたすらコンテンツを消費しているだけという話だ。

一方ではてブを見ると、ブックマークにコメントが付いている割合(生産者率)が高い。 2022年6月11日のホットエントリーの記事執筆時点でのコメント率を調べてみると以下のような感じだった。

コメント率

中央値 平均 最大 最小
38.1% 38.4% 76.8% 2.5%

この日のホットエントリーの 1/4 以上が 50% 以上のコメント率となっている。この生産者率は CGM サービスとしては高い方だと思う。

生産者率が高い理由とその影響

生産者率が高いのは以下の背景があると考える。

  1. コメントをしやすい設計になっている
    コメントが 100 文字一回だけで投稿の敷居が低く、また他人のコメントを読むコストも小さい。
  2. 安全地帯からコメントできる
    ブックマークされるコンテンツの著者からは直接言い返されることのない安全地帯からコメントすることができる。
  3. 無名ユーザーでも承認欲求を満たしやすい
    フォロワーの多寡に関係なく内容本意で評価されてスターをもらえるため、承認欲求を満たしやすい。例えば Twitter であればたくさんいいねをもらうためにはフォロワーが沢山いるか、拡散力のある人からフォローされていないといけない。はてブではブックマークされるコンテンツが主なので、今日登録したアカウント(お気に入られがゼロ)でもコメントが面白ければ評価される。

コメントをしやすいことと、反論されにくいこと、承認欲求を満たしやすい特性から、ときにはネガティブなコメントが集まる力学が働いてしまっていると考えられる。

ブックマークされるコンテンツ

ブックマークされるコンテンツの変化

はてブにブックマークされるコンテンツにはここ数年変化があったのではないかと思っている。昔は Photoshop や CSS テクニック、 jQuery プラグインの話のほか、 PHP やセキュリティの話題、シリコンバレーのテック界隈事情、ポール・グレアムやアーロン・シュワルツの翻訳などを見かけることが多かったが、ウェブ開発系の話題は減り、増田とニュースサイトの記事、そして Togetter が目立つようになった。

実際のところどうだろうと思って、 5/13 ~ 6/11 の 30 日間の人気エントリーページに掲載されているコンテンツのドメイン別のブックマーク数を、 2022 年から 2007 年まで遡って調べてみた。

2010 年頃までは個人のブログやウェブサイトでもランキング上位に入れていたが、 2011 年頃からまとめサイト系が勢力を伸ばしてきている様子がうかがえる。ただしまとめサイト系も転載問題や2ちゃんねるの規制強化で情報転載元がなくなりすぐに失速している。

2012 年から 2010 年と 2011 年に勢いがあった Photoshop VIP のサイトが下落し始める。 CSS や Photoshop 、 jQuery プラグイン的なアレだ。 2010 年代前半までは本当によく目にしていた。 2014 年に Photoshop VIP はランク外となる。

2010 年代中盤以降は今日と同じような顔ぶれに変わる。 ITmedia や CNET など老舗のネットニュースメディアや Lifehacker 、 GIGAZINE などの翻訳転載系・暇つぶし系ネットメディアは上位に入りづらくなった。かわりに NHK や新聞社が目立つようになる。かつて新聞社はインターネットにちゃんと取り組んでなくて、サイトにニュースはほとんどなく、ニュースはポータルサイトで読むみたいな時代が続いていた。スマートフォン全盛時代を迎えて一般ユーザーがインターネットに増えてきたので、それにあわせてマスコミも考えを変えてきたのだと思う。

なお一位と二位はここ数年はてな匿名ダイアリーと Togetter が確保している。この点については後ほど詳しく述べる。

下がるブックマークされるコンテンツの多様性

総ブックマーク数と総コンテンツ数を見るとこうなっていた。

総ブックマーク数と総コンテンツ数

両者とも右肩上がりで好ましいように見える。 2022 年の総ブックマークが下がっているが、これはタイムラグが存在するためで、この集計後もブックマーク数はじわじわ伸びると思われる。

30 日間でブックマークされるホスト(ドメイン)の数を集計してみるとこうだった。

ホスト数

2014 年頃に 400 ホスト超あったのが 2018 年に 167 ホストまで大きく落ち込み、その後少し回復したが 2017 以前の水準には戻っていない。

なお、 2018 年に総コンテンツ数とホスト数が減っているが、この年の 5 ~ 6 月にはてブはシステムリニューアルをしていたようだ。総コンテンツ数とホスト数が減っているのはその影響だろう。

ブックマーク数が多い上位 10 ホストへのブックマーク数、ブックマークコンテンツ数の集中度合いを調べたものが以下だ。

ブックマークの集中度合い

ブックマーク数もコンテンツ数も年々集中度合いが高まってきている。 2018 年頃に 50% を超えて、いまでは 6 割近くが上位 10 ホストのコンテンツで埋め尽くされている。いつはてブを開いても同じようなサイトの記事ばかり並んでいるなぁと思っていたが、それが印象ではなくデータとして裏付けられた。

また昔の話に戻るが、ホームページを作る人のネタ帳というブログがある。 CSS ネタなどの合間に話題となるような世俗的な記事を挟み、かつては 1000 ブックマーク以上つくような記事を量産していた。最近、ホットエントリーに入っていないなと思ってる方も多いのじゃないかと思う。もうなくなったのかなと思ってサイトを見に行ってみたところまだ存在していて、かつてほどではないにせよいまも記事が投稿されていた。しかしこのサイトの最近のブックマーク数は 100 にも到達していない。一桁のものも目立つ。とはいえ 1000 ブックマーク付いていた頃と比べて内容が変わったようには思えない。

ホームページを作る人のネタ帳の人気エントリー ホームページを作る人のネタ帳の最近のエントリー
ホームページを作る人のネタ帳はかつては 1000 以上ブックマークされる記事を量産していた(画像一枚目)が、最近の記事は少ししかブックマークされていない(画像二枚目)

はてブのユーザー層が変わったから? それだけではないと思う。ブックマークされるコンテンツの集中度合いが高まることによる影響だと考える。

はてブではホットエントリーに入ることでブーストされてさらにブックマーク数が伸びるという現象がある。昔は個人サイト・ブログでもホットエントリー入りが容易だったが、今日ではマスコミのニュース記事がブックマークされるコンテンツとして大勢を占めるようなり、個人サイトがホットエントリー入りしづらくなってきている。ホットエントリー入りしなければ以前と同じようなコンテンツでもブックマーク数が伸びづらくなってくる。

伝統的な経済学は有限な資源をどう配分するかを問題としてきた。資源とは天然資源のことだけではなく、商品一般とかお金のことを指すこともある。しかしインターネットの世界では限界費用がゼロなので、コンテンツ自体は無限に複製できる。有限なのは人間の時間の方だ。なのでユーザーの時間をどのように効率的に配分していくかが重要になってくる。その貴重なユーザーの時間の争奪戦に個人サイトが参入しづらくなってきている。

ユーザー層の変化

ブックマークされるコンテンツが変わったということは、ユーザー層も変わってきているのではないかと考えられる。

上述の通りホットエントリーの総合でウェブデザインや HTML 系の話題を見かけることはなくなった。かつて目立っていたソフトウェアエンジニアやデザイナーの割合は減ってきていると思われる。かわりにオフィス勤務の事務職やフリーランスの非 IT 技術者が増えている印象がある。妄想ユーザー像は以下だ。

高学歴理系男性で IT リテラシーが高く、パソコンを使う仕事をしていて仕事中に自由にインターネットを使える人が多そうだ。

思想的な特徴はリベラル寄り(立憲民主党支持)だ。ただ、ロシアのウクライナ侵攻や立憲民主党の党首交代でちょっと雰囲気が変わった気もする。

資産運用やマンション購入などの記事が定期的に話題になるのでそこそこ経済的にゆとりがある人が多そうだ。ただしめちゃくちゃリッチな人は少ない印象。関東や東海、近畿の大都市で中の上くらいの暮らしをしていて実家は朝日新聞を購読してる、みたいな感じの人が多そうだ。

はてブに寄生するウェブサイト・サービス

Togetter の脅威

2021年どこのサイトが最もはてブのホットエントリに入ったかという記事があって、ここ 3 年のブックマークされたコンテンツ数をドメインごとに集計すると、一位がはてな匿名ダイアリー(増田)で二位が Togetter のようだ。段々増田と Togetter の差が縮まり、2021年は肉薄している。

増田 Togetter
2019 14.2% 13.3%
2020 13.3% 11.3%
2021 12.4% 12.1%

先ほどの表でもここ数年、一位と二位は増田と Togetter だったが、今年は Togetter に逆転されて匿名ダイアリーが二位になってしまった。

Togetter ははてなのエコシステムにとって脅威だ。折角はてブが集めたアテンションを奪っている。個人的に最も問題だと感じるのが Togetter に表示されるエログロマンガや豊胸、手のシミ除去、精力剤、毛生え薬、歯の黄ばみ除去、鼻の毛穴につまった脂除去などのグロテスクで低俗な広告で、はてブを見ていると必然的に Togetter も見ることになり、 Togetter の悪趣味な広告がはてブの UX も悪化させている。一時に比べれば減ったが、5ちゃんねる系のまとめサイトや Twitter まとめブログのようなものは今日も生き残っていて、はてブ経由で獲得したユーザーに対して低俗な広告を表示している。 Togetter とあわせてはてブに寄生する厄介な寄生虫のようなものだと思う。

はてブからまとめサイトなどを除外したホットエントリー一覧ページを作って公開しているサイトなんてのもある。自分のブログへのリファラーとして残っているだけでも以下だ。俗悪コンテンツを削除した上で独自の広告を入れているものもある。

Togetter やこれらのはてブのデータを加工したサイトは、はてブから獲得したアテンションやはてブのコンテンツを無料で利用し、お金(広告収益)に換えている。

はてブの競合

はてブの価値訴求が「インターネットで何が話題になっているかがわかる」と、「ほかの人がコンテンツにどのような評価をしているか確認できる」、「見かけた情報をあとで参照するために保存しておける」であることは最初に述べた。競合に関してはそれぞれの価値ごとにリストアップできる。

「インターネットで何が話題になっているかがわかる」サービスとしての競合

  • Twitter

Twitter の Explorer ははてブにとって驚異だと思う。まだいまはローカライズやパーソナライズが甘い(話題が広すぎる)気がするが、もっとニッチな情報や属性に応じた情報の出し分けが進めばいまはてブを見る専で使っている層にも響くかもしれない。現実問題、一般のインターネットユーザーやテレビ局の人達は Twitter の Explorer 経由でインターネットの動きを把握してそうだ。

「ほかの人がコンテンツにどのような評価をしているか確認できる」サービスとしての競合

  • NewsPicks
    • ニュースに対する識者のコメントを読める
  • Yahoo! ニュース
    • 有象無象のコメントを読める
  • Twitter
    • いろんなユーザーのコメントを読めるがあまりまとまっていない
  • 5ちゃんねる?
    • まともな人はもう使ってなさげ

ニュース記事に他の人がどんな評価をしているか、ニュースの背景に何があるのかを知りたくてはてブを見ることが多い。はてなユーザーのなかにはその分野の識者のような人がいて、ニュースの背景にある事実を解説してくれてたりする。

その識者のコメントを読める部分を強化しているのが NewsPicks だと思う。ちょいと前に以下のような記事を書いた。

人間は見たものをどう評価・解釈するかを他の人と共有したい欲求がありそうだ。また、他の人がどう思っているかを知りたい、それを見てからコンテンツを消費するか決めたいというコンテンツ消費の二軍みたいな人たちもいる。コンテンツが無数に溢れているから、あまり面白くないコンテンツで時間を無駄にしたくないという心理が働くのだろう。

人々は情報を摂取するときに、みんなで情報を咀嚼したいという欲求があるように思う。ラピュタの放送があるときに Twitter で「バルス」と言ったり。みんなでコンテンツを消費する方が楽しいのだ。

また数多くあるコンテンツの中からどれを消費すれば良いかわからない、というのもある。自分が信頼するあの人(はてブのお気に入りユーザー、 NewsPicks の著名人)がコメントしているものを読みたい、という欲求もあるだろう。

はてブはこのような仕組みを作ったパイオニアだとは思うが、 NewsPicks はもっと洗練したやり方でこの手法をコピーしていると思う。

はてブと NewsPicks の比較.svg

はてブにはかつてははてなダイアリー、いまははてなブログや匿名ダイアリーなどがあってブックマークしたくなるコンテンツがあり、そこにブックマークコメントが集まってみんなでコンテンツを消費する循環ができていた。

NewsPicks がその仕組みを真似たのかどうかは知らないが、一般のニュースや識者によるコンテンツと企業経営者などを集めてきてコメントしてもらい、一般のユーザーを集めている。

「見かけた情報をあとで参照するために保存しておける」サービスとしての競合

  • Pocket
  • Instapaper
  • ブラウザーのネイティブブックマーク
    • Safari や Chrome にはリーディングリスト(あとで読む)機能がある

最近はブラウザーにリーディングリスト機能が実装され、クロスデバイスでブックマークを同期するようになってきているのでオンラインブックマークの役割は薄れつつある。またブラウザーのブックマークと違い、オンラインブックマークを繰り返し見ることはないはず。ショートカット的な利用はブラウザー内のブックマークの方が便利だ。

はてブはニュースサービス、コメントサービス(ほかの人の感想・要約確認サービス)としての側面を強化していくのが良いと思う。ブックマーク機能ではブラウザーのネイティブブックマークに勝てないと思う。

はてブのマネタイズ

はてブの課題は、折角集めたアテンションを Togetter などの寄生するサービスに奪われてマネタイズの機会を逃していることだ思う。ユーザーは俗悪・低劣な低俗広告を見せられ、儲かるのは寄生サービスだけだ。はてなもユーザーも損をしている。折角はてブで獲得したアテンションを外部の人達にマネタイズされないようにしないともったいない。

UA で外部サイトからブロックされてしまう危険も伴うが、有料プランを作って有料プラン加入者には AdBlock サービスを提供したり、 Reader モードでの閲覧を可能にすると良いだろう1。 Twitter Blue のようなサービスだ。 Togetter などに表示される手のシミ、インプラント、増毛、豊胸、エログロマンガなどの低俗広告を見なくて済むようになるのであれば自分は加入したい。

はてブの中でもっとも価値があると思われるホットエントリーの情報をぶっこ抜いて自サイトの広告に置き換えて流用するサイト、サービスも問題だ。 Twitter が外部クライアントの API 利用を制限してきたことは問題視されてきた。一インターネットユーザーとしては Tweetbot など好きな Twitter クライアントで Twitter を利用したいが、 Twitter 自体のマネタイズを考慮すると、(広告を入れるために)あのような API 利用制限は仕方がなかったと思う。はてブでも何らかの近しいことをして、ホットエントリーなどの貴重な情報を簡単に他者が利用できるような状況は是正しなければならないと思う。もし使いたい第三者がいるならば、登録制にしてきちんと対価を得るべきだ。

いまはもうなくなってしまったはてブの有料プラン、はてなブックマークプラスの機能を見ると、想定するターゲットユーザーがはてブのアクティブなユーザー(プラットフォームの生産者的な側面が強い人達)を対象にしていたように思う。例えばタグの一括編集とか。そんなのにお金を払いたい人は多くはないだろう。

Autify CEO の近澤さんのブログに書かれているみたいに、顧客の Burning needs をつかみに行くことが大切だ。

はてブの大多数の物静かなユーザーは何を求めているのだろうか。

はてブの未来

この記事を書いていてはてブを作った伊藤直也さんのブログ(元ははてなダイアリー)を読んだ。

直也さんは HBFav を作ったときの記事(「はてブよりソーシャルゲームじゃなかったのかセニョール」)で、今後人々は知っている人経由でニュースを読むようになるというマーク・ザッカーバーグの発言を引用している。

また以下の記事で、他人との関係性がコンテンツ価値に影響を与える( t_wada さんの食に関するツイートは無価値的な話)とも書いている。

これまでは確かにそうだったかもしれないが、今後は違うのではないかと思っている。上の方で述べたブックマークされるコンテンツの集中度合いが高まってきていることからも明らかだが、より普通の人がインターネットに増えてきていることが関係している。普通の人は SNS で気が合いそうな人を見つけてフォローしたりしない。 Instagram で誰かフォローするにしてもセレブや有名人ばかりという人は多いんじゃないだろうか。

ソーシャルなつながりによって閲覧するコンテンツを探したいと思っているのは我々インターネット老人だけなのではないかと思う。デジタルの世の中では時間が最も希少価値が高いものだと書いた。そういう時代にあって人々が求めるのは外さないコンテンツだろうと思う。ど定番の巨人・大鵬・卵焼き的なコンテンツか、その人の趣味嗜好を反映し高度にパーソナライズされたコンテンツだろう。

その上で、これからのはてブが提供できる価値は他者と共同でコンテンツを消費する部分にあるのではないかと思っている。

  • みんなと一緒に一つのコンテンツを消費することで理解を深める
  • より深くコンテンツを楽しめる
  • ソーシャルリーディング

跋文

最後に、今回のユーザーインタビューの募り方に関しては疑問がある。公式ブログでインタビュー候補者を募るとはてブ愛が強い層が応募してきてインタビュー結果に偏りが出ると思う。

日頃のはてなブックマーク開発ブログの文面からも、はてブ開発チームの皆さんが既存ユーザーを大切にしていることが伝わってくる。もちろん既存ユーザーを大切にすることは大事なのだが、はてブはインターネットが大好きなインターネットおじさんをターゲットにしているだけでは伸び代が限られると思う。

スマートフォンが普及してからインターネットを使うようになった層ははてブを通り越して NewsPicks やスマートニュースなんかを使っていそうだ。そういうライトユーザーをどう引き寄せるかがはてブの今後の成長の鍵になると思う。インターネット老人はいずれ死ぬし数も限られている。

難しいかもしれないが、はてブに登録してすぐ使わなくなった離脱ユーザーとか、そういうおとなしいユーザーを見つけてきてインタビューする方が有益なインサイトが得られると思う。少なくともインタビュー相手は応募してくるのを待つのではなく、利用状況を分析してはてブ側が話を聞きたい相手をリクルーティングしていくやり方の方がよいと思う(もし見えないところでそういうことをされてたらすみません 🙇🏻‍♂️ )。

インターネットはこのまま放っておくと我々インターネット老人がインターネットを始めた 1990 年代末期とは異なる世界になっていくと思う。自分には進化しているようで退化しているように感じられる。そのうち別に記事を書こうと思っているが、 RSS が使われなくなったかわりにメールマガジン(ニュースレター)が流行るとか、トラックバックがなくなって、誰かのブログに言及してブログを書いたときには SNS で知らせる必要があるとか、文章で読めば 1, 2 分で済む内容がわざわざ動画化されていて 10 分強じっと動画を見なければならないとか、昔のインターネットの方が進んでいた、というような状況はいくつかある。我々が失ったウェブ的な話だ。

はてブとはてなにはインターネットの先進性をキープしつつも、 2020 年代の人々のニーズにマッチする機能を提供していって欲しい


  1. ただしはてな自体が広告モデルのビジネスをやっているので蛸が自分の足を食べるみたいな状況になってしまう懸念はある 

| @ブログ

インデックスページをいじって各カテゴリーの最新記事 4 件を配置するようにしてみた。最近の個人サイト復興ブームでみなさんインデックスページを工夫されているのを見ていて真似したくなってやった。

カテゴリーごとに最新記事 4 件を表示

昔ながらのブログだとインデックスページというのは最新の記事 10 件くらいが表示されていて、「次へ」を押すと古い記事が出てくるという構成になっている。以前のこのブログもそうだった。

しかし自分自身が他人のブログで「次へ」を押して次々に記事を読んでいくということをやった記憶がほとんどない。自分のブログでだって何か目的があって特定のキーワードで検索したあとに引っかかった記事を読むという感じなので、時系列に本文とセットで記事が 10 件ずつ表示される UI というのは意味をなしていないと思った。そもそもインデックスという名称なのに最近の記事数件しか表示していないのはおかしい。インデックスというからにはすべての記事の目次になるべきだ。

このブログはカテゴリーがあるので、サイトマップを作るとするとこんな感じになると思う。

+----------+        +------------+        +-----------+
|          |        |            |        |           |
|   Blog   +---+--->+  Category  +------->+   Entry   |
|          |   |    |            |        |           |
+----------+   |    +------------+        +-----------+
               |
               |
               |    +------------+        +-----------+
               |    |            |        |           |
               +--->+  Category  +---+--->+   Entry   |
                    |            |   |    |           |
                    +------------+   |    +-----------+
                                     |
                                     |
                                     |    +-----------+
                                     |    |           |
                                     +--->+   Entry   |
                                     |    |           |
                                     |    +-----------+
                                     |
                                     |
                                     |    +-----------+
                                     |    |           |
                                     +--->+   Entry   |
                                          |           |
                                          +-----------+

第一階層がインデックスページで、第二階層がカテゴリートップ、そして各記事がある。なのでインデックスページは二階層目の一覧ページになっているのが望ましいはずだ。しかし伝統的なブログはカテゴリーという記事をまとめる概念がありつつも、インデックスページから各記事ページへ直接遷移するのが主な導線だった。常に最新の記事が時系列順に並んでいるだけでは味気ないし、常連の読者ではないコンテキストを知らない訪問者には不親切だろう。

しかも SNS の隆盛で個人のブログのインデックスページが参照される機会というのはとんとなくなってしまった。個人が書いたブログ記事は SNS 経由で読まれ、個別記事だけが読まれる。インデックスページやトップページが読まれることはほとんどない。 SNS でシェアされている URL をクリックして個別記事を読んで、それ以上そのブログのほかの記事を読むことなく離脱してしまう。前後のコンテキストは無視して、一つのコンテンツだけがつまみ食いされてしまう。そんな流れにあらがいたいと思った。

これまで関連記事を記事下に表示するなどやってきたが、気に入っていくつか記事を読んで「ホーム」( = インデックスページ)を訪れたユーザーがもう少しブログを深掘りしてみたくなるようにインデックスページを各カテゴリーの最新記事一覧とするようにしてみた。このブログは現在カテゴリーが 13 個あるので、それぞれから 4 件ずつ記事を取得すると 52 記事になる。全カテゴリーからまんべんなく 4 記事ずつ取得して表示するのは簡単なようで結構難しい。普通の SQL ではできない。 OR マッパーではまず無理だろう。

いろいろ調べてみた結果、 MySQL では GROUP_CONCAT というのが使えそうだった。以下のような SQL を書いた。

select entries.id
from entries
inner join (
  select
    category_id,
    GROUP_CONCAT(id order by created_at desc) as entry_ids,
    max(created_at) as last_created_at
  from entries
  where entries.draft = false
  group by category_id
) as grouped_entries
on grouped_entries.category_id = entries.category_id
and FIND_IN_SET(id, entry_ids) between 1 and 4
order by last_created_at desc, entries.id desc;

GROUP_CONCATFIND_IN_SET という関数を組み合わせることで、各カテゴリーから作成日の降順に記事を 4 件ずつ取得できた。このクエリでは記事 id のみ取得して、もう一回 DB に記事を取得するクエリを ActiveRecord で投げる。 ActiveRecord でクエリを組み立てるときは N+1 が起こらないように関連テーブルを JOIN する。

query = <<~SQL
  select entries.id
  from entries
  inner join (
    select
      category_id,
      group_concat(id order by created_at desc) as entry_ids,
      max(created_at) as last_created_at
    from entries
    where entries.draft = false
    group by category_id
  ) as grouped_entries
    on grouped_entries.category_id = entries.category_id
    and find_in_set(id, entry_ids) between 1 and 4
  inner join categories on categories.id = entries.category_id
  order by last_created_at desc, entries.id desc;
SQL
entry_ids = ActiveRecord::Base.connection.select_all(query).rows.flatten
entries = Entry.includes(:category, :user, :tags, :comments).where(id: entry_ids)

PostgreSQL のときに最初に取得した entry_ids の並び順通りに結果が受け取れるかは怪しいが、 MySQL の場合は一回目のクエリで取得した id 順に各レコードが ActiveRecord のクエリ結果として取得できた。あとはこれをカテゴリーごとにグルーピングして View でよろしくやれば良い。

なお各カテゴリーはカテゴリー内の最新の記事の作成日で降順ソートするようにしている。例えば現在のインデックスページの最下部には音楽カテゴリーがあるが、これは音楽についての記事を最後に書いたのが一年以上前だからだ。もしいま音楽の記事を書けば音楽カテゴリーがトップに浮上するようになっている。

見た目に関しては各カテゴリーの記事最新一件は大きなサイズで表示している。最も最近書かれた記事なのでより多く人の目に付いた方がよいだろうという考えだ。またすべての記事にサムネイルというか、アイキャッチ画像を表示するようにした。画像がない記事に関してはデフォルトのサイトアイコン画像を表示するようにしている。やっぱり視覚的に情報を捉えられるのは重要だ。画像がごちゃごちゃ表示されるのを嫌う人もいるかもしれないが、テキストだけでは人間の認知というのはどうしても追いつかない。

あわせて今回、インデックスページの冒頭部にこのサイトについての説明文を載せることにした。ながしまきょうさんr7kamura さんがやっているののパクりだ。伝統的なブログのインデックスページは初めて訪れた人のことを無視しすぎていたと思う。そのブログ自体について説明するページがあるブログは少ない。最初の記事でブログを始めた経緯みたいなことが書かれたきり、そのブログは何なのか、誰が書いているのかが書かれることは希だ。きちんとブログについての説明ページと著者についての説明ページがあっても、左右のサイドバーやトップのナビゲーションの端っこに押し込まれて見られることはない。これではいけないだろう。というわけでインデックスページの一番目立つ位置にブログと自分自身の簡単な紹介を入れた。

インデックスページトップに紹介文を表示

ブログはなぜ衰退したかを考えてみると、 Facebook や Twitter の隆盛はあるにせよ、ブログ自体に初めて訪れた人に読まれるための工夫が欠けていたのだと思う。誰も自分のブログの継続率を計測したりコホート分析したりはしない。読者が前後の記事を読んでいることを前提に書かれた記事やサイト構成では初めて訪れた人はどうやっても離脱してしまう。特に書き手が芸能人でもない一般人の場合はなおさらだ。誰も RSS フィードを購読していないし、ほとんどの読者は初めて訪れる人なのだから、そういう人たちが読んでブログのテーマや著者の人となりが分かる構成にしていかなければならないのだと思う。でないと SNS でたまにバズったときだけ読んでもらえる、ソーシャルメディアの肥やしにしかならない。

この新しいインデックスページが正解なのかどうかは分からないが、ブログ衰退の流れにあらがっていきたい。

| @ブログ

blog.8-p.info の過去記事ページの真似をして、 Archive ページにタグを表示するようにしてみた。

Archive ページにタグを表示

タグはあまり使っていなかったのだけど、一覧で記事タイトルだけ並んだときその記事にどんな内容が書いてあるのかを把握するためにはタグが便利だなと思い直し、タグを表示させてみることにした。いくつか過去のタグが付いていない記事にタグを振ってもみた。

このブログは技術情報からポエム、日々の日記まで何でもありのごった煮ブログなので、カテゴリーによる情報分類には限界がある。現在 13 個のカテゴリーがあるが、記事数にバラツキがあり、情報分類としてあまり機能していない。カテゴリーの粒度をもっと荒くして緩い分類に変更し、そこから先はタグによって超細かくラベリングすると情報の分類としてはまともになるのではないかと思った。

いま、カテゴリーの内訳がこんな感じ。

- "雑談":303
- "技術/プログラミング":272
- "映画/ドラマ/テレビ":150
- "Mac/iPhone":134
- "WWW":113
- "散財":95
- "旅行/ハイキング":70
- "ブログ":69
- "音楽":63
- "読書":34
- "写真":32
- "料理/食事":31
- "労働":27

もっと緩い分類にして以下みたいな感じにするとよさそう。

- 雑記
- パソコン・インターネット
- 見た・読んだ・聞いた
- 出かけた・撮った・食べた

カテゴリーとタグの使い分けは 10 年以上前から悩んでいる気がする。

情報分類の手法でありつつコンテンツの内容そのものを指し示すものでもあるからだろう。インスタグラムで #ラーメン #からの #うどん とかやってる投稿を見るととても嫌な気持ちになるのだけど、そういうことがされるくらいにタグというものは不安定なもので、正しく使おうとか気負わず、もっと緩く使えばいいのかもしれない。

もう廃れてしまったが、フォークソノミーが勢いを取り戻して、情報の発信者ではなく受け取り側がコンテンツにタグ付けできるような世の中になるとおもしろいのかもしれない。

| @労働

DHH が Twitter で言及していた記事がおもしろかったので著者の許諾をもらった上で翻訳しました。

Salesforce の Product Manager 、 Blair Reeves さんの記事。


僕は自分のテクノロジー業界でのキャリアのすべての期間をリモートワーク擁護者として過ごしてきた。それは自分自身のリモートワークの経験から始まった(ありがとう IBM !)。以前も書いたことがあるが、リモートワークというものは破壊的なテクノロジーでその優位は揺るぎない。このことは自明なのでここでは労力を割かない。

今週、 Facebook が一部の従業員に対して好きなところに住んでリモートワークすることを認めた(訳注: Zuckerberg says employees moving out of Silicon Valley may face pay cuts )ことで、これまでたびたび論争になっていたリモートワーカーへの報酬についての議論が再燃した。この問題は究極的にはリモートワーカーにいかに "公平に" 支払うか、ということだ。このことが報酬についての議論を難しくしている。たくさんの会社がこの件に悪戦苦闘しているが、それはよこしまな理由からではない。

とはいえ、正しい議論と間違った議論があると思う。現実主義によって多少脚色されている。

現実的な観点では、テック部門の人件費をサンフランシスコやニューヨーク以外のレートに切り詰めるということだ。たとえば Facebook の Product Marketing Manager の初任給から 20% 削減された金額だとしても、ウィンストン・セーレムやジャクソンビル、リトル・ロック、ブルーミントン(訳注: すべてアメリカの地方都市)に住んでる人には魅力的に思えるだろう。多くの雇い主が給与額で競争するような状況が我々にとっては望ましい。機会が増えることは常に望ましい。だからどんどんやって欲しい。

上記を踏まえた上で主張するが、生活コストに応じた給与額の調整はとても不公平だしよくない習慣だと思う。同じ仕事をして同じ価値を発揮している人には同じ給料を支払うべきだ。

何が変わったか

最近までフルリモートで働くことは多くの人にとって選択肢になかった。もし X 社で働きたいと思ったなら、 X 社のオフィスがある大都市に引っ越す必要があった。それが取引だった。

しかしこれまで自分が働いてきたソフトウェア企業では、ほとんどの人の仕事はオンラインかつリモートでこなすことが可能だったし、実際にそうしていた。そう、すべてだ。プロダクトマネジメント、エンジニアリング、デザイン、オペレーション、マーケティングなどなど。リモートワークに懐疑的な人でさえ心の底ではこのことはわかっている。そしていま、(訳注: コロナウイルスの影響でリモートワークをするようになり)長い間信じられてきたリモートワークの優位性が実際に証明されてしまった。リモートワークで問題ないのだ。リモートワーク懐疑主義者達が間違っていたことが完全に証明された。

言い換えれば、従業員を大都市圏に住まわせることのビジネス面での合理性は崩壊したということだ。多くの人がニューヨークのような大都市に住みたいと思っているが、大都市に住むことは会社の成功にとって重要ではないし実際には無関係だ。ソースコードの善し悪しにどこで書かれたかは関係ない。ユーザーストーリーも、デザインモックアップも、販促資料もだ。テンペ(訳注: アリゾナ州の人口 16 万人の都市)でできることはメンロパーク(訳注: Facebook の本社があるシリコンバレーの都市)でもできる。

(ここはインターネットなのであら探しが好きな人もいるから捕捉しておくと、確かにある種の人たちは実際にビジネス上の理由で特定のエリアに住む必要があるだろう。具体的には顧客対応が必要な仕事、営業やカスタマーサクセスだ。これらの職種は希な例外としておく)

生活コストベースの報酬の理論的根拠が生活費が高い大都市に住む従業員への配慮なのだとしたら、もし雇用者が大都市の労働者を好まなくなったとしたらどうなるだろう? 違う言い方をしてみよう。「なぜ生活費が安い場所に住んでる連中が必要以上のお金を欲しがるんだ?」という問いをひっくり返すと「なぜ会社はサンフランシスコに住んでる連中が必要なんだっけ?」になる。

生活費が高い/安い場所で、労働者がゆとりのある生活を送るために必要な報酬はいくらだろう、というのはよく議論の的になる。ただ、こういう問いの立て方は問題に対する間違ったアプローチで、どのくらいの生活費がかかる場所に住むかというのは完全に個人の問題だ。もしサンフランシスコに住んでる人が自分の収入の大半をサンフランシスコに住むために使いたいとしたら、それは結構なことだし、その人自身の選択だ。一方でもしサンマテオ(訳注: シリコンバレーの街。 YouTube の創業地)でリモートワークをしている(あるいはオフィスで働いている)人が、 リトル・ロック(訳注: アーカンソー州の人口 18 万人の街)に住んでいる同僚と全く同じ働きをしているとして、どうして一方は給料を優遇されてもう一方は減額されないといけないのだろうか? もしリトル・ロックの従業員には子どもがいて年老いた親の面倒も見ていたとしたら? 一方でサンマテオの従業員は独身で単身者だったとしたら? 必要な額を考慮するとき、こういった個人の家庭の事情は考慮されないのはどうしてだろう? つまり、生活コストによる給与の調整は、従業員はこういう風にお金を使うべきという本質的に不適切な思い込みに基づいて行われている訳だ。生活費の高い大都市に住むことは価値のある選択で、そうでない選択は価値がないと言っているに等しい。

例えば GitLab はこんな風に公言している。

もしみんなが標準的な給料を受け取ったら、所得の高いエリアに住んでる人たちは所得の低いエリアに住んでいる人たちに比べて可処分所得が少なくなってしまう。

えーっと、はい。これがポイントだ。

住む場所の選択によって発生する生活コストの違いは不可避的に、誰かにとっては補助金的なものであり、誰かにとってはペナルティのようなものなのだ。多くの人が住みたがる、生活コストの高い大都市に住む人に対して企業が高い給料を払う義理はないのだ。どこに住むかというのは、これまでもこれからも消費選択の問題に過ぎない。その選択の問題が今日、よりくっきりと明らかになったのだ。

インターネット全体で労働力の供給と需要が行われる

生活コストを報酬の決定に加味する件に関してよく言われることの一つに、労働力の需要と供給の問題がある。すなわち、市場メカニズムが地域ごとに異なる給与額を規定するので、企業はその地方の基準に従って支払うしかないのだと。 GitLab のような、完全にリモートで従業員を採用している会社がよくとるアプローチだ。彼らは報酬調整の式を公開している

この方法の問題点は、 "労働力供給" の定義だ。オフィスへの出社を求める企業にとって、潜在的な労働力というのは会社の半径 20 マイルに住んでいる人々のことだ。しかしリモート企業では、 "インターネット全体" が潜在的な労働力だ。(もっと実務的な言い方をすると、裁判所の管轄権の及ぶ居住者全体だ。あとで詳しく述べる。)これらの観点から、フォート・ウェイン(訳注: インディアナ州の人口 25 万人の街)に住んでいる労働者にとって、彼女の住んでいる街には "競争相手" がいない(企業側からしても、労働者側からしても)。メンフィスやスポーケン、シュリーブポートあたりの人だってそうだ。企業が市場経済の仕組みによって給料を減額調整しようとするのは、本当のところ仕事ぶりとは無関係に懲罰的に給料を下げようとしているということと同じなのだ。ある従業員の地理的選好によって補助金を出すのは、組織としてビジネス的に意味のないひいきをしていると表明しているのと同じだ。

ある人はこのモデルを "底辺への競争" (訳注: 規制緩和でかえって経済全体が貧しくなること。底辺への競争 - Wikipedia)と見るだろう。僕は違う。機会の拡大だと捉えている。もしどこか別の場所により少ない給料で与えられた仕事を完璧にこなす人がいたとしたら、その人に仕事をしてもらうのが合理的だ。これは Menlo Park で働き一年で 50 万ドルを稼ぎ出す Facebook のエンジニアにとって驚異だろう。ほとんどのリモート企業が希少な才能を必要としていることを考えると、バンガー(訳注: メーン州の街)やリノ(訳注: ネバダ州の街)で仕事をしている人にとっては、幾ばくか値切られたとしてもリモートワークの報酬は充分によい、中の上レベルの給与になるだろう。

ではここで質問だ。このやり方はどこまで認められるだろう?

慎重な反論を紹介しよう。論理的に考えれば、世の中のテック系の仕事がすべてリモートワークへ移行すると、アメリカ中から条件のよい仕事はなくなってしまって、すべて外国に奪われてしまうだろう。結局のところ、ハイデラバード(訳注: インドの大都市)やキエフ(訳注: ウクライナの首都)、ラゴス(訳注: ナイジェリアの旧首都)に住んでる連中も充分に賢くて、アメリカのテック企業で必要とされる水準の働きをするだろう。文字通り 1990 年代にはソフトウェア産業でエンジニアリングの領域はオフショアの波に呑まれてしまうだろうと言われていた( 90 年代後半にはマジで大問題だと認識されていた)。しかしそうはならなかったどころか、アメリカ国内のエンジニアや頭脳労働者の求人は拡大する一方だ。恐らくこの傾向は続くだろう。主にアメリカで使われることを想定したプロダクトを作っている会社はアメリカ人の労働者を重要視する。リモートでの雇用は国境ほどには州境を気にしない。精々法規制や税金のことくらいだ。

(政策決定の観点からすると、アメリカのリーダーたちは、高給の仕事を大規模にオフショアすることを規制すべきだ。代替案のないグローバリゼーションがいかにアメリカの労働者階級の雇用を悪化させたかという興味深い議論がある。しかしこの議論は別の投稿で行うとしよう。いまは企業レベルの話をしている。)

報酬の話になると、多くのアメリカ人がバンガロール(訳注: インドの IT 産業の中心地)に住んでいる Puja やイズミル(訳注: トルコの大都市)に住んでいる Mustafa に、パロアルト(訳注: シリコンバレーの街。スタンフォード大学やヒューレット・パッカードがある)に住んでいるプロダクトデザイナーと同額の給料を払うのは不合理だと言うだろう。僕はこういうのは自己中心的だと思うし、 Puja や Mustafa も同意しないだろう。彼らが確実に同じ価値を会社に対して提供しているのなら、同じ額の給料を支払うのが正しいはずだ。もし Puja と Mustafa が王様や女王様のような暮らしをしたとしても気にする必要はない。それでいいじゃないか。ひどく安い給料でオフショアの人々を雇うのは、本人の意思で決めることができない生まれた場所に基づいて労働者にペナルティを与えているようなもので、自分の意思で住む場所を決めた人に対して給料の調整を行うのよりももっと正当化できない。

人件費が高くなりすぎやしないかって? さぁ、どうだろう。確かに人件費は高くなるだろう。しかし例えば GitLab は 5 億ドルも VC から調達している。従業員に公平に支払う余裕はあるはずだ。じゃあ Microsoft や IBM のような、何千人も雇っていて物価の安い国ではアメリカでの給料よりも低い給料で従業員を雇用している会社はどうだろう? 僕には答えがわからない。ただ、正しいことは常に正しい。人は国籍によらず平等に給料を支払われるべきだ。バンガロールで雇われてる人がアメリカ人よりも給料が少なかったとしても、バンガロールの標準的な給料に比べたらずっといいじゃないか、という現実主義的な反論があるのはわかってる。審判を下せる問いではない。でもこれって公平かな? いや、まったく公平じゃない。

Day one

企業が従業員に特定の場所に居住してもらう必要がある場合には、その土地に応じた給料を支払うことが正当化できる。でもそうでない場合には — 多くのソフトウェア開発の仕事が当てはまる — 労働市場ってのはかつてなく広がっていて深さもある。

この数ヶ月、もしくは数年でこの激震の勝者と敗者がはっきりするだろう。どういう結末になるかは誰にもわからない。しかし給料の良いテック企業で働くには西海岸か東海岸に住まなければならないという制約は崩壊し、我々の社会と産業は随分よくなるだろう。リモートワークは会社にとってもチームにとってもよい。従業員にとっても、その家族やコミュニティーにとってもよい。みんながリモートワークを好きになれるわけじゃないが、オフィスで働くのだってそうだ。(リモートがよいかオフィスがよいかについて、これまで個人の好みが問題になったことはないはずだ)

リモートワークは津波のように我々の上にのしかかったわけではない。近い将来に関していうと、いくつかの企業はリモートワークを躊躇し続けるだろう。僕はコロナ禍がリモートワークを推し進めるだろうと楽観しているが、油断はできない。僕の考えは間違っているかもしれないが、大躍進ではなくとも小さな一歩を踏み出すことになるだろう。ところで確信していることもある。僕がシリコンバレーで長期の商業ビルの賃貸契約をすることは決してないだろう。


リモートワークをしていて、地方に住んでいるからという理由で給料を少なくされたらやっぱりいい気もちはしない。同じ仕事をしているのに、自分だけコンビニの 100 円コーヒーで我慢しないといけなくて、同僚はスターバックスのコーヒーを飲んでる、という状況を想像してみて欲しい(自分にはそういう経験がある)。会社の中で所得の格差がありすぎると、ただでさえリモートワークでは同僚と雑談する機会が少なくて打ち解けにくいのに、より一層個人個人の間に壁を作ってしまって会社やチームになじむことができないと思う。日本国内では居住地による所得格差はアメリカほどには大きくないかもしれないが、コロナウイルスの影響でリモートワークが普及するにつれ、同じような問題に直面するケースが出てくるかもしれない。そのとき、リモートワーカーは決して安い給料に甘んじてはいけないと思う。

| @ブログ

75 件ほどあった tech.portalshit.net の記事を取り込んだ。実家に住んでいた 10 年前に始めた技術ブログで、最初は Rails 製の Mephisto 、その次に Jekyll で構築した。まだ GitHub Pages の仕組みが存在する前で、自前で用意したさくら VPS に git push すると自動でビルドして記事が公開されるような仕組みを作ったりしてた。

職業プログラマーになろうとしてもがいてた頃にやってたブログで、いま読み返すと「頑張ってたんだな」感があっていなたい記事が多い。

だいぶ放置していて、いまは S3 で静的サイトとして公開していたのでそのまま放置でもよかったが、 10 年前と違って何でも一カ所にまとめて書いておきたいという気持ちが強くなって取り込むことにした。ブログはトピックを混ぜずに一つのトピックにフォーカスした方がよいと 10 年前は考えていたのだけど、最近の世の中のブログ記事の読まれ方は変わってきていて、一人の人のブログをフィードリーダーに登録して読むというより、 SNS をだら見していて流れてきた記事を適当に消費するというスタイルに変わってきているので、一つのブログに一つのテーマという書き分けは不要になったと感じる。

tech.portalshit.net を取り込んだおかげで Archive ページのグラフに占める技術記事の割合が増えた。

Tech category Bar extension

ちなみに取り込みは以下のようなコードを書いて SQL の INSERT 文に変換した。

require 'yaml'
require 'pathname'

files = Dir.glob(File.join(__dir__, '_posts', '*.markdown'))
files.each do |file|
  content = File.read(file)
  _, header, body = content.split('---')
  header_yml = YAML.load(header)
  title = header_yml['title']
  tags = header_yml['category']
  tags = tags.is_a?(Array) ? tags.map(&:downcase) : [tags&.downcase]
  slug = Pathname.new(file).basename.to_s.sub(/\d{4}\-\d{2}\-\d{2}\-(.+?)\.markdown/, '\1').gsub('_', '-')
  body = body.strip.gsub(/\n/, "\\n").gsub('\'', '\'\'')
  created_at = File.birthtime(file).to_s.sub(' +0900', '')
  updated_at = File.mtime(file).to_s.sub(' +0900', '')
  puts <<~EOS
    INSERT INTO entries(title, user_id, category_id, slug, markup, type, draft, body, frozen_tag_list, created_at, updated_at) VALUES('#{title}', 1, 6, '#{slug}', 'redcarpet', 'Post', 0, '#{body}', '#{tags.join(',')}', '#{created_at}', '#{updated_at}');
  EOS
end

| @技術/プログラミング

Chart

Rechars という React のチャートライブラリを利用して、 Archive ページにカテゴリーごとに記事を集計してグラフ化する機能を作った。

グラフの Bar にカーソルを載せると Tooltip が表示されて、具体的な件数がわかる。

Chart Tooltip

カテゴリごとに表示・非表示を切り替えることも可能。グラフ下のカテゴリー名( Legend )をクリックして切り替えられる。

Chart Show-Hide Toggle

ただし残念なことに Bar を非表示にしたときに Legend の表示を変化させるのが難しくてできていない。

仕事で使ってる Looker とか Redash であれば Legend をクリックして表示・非表示を切り替えることができ、それに連動して Legend の色をトーンダウンさせたりする機能が付属しているが、利用した Recharts にはその機能がなかった。 Bar の表示・非表示切り替えも標準サポートされていなかったので、 GitHub の Issue の情報を頼りに無理矢理実装した。

コードはこんな感じ。結構汚い Hack で、 Bar の表示・非表示を、表示用のキー文字列に空白を追加するかしないかで切り替えている。

  // クリックされたアイテムが `this.state.disabled` 配列の中にすでに存在していれば除外し、
  // 存在してなければ追加する
  selectBar(event) {
    let dataKey = event.dataKey.trim()
    if (this.state.disabled.includes(dataKey)) {
      this.setState({ disabled: this.state.disabled.filter(item => item !== dataKey) })
    } else {
      this.setState({ disabled: this.state.disabled.concat([dataKey]) })
    }
  }

  render() {
    return (
      <ResponsiveContainer height={500}>
        <BarChart
          data={this.state.data}
          margin={{
            top: 20, right: 20, left: 0, bottom: 20,
          }}
          style={{ fontSize: '14px' }}
        >
          <CartesianGrid strokeDasharray="3 3" />
          <XAxis dataKey="year" />
          <YAxis />
          <Tooltip labelStyle={{ color: '#000', fontWeight: 'bold' }} itemStyle={{ margin: '0 2px 0 4px', padding: '0' }} />
          {// Legend クリック時のコールバックに `this.selectBar` を指定する }
          <Legend onClick={this.selectBar} />
          {/*
            `this.state.categories` 配列と `this.state.disabled` 配列の内容を比較し、
            `this.state.disabled` に追加済のカテゴリーは dataKey に空白を追加することで非表示に
          */}
          {this.state.categories.map((category, index) => {
            let dataKey = this.state.disabled.includes(category) ? category + " " : category
            let color = this.colors[index % this.colors.length]
            return(<Bar key={index} dataKey={dataKey} stackId="a" fill={color} />)
          })}
        </BarChart>
      </ResponsiveContainer>
    );
  }