vue 3ソースコードの解読のためのタイムスリップの使い方


今日は皆さんにソース解析の文章を持ってきました。emはvue 3についてのものです。vue 3のソースコードが放出された後、多くの文章がソースを分析しています。
しかし、今日私が解析したい部分はすでに廃案されたtime sling部分で、この部分のソースはすでにvue conf 2018のビデオに現れましたが、ソースはすでに取り消されました。その後も注目されないかもしれません。だから、大通りを壊すことはないはずです。
包装する
ソースを読む前に、まず包装して、きれいに調整できるファイルを包装することが重要です。
vue 3で使うrollupを包装します。まず改造します。

import cleanup from 'rollup-plugin-cleanup'
plugins: [
  cleanup() //      cleanup   
   
  tsPlugin,
  aliasPlugin,
  createReplacePlugin(isProductionBuild, isBunlderESMBuild, isCompat),
  ...plugins
],

cleanupプラグインを追加する目的は、コメントなしのファイルをパッケージ化することです。
以上、私個人がソースを読む習慣です。注釈とタイプの作用は目障りだと思います。
用例
私たちはソースを読む前に、正しい用例を実現する必要がありますが、このバージョンのソースコードを読んでいますか?それともclassのですか?どうすればいいですか?
この時、私達はテストの用例によって推測してコードを与えることができます。

function block () {
 const start = performance.now()
 while (performance.now() - start < 2) {
 }
}

class Test extend Component {
 render (props) {
  block()
  return h('li', props.msg)
 }
}

class App extend Component {
 msg = ''
 render () {
  const list = []
  for (let i = 0; i < 200; i++) {
   list.push(h(Test, { key: i, msg: this.msg }))
  }
  return [
   h('input', {
    onInput: e => {
     this.msg = e.target.value
    }
   }),
   h('div',list)
  ]
 }
}

とても良くて、今私達は1つの努力があって、簡単な用例、続いて1筋の脳は調整します。
デバッグ
frefの中で時間スライスを実現したので、私はそれをよく知っています。その作用原理を知っています。だから、直接マクロタスクを探します。はあ、やっぱりあります。

window.addEventListener('message', event => {
  if (event.source !== window || event.data !== key) {
    return;
  }
  flushStartTimestamp = getNow();
  try {
    flush();
  }
  catch (e) {
    handleError(e);
  }
}, false);
function flushAfterMacroTask() {
  window.postMessage(key, `*`);
}
このコードは非常に分かりやすいです。マクロタスクのキューでflush関数を実行して、続けます。
そして鍵が来ました。

function flush() {
  let job;
  while (true) {
    job = stageQueue.shift();
    if (job) {
      stageJob(job);
    }
    else {
      break;
    }
    {
      const now = getNow();
      if (now - flushStartTimestamp > frameBudget && job.expiration > now) {
        break; //      ,     16ms,      ,    
      }
    }
  }
  ...       ...
上のサイクルはとても肝心で、それのすることはとても簡単で、stageQueの中からスタックの1つの任務を出して、それからstateJobを実行します。
stateJobさんがすることは簡単です。comitQueにプッシュするという仕事です。

function stageJob(job) {
  if (job.ops.length === 0) {
    currentJob = job;
    job.cleanup = job();
    currentJob = null;
    commitQueue.push(job); //     
    job.status = 2;
  }
}
今までソースを読んでいましたが、ほとんど読み終わりました。
その本質は、マクロタスクの中で、stageQueが優先順位の低いタスク・キューとして、連続的にスタックを出して、そしてバッチ(16 msのしきい値)を分けて、comitQueの中に入ることです。
えっと、実は文章じゃないなら、ここまででいいですが、文章を書くのは文字数を集めるためです。続けます。
上の列はもう二つ分かりました。stageQueとcomitQueですが、彼らの中は全部何ですか?
何がスケジュールされていますか?プリントしてください。

console.log(stageQueue,commitQueue)
結果は

function mountComponentInstance(){...}
名前からわかるのはコンポーネントマウント関数です。もちろんコンポーネントの更新とアンインストールの関数も同じです。
今までも、スケジュールに参加しているのはコンポーネントのアップロードの関数であることが分かりました。だから、本質的には、vueのタイムスライスの基本単位はコンポーネントです。つまり、もしあなたのコンポーネントのマウントに一時間かかるなら、まだカードを一時間必要とします。
字数をそろえる
残りの内容は文字を集めただけです。コアスケジュール以外のものです。
たとえば、comitQueはdomを操作しています。どうやって操作しますか?

function commitJob(job) {
  const { ops, postEffects } = job;
  for (let i = 0; i < ops.length; i++) {
    applyOp(ops[i]); //      
  }
  if (postEffects) {
    postEffectsQueue.push(...postEffects);
  }
  resetJob(job);
  job.status = 0;
}
このように、opsを手に入れて操作してください。opsとは何かを確認してください。

[<div></div>, <li></li>, function CreactElement(){}]
間に合わせは、配列です。dom操作の方法と操作される要素が含まれています。
そして、このプロセスは同期して完了しました。いわゆる高優先度タスクは、完全に収集されてから循環的に実行できます。
これを仕上げます。postEffect Queは主に副作用と清掃作業があります。文字数が足りないので、印刷しません。
締め括りをつける
最後に私達は一番ストレートな言葉でまとめます。
マクロタスクのキューでは、常にstageQueサブバッチ(16 ms)からコンポーネントの関数をcomitQueに移し、転送が完了し、同時にdomを操作します。
原理はやはりマクロタスクの行列を利用していますが、実は今のvueのやり方はfreeと少し似ています。freeはマクロタスクの中で、できるだけ多くのreconcileを訪問します。
廃止について
先に述べたように、time slingという部分はもうマスターの枝から取り除かれました。なぜ廃止されたのかについて、わざわざissueを送りました。ここを突いてもいいです。
https://github.com/vuejs/rfcs/issues/89
簡単に言えば、time slingの収益は大きくないです。issueの中で言及された以外に、そのシーン自体が少ないです。
また、vueは現在の実装のため、スケジューリングの基本単位はコンポーネントであるため、依然としてコンポーネント内部の論理によってブロックされてしまうことがあります。
例えば、用例でブロックに使っていたblock関数を1 sに変更したら、完全にカードが死んでしまいました。
思考
issueとソース自体から、私たちはいくつかの問題を考えることができますが、文字数を集めるために使用されます。
時間スライスは必要ですか?
答えは否定です。尤の返事はもう十分です。https://github.com/vuejs/rfcs/issues/89#issuecomment-546988615
大体2点があります
  • は、高フレームレートアニメーションを除いて、他のシーンのほとんどが、手ぶれ防止と節流を使用して応答性能を向上させることができる
  • vue現在の実現は、粒径が大きすぎて、最終的な効果は非常に限られています。
  • に値しません。
    じゃ、freeは?
    frの非同期レンダリングは、この問題があるかどうかは、frは粒度が小さいが、コンポーネント内部のブロッキングによって解決できますが、要素自体も遮断されます。
    そして最初の問題もあります。適用シーンがあまりないです。
    しかし、freaソースのレベルはまだ意味があります。これを作っても、副作用が少ないことを発見しました。しかし、freeは私個人の学習と研究のプロジェクトとして、その価値は業務レベルではありません。
    ただ、私は止まって、非同期のレンダリングは終わったはずです。ただ、ソースコードの実現を示しています。将来はreactに従って一連の業務APIをやってはいけません。例えば、useTransitionなどです。
    ソースについて?
    vue 3のリリース当日は、ソースコードの解読がリリースされましたが、これまでのところ、すべてのソースコードの解読はすべて手応えがあります。
    近い将来、vueのソースコードはまたぼろぼろの街になります。
    このような現象は反省を引き起こして、私達はソースコードを読むのは一体何のためですか?面接のためですか?業務をよりよく書くために?
    私にとってはただ興味があります。この部分のソースコードに興味があります。
    実は皆さんも見ました。私はソースの解読の文章をあまり書きません。いわゆる「通読ソース」に反対しています。
    ソースを読んで仕事として、同じ小さな関数として、何度も読んで、労働を缲り返します。
    これは糊と何の違いがありますか?
    以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。