Make api fetch once, and then have the “input” event merely do the filtering

My code fires a new ajax request on every single keystroke and i don’t know how to make my api fetch once, and then have the input event do the filtering.

My code works fine , but if i would live it like that it would take years to load when i would have a large json content.

The states.json data is still the same (and usualy is in autocomplete), i should load it once instead of every keystroke. Extra request for each key is not a good idea. So can someone please help me?

<!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="css/main.css">
        <title>Test</title>
    </head>
    <body>
        <div class="container">
            <div class="search-wrapper">
                <input type="text" name="" autocomplete="off" id="search" placeholder="Search now">
                <ul class="match-list">
                    
                </ul>
            </div>
        </div>
    
        <script src="function.js"></script>
    </body>
    
    </html>

and here is my javascript

const search = document.querySelector("#search");
const matchList = document.querySelector(".match-list");

// search states.json and filter it
const searchStates = async searchText => {
    const res = await fetch('data/states.json');
    const states = await res.json();

    //Get matches to current text input
    let matches = states.filter(state => {
        const regex = new RegExp(`^${searchText}`, 'gi');
        return state.name.match(regex) || state.abbr.match(regex);
    });

    if (searchText.length === 0) {
        matches = [];
    };

    

    outputHtml(matches)
};

//show results in html
const outputHtml = matches => {
    if (matches.length > 0) {
        const html = matches.map(match =>`
        <li class="match-list-element">
        <h4 class="">${match.name} (${match.abbr})</h4>
        <span class="">${match.capital}</span>
        <small class="">Lat:${match.lat}/ Long: ${match.long}</small>
        </li>
        `
        ).join('');

        matchList.innerHTML = html;

    } else {
        matchList.innerHTML = null;
    }

}


search.addEventListener('input', () => searchStates(search.value));