Omi官方外掛系列 - omi-transform介紹

【當耐特】發表於2017-04-05

原文連結 - https://github.com/AlloyTeam/omi/tree/master/tutorial

寫在前面

Omi框架正式釋出了omi-transform作為Omi元件化開發特效運動解決方案,讓你輕鬆在Omi專案裡快速簡便支援CSS3 Transform設定。先說說 transform.js (npm上的名字是 css3transform)。transform.js作為移動Web特效解決方案,在手Q興趣部落、日跡、QQ群、QQ附近等專案中廣泛使用,以激進的修改DOM屬性為代價,帶來極為便利的可程式設計性。

你可以通過http://alloyteam.github.io/AlloyTouch/transformjs/快速瞭解它。

上面官網的例子都是原聲js的,transformjs也擁有react版本,你也可以在react中以宣告式的方式使用transformjs:

render() {
    return (
        <Transform
          translateX={100}
          scaleX={0.5}
          originX={0.5}>
          <div>sth</div>
        </Transform>
    );
}

3分鐘掌握omi-transform

演示

http://alloyteam.github.io/omi/plugins/omi-transform/example/simple/

通過npm安裝

npm install omi-transform

使用

import Omi from 'omi';
import OmiTransform from '../../omi-transform.js';

OmiTransform.init();

class App extends Omi.Component {
    constructor(data) {
        super(data);
    }

    installed(){
        setInterval(function(){
            this.refs.test.rotateZ += 0.1;
        }.bind(this));
    }

    render() {
        return  `
            <div omi-transform class="test" ref="test" rotateZ="45" translateX="100" perspective="400">
                omi-transform
            </div>

        `;
    }
}

Omi.render(new App(),"#container");
  • 在需要使用transformjs的DOM上標記 omi-transform 和 ref="xxx"
  • 在元件函式裡便可以使用 this.refs.xxx 來讀取或者設定 css transform屬性
  • this.refs.xxx 支援 "translateX", "translateY", "translateZ", "scaleX", "scaleY", "scaleZ", "rotateX", "rotateY", "rotateZ", "skewX", "skewY", "originX", "originY", "originZ", "perspective"這些屬性設定和讀取
  • 沒有標記perspective的話程式碼沒有透視投影

效能對比

因為react版本會有diff過程,然後apply diff to dom的過程,state改變不會整個innerHTML全部替換,所以對瀏覽器渲染來說還是很便宜,但是在js裡diff的過程的耗時還是需要去profiles一把,如果耗時嚴重,不在webworker裡跑還是會卡住UI執行緒導致卡頓,互動延緩等。所以要看一看CPU的耗時還是很有必要的。

下面資料是對比omi-transform和react-transform,兩種方式使用chrome profiles了一把。

先看總耗時對比

react-transform:
Omi官方外掛系列 - omi-transform介紹

omi-transform:
Omi官方外掛系列 - omi-transform介紹

  • react在8739秒內CPU耗時花費了近似1686ms
  • Omi方式在9254ms秒內CPU耗時花費近似700ms

在不進行profiles就能想象到react是一定會更慢一些,因為state的改變要走把react生命週期走一遍,但是可以看到react的耗時還是在可以接受的範圍,沒有慢到難以接受。

而Omi的方式則和傳統的原生js的耗時一模一樣。以為運動過程不進行DOMI Diff!!

慢著?不進行Diff?意思就是元件不進行update?
意思就是萬一元件update,所有運動的狀態都會丟失?Omi怎麼解決這個問題?

狀態儲存

元件裡的某個DOM在運動過程中,可能會由於其他邏輯,進行update。有可能是使用者互動,有可能是資料返回的回撥。所以,update前後,DOM的狀態的保留顯得尤其重要,不然的話就會有閃爍、跳躍的效果或者其他顯示邏輯錯誤。

    ...
    constructor(data) {
        super(data);
        //初始狀態
        this.rotateZ  = 45;
    }

    installed(){
        setInterval(() =>{
            //sync for update 記錄同步到this.rotateZ
            this.rotateZ = this.refs.test.rotateZ += 0.1;
        });
    }

    render() {
        //通過 ${this.rotateZ} 設定rotateZ
        return  `
            <div omi-transform class="test" ref="test" rotateZ="${this.rotateZ}" translateX="100" perspective="400" >
                omi-transform
            </div>

        `;
    }
    ...

上面的所有例子和程式碼可以在這裡找到。

Omi相關

Omi官方外掛系列 - omi-transform介紹

相關文章