リマールエステート株式会社 / エンジニア
自社サービスのパフォーマンスチューニング
【サービス】 BtoB向けの不動産売買サービス ユーザーが売りたい不動産と顧客のリストを登録することで、 - 自分が持っている不動産の管理 - 物件多数の顧客に一括で物件を紹介する - ユーザーと不動産を紹介した顧客でのやりとり などを行うことができる 【課題】 上記サービスの中で不動産や顧客の登録が数千を超えるユーザーが多くなり、ユーザーによっては特定の処理でタイムアウトを起こしてしまう例が発生した 原因を深堀りした結果、以下の3点が主原因であることがわかった 1. ページングを使わずに全てのデータを取得した後に一覧で表示していたため、ブラウザのメモリを過剰に消費していた。(上記の実装はVuexのstoreに全データを保存し、全データの対してフロントで検索、絞り込み、ソートを行えるようにしたいというサービス内の要望から発生した) 2. バックエンドではPythonを使用しており、ORMはSQLAlchemyを使用している。これまでの開発においては実際に吐き出されるクエリの考慮が足りていなかったため、n+1問題、forループの重複、不要なクエリが存在していた 3. 顧客に一括で不動産を紹介する処理が同期的に行われており、数千件を紹介したときに処理に時間がかかってしまう 【行なった取り組み】 ■ フロントエンド 1に対しての取り組み: 大量のデータをページング機能を使わず一覧で表示するという要望を満たしたまま、ブラウザメモリ量を抑えるために、仮想スクローラー(vue-virtual-scroller)を使用してユーザーの可視領域だけDOMを作成する事で一覧表示時のメモリを抑えるようにした ■ バックエンド 2に対しての取り組み: ORMによってクエリを意識せず書かれていた箇所を洗い出し、eager-loadを使ったn+1の改善、forループの重複の改善、不要なクエリの見直しを行なった 3に対しての取り組み: 処理の非同期化を実現するためにRedisと、通常のapi処理とは独立した紹介処理用のdockerコンテナを新たに立ち上げ、 - 紹介処理に必要となるデータをRedisにキューイングする - キューイングされたデータを紹介処理用のコンテナで、順次取り出し紹介処理を行う という構成を追加で実装した 【 担当】 3人チームの中で、フロントエンドとバックエンドを担当 【主な使用技術】 - Vue.js - Nuxt.js - TypeScript - Python - pyramid - SQLAlchemy 【成果】 - 表示スピードが平均でおおよそ70%ほどの改善ができた - 数千件の一括紹介処理はユーザーの画面上でほぼノータイムで動作するようになった