由于angular中使用了大量自定义标签,所有会在浏览器端做很多的计算工作,有没有一种工具可以将这件事情在发布前先编译好,这样就可以避免大部分浏览器的计算工作,有这样的工具吗?
某草草2017-05-15 16:52:43
实际上这是一个很大的话题,不过我不打算在这里展开讲,因为太费劲了——要搞明白这里面的全部细节,只懂 Angular 是不够的。
重点概述我就说两点:
模板的预编译不难(此处指的是把静态的模版缓存至 $templateCache
,从而在应用加载的时候直接把模版载入内存),但是对 Angular 这样重度依赖数据绑定的框架来说,编译模版那点工作量不值一提。除非说你的项目无比庞大,模版多的管理不过来——但此时更严重的是本地开发时模版预编译的时间损耗——所以把巨型应用模块化分割才是正途;这就有点跑题了。像 ng-repeat
这类的指令会是我们想“减轻浏览器负担”的目标,也就是在浏览器载入之前就把此类指令展开,填充 DOM;而像 ng-if
这类的指令则不能预先处理,因为它们很多时候都依赖“数据绑定”。
我给你举个例子,比如说页面上有一个部分由 ng-if
控制,根据当前用户是否有权限来判断,但是是否有权限这个状态必须得等用户登录(或者别的预置条件)之后才能获取到——我们要如何在浏览器之外预处理 ng-if
?它会涉及到 DOM 操作,它也会影响到浏览器性能,你说是预处理还是不预处理?如果所有这样的标签都要作一番权衡才能决定是否预处理,那这个代价也太大了,不如不用 Angular。Angular 做不到完全的静态化(顺便一提,ESNext 的 Object.observe()
将是解决的钥匙),而半静态化则是可以的,但往往不是因为浏览器性能的缘故。
实际上你要相信现代浏览器的性能是很强的,客户端渲染并非很多人想象中的“性能瓶颈”,很多在服务端渲染的尝试(对于 Angular 来说)反而主要是为了搜索引擎优化而不是性能提升。我给你一些关键字去调研吧,这是一个学习的好机会(用英文搜索引擎,中文的没什么有用的结果):
总结一下。对于基于“数据绑定”为主的 JS 应用来说(如 Angular),由于目前语言与环境层面的支持还不到位(如前面提到的 Object.observe()
等),因而无法在 DOM 层面实现完整的预编译或静态化。在进入浏览器之前,通过其他方式预处理部分 DOM 是可能的,但是对应用的整体性能提升或/及浏览器的性能提升并没有天差地别的影响,并且实现这些预处理本身的代价并不小;除非你是做对性能严苛至极的应用(比如淘宝这样的?),否则还是斟酌而定吧。
ringa_lee2017-05-15 16:52:43
从搜索引擎优化角度看,这么做也是很有意义的。适合AngularJS 的现成工具有
prerender.io
angularjs-server
淘宝的中途岛应该也是相近的出发点