본문 바로가기

Programmer/JAVASCRIPT

jQuery Ajax async:false 사용 시 렌더링이 멈추는 이유와 해결 방법

웹 개발을 하다 보면 jQuery ajax에서 async:false를 사용했을 때

로딩 UI가 보이지 않거나 화면 렌더링이 멈추는 현상을 경험할 수 있습니다.

 

최근 예전에 만들어진 소스를 유지보수 중에도 “로딩이 보이지 않는다”는 이슈가 발생했습니다.
확인해보니 로딩 이미지를 표시하는 코드가 분명히 존재했지만 실제 화면에서는 전혀 보이지 않았습니다.

 

코드를 확인하던 중 ajax 요청에서 async:false가 사용되고 있었고,
이 때문에 브라우저 렌더링이 차단되어 로딩 UI가 표시되지 않는 문제였습니다.

이번 글에서는 async:false가 왜 렌더링을 막는지, 그리고 어떻게 해결할 수 있는지 정리해보겠습니다.


1. async:false란 무엇인가

async:false는 동기(Synchronous) Ajax 요청입니다.

$.ajax({
    url: "/test",
    async: false,
    success: function(data){
        console.log(data);
    }
});

 

동기 요청의 특징은 서버 응답이 올 때까지 다음 코드가 실행되지 않는 것입니다.

즉 다음과 같은 흐름으로 동작합니다.

JS 실행 → Ajax 요청 →  서버 응답 기다림 (JS 스레드 BLOCK) →  응답 후 다음 코드 실행

2. 왜 화면 렌더링이 멈출까

브라우저는 JavaScript 실행이 끝난 후에 렌더링을 수행합니다.

하지만 async:false는 JavaScript 실행을 멈춘 상태로 서버 응답을 기다리기 때문에
렌더링도 함께 멈추게 됩니다.

예를 들어 아래 코드가 있다고 가정해 보겠습니다.

$('#loading').show();

$.ajax({
    url: "/test",
    async: false
});

 

기대한 내용은 아래 내용과 같을 겁니다.

로딩 표시 → Ajax 요청 → 응답 후 로딩 제거

 

하지만 하지만 실제 동작은 다음과 같습니다.

로딩 표시 요청 → Ajax 요청 (JS BLOCK) → 서버 응답 → JS 종료 → 그때 화면 렌더링

 

결과적으로 로딩 UI가 전혀 보이지 않게 됩니다.


3. setTimeout을 이용한 해결 방법

일부 경우 setTimeout을 사용하면 렌더링을 먼저 실행할 수 있습니다.

$('#loading').show();

setTimeout(function(){
    $.ajax({
        url: "/test",
        async: false
    });
}, 0);

 

위 부분을 실행하면 아래와 같이 동작합니다.

loading show → JS 실행 종료 → 브라우저 렌더링 → setTimeout 실행 → ajax 실행

 

이렇게 하면 로딩 UI가 화면에 보이게 됩니다.

하지만 이 방법은 임시 해결 방법에 가깝습니다.


4. 가장 좋은 해결 방법 (비동기 요청)

왠만하면 async:false 사용을 하지 않는게 좋습니다.
비동기 방식(async:true)으로 처리하는 것이 가장 좋은 방법입니다.

$('#loading').show();

$.ajax({
    url: "/test",
    success: function(data){
        $('#loading').hide();
    }
});

 

이 방식의 흐름은 다음과 같습니다.

로딩 표시 → Ajax 요청 (비동기) → 브라우저 렌더링 정상 작동 → 응답 도착 → 로딩 제거

 

이렇게 하면 브라우저 UI가 멈추지 않고 로딩 UI도 정상적으로 표시됩니다.

또한 Ajax 호출 이후에 다른 메서드를 실행해야 하는 경우에는 callback을 활용하는 방법도 사용할 수 있습니다.

예를 들어 Ajax 응답을 받은 후 특정 메서드를 호출해야 한다면 다음과 같이 작성할 수 있습니다.

function loadData(callback){
    $.ajax({
        url: "/test",
        success: function(data){
            if(callback){
                callback(data);
            }
        }
    });
}

loadData(function(){
    nextProcess();
});

 

이처럼 callback을 사용하면 동기 방식(async:false)을 사용하지 않아도 원하는 순서로 로직을 실행할 수 있습니다.


5. async:false 대신 사용할 수 있는 방법

다음과 같은 방식도 사용할 수 있습니다.

$.ajax({
    url: "/test"
}).then(function(data){
    console.log(data);
});

 

또는

async function loadData(){

    const result = await $.ajax({
        url: "/test"
    });

    console.log(result);
}

이 방법은 동기 코드처럼 작성하면서도 비동기 방식으로 동작합니다.


결론

예전 소스에서 async:false가 사용된 부분이 보인다면 한 번쯤 점검하고 수정하는 것이 좋습니다.

 

async:false는 서버 응답이 올 때까지 JavaScript 실행을 멈추기 때문에 브라우저 렌더링까지 함께 차단될 수 있습니다.

 

대신 비동기 방식으로 Ajax를 처리하고 callback 등을 활용하여 로직을 구성하는 것이 더 안정적이고 사용자 경험 측면에서도 좋은 방법입니다.