【转】一些对TLF和FTE的思考

[原文链接: Some Thoughts on TLF & FTE 原文创作时间: July 13, 2010 原文作者: Grant Skinner ]

[原创翻译链接: http://www.smithfox.com/?e=74 , 转载请保留此声明, 谢谢]

[部分内容参考了 Tomyail的blog 的翻译文章 一些对TLF和FTE的思考 ]

这篇文章阐述了作者对Adobe TLF的架构实现的不足, 以及他的一些期望. 很少很少FTE相关内容. 没有怎么使用TLF的例子之类的内容. 但看完作者精辟的分析, 肯定使你对当前TLF不足, 乃至 Adobe framework 都会有一定的了解.

下面的翻译内容:

几个月前,我一直在思考关于TLF的一些事情: 怎么使用它,哪些是我喜欢的特征, 以及那些我所遇到的bug. 但不仅仅是这些, 还有关于它的原理和底层模型。我期望能过分享这些思考和来自社区的建议, 我能提供一些有用的反馈给Adobe,这将有助于TLF的未来发展.

背景

flash player 10 引入了新的flash.text.engine.*(FTE)包,这个包提供了一些处理低级文本的类。FTE又被flashx.textLayout.*包下面的一组类所继承, 这组类就是Text Layout Framework (TLF),TLF同时被flex和flash共享. TLF在FTE基础上做了一些抽象, 但仍然是比较低级的.

Flash通过一个新的组件, TLFTextField对外提供TLF功能, 这个组件集成在IDE里面了, 它提供了类似TextField API的高级抽象方法, 并且提供多种文字排版功能. 这些功能包括多列文本,文本线程(texttreads又称链接文本域),右到左和垂直的文字,以及一些印刷方面的增强.

Flex4框架通过3个基本组件实现TLF:Label,RichText以及RichEditableText,这些组件增加了文字处理能力.Label用于显示单行, 提供了对文本进行格式化的部分功能, RichText支持多行文本,并且可以嵌入图形以及文本格式化的全部功能.RichEditableText增加了链接,编辑,滚动以及选择功能. 但Flex并不支持文本线程(text threads).

原理

TLF说明了Adobe在API开发上思想转变, 借助TLF, Adobe选择了只暴露一些非常低级的player API, 然后在其之上建立一个"标准"的高级AS3 API. 这样做的原因主要考虑到减小播放器的尺寸,并且使TLF库的发展不依赖于播放器的升级而变化. 这意味着开发人员可以在新的播放器一发布出来就能利用新的TLF特征, 而不必再等到新播放器达到一个可接受的普及程度再考虑使用了。

其意图是好的,但我并不觉得这是最好的解决办法. 几乎没有例外, 文本是在Flash平台上的每一个项目的核心元素, 使文本功能依赖于Actionscript库所带来的各种问题, 个人觉得远远超过了上述所说的各种优点.

文件大小

核心TLF库的大小大约是160Kb.它是在你swf文件之外的一个签名的RSL(.swz)文件. 这意味着一旦用户下载了这个swz文件.它将存储在本地缓存中并且下次不用重新下载就可重复使用,多个域名也可以共享这个swz的.

这样很好, 但如果TLF是未来Flash的文本框架, 而文本又是用户体验的核心, 这会使flash播放器变小一点的优势变得没有意义.如果所有用户无论如何都得下载这个RSL, 你们就是在将问题扩大. 我也有这样的感觉(也许是错误的):这个功能直接内置在player中实现会更小一些。

即使使用RSL, 在flash专业版中使用TLFTTextField类也将使你的swf增加60kb.This is a pretty big hit for just putting hello world on the stage, and makes TLFunusable for banners and other experiences with file size restrictions. 使这一问题更加突出的是: Flash是将TLF作为文本选项, 而不是一个文本组件, 这使得用TLF的潜在成本更不清楚.

性能

由于TLF是用ActionScript写的, 所以它和别的as代码一样同样面临性能和内存问题. 相比以前AS的性能已经有所提高, 而且10.1在内存使用方面也有了明显的改善, 但AS的运行效率比原生代码还是要慢 *很多* (在许多情况下有10 ~ 100倍的差距),并且内存的使用量仍然很大。TLF很大程序上因此而表现糟糕, 相比于TextField, TLF使用了更多的CPU资源计算以及处理显示对象, 基于这个原因, Adobe不建议将TLF用于手机产品. 并且正在考虑专为移动设备开发另外一套轻量级的TLF实现, 我觉得很失望,有点讽刺是, 很重要的Flash平台的两个 新 举措, 同时开发却互不兼容。

另外TLF比TextField占用更多的内存, 除了自身的AS framework所需内存外, 它必须产生大量AS对象来描述文本的结构和排版, 还必须产生大量的显示对象(TextLine) 来显示文本.

更糟糕的是, 这些占用内存的对象始终为所有文本而产生和维护着, 而不是只处理屏幕或者滚动条内可见的部分文本. 当只有那些可见的文本渲染到屏幕时, 由于必须要被再次遍历全部TextLine实例, 从而计算是否应该排除在scroll rect范围外,使得每一个TextLine仍然有显示的消耗(display cost). 这意味着在滚动区域内有大量的文本, 将会在内存和性能两方面都有着非常高的成本, 而在TextField中, 这个成本是很低的.

Flash性能已经是够热的话题。TLF的AS实现将会使情况变得更糟。

一致性和复杂性

TLF代表了flash和flex团队的一次重大合作, 这次合作是一次 *伟大* 的事件!! 这些团队真的需要共同努力以创造一个统一的组件框架和综合创造平台. 我希望TLF提供了一个机会真正测试一下, 但不幸的是, 我认为他们做的还不够.

目前, Flash Pro有用TLFTextField提供了一个非常象样的TLF高级抽象, 它公开一个以几乎和TextField相同的API, 而且增加了很多的附加接口。这使得它的易于使用和便于扩展。

令人遗憾的是, Flex中似乎没有任何类似的TLF高级文本控制。即使TextArea也缺乏TextField的大部分功能. 即使为了实现一个非常简单的任务, 比如找一个字符位置, 你不得不费力地通过TLF库甚至涉及FTE来实现。

在这一点上, 我担心难以改造这些功能而集成到Flex的spark架构中。我同时也感到纳闷: 是否是因为这些功能用AS实现而产生了性能问题, 从而导致了在flex中还没有这些功能。

版本

我明白将TLF版本和flash player分开而带来的好处, 但也正是因为它带来了其它的问题: 首先, 它减少了缓存的RSL的效果, 它必须下载每一个新版本而缓存起来. 它也明显影响所有基于TLF的团队开发、自定义控件、商业或OSS(开放源码) 软件库/组件,就算这些都不是(也许除了最后一个)大问题, 他们也还是降低了该模型的整体效应。

思考

如果有位同学在深入地用尽了TextField API之后也搞不定某些事, 他就会被迫转而尝试用其它方法, 很可能是FTE(多列, 文本装饰). 我赞同flash player中包含低级的文本API, 不过, 我认为 文本 是互动媒体不可或缺的部分, 也应该是 平台 的不能不用的高性能的核心部分.

我真的很想看到的, 和FTE API一样低级的, 扩展自playe层面的和现在TLF相似的文本排版API. 这可能是 建立在 一组接口 ( 因为它已经 在很大程度上 是)之上 , 以方便 替换现有的 AS3 实现的这些类。此外, 我希望看到的一个可用的player层面实现的TextField, 实现了现在TLFTextField的大部分功能。而且会有一个ITextField接口, TextField也将改造实现这个接口。

理想的情况下,这将大大增强性能和减少内存占用,同时使开发人员能深入挖掘和创建自定义实现。还可保证Flash和Flex有一个一致的API和实现,甚至允许开发人员在不知道容器是是TLF还是TextField的情况下处理文字。虽然这会增加player的大小,它会占用一点整体带宽来用来下载有TLF有关的内容。Adobe甚至可以扩展player内建类而生成AS3类, 通过不断更新这些AS3类来更新TLF的某些方面。

可能为时已晚,但我不这么认为。当前player API不必改变, 这意味着目前的工作将不会中断。目前TLF API和TLFTextField能原生地在flash.*包中实现, 而不必中断当前的AS3版本. 未来版本的Flex框架能以非常小的影响而迁移到原生API中. 同样, Flash Pro的 TLFTextField 也可被剥离, and become viable for banners and mobile.

如果不能做到这点, 我想至少花时间修复和增强的TextField, 在TLF根本不是最好的选择的时候, 使我们可以继续使用它.

即使是来不及修复(在我看来)TLF,我觉得人们在讨论未来的决策时, 明确Adobe的新理念和忠告也是很重要的。我不认为Adobe应该象MS Silverlight那样(其中控制/组件都嵌入在播放器中),但我认为作为核心元素,TLF应该在播放器中。

我 想说的还有很 多 , 但是这 太长了 , 我认为 本文涵盖了 最紧迫的 话题。 我很想 听听 你 的意见 看法。

[原创翻译链接: http://www.smithfox.com/?e=74 , 转载请保留此声明, 谢谢]

[部分内容参考了 Tomyail的blog 的翻译文章 一些对TLF和FTE的思考 ]

在原文的comments中看到了一个adobe的和FTE的bug, https://bugs.adobe.com/jira/browse/FP-3133, 大家可以去投票, 促使adobe早点改进

smithfox said: 06-02-'11 22:18

不知在你认真看完这篇文章后, 你是否有和我有一样的感觉: 一片茫然.
我们应该怎么选择文本框架? 或是我们还有选择吗?
不过我不是一个迷信的人, 尽管这篇文章是很牛的Grant Skinner写的.

让我们看一下作者说TLF的不足的重点: TLF是用AS3库的方式来实现的, 而没有在flash player中用native实现.

  1. 从adobe来说, 其实TextField(在flash player中实现)本身就有很多的bug, TLF是比较复杂的, 放在player无疑会使flash player在相当长时间内无法稳定.
  2. 将TLF放在player还是AS3 lib中, 对于flash app来说, 其实不是非常重要,对flash app来说最重要的是API的稳定, 我们肯定不希望因为adobe将实现从as3 lib移到player中(或是相反), 我们就必须要大量改动现有的代码. TLF2.0和FXG相结合, 为API的长期稳定打下了基础.
  3. 我们最期望, 也是最有可能的是, AS3的运行效率将会持续地不断地得到提高, 这一点我们可以从Java的发展路线中得到启示.
    而且现在已经有这样的更高效的AS3的运行效率尝试了, 见 JITB http://blog.joa-ebert.com/2010/08/19/int..
    以这种方式提高效率, 对用户来说是代价最低的(不用改代码, 最多是重新编译, 这样可以省去大量regression bug的验证成本).
  4. 我们的大部分程序不是专门的文本处理程序, 要显示的最多也就一屏的字, 也不会用到很多不同风格的文本格式. 所以因scroll的出现面形成的TLF浪费很多的TextLine实例的可能性就很小.
  5. 幸运的是, FTE还是建立在player中的. 见 http://opensource.adobe.com/wiki/display..and TLF text in MX components
    原文如下: "FTE is the foundation for all future text functionality in the Player. TextField will be maintained for backward compatibility, but it will no longer be enhanced, and bug fixes are unlikely."
  6. 我在另一篇和本文有着很想似的外国文章的comments中看到了不同的声音, 呵呵, 这篇文章的标题更直接: "请少一点AS3 Lib,多一点原生的API吧, adobe求你了",http://artman.fi/2010/08/less-as3-framew..
    Paul.e.Taylor的comments中有一段说: 因为自己有做过一个Rich Text Framework的经验, 他想说FTE做的真的已经他妈的很完美了, 要知道文本的 "装饰/交互/排版" 和FTE要解决的事情完全是两码事, 用FTE的方式来处理TLF, 你会发现那是难以置信的低效.
    Paul.e.Taylor的感受, 用中国人的话就是"不养儿, 不知父母恩"呀, 这个观点正好对应Grant Skinner同学在文中说 "象FTE一样地处理TLF"的倡议.
  7. 对于有人用MS的Silverlight方式, 所有都放在player中实现, Paul.e.Taylor也指出了MS的特定性.
  8. 如果你不知道Paul.e.Taylor是何方神圣, 那就在网上找一下tinyTLF吧.http://www.tinytlf.org/
  9. 某blog中说: FTE 不但显示效果比 TextField 对象好,而且允许更精确地定位文本。可以使用 TextLine 的 ascent、descent、textWidth 和 textHeight 等属性精确地定位文本。
  10. 7yue在微博(http://t.sina.com.cn/7yue)中写道: AS3优化小技巧:Flash里处理只读字体效率最高的类是TextLine,而非TextField。如果你的Flash需要从外部加载文字并显示在Stage上,不需要用户编辑什么,请使用TextBlock.createTextLine方法(因为TextLine不能直接实例化)。
  11. 7yue在CSDN上授课说: 只读文字用flash.text.engine(FTE)、输入文本尽可能用textfield类、对于textfield对象不要使用=运算符,而使用appendtext()方法.
  12. Text Input - FTE TextField, TLFTextField, Custom Classhttp://forums.adobe.com/message/3255803