Merge pull request #5395 from overleaf/msm-pdf-metrics

Added PdfJsMetrics to React PDF Viewer

GitOrigin-RevId: ff749d67baec243ca2c8e51409754716f4cef62c
This commit is contained in:
June Kelly 2021-10-20 09:45:10 +01:00 committed by Copybot
parent e0b0d10143
commit 4f29ca5cbd
3 changed files with 37 additions and 3 deletions

View file

@ -10,11 +10,13 @@ import PDFJSWrapper from '../util/pdf-js-wrapper'
import withErrorBoundary from '../../../infrastructure/error-boundary' import withErrorBoundary from '../../../infrastructure/error-boundary'
import ErrorBoundaryFallback from './error-boundary-fallback' import ErrorBoundaryFallback from './error-boundary-fallback'
import { useCompileContext } from '../../../shared/context/compile-context' import { useCompileContext } from '../../../shared/context/compile-context'
import getMeta from '../../../utils/meta'
function PdfJsViewer({ url }) { function PdfJsViewer({ url }) {
const { _id: projectId } = useProjectContext() const { _id: projectId } = useProjectContext()
const { setError } = useCompileContext() const { setError, firstRenderDone } = useCompileContext()
const [timePDFFetched, setTimePDFFetched] = useState()
// state values persisted in localStorage to restore on load // state values persisted in localStorage to restore on load
const [scale, setScale] = usePersistedState( const [scale, setScale] = usePersistedState(
@ -42,15 +44,32 @@ function PdfJsViewer({ url }) {
// listen for initialize event // listen for initialize event
useEffect(() => { useEffect(() => {
if (pdfJsWrapper) { if (pdfJsWrapper) {
const handlePagesinit = () => setInitialised(true) const handlePagesinit = () => {
setInitialised(true)
if (getMeta('ol-trackPdfDownload') && firstRenderDone) {
const visible = !document.hidden
if (!visible) {
firstRenderDone({
timePDFFetched,
})
} else {
const timePDFRendered = performance.now()
firstRenderDone({
timePDFFetched,
timePDFRendered,
})
}
}
}
pdfJsWrapper.eventBus.on('pagesinit', handlePagesinit) pdfJsWrapper.eventBus.on('pagesinit', handlePagesinit)
return () => pdfJsWrapper.eventBus.off('pagesinit', handlePagesinit) return () => pdfJsWrapper.eventBus.off('pagesinit', handlePagesinit)
} }
}, [pdfJsWrapper]) }, [pdfJsWrapper, firstRenderDone, timePDFFetched])
// load the PDF document from the URL // load the PDF document from the URL
useEffect(() => { useEffect(() => {
if (pdfJsWrapper && url) { if (pdfJsWrapper && url) {
setTimePDFFetched(performance.now())
setInitialised(false) setInitialised(false)
setError(undefined) setError(undefined)

View file

@ -3,6 +3,7 @@ import getMeta from '../../../utils/meta'
import { sendMBSampled } from '../../../infrastructure/event-tracking' import { sendMBSampled } from '../../../infrastructure/event-tracking'
import { deleteJSON, postJSON } from '../../../infrastructure/fetch-json' import { deleteJSON, postJSON } from '../../../infrastructure/fetch-json'
import { debounce } from 'lodash' import { debounce } from 'lodash'
import { trackPdfDownload } from '../../../ide/pdf/controllers/PdfJsMetrics'
const AUTO_COMPILE_MAX_WAIT = 5000 const AUTO_COMPILE_MAX_WAIT = 5000
// We add a 1 second debounce to sending user changes to server if they aren't // We add a 1 second debounce to sending user changes to server if they aren't
@ -19,6 +20,7 @@ export default class DocumentCompiler {
setChangedAt, setChangedAt,
setCompiling, setCompiling,
setData, setData,
setFirstRenderDone,
setError, setError,
signal, signal,
}) { }) {
@ -26,6 +28,7 @@ export default class DocumentCompiler {
this.setChangedAt = setChangedAt this.setChangedAt = setChangedAt
this.setCompiling = setCompiling this.setCompiling = setCompiling
this.setData = setData this.setData = setData
this.setFirstRenderDone = setFirstRenderDone
this.setError = setError this.setError = setError
this.signal = signal this.signal = signal
@ -72,6 +75,8 @@ export default class DocumentCompiler {
const params = this.buildCompileParams(options) const params = this.buildCompileParams(options)
const t0 = performance.now()
const data = await postJSON( const data = await postJSON(
`/project/${this.project._id}/compile?${params}`, `/project/${this.project._id}/compile?${params}`,
{ {
@ -86,6 +91,9 @@ export default class DocumentCompiler {
signal: this.signal, signal: this.signal,
} }
) )
const compileTimeClientE2E = performance.now() - t0
const { firstRenderDone } = trackPdfDownload(data, compileTimeClientE2E)
this.setFirstRenderDone(() => firstRenderDone)
data.options = options data.options = options
this.setData(data) this.setData(data)
} catch (error) { } catch (error) {

View file

@ -53,6 +53,7 @@ CompileContext.Provider.propTypes = {
stopOnValidationError: PropTypes.bool.isRequired, stopOnValidationError: PropTypes.bool.isRequired,
uncompiled: PropTypes.bool, uncompiled: PropTypes.bool,
validationIssues: PropTypes.object, validationIssues: PropTypes.object,
firstRenderDone: PropTypes.func,
}), }),
} }
@ -91,6 +92,9 @@ export function CompileProvider({ children }) {
// data received in response to a compile request // data received in response to a compile request
const [data, setData] = useState() const [data, setData] = useState()
// callback to be invoked for PdfJsMetrics
const [firstRenderDone, setFirstRenderDone] = useState()
// whether the project has been compiled yet // whether the project has been compiled yet
const [compiledOnce, setCompiledOnce] = useState(false) const [compiledOnce, setCompiledOnce] = useState(false)
@ -150,6 +154,7 @@ export function CompileProvider({ children }) {
setChangedAt, setChangedAt,
setCompiling, setCompiling,
setData, setData,
setFirstRenderDone,
setError, setError,
signal, signal,
}) })
@ -422,6 +427,7 @@ export function CompileProvider({ children }) {
stopOnValidationError, stopOnValidationError,
uncompiled, uncompiled,
validationIssues, validationIssues,
firstRenderDone,
}), }),
[ [
autoCompile, autoCompile,
@ -452,6 +458,7 @@ export function CompileProvider({ children }) {
stopOnValidationError, stopOnValidationError,
uncompiled, uncompiled,
validationIssues, validationIssues,
firstRenderDone,
] ]
) )