[JavaScript] html에서 <script> 태그의 적절한 위치는 어디인가
지금까지 JavaScript를 사용하다 보면 html 파일안에 <script>태그를 <head>에 넣었는데
해외 예제를 보던중 지금까지 했던 방식으로 했더니 동작이 안되는것이였다.
예제는 [Automatically Maximize Text Contrast On A Page] 였는데, ColorPicker를 이용 background를 비동기적으로 변경하는 예제였다.
소스참조
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<script>
function splitComponent(color) {
var rgbColors = new Object();
color = color.substring(color.indexOf('(') + 1, color.indexOf(')'));
var result = color.split(',', 3);
return result ? {
r: parseFloat(result[0] / 255),
g: parseFloat(result[1] / 255),
b: parseFloat(result[2] / 255)
} : null;
}
var gamma = 2.2,
test = document.getElementById("test");
function changeBG(colorValue) {
test.style.backgroundColor = colorValue;
var computedStyle = getComputedStyle(test, null);
var bgColor = computedStyle.backgroundColor;
var luminosity = 0.2126 * Math.pow(splitComponent(bgColor).r, gamma) + 0.7152 * Math.pow(splitComponent(bgColor).g, gamma) + 0.0722 * Math.pow(splitComponent(bgColor).b, gamma);
if (luminosity < 0.5) { test.style.color = "#fff" } else { test.style.color = "#000" }
}
</script>
<style>
#test { background-color: #332; color: #fff; font-family: Avenir, sans-serif; padding: 2rem; text-align: center; }
</style>
</head>
<body>
<div id="test">
<h1>I SHALL ALWAYS REMAIN LEDGIBLE</h1>
<label for="bgcolor" >Set the background color for this element:</label>
<input type="color" value="#777777" id="testbg" name="testbg" oninput="changeBG(testbg.value)" />
</div>
</body>
</html>
이렇게 하고 돌렸는데 안먹힌다... 크롬에서는 요렇게!
test가 null 이라고 뜬다. 함수를 못불러오는거다. html 이 로딩이 안된것처럼 받아들인다는것...
한참동안 끙끙거리고 있다가 문득 책에서 <script>태그의 위치는 html파일의 로딩이 끝난뒤 불러오는 </body>의 바로 윗쪽에 위치시키는것이 좋은 습관이다 라는걸 생각해내서 위치를 바꿔봤다!
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<style>
#test { background-color: #332; color: #fff; font-family: Avenir, sans-serif; padding: 2rem; text-align: center; }
</style>
</head>
<body>
<div id="test">
<h1>I SHALL ALWAYS REMAIN LEDGIBLE</h1>
<label for="bgcolor" >Set the background color for this element:</label>
<input type="color" value="#777777" id="testbg" name="testbg" oninput="changeBG(testbg.value)" />
</div>
</body>
<script>
function splitComponent(color) {
var rgbColors = new Object();
color = color.substring(color.indexOf('(') + 1, color.indexOf(')'));
var result = color.split(',', 3);
return result ? {
r: parseFloat(result[0] / 255),
g: parseFloat(result[1] / 255),
b: parseFloat(result[2] / 255)
} : null;
}
var gamma = 2.2,
test = document.getElementById("test");
function changeBG(colorValue) {
test.style.backgroundColor = colorValue;
var computedStyle = getComputedStyle(test, null);
var bgColor = computedStyle.backgroundColor;
var luminosity = 0.2126 * Math.pow(splitComponent(bgColor).r, gamma) + 0.7152 * Math.pow(splitComponent(bgColor).g, gamma) + 0.0722 * Math.pow(splitComponent(bgColor).b, gamma);
if (luminosity < 0.5) { test.style.color = "#fff" } else { test.style.color = "#000" }
}
</script>
</html>
정상적으로 동작한다.
<script>의 위치가 <body>를 모두 읽어온 후에 읽어야 제대로 동작하던데...
페이지의 로딩 속도 측면에서도 <script>태그를 하단에 위치시켜야 속도향상에도 도움이 된다.
그 이유인즉슨... 보통 <script>외부 태그나 외부적으로 다운로드하게 되는데 <script>파일의 크기가 크거나 혹은 정상 다운로드가 되지 않으면 html 파일이 정상적으로 로딩되지않게되어 화면이 뜨지 않거나 늦게 뜨게 된다.
이런 점을 고려해 속도 향상을 하려면 <script>태그(html 내용이 전부 읽히고 나서 후에 실행되는 함수내용들)는 </html>의 바로 윗부분에 위치시키는게 좋다.
하지만 html태그가 읽히기전에 수행되어야하는 <script>태그들은 윗부분에 위치시켜야 한다.또한 jQuery같이 여러 페이지에서 같이 동작해야 하는 것들도 <head>태그에 놓는게 좋다.
추가로 <css>는 항상 <head>태그 사이에 위치시켜야 한다. 하단에 위치시키게되면 html 파일을 두번 읽어서 적용시킨다.