do7be.exports

寿司の話かエンジニアリングの話

画像がキャッシュされてjQuery.on('load')が効かない場合

画像のロードが既に終わっていて、再度同じ画像を含むDOMをappendしてloadイベントやerrorイベントハンドラを貼りたい場合、サーバからキャッシュされた画像が返されるとloadイベントが発火されない。

// 何度も下記処理が走る場合
const url = httpRequestHoge() // 何度も同じ画像が返ってくる可能性あり
imgTag = $(`<img src="#{url}">`)
$('body').append(imgTag)

imgTag
.on('load', function () {
  $(this).css('height', 0)
})

だとloadイベントが発火されない場合がある。

const url = httpRequestHoge()
imgTag = $('<img>') // ここではsrcに入れない
$('body').append(imgTag)

imgTag
.on('load', function () {
  $(this).css('height', 0)
})
.attr('src', url) // イベントハンドラを貼ってからsrc指定

loadはdocumentに存在しないDOMにはハンドラが貼れないらしいのでめんどい。

アクアリウム始めました

f:id:do7be:20160717230150j:plain

実は5月中旬から人生初のアクアリウムを始めていました。

さっき模様替えとかが終わったので写真に収めておきましたぞ。

立ち上げ

初めてだったのでいろいろ手間取りましたが、なんとか水槽台と水槽を立ち上げ。

f:id:do7be:20160717224746j:plain f:id:do7be:20160717224804j:plain f:id:do7be:20160717224811j:plain f:id:do7be:20160717224827j:plain

以下スペック。

現在の水槽の様子

f:id:do7be:20160717224916j:plain

f:id:do7be:20160717225509j:plainf:id:do7be:20160717225604j:plainf:id:do7be:20160717225651j:plainf:id:do7be:20160717225656j:plainf:id:do7be:20160717225659j:plainf:id:do7be:20160717225704j:plainf:id:do7be:20160717225718j:plainf:id:do7be:20160717225721j:plain

f:id:do7be:20160717233858p:plain

ソイルこぼれてたりウィローモストリミングできてなかったりでよくないですねー。

生体は

来週辺りコリドラス パンダも入れようかと。

赤虫あげてコリドラス軍団のモフモフを堪能したいですなあ。

f:id:do7be:20160717225735j:plain

jQuery .findでreflowが発生する

最近の業務ではフロントエンドの最適化もやっているのですが、そこで奇妙な現象に遭遇しました。

jQuery.findという、DOMツリーからセレクタに該当するDOM群のjQueryオブジェクト取得関数があるのですが、これでなぜか実行するたびにreflowが発生していました。

$('.hoge').find('.fuga:not(.piyo)')

このような状況です。jQuery 1.11でも3.0でも起きていました。これがscrollのたびに走っていると、インスペクタの.hogeが点滅し続けます。

いくつかのケースでreflowが発生するかどうか試してみましたが、どうやら.find:notを使用した時のみ発生するようです。

  • $('.hoge')
    • →しない
  • $('.hoge').find('.fuga')
    • →しない
  • $('.hoge').find('.fuga:not(.piyo)')
    • →する
  • $('.hoge').find(':not(.piyo)')
    • →する
  • $(':not(.piyo)')
    • →しない

実装を読んでないので.findでreflowが発生するのが腑に落ちないのですが、このようなケースでは.filterもしくは.notでさらに絞り込めばreflowが起きないので書き換えると良さそうです。

社内ISUCONで猛威を振るってきました

先週の1/25,26の2日間にかけて、社内ISUCONが開催されていたので参加してきました。

1,2人のチームで2日間のうちどちらかの日に参加し、4時間かけて本家ISUCONのような課題WEBサービスのチューニングを競う、という内容です。

出題者は弊社エバンジェリスト@takashabeです。

出題サービスのソースコードとベンチマーカを載せておきます。

github.com

作業内容はGitHubにpushしておきました。

github.com

当日の振り返り

参加者は合計15人。1日目に影響され、2日目にエントリーした方が何名かいました。

僕はスケジュール上2日目に1人で参加しました。と言っても実は全員ぼっちチームでした。チーム名は「https://goo.gl/6YBEht」です。短縮URLをチーム名にしました。

チューニングのお題としてはISUCON5と同じような構成で、Twitterを模したサービスでした。指定されたEC2に入るだけだったので、そのへんは本家よりカジュアルに参加できる感じでよかったです。

作業内容

とりあえずサービスに紐付いている動作中のプロセスを確認し、Gitなどの環境を構築しました。言語は初期がRubyになっていたのでsystemdでPHPに切り替えました。言語を切り替えただけでスコアが500→1000に。

テーブルを確認し、必要そうな箇所にインデックスを貼って見たらなんとスコアが1000→2000に。

続けてフォロー一覧やフォロワー一覧ページの無駄に叩かれるクエリを最適化していきました。foreachで何度も叩いているクエリを結合して1回のクエリで済ませるようにしたり、count文にしたり。

このへんで約2時間。スコアは3000まであがりました。なんとこの時点でのトップを独走しており、2位以下は1000点に達していないような状況でした。

ここで余裕が出てきたので、Redisに載せ変えようと考えpeclyum installしました。

するとなんとスコアが2500に!使用中のモジュールまで更新されたかなにかで以降スコアが下がったままになってしまいました。しかもうまくPHPにてRedisを導入できず、結局諦めミドルウェアまわりのチューニングにとりかかりました。

nginx, mysql, カーネルまわりのチューニングをしましたが、スコアは伸びず。今回のサービスは通信量が少ないため、ボトルネックはネットワークではなくクエリにあったためです。

と、ここでスコア4000を叩き出すエンジニアが登場。

結局最終的にはスコア2500でフィニッシュ。

最終結果

1位は@pe10:3000点くらい

2位はなんと、僕でした!

4000スコア出していた人は再起動後にFAILになり失格だったそうです。

惜しくも2位でしたが、2日目1位となり、amazonギフト券をいただきました!!!!

f:id:do7be:20160130163852j:plain

感想

ISUCON5に参加した方々が総じてスコアが高く、やはりアドバンテージがあったのだと思います。

言語切り換えやベンチマークの動かし方、チューニング対象の絞り方などは、ISUCONならではな感じがします。

スコアが高かったのもありますが、こういうイベントを楽しんで参加することができたことが嬉しかったです。

今後も本家ISUCONや何か面白そうなイベントには参加していきたいと思います。

エバンジェリスト、お疲れ様でした。

勉強会を主催するということ

本記事はマイネット Advent Calendar 12日目の記事です。

3日目9日目も書きました@do7beです。

何の話か

エンジニアのみなさんは社内・社外問わず勉強会というものにこれまで少なからず一度は参加したことがあるかと思います。

中には企業が開催しているイベントもあるでしょう。しかし、勉強会やイベントの多くは数名または個人が主催しています。みな一般のエンジニアです。

今回は僕が社内勉強会を開いた経験から、「なぜ開くのか」「何に気をつければいいのか」を書いていきたいと思います。

社内勉強会を開催した動機

www.slideshare.net

社内で職種問わずLT大会というものを主催していたのですが、第8回目でのクロージングにて、YAPCで「聞きたい内容があれば自分が開催しろ」という言葉に衝撃を受けたという話をしました。

弊社ではJavaScriptに関するイベントなどがなく、JS好きな僕としては非常にもどかしい気持ちがありました。そこで、前にブログに書いたJSワークショップを開催することになりました。

主催側が気をつけること

  • 目的
  • 目標
  • 内容

は、はっきり決めておき公開しましょう。「適当に開いてみんな適当にやればいい」というスタンスだと続きません。(何度か失敗した)

また、参加側は基本的にレベルがバラバラです。あらかじめレベル感がつかめる情報を公開するか、勉強会中にフォローできる余裕を準備しておきましょう。

勉強会を開催してみての所感

個人で開催すると、資料の準備などが大変なので何度も開催することが困難になってきます。数人で持ち回りをローテーションするほうがいいと思います。

また、よほど意識が高いか時間に余裕がある集団でない限り、なかなか参加者は増えません。社内のいろいろな方を誘いましょう。そのうち社外からゲストを招いてもいいと思います。

まとめ

勉強会やイベントに参加することはエンジニアにとって得るものがありますのでいいと思います。しかし、自分が本当に知りたい分野や議論したい内容に関しては、誰かが開いてくれるのを待つのではなく、自分から開いてみてはいかがでしょうか?

いきなり社外勉強会を開くのはハードルが高いと思いますので、まずは数名で、仲の良い方など誘って開催してみると良いと思います。

備考

過去のJSワークショップの資料を載せておきます。