【IT168 评论】Web应用程序开发是倾向于在客户端运行所有用户逻辑和交互代码,让服务器暴露REST或者RPC接口。编译器是针对JS作为一个平台,第二版ECMAScript正是考虑到这一点在设计。客户端框架例如Backbone, Ember和Require鼓励创建功能丰富的应用程序,不仅有丰富的代码,而且各个组件,组件与数据之间有很多相互作用。
这真的很好,或许还能产生一些优秀的用户体验,但是毫无疑问的是,这是很难开发web应用程序和web页面。
根本原因是在互联网上服务你的代码和数据,运行在一些随机的浏览器上,在javascript中,这是一种你需要特别小心的语言,它是一个完全缺乏代码部署的平台。而且它不会很快就得到改善。我觉得如果星际迷航是现实生活,那么Jean-Luc Picard队长每隔一段时间不能打架的原因是他仍然是克林仪表板加载。
我想强调的是三个相对常见的错误和容易的解决方案,并且谈谈一些我们遇到的从ReadyForZero学到的特别的事情。
1.剥离“缓存清除”头信息
你可能使用CDN来缓存静态资源,这当然是合理的。如果你向服务器请求非缓存的资源(比如在AWS
http://example.com/js/main__V0123456789abcdef__.js
这很容易做到,你可以选择任意的Hash算法来生成一段指纹信息作为这个字符串,这样它就会随着文件内容变化而变化。当新的url被引用时,它不可能被缓存,这样就可以获取到服务器上的新版本。错误就发生在这里。在网络上有很多都建议剥离“缓存清除”头信息,而是让你的服务器直接提供新版本的文件。如果你有多台服务器集群这可能导致你的站点上不同文件(如:html、js)的版本不一致(如js已更新但是html(从另一台服务器请求)仍然是旧的),不仅如此,更严重是它很容易导致CDN缓存了错误的版本。这个错误是这样发生的:
• 初始阶段,所有的服务器都是HTML1 和JS1。
• 服务器A重启了,并提供HTML2和JS2。
• 一个客户端向CDN请求main__V2__.js,这个时候这个文件是新的所以CDN上没有缓存。
• CDN把这个请求传给了你设置的custom origin, 碰巧这个请求发到了服务器B上。
• 服务器B剥离了“缓存清除”字符串并返回旧的版本。
• CDN把旧版的的文件当新的缓存了。
这件事情考虑起来很简单明了,但是盲目的听从网络上的建议很可能导致错误。更糟糕的是在你这看起来一切都是好的你根本不知道发生了错误,但是其它地区的用户使用了不同CDN很可能缓存了错误的版本。解决方案是不要剥离“缓存清除”字符串并将静态资源存放在能够正确支持各个版本的地方。
2. 处理庞大的JS炸弹
每个人都知道,我们需要压缩我们的javascript文件,并把它们连接在一起。但是盲目地这样做并非明智之举。如果连接的文件很大,那么更有效的方法就是并行化。另外,如果你需要频繁的修改文件的某一部分,你可能会导致很多地方失效,而文件很大部分却没有被修改过。