renderReport(lhr, rootEl, opts) {
    // Allow legacy report rendering API
    if (!this._dom.rootEl && rootEl) {
      // eslint-disable-next-line no-console
      console.warn('Please adopt the new report API in renderer/api.js.');
      const closestRoot = rootEl.closest('.lh-root');
      if (closestRoot) {
        this._dom.rootEl = /** @type {HTMLElement} */ (closestRoot);
      } else {
        rootEl.classList.add('lh-root', 'lh-vars');
        this._dom.rootEl = rootEl;
      }
    } else if (this._dom.rootEl && rootEl) {
      // Handle legacy flow-report case
      this._dom.rootEl = rootEl;
    }
    if (opts) {
      this._opts = opts;
    }

    this._dom.setLighthouseChannel(lhr.configSettings.channel || 'unknown');

    const report = ReportUtils.prepareReportResult(lhr);

    this._dom.rootEl.textContent = ''; // Remove previous report.
    this._dom.rootEl.append(this._renderReport(report));

    if (this._opts.occupyEntireViewport) {
      this._dom.rootEl.classList.add('lh-max-viewport');
    }

    return this._dom.rootEl;
  }
@param {LH.Result} lhr
@param {HTMLElement?} rootEl Report root element containing the report
@param {LH.Renderer.Options=} opts
@return {!Element}