犯人を捜す
4834 ワード
犯人を捜す
これは1篇のストーリで、技术のようで、私达が追求したのは1つの结末ではありませんて、あれらが深く启発されて共感する过程で、それは私达の成长の経験と生产力の积み重ねです!
物語は「狂った」ionic 3アプリケーションから始まる
ページが開いて、何もしていない5 sの中でangularのコードはずっと走っているようです!
chromeパフォーマンスデバッグツールを開くと、recorded 5秒、密な呼び出しスタックが、見るに忍びない!
Quistion 1:まさか真犯人はangular臓検査で、循環臓検査が発生しましたか??この問題を明らかにする前に、angular臓検査という大物を紹介します.
Rope 1:angular 2以降の汚れ検査方式
次世代のangularはangularjs(ng 1)で唾棄された汚い検査戦略を変えた.
データ・ストリームの変更
Angularjsの戦略::again and againが安定するまでです.すなわち、非同期イベントが汚れ検査をトリガーした後、汚れ検査の発生中にscope値が変化すると、scope上のデータが安定するまで汚れ検査が再びトリガーされます.このようなプロセスでは、汚れチェックがいつ、どのオブジェクトが変更されたかによるdom更新を見つけるのは難しい.Angularのポリシー:コンポーネントツリーの上から下まで、各コンポーネントは順番に自分の汚れ検査を行います.以下の図のように、左側がmodel右側がdomツリーであり、コンポーネントツリーでもあり、modelデータの変更ごとに汚れ検査がトリガーされ、検査ごとにノードから一方向に下に下がり、今回の検査時間のクリップではmodelの変更は許可されず、modelデータは安定した状態にある.
誰がangularに汚い検査の変化を教えたの?
Angularjsの方法:ngイベントを注入して汚れ検査を通知します.たとえば、jsオリジナルのsettimeoutでmodel値を変更することはできません.ngイベント$settimeoutを注入する必要があります.Angularjs方式:zone.js(big manでもあり、私のNgZone.jsの文章を読むことができます.https://segmentfault.com/a/11...).何もしないで、原生は勝手に書いて、自然にangularに汚い検査をするように知らせます.answer 1:以上の手がかりからangularが循環汚れ検査を起こしたわけではないと断定できる
Quistion 2:コンポーネントツリーの上から下へコンポーネントを1つずつ汚れ検査を行っているのではないでしょうか.コンポーネントツリーが膨大でlogが多すぎてcheckedが多すぎて、単一のコンポーネント汚れ検査を何度も実行しているのではないでしょうか.
Rope 2:angular汚れ検査ポリシー
まず現場を見てみましょう.上の図にはコードchangeDetection:ChangeDetection Strategyが囲まれています.OnPush、それは何をしていますか?汚れた検査のポリシーを変えることができます.上のコンポーネントツリーのノードeventが汚れ検査をトリガーし、コンポーネントツリー全体のノードが汚れ検査をしますよね?はい、デフォルトのポリシーはこうです.しかしangularは、OnPushポリシーを使用してより賢くすることができます.このポリシーにより、inputオブジェクト参照ポインタが変化していないときに、コンポーネントがノードおよびノードの汚れチェックをスキップします(注意:オブジェクト参照ポインタの変化です).example 1:
依然として上から下まで、angularはコンポーネントのパスを含むすべてのcomponentを見つけて汚い検査を行います(最上位コンポーネントがonPushポリシーを設定している場合でも).
answer 2:コンポーネントツリーが膨大で汚れの検査が多くないことは明らかです.onPushポリシーを追加したため、inputも変更されていません.このコンポーネントとこのコンポーネントの下のコンポーネントは汚れていないはずです.onPushポリシーを追加したが、ページにはまだ実行すべきでないコードがたくさん実行されています.下図は、ページが安定して静止している状態で5 s以内のブラウザの実行状況を記録しています.左図はonPushポリシーが追加されていないレコード、右図はonPushポリシーが追加されたレコードで、onPushポリシーが追加されているのはscript、render、Paintingが実行されていることがわかります.
呼び出しスタックを見てみましょう.次の図です.
図からスタックNgZoneを呼び出すコードが実行されていることを発見しました.Rope 1でNgZoneに言及したことを覚えていますか.汚い検査を開始する通知者は、オリジナルイベントを代理し、任意のオリジナル非同期イベントのトリガがNgZoneの実行を引き起こす.では、きっとオリジナルイベントがずっとLoopで実行されているに違いない!
【注:注意深い人は図の中にangular.coreのコードが実行されていることを発見する学生もいるかもしれません.answer 2で汚れ検査はしないと言っているのではないでしょうか.確かに汚れ検査はしません.rope 2でも汚れ検査戦略の原理を説明しています.汚れ検査の前にチェックコンポーネントinputを引用して汚れ検査をするかどうかを決めることを忘れないでください.
Quistion 3:誰がNgZoneをからかってるの?パフォーマンス分析の呼び出しスタックを見続けます.この関数が「犯罪現場」に入ったことがあれば、足跡を見つけることができます.Look this!animationを見つけたjsが実行するstep関数.
look this!やはりrequestAnimationFrameタイマ()のオリジナルイベントが実行され、破棄されていません!
answer 3:ヤクザはechartsのanimationだったのか.jsあるいはechartsコアコンポーネントzrenderはアニメーション終了後にanimationのstopメソッドを呼び出さず、とにかく真犯人はecharts!(echartsを使用している場合は、デバッグツールを開くと、そのコードがloopで実行されていることがわかります)
犯人が見つかったが、被害者はまだ慰めて解決しなければならない.どうやって解決するのか.echartsを廃棄しますか?嫌がらせをしてもやめられないごろつきがいることを知っておく必要があります.echartsの描画効率はモバイル端末では悪くないことを認めなければなりません.地図もあります.他のchart pluginで誰が市の地図を描いてあげますか.この時Angularをもう1本持たなければならなくて、私たちはechartsを管理できませんが、NgZoneはとても開放的なやつです.私たちに多くの自由な操作の空間を与えて、下のsampleのようにrunOutsideAngularを使って小包の関数の内部で実行するコードをzoneをスキップします.jsのパッケージ.あのechartsのrequestAnimationFrameは二度と私たちのNgZoneに迷惑をかけない.
最適化後5 s以内のperfermanceを図に示す.
物語の結末
最適化の結果は最も完璧ではないが、ページが安定して静止している状態でscript(echartsのbad code)が実行されていることが図からわかる.echartsのloop requestAnimationFrame問題をどのように解決するか、その後issueをechartsチームに残して解決しましょう.
これは1篇のストーリで、技术のようで、私达が追求したのは1つの结末ではありませんて、あれらが深く启発されて共感する过程で、それは私达の成长の経験と生产力の积み重ねです!
物語は「狂った」ionic 3アプリケーションから始まる
ページが開いて、何もしていない5 sの中でangularのコードはずっと走っているようです!
chromeパフォーマンスデバッグツールを開くと、recorded 5秒、密な呼び出しスタックが、見るに忍びない!
Quistion 1:まさか真犯人はangular臓検査で、循環臓検査が発生しましたか??この問題を明らかにする前に、angular臓検査という大物を紹介します.
Rope 1:angular 2以降の汚れ検査方式
次世代のangularはangularjs(ng 1)で唾棄された汚い検査戦略を変えた.
データ・ストリームの変更
Angularjsの戦略::again and againが安定するまでです.すなわち、非同期イベントが汚れ検査をトリガーした後、汚れ検査の発生中にscope値が変化すると、scope上のデータが安定するまで汚れ検査が再びトリガーされます.このようなプロセスでは、汚れチェックがいつ、どのオブジェクトが変更されたかによるdom更新を見つけるのは難しい.Angularのポリシー:コンポーネントツリーの上から下まで、各コンポーネントは順番に自分の汚れ検査を行います.以下の図のように、左側がmodel右側がdomツリーであり、コンポーネントツリーでもあり、modelデータの変更ごとに汚れ検査がトリガーされ、検査ごとにノードから一方向に下に下がり、今回の検査時間のクリップではmodelの変更は許可されず、modelデータは安定した状態にある.
誰がangularに汚い検査の変化を教えたの?
Angularjsの方法:ngイベントを注入して汚れ検査を通知します.たとえば、jsオリジナルのsettimeoutでmodel値を変更することはできません.ngイベント$settimeoutを注入する必要があります.Angularjs方式:zone.js(big manでもあり、私のNgZone.jsの文章を読むことができます.https://segmentfault.com/a/11...).何もしないで、原生は勝手に書いて、自然にangularに汚い検査をするように知らせます.answer 1:以上の手がかりからangularが循環汚れ検査を起こしたわけではないと断定できる
Quistion 2:コンポーネントツリーの上から下へコンポーネントを1つずつ汚れ検査を行っているのではないでしょうか.コンポーネントツリーが膨大でlogが多すぎてcheckedが多すぎて、単一のコンポーネント汚れ検査を何度も実行しているのではないでしょうか.
Rope 2:angular汚れ検査ポリシー
まず現場を見てみましょう.上の図にはコードchangeDetection:ChangeDetection Strategyが囲まれています.OnPush、それは何をしていますか?汚れた検査のポリシーを変えることができます.上のコンポーネントツリーのノードeventが汚れ検査をトリガーし、コンポーネントツリー全体のノードが汚れ検査をしますよね?はい、デフォルトのポリシーはこうです.しかしangularは、OnPushポリシーを使用してより賢くすることができます.このポリシーにより、inputオブジェクト参照ポインタが変化していないときに、コンポーネントがノードおよびノードの汚れチェックをスキップします(注意:オブジェクト参照ポインタの変化です).example 1:
@Component({ selector: 'echart', template: `
`, changeDetection: ChangeDetectionStrategy.OnPush }) export class ChartComponent { @Input('option') option: any; constructor() { } ngOnInit(): void { window.addEventListener('resize', this.resize, true); } click():void{ this.option= { title:'hi' } } resize() { this.option.title = 'Hi' } }
这个例子中,当页面窗口发生变化是resize中修改title,,dom不会有任何更新。如下图:
而当click方法触发时,该组件会进行脏检查并更新dom。
如果使用了OnPush策略,又想让resize中的修改能能更新dom怎么办?代码如下
constructor(private ref: ChangeDetectorRef) {}
resize() {
this.option.title = 'Hi'
this.ref.markForCheck();
}
依然として上から下まで、angularはコンポーネントのパスを含むすべてのcomponentを見つけて汚い検査を行います(最上位コンポーネントがonPushポリシーを設定している場合でも).
answer 2:コンポーネントツリーが膨大で汚れの検査が多くないことは明らかです.onPushポリシーを追加したため、inputも変更されていません.このコンポーネントとこのコンポーネントの下のコンポーネントは汚れていないはずです.onPushポリシーを追加したが、ページにはまだ実行すべきでないコードがたくさん実行されています.下図は、ページが安定して静止している状態で5 s以内のブラウザの実行状況を記録しています.左図はonPushポリシーが追加されていないレコード、右図はonPushポリシーが追加されたレコードで、onPushポリシーが追加されているのはscript、render、Paintingが実行されていることがわかります.
呼び出しスタックを見てみましょう.次の図です.
図からスタックNgZoneを呼び出すコードが実行されていることを発見しました.Rope 1でNgZoneに言及したことを覚えていますか.汚い検査を開始する通知者は、オリジナルイベントを代理し、任意のオリジナル非同期イベントのトリガがNgZoneの実行を引き起こす.では、きっとオリジナルイベントがずっとLoopで実行されているに違いない!
【注:注意深い人は図の中にangular.coreのコードが実行されていることを発見する学生もいるかもしれません.answer 2で汚れ検査はしないと言っているのではないでしょうか.確かに汚れ検査はしません.rope 2でも汚れ検査戦略の原理を説明しています.汚れ検査の前にチェックコンポーネントinputを引用して汚れ検査をするかどうかを決めることを忘れないでください.
Quistion 3:誰がNgZoneをからかってるの?パフォーマンス分析の呼び出しスタックを見続けます.この関数が「犯罪現場」に入ったことがあれば、足跡を見つけることができます.Look this!animationを見つけたjsが実行するstep関数.
look this!やはりrequestAnimationFrameタイマ()のオリジナルイベントが実行され、破棄されていません!
answer 3:ヤクザはechartsのanimationだったのか.jsあるいはechartsコアコンポーネントzrenderはアニメーション終了後にanimationのstopメソッドを呼び出さず、とにかく真犯人はecharts!(echartsを使用している場合は、デバッグツールを開くと、そのコードがloopで実行されていることがわかります)
犯人が見つかったが、被害者はまだ慰めて解決しなければならない.どうやって解決するのか.echartsを廃棄しますか?嫌がらせをしてもやめられないごろつきがいることを知っておく必要があります.echartsの描画効率はモバイル端末では悪くないことを認めなければなりません.地図もあります.他のchart pluginで誰が市の地図を描いてあげますか.この時Angularをもう1本持たなければならなくて、私たちはechartsを管理できませんが、NgZoneはとても開放的なやつです.私たちに多くの自由な操作の空間を与えて、下のsampleのようにrunOutsideAngularを使って小包の関数の内部で実行するコードをzoneをスキップします.jsのパッケージ.あのechartsのrequestAnimationFrameは二度と私たちのNgZoneに迷惑をかけない.
export class EChartsComponent implements OnInit, OnDestroy {
@Input() chartid: string;
@Input('option') option: any;
private chart: any;
@ViewChild('root')
private root;
constructor(private ngZone: NgZone) {
}
resizeListener = () => this.resize();
ngOnInit(): void {
this.ngZone.runOutsideAngular(() => {
this.chart = echarts.init(this.root.nativeElement);
this.chart.setOption(this.option, true);
window.addEventListener('resize', this.resizeListener, true);
})
}
}
最適化後5 s以内のperfermanceを図に示す.
物語の結末
最適化の結果は最も完璧ではないが、ページが安定して静止している状態でscript(echartsのbad code)が実行されていることが図からわかる.echartsのloop requestAnimationFrame問題をどのように解決するか、その後issueをechartsチームに残して解決しましょう.