static createImpactTasks(tasks, taskToImpact, taskToBlockingTime) {
    /** @type {LH.Artifacts.TBTImpactTask[]} */
    const tbtImpactTasks = [];

    for (const task of tasks) {
      const tbtImpact = taskToImpact.get(task) || 0;
      let selfTbtImpact = tbtImpact;

      const blockingTime = taskToBlockingTime.get(task) || 0;
      let selfBlockingTime = blockingTime;

      for (const child of task.children) {
        const childTbtImpact = taskToImpact.get(child) || 0;
        selfTbtImpact -= childTbtImpact;

        const childBlockingTime = taskToBlockingTime.get(child) || 0;
        selfBlockingTime -= childBlockingTime;
      }

      tbtImpactTasks.push({
        ...task,
        // Floating point numbers are not perfectly precise, so the subtraction operations above
        // can sometimes output negative numbers close to 0 here. To prevent potentially confusing
        // output we should bump those values to 0.
        tbtImpact: Math.max(tbtImpact, 0),
        selfTbtImpact: Math.max(selfTbtImpact, 0),
        selfBlockingTime: Math.max(selfBlockingTime, 0),
      });
    }

    return tbtImpactTasks;
  }
@param {LH.Artifacts.TaskNode[]} tasks
@param {Map<LH.Artifacts.TaskNode, number>} taskToImpact
@param {Map<LH.Artifacts.TaskNode, number>} taskToBlockingTime