_replaceReportHtml(json) {
    const container = dom.find('main');

    // Reset container content.
    container.textContent = '';
    const rootEl = dom.createElement('div');
    container.append(rootEl);

    // Only give gist-saving callback if current report isn't from a gist.
    let saveGistCallback;
    if (!this._reportIsFromGist) {
      saveGistCallback = this._onSaveJson;
    }

    try {
      if (this._isFlowReport(json)) {
        this._renderFlowResult(json, rootEl, saveGistCallback);
        if (window.gtag) window.gtag('event', 'report', {type: 'flow-report'});
      } else {
        this._renderLhr(json, rootEl, saveGistCallback);
        if (window.gtag) window.gtag('event', 'report', {type: 'report'});
      }

      // Only clear query string if current report isn't from a gist or PSI.
      if (!this._reportIsFromGist && !this._reportIsFromPSI && !this._reportIsFromJSON) {
        history.pushState({}, '', LighthouseReportViewer.APP_URL);
      }
    } catch (e) {
      logger.error(`Error rendering report: ${e.stack}`);
      container.textContent = '';
      throw e;
    } finally {
      this._reportIsFromGist = this._reportIsFromPSI = this._reportIsFromJSON = false;
    }

    // Remove the placeholder UI once the user has loaded a report.
    const placeholder = document.querySelector('.viewer-placeholder');
    if (placeholder) {
      placeholder.remove();
    }

    if (window.gtag) {
      window.gtag('event', 'view');
    }
  }
@param {LH.Result | LH.FlowResult} json
@private