유니티 파일을 webGL로 빼서 웹에서 띄우는 과정에서 로드시간이 너무 긴 문제가 발생했다.
그래서 정보를 찾아보니
브라우저 캐싱: 웹사이트에서 자주 사용되는 정적 파일(HTML, CSS, JavaScript 등)은 클라이언트의 장치(브라우저)에 저장하여 재방문 시 서버로부터 해당 파일을 다시 받아오지 않도록 할 수 있습니다. 이와 비슷한 방식으로 WebGL 프로젝트에서도 한 번 로딩된 3D 모델 데이터를 클라이언트 쪽에서 캐싱하여 재사용하는 것이 가능합니다.
하지만 Unity WebGL 프로젝트에서 직접적으로 브라우져 캐시를 컨트롤하는 것은 어렵습니다. 대신 서버 설정(HTTP headers 등)을 변경하여 해당 리소스들(모델링 데이터 등)에 대한 캐싱 정책을 변경해야 합니다.
또 다른 방법으로 Unity WebGL과 함께 Service Workers나 IndexedDB 같은 웹 API들을 활용해서 복잡한 클라이언트 사이드 캐싱 전략을 구현할 수도 있겠지만, 이런 접근법은 상당히 고급 개발 지식과 경험이 요구됩니다.
위와 같은 접근법들은 도움이 될 수 있지만, 웹에서 큰 3D 모델을 로드하고 렌더링하는 것은 어느 정도의 복잡성과 성능 문제를 항상 동반하게 됩니다. 따라서 가장 효과적인 해결책은 여전히 모델 최적화와 적절한 로딩 전략을 사용하는 것입니다.
Unity WebGL에서 3D 모델을 클라이언트 쪽에서 캐싱하여 재사용하는 것은 직접적으로 Unity 내부에서 제어할 수 있는 기능이 아닙니다. 이는 웹 서버 설정과 브라우저의 동작에 의존하는 부분입니다.
브라우저는 일반적으로 HTTP 헤더를 통해 제공되는 캐시 제어 지시자를 따릅니다. 이러한 지시자들은 어떤 파일을 얼마나 오래동안 캐시할지, 언제 새로고침해야 하는지 등을 결정합니다. 이러한 설정은 웹 서버에서 관리되므로, 웹 서버의 설정을 변경하여 파일에 대한 캐싱 정책을 조정할 수 있습니다.
만약 웹 서버가 Apache인 경우, .htaccess 파일에 다음과 같은 코드를 추가함으로써 브라우저가 리소스를 최대 1년간 저장하도록 지시할 수 있습니다.
이런 내용을 찾아서 당연하게 Tomcat서버에 있는 web.xml 에
<filter>
<filter-name>cacheControlFilter</filter-name>
<filter-class>com.config.CacheControlFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cacheControlFilter</filter-name>
<url-pattern>*.js</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>cacheControlFilter</filter-name>
<url-pattern>*.css</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>cacheControlFilter</fileter-name>
<url-pattern>*.png</url-pattern>
</fileter-mapping>
<fileter-mapping>
<fileter-name>cacheControlFileter</fileter-name>
<url-pattern>*.jpg</url-pattern>
</fileter-mapping >
<fileter-mapping>
<fileter-name>cacheContorlFileter</fileter-name>
<url-pattern>*.unityweb</url-pattern >
</filter-mapping >
이런 내용의 코드를 추가하고 프로젝트에는 아래와 같이 설정했는데
package com.config;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
public class test implements Filter{
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse httpResponse = (HttpServletResponse) response;
System.out.println("에러테스트 Filter입니다");
System.out.println(response);
System.out.println("에러테스트 Filter입니다");
httpResponse.setHeader("Cache-Control", "public, max-age=31536000"); // Set cache policy
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("에러테스트 init입니다");
// Initialization logic...
}
@Override
public void destroy() {
System.out.println("에러테스트 destory입니다");
// Cleanup logic...
}
}
GPT에게물어봐 추가한 내용이였다..근데 서버에 web.xml에 필터를 설정하면 자꾸 서버가 404 에러가 생기는 문제가 발생해서 필터 위치도 옮겨보고..코드도 바꿔보고 다해보았지만 같은 결과였다. 그러다 문득 왜 서버 전체를 관리하는 web.xml에 설정을 해야하나?
나는 특정 프로젝트의 정적 리소스만 캐시데이터에 저장하고싶은데
라는 생각에 GPT 와 다시 씨름을한 결과 프로젝트에 web.xml을 추가하고 해당 코드를 넣어보기로했다!!
결과는!!!
똑같았다 아무리 설정을해도 Cache-Control값은 변하지 않았다.
그러다가 로그인처리를 위해 로그인 인터셉터를 한부분이 생각났는데 어떤 페이지를 가던 로그인 유무를 확인해 처리하는 부분이니 페이지가 로드될때 캐시값을 지정할수있지 않을까 라는 생각에 WebMvcCofig라는 파일을 보앗다 이곳에서 로그인인터셉터를 등록하니까!!
package com.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.CacheControl;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.concurrent.TimeUnit;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
private final LoginInterceptor loginInterceptor;
public WebMvcConfig(LoginInterceptor loginInterceptor) {
this.loginInterceptor = loginInterceptor;
}
// @Override
public void addInterceptors(InterceptorRegistry registry) {
System.out.println("로그인 인터셉터 등록");
registry.addInterceptor(loginInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/");
}
@Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/templates/", "classpath:/static/")
.setCacheControl(CacheControl.maxAge(10, TimeUnit.MINUTES));
}
}
코드를 보니 setCacheControl이 보엿다.. maxAge또한 개발자도구에서 확인한 값 같았다. 그래서 이부분을
.setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS).cachePublic());
이렇게 수정하니 CacheControl값이 1년으로 변했다. 이렇게 지정하면 서버는 처음에만 정적컨텐츠를 다운받고 그뒤로 1년까지는 캐시데이터에서 자료를 받아와서 유니티같은 큰 파일의 로드시간을 단축할수있다.
GPT와 말싸움한 시간이 아깝긴 하지만 좋은 정보를 알아가서 다행이다!!
위에 했던 서버에 설정하고 web.xml을 설정하는게 틀린건 아니다 다만 이 프로젝트의 방식에는 사용하지 않을뿐!!다른곳에서는 쓰일테니 기억하고 있어야겠다.
시간이 줄어든걸 확인할수있다!