View Full Version : JavaScript Size Problem
engelman
12-03-2002, 08:43 PM
Hello,
I’d appreciate any help anyone can offer on the following problem.
I have a JavaScript function that loads a city combo box with all cities in the state chosen in an associated state combo box. The function is about 825KB, and downloads very slowly. I’ve tried some of the publicly available JavaScript compressors, which only resulted in a small percentage file size reduction. I’ve also tried a JavaScript compiler, which did achieve a very high space reduction percentage, but unfortunately takes a long time to unpack once downloaded.
Does anyone have any ideas? I’m open to any alternative. Perhaps there are some very good JavaScript compressors or compilers that I’m unaware of. I’d appreciate any advice in this area.
Also, does anyone know if it’s possible to run machine code from MSIE? In theory, I could convert the JavaScript function to fully compiled machine code (such as Visual Basic). I don’t know if IE could run such code. I’d also appreciate any comments relative to this idea.
Thanks very much, Stewart Engelman
Vladdy
12-03-2002, 09:15 PM
Is it data that takes most of the space? How many cities are there?
I posted a JS "white space remover" in Post JavaScript forum, but it does not really compress.
Also I would be interested to see the code and if there is possibility to optimize it. I mean, if the file is 800Kb and an average city has 10 characters per name, you either have 50,000+ citinames stored in it, or code is a mess - populating combobox is no more than 10 lines of code (... thinking out loud below):
cities = new Array('London','Boston','New York');
function populate()
{ cbox = document.getElementById('MyForm').elements['Cities'];
for(i=0; i<cities.length; i++)
{ option = document.createElement('option');
option.text = cities[i];
option.value = cities[i];
cbox.add(option);
}
return;
}
EDIT: one more thought. If your application is to populate cities combobox based on selection of state combobox, do not load all the city names with the page. Have separate js files with city names for each state and load the one you need when a state is selected.
ShriekForth
12-03-2002, 09:50 PM
It occurred to me as well that if you have enough cities per state, the list would be long even if you removed white space. So... what if you only loaded the cities you needed for a particular state? I saw this loadContent function here and thought it might be useful at some point, but could not decide where. I know now.
This example will only work in a DOM compliant browser, but I know that you can change the .src of a script in IE and have it load dynamically. This is not a full solution, but something to think about.
<html>
<head>
<script type="text/javascript" src="./first.js" id="citiesScript"></script>
<script type="text/javascript">
function changeSrc(src){
document.getElementById('first').setAttribute('src',"./" + src + ".js");
alert(document.getElementById('first').src);
}
function showSrc(){
alert(document.getElementById('first').src);
}
function loadContent(file){
var scriptTag = document.getElementById('citiesScript');
var head = document.getElementsByTagName('head').item(0)
if(scriptTag) head.removeChild(scriptTag);
script = document.createElement('script');
script.src = file;
script.type = 'text/javascript';
script.id = 'citiesScript';
head.appendChild(script);
}
function showCities(){
alert(cities[0] + " " + cities[1] + " \n You get the idea ");
}
</script>
</head>
<body>
<a href="javascript:loadContent('first.js')">changeSrc(first)</a><br>
<a href="javascript:loadContent('second.js')">changeSrc(second)</a><br>
<a href="javascript:getSrc()">getSrc()</a><br>
<a href="javascript:showCities()">showCities()</a><br>
<a href="javascript:showSrc()">showSrc()</a><br>
</body>
</html>
first.js
var cities = Array('Sacramento', 'Oakland')
function getSrc(){
alert("first.js");
}
second.js
var cities = Array('Portland', 'Seattle')
function getSrc(){
alert("second.js");
}
Anyway, I thought you could have a separate .js file/array for each state, and load it dynamically as the user selects a state. This would keep the user from downloading the extra cities. You may even be able to work a similar solution using frames... The user in either case will notice a bit of a delay if they are on a slow connection I would guess.
ShriekForth
engelman
12-03-2002, 10:21 PM
Dear Vladdy, thanks for offering to help. I've uploaded part of my code in a zip archive. I'll upload the rest in a subsequent reply (the code is being split due to the upload size limitation of 50KB).
ShriekForth-Thanks for the idea of splitting the job into multiple server calls. I considered this idea, but wish to avoid it if possible due to the "blip" the user will see whenever states are changed.
engelman
12-03-2002, 10:22 PM
Hello, here is the rest of the code (attached). Stu
Vladdy
12-03-2002, 10:30 PM
As I suspected the code is a disaster.
I assume the values are the ZIP codes...
First define the city object:
function c(name,zip)
{ this.name=name;
this.zip=zip;
}
Then define states array and populate it:
var s = new Array();
s["AK"] = new Array(
new c('Anchorage','99508/99516'),
new c(...,...),
);
s["..."] = new Array(
...
)
// and so on...
then for your ReloadCities do the following:
function ReloadCities(st)
{ cbox = document.getElementById('MyForm').elements['Cities'];
while(cBox.options[0]) cBox.options.remove(0);
for(i=0; i<s[st].length; i++)
{ option = document.createElement('option');
option.text = s[st][i].name;
option.value = s[st][i].zip;
cbox.add(option);
}
return;
}
I bet the file size will be under 100k
vBulletin® v3.8.2, Copyright ©2000-2012, Jelsoft Enterprises Ltd.