🌊

【チームプロジェクトRefactoring②】AJAX機能を活用し、debounceで性能強化

2024/02/20に公開

はじめに

本日は、デプロイ前の最後のリファクタリングを行いました。
会員登録機能のリアタイム重複検査機能でした。
jsのfetch()関数を利用し、debounce機能(lodashのライブラリ)を使ってリソースの無駄を減らすことで性能を向上しました。

fetch()

会員登録(POST)要請を送る前に、重複検査が必要なデーターをリアルタイムで確認する機能を具象した結果、AJAXが必要だと考え、JSのfetch()関数を活用してみました。
まず、サーバーと通信する思い関数なので、関数を分離して作成しました。

const memberIdEl = document.querySelector('#memberId');
const duplicatedId = document.querySelector('#duplicatedId');
const notDuplicatedId = document.querySelector('#notDuplicatedId')
.
.
.

memberIdEl.addEventListener('keyup',()=>{
    const memberId = memberIdEl.value;
    notDuplicatedId.classList.add('hide');
    duplicatedId.classList.add('hide');
    if(memberId.length < 5) return;
    CheckDuplicatedId(memberId);
});

IDの場合、5字以上からという条件があるため、4字まではfetch() 関数が動作されず、undefinedでリターンされるため、呼び出されずに、終わります。
また、**一回重複検査の結果が出た場合、結果が残ってしまうことになり、**検査を終わったり、新しい字が入力されイベントが発生される場合、まず検査結果をなくすUIロジックを追加しました。

下はfetch()関数です。

/*ID AJAX(サーバーに重複検査Request) */
function checkDuplicatedId(memberId){
    //urlとhttpメッセージ内容
    fetch('/members/duplication-check/id', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({memberId}) // {memberId:memberId} -> {memberId}
    })
        .then(response => response.json())
        .then(count =>{
                if(count===1) {
                    duplicatedId.classList.remove('hide');
                    notDuplicatedId.classList.add('hide')
                }
                else{
                    notDuplicatedId.classList.remove('hide');
                    duplicatedId.classList.add('hide')
                }

            }
        )
        .catch(console.log);
}

SpringBoot @RequestBody、@ResponseBody

@RequestParamの場合、NULLが出たので、検索した結果、JSON通信の場合、@RequestBodyでJSONをもらうことが分かり、以下のようにコードを作成しました。
Service → Repositoryから検査が終わり、重複したデーターがある場合、1をない場合は0をリターンするように組みました。

MemberController.java
@PostMapping("/duplication-check/id")
    @ResponseBody
    public int showDuplicatedId(@RequestBody Map<String,String> memberIdJson){
        String memberId = memberIdJson.get("memberId");
        return memberService.checkDuplicatedId(memberId);
    }
membermapper.xml
 <select id="countById" parameterType="String" resultType="int">
        select count(member_id) from member where member_id = #{memberId};
    </select>

その結果、無事に検査が行われることが確認できました。

debounced


eventをkeyupに設定したころから、一つの文字を打つたびにfetch()が行われることが分かり、
友人のエンジニアからdebouncing, throttleについて紹介してもらいました。

要するに、入力の途中はfetch()をせずに、終わる際もしくは入力が終わってから何秒後にfetch()関数を実行させる機能でした。
有料APIの場合、お金がかかるので、このような無駄を減らし、性能的にもリソースを節約することでできるため、重要だと考えました。

memberIdEl.addEventListener('keyup',()=>{
    const memberId = memberIdEl.value;
    notDuplicatedId.classList.add('hide');
    duplicatedId.classList.add('hide');
    if(memberId.length < 5) return;
    debouncedCheckDuplicatedId(memberId);
});

.
.
.
const debouncedCheckDuplicatedId = _.debounce(checkDuplicatedId, 300);

lodashからライブラリをダウンロードし、debounce機能を具象した関数を使うことで、無駄を減らしました。下に作成した関数はHoistingにより上に上がるので、下に作成しました。

改善した結果は、ログに記録しました。

Discussion