# Profiling Code Performance and Arc XP

Source: https://dev.arcxp.com/pagebuilder-engine/how-to-guides/optimization-and-deployment/profiling-code-performance-and-arc-xp/

Fast and performant sites encourage readers to spend more time on them and boost page ranking. Dealing with a site that is performing below those high expectations can be frustrating. This article provides tips and tools to help diagnose and improve your site’s codebase to be more performant.

> **Note:**
> 
> Arc XP is specifically designed to be most performant in _**production environments only.**_ Slower responses in staging or local environments are expected behavior.

## Logs

The first step in profiling your code’s performance is log forwarding, which you can request from [Arc XP Customer Support](https://support.arcpublishing.com/). Find more information on log forwarding in [PageBuilder Engine log forwarding](https://dev.arcxp.com/pagebuilder-engine/developer-docs/pagebuilder-engine-log-forwarding/). Once you have these logs, use the following tips to read them.

- The built-in console logger (`console.log`) is a good general-purpose solution, but anything you write to `stdout` will also appear in the logs.
- Node.js provides a built-in package (`perf_hooks`) for measuring code’s runtime performance. See [Node.js documentation](https://nodejs.org/api/perf%5Fhooks.html) for more information.
- Use distinct, easily searchable messages. `"[fetch-timer] example.tld/extension 31ms”` is easier to find than `“31”`.

## Sample profiler code

One approach to profiling code is to use timers to measure how long a function takes to finish running. Below is a sample implementation for this type of profiler:

```js
const { performance } = require('perf_hooks');

/**
  * Profile synchronous code.
*/
const profile = (name, fn) => {
  return (...args) => {
    const start = performance.now();
    const result = fn(...args);
    const end = performance.now();
    console.log(`[sync-profiler(${name})]: started at ${start}ms, ended at ${end}ms, took ${end - start}ms`);
    return result;
  };
};

profile.sync = profile;

/**
  * Profile asynchronous code.
  */
profile.async = (name, fn) => {
  return async (...args) => {
    const start = performance.now();
    const result = await fn(...args);
    const end = performance.now();
    console.log(`[async-profiler(${name})]: started at ${start}ms, ended at ${end}ms, took ${end - start}ms`);
    return result;
  };
};
```

If you have a function that seems to perform poorly, you can use a profiler to measure it with the profiler functions:

```js
/**
 * This function will not resolve until at least one second has passed.
*/
const asyncFunction = async () => {
  await new Promise((resolve) => setTimeout(resolve, 1000));
  return 'Waited for at least one second!';
};

/**
 * This function will count to one-billion.
*/
const syncFunction = () => {
  for (let i = 0; i < 1E9; ++i) {
    // do nothing
  }
  return 'Counted to one-billion!';
};

/**
 * This function will wait for a full second, and then it will write
 * the profiler's log message to the console.
*/
const profiledAsyncFunction = profile.async('asyncFunction', asyncFunction);

/**
 * This function will count to one-billion, and then it will write the
 * profiler's log message to the console.
*/
const profiledSyncFunction = profile.sync('syncFunction', syncFunction);

/**
 * This line will run the profiled async function.
*/
profiledAsyncFunction(1000).then(console.log);

/**
 * This line will run the profiled sync function.
*/
profiledSyncFunction(1E7);
```

This type of feedback is useful for finding performance problems and measuring your progress toward resolving them.

You can find more examples of code profiling in the following resources:

- [Node.Js V14.20.0 Documentation](https://nodejs.org/docs/latest-v14.x/api/perf%5Fhooks.html)
- [Measuring Performance In Node.Js With Performance Hooks](https://dev.to/bearer/measuring-performance-in-node-js-with-performance-hooks-585p)
- [Experimental Node.Js: Testing The New Performance Hooks](https://blog.logrocket.com/experimental-node-js-testing-the-new-performance-hooks-31fcdd2a747e/)

## Additional resources

- [PageBuilder Engine log forwarding](https://dev.arcxp.com/pagebuilder-engine/developer-docs/pagebuilder-engine-log-forwarding/)
- [How to Request Tracing in Content Sources with PageBuilder Engine](https://dev.arcxp.com/pagebuilder-engine/developer-docs/how-to-request-tracing-in-content-sources-with-pagebuilder-engine/)
- [Self-service Performance Debugging](https://dev.arcxp.com/pagebuilder-engine/developer-docs/self-service-performance-debugging/)
- [How To Read Engine Logs](https://dev.arcxp.com/pagebuilder-engine/developer-docs/how-to-read-engine-logs/)
