extjs中js资源缓存策略

简介: http的缓存协商 浏览器对静态文件的缓存主要是通过cache-control来控制的,cache-control可以设置no-cache,max-age以及must-revalidate等来设置缓存策略。 如果max-age> 0则会在max-age的时间内不访问服务器,用本地缓存的静态文件代替。 如果max-age<=0则会每次都询问服务器,资源文件是否有修改,

http的缓存协商

浏览器对静态文件的缓存主要是通过cache-control来控制的,cache-control可以设置no-cache,max-age以及must-revalidate等来设置缓存策略。
如果max-age> 0则会在max-age的时间内不访问服务器,用本地缓存的静态文件代替。
如果max-age<=0则会每次都询问服务器,资源文件是否有修改,有则200,无则304。这相当于f5操作。
no-cache表示不理会缓存协商,全部重新加载。这相当于是ctrl+f5操作。
must-revalidate表示必须遵循策略规则。因为浏览器有时候会提取过期的缓存,设置了这个策略后,浏览器会严格遵循客户设置的策略。

服务器在首次应答客户的request时,会返回last-modified和etag给浏览器,浏览器将cache住这些信息,下一次request服务器时就会在header里带上if-modified-since和if-non-match信息,这两个分别对应last-modified和etag。服务器会提取对应资源的modified时间和etag来做对比,如果有改变则返回200并且response last-modified和etag给客户端,没变则返回304不需要改变。

目前tomcat已经支持etag, tomcat是根据文件的contentLength和lastModified混合编码生成串儿。因为last-modified因为只支持到秒级,所以对于秒内频繁修改的静态资源效率会比较低下,etag则很好的避免了这一点。

对静态资源的处理策略

一般对于静态资源,服务器端会通过过滤机制,自动为响应的header里添加max-age信息,这样浏览器就会在本地cache住这些资源。

我们最近的一个项目,前台使用extjs,使用extjs带来的成本就是所有的页面几乎都是js页面了。因为静态js的文件量大,且我们系统的运营地点非洲网络条件不太好,带宽资源比较宝贵,不能承受频繁的静态资源请求(这里需要提一点,即使是web服务器最终响应不需要更改的304请求,对系统也是一次带宽开销,我们也想尽力避免),于是我们想通过cache-contro将js文件cache在本地。但是这就带来一个问题,对于紧急发布的一些前台界面,因为超时机制会无法及时在系统层面体现。

所以我们必须实现一种机制,在发布了新的js后,对应的引用该js的地方都要能自动刷新。所以最简单的方法就是每次编译完后生成一个版本号,然后对每个引用js的url都添加上版本号就ok。这样就可以保证在一次发布周期内始终只有一个js版本。

Extjs的动态加载策略

Extjs实现了一套动态加载策略,可以通过js语言的方式去直接引入一个资源(Ext.require),这和我们平时使用的静态引用(<script src=" xxx")是完全不同的。所以决定研究一下extjs的动态加载机制。

目前网上有开源的extjs4的源码,在动态load script时,会读取config配置信息,config可以通过loader.setConfig来配置。config里有两个参数需要注意,一个是disableCachingParam还有一个是disableCaching,后者代表是否需要为每一个请求都声称一个版本信息,前者是版本信息的参数名,默认是_dc.

loadScriptFile: function(url, onLoad, onError, scope, synchronous) {
            if (isFileLoaded[url]) {
                return Loader;
            }

            var config = Loader.getConfig(),
                noCacheUrl = url + (config.disableCaching ? ('?' + config.disableCachingParam + '=' + Ext.Date.now()) : ''),
                isCrossOriginRestricted = false,
            
            if (!synchronous) {
                onScriptError = function() {
                    //<debug error>
                    onError.call(scope, "Failed loading '" + url + "', please verify that the file exists", synchronous);
                    //</debug>
                };

                scriptElements[url] = Loader.injectScriptElement(noCacheUrl, onLoad, onScriptError, scope);
            } else {
                /**
                * 组装xmlhttprequest对象,根据浏览器支持情况初始化activexobject或者xmlhttprquest
                */
                try {
                    xhr.open('GET', noCacheUrl, false);
                    xhr.send(null);
                } catch (e) {
                    isCrossOriginRestricted = true;
                }

                /**
* 伪代码,跨域失败,执行onerror回调函数
*/

                else if ((status >= 200 && status < 300) || (status === 304)
                    //<if isNonBrowser>
                    || isPhantomJS
                    //</if>
                ) {
                    //调用成功, 记录调试信息
           Ext.globalEval(xhr.responseText + debugSourceURL);
                    onLoad.call(scope);
                }
                else {
                   /**
   * 伪代码,执行onerror回调函数
   */
                }

                // Prevent potential IE memory leak
                xhr = null;
            }
        }

代码很好理解,同步时直接加载,并且通过eval方法直接执行响应的js文件(responseText),异步时则通过injectScriptElement加载,同步还是异步可以通过loader里的syncModeEnabled来设置,默认是false。

注意下这个方法里的noCacheUrl,根据disableCaching决定要不要为url加上版本信息,缓存无效时会默认以当前时间为版本号。

injectScriptElement: function(url, onLoad, onError, scope, charset) {
            var script = document.createElement('script'),
                dispatched = false,
                /**
* 设置onload和onerror的回调函数,主要是通过dispatched参数做幂等性校验
                * 为了兼容ie,script需要支持onreadystatechange事件,这个事件会又多个状态,所以需要做幂等校验
*/

            script.type = 'text/javascript';
            script.onerror = onErrorFn;
            charset = charset || config.scriptCharset;
            if (charset) {
                script.charset = charset;
            }

            //兼容ie
            if ('addEventListener' in script ) {
                script.onload = onLoadFn;
            } else if ('readyState' in script) {   // for <IE9 Compatability
                script.onreadystatechange = function() {
                    if ( this.readyState == 'loaded' || this.readyState == 'complete' ) {
                        onLoadFn();
                    }
                };
            } else {
                 script.onload = onLoadFn;
            }

            script.src = url;
            (Loader.documentHead || document.getElementsByTagName('head')[0]).appendChild(script);

            return script;
        }
该方法主要是创建了一个script的元素,url是前面方法生成的。

因为我们需要的是基于发布版本信息的缓存,所以只需要将noCacheUrl的版本信息由当前时间戳改成编译产生的版本信息即可。

最后,注意,因为extjs6做了比较大的重构,url生成挪到了ext.data.proxy.server里的buildUrl里:
url = Ext.urlAppend(url, Ext.String.format("{0}={1}", me.getCacheString(), Ext.Date.now())),搜索这一行即可。


目录
相关文章
|
4月前
|
缓存 负载均衡 网络协议
电商API接口性能优化技术揭秘:缓存策略与负载均衡详解
电商API接口性能优化是提升系统稳定性和用户体验的关键。本文聚焦缓存策略与负载均衡两大核心,详解其在电商业务中的实践。缓存策略涵盖本地、分布式及CDN缓存,通过全量或部分缓存设计和一致性维护,减少后端压力;负载均衡则利用反向代理、DNS轮询等技术,结合动态调整与冗余部署,提高吞吐量与可用性。文中引用大型及跨境电商平台案例,展示优化效果,强调持续监控与迭代的重要性,为电商企业提供了切实可行的性能优化路径。
|
5月前
|
监控 算法 JavaScript
公司局域网管理视域下 Node.js 图算法的深度应用研究:拓扑结构建模与流量优化策略探析
本文探讨了图论算法在公司局域网管理中的应用,针对设备互联复杂、流量调度低效及安全监控困难等问题,提出基于图论的解决方案。通过节点与边建模局域网拓扑结构,利用DFS/BFS实现设备快速发现,Dijkstra算法优化流量路径,社区检测算法识别安全风险。结合WorkWin软件实例,展示了算法在设备管理、流量调度与安全监控中的价值,为智能化局域网管理提供了理论与实践指导。
133 3
|
5月前
|
缓存 搜索推荐 CDN
HTTP缓存策略的区别和解决的问题
总的来说,HTTP缓存策略是一种权衡,需要根据具体的应用场景和需求来选择合适的策略。理解和掌握这些策略,可以帮助我们更好地优化网页性能,提高用户的浏览体验。
129 11
|
4月前
|
存储 缓存
.NET 6中Startup.cs文件注入本地缓存策略与服务生命周期管理实践:AddTransient, AddScoped, AddSingleton。
记住,选择正确的服务生命周期并妥善管理它们是至关重要的,因为它们直接影响你的应用程序的性能和行为。就像一个成功的建筑工地,工具箱如果整理得当,工具选择和使用得当,工地的整体效率将会大大提高。
162 0
|
7月前
|
数据采集 缓存 JavaScript
数据抓取的缓存策略:减少重复请求与资源消耗
本教程聚焦于提升爬虫效率与稳定性,通过结合缓存策略、代理IP技术(如爬虫代理)、Cookie和User-Agent设置,优化数据采集流程。以知乎为例,详细讲解如何抓取指定关键词的文章标题和内容。内容涵盖环境准备、代码实现、常见问题及解决方案,并提供延伸练习,帮助读者掌握高效爬虫技巧。适合具备Python基础的初学者,助你规避网站机制,顺利获取目标数据。
177 2
数据抓取的缓存策略:减少重复请求与资源消耗
|
8月前
|
JavaScript 前端开发
Node.js 中实现多任务下载的并发控制策略
Node.js 中实现多任务下载的并发控制策略
179 15
|
11月前
|
缓存 监控 前端开发
在资源加载优化中,如何利用浏览器缓存提升性能?
通过以上这些方法,可以有效地利用浏览器缓存来提升资源加载的性能,减少网络请求次数,提高用户体验和应用的响应速度。同时,需要根据具体的应用场景和资源特点进行灵活调整和优化,以达到最佳的效果。此外,随着技术的不断发展和变化,还需要持续关注和学习新的缓存优化方法和策略。
309 53
|
11月前
|
Web App开发 缓存 UED
如何设置浏览器的缓存策略?
【10月更文挑战第23天】通过合理地设置浏览器的缓存策略,可以在提高网页性能、减少网络流量的同时,确保用户能够获取到最新的内容,从而提升用户体验和网站的性能优化效果。
893 60
|
10月前
|
缓存 API C#
C# 一分钟浅谈:GraphQL 中的缓存策略
本文介绍了在现代 Web 应用中,随着数据复杂度的增加,GraphQL 作为一种更灵活的数据查询语言的重要性,以及如何通过缓存策略优化其性能。文章详细探讨了客户端缓存、网络层缓存和服务器端缓存的实现方法,并提供了 C# 示例代码,帮助开发者理解和应用这些技术。同时,文中还讨论了缓存设计中的常见问题及解决方案,如缓存键设计、缓存失效策略等,旨在提升应用的响应速度和稳定性。
131 13
|
11月前
|
缓存 监控 JavaScript
Vue.js 框架下的性能优化策略与实践
Vue.js 框架下的性能优化策略与实践