Well, the answer to whether there is a better way to store that data depends on two things: the data itself and how you're using it.
The data itself may lend itself to some system that will let you automatically generate some or all of the data, depending on what that data is. If you can automatically generate any of that data, then you're probably better off doing that as that data is needed, since storing too much data in the game's history can slow down your game during passage transitions, saves, and loads.
A more important factor though, is how you're using that data. If much of the data will never change throughout the game, you can reduce the history data even more by reading those values as needed from the SugarCube "setup" object variable, instead of using a story variable. If, for example, you have a list of items that will never change during the game, you could create a "setup.items" array or generic object to store the unchanging information of those items. You would load them up initially in either your JavaScript section or your StoryInit passage, and then you could just refer to "setup.items" to get that data. Information on the setup object doesn't get stored in the history or saved with the game, so it should help prevent slowdown, but the fact that it isn't saved is why you can't change that data as the game is played.
Another thing I might suggest would be, instead of storing the data in a passage, save it to a JavaScript file, which you could then load using the SugarCube importScripts() function (which works with both online and local files). Here's the code I use to do that in my JavaScript section in a few of my projects:
if (window.hasOwnProperty("storyFormat")) {
// Change this to the path where the your HTML file is
// located if you want to run this from inside Twine.
setup.Path = "C:/Games/MyGame/"; // Running inside Twine application
} else {
setup.Path = ""; // Running in a browser
}
setup.SoundPath = setup.Path + "sounds/";
setup.ImagePath = setup.Path + "images/";
setup.JSLoaded = false;
importScripts(setup.Path + "jquery-ui.js")
.then(function() {
setup.JSLoaded = true;
}).catch(function(error) {
alert("Error: Could not find file 'jquery-ui.js'.");
}
);
You'll need to change "C:/Games/MyGame/" to your game's path so that this code will work from within Twine (Note: you may want to remove that from release versions if you don't want people to possibly know your directory path) and change "jquery-ui.js" to the name of your JavaScript file. The above code assumes that the JavaScript file is in the same directory as the HTML file when this is used outside of Twine. Also note that the importScripts() function is asynchronous, which means that any code after that function will be executed immediately as normal, however that JavaScript file won't actually be loaded until later on. The .then() part is triggered to let you know when it's done importing the script(s), or if the file can't be loaded then the .catch() part will be triggered instead so you can show an error message or whatever you want there (see the following link for more information on using Promise objects like that one).
Hope that helps! :-)