Home / Page Compiler

Page Compiler

What Is a Custom Page Compiler?

Site pages in Oracle Content Management are rendered by combining the page metadata (page-ID.json file) with the page layout HTML file that’s used as the basis for the page. A page layout defines how content is arranged on the page. Different layouts can contain a different number of named slots, which are regions spanning the width of the page. A slot can contain one or more types of content.

When a site page is compiled, the page layout is also used as the basis for the generated HTML output. A custom page compiler allows you to alter the HTML output that’s returned by the page layout. For example, you may want to a compile site navigation menu directly into the generated HTML for the page rather than having the menu render dynamically at runtime.

Define a Custom Page Compiler

Page layouts are associated with a site theme and located in the ‘layouts’ folder of the theme. To create a custom page compiler for the page layout, you create an .mjs file named <pageLayoutName>-compile.mjs in the theme. For example, if you have a page layout called “threeslot.html,” then the corresponding page compiler for this page layout would be “threeslot-compile.mjs”. The minimum implementation for a page compiler compile.mjs file would be:

export default class {
    constructor () {}
 
    compile (args) {
        const SCSCompileAPI = args.SCSCompileAPI;
        let compiledPage = args.layoutMarkup;
 
        return new Promise((resolve, reject) => {
            // Example: use string replace on the page layout to convert it to runtime values
            compiledPage = compiledPage.replace('opacity: 0;', 'opacity: 1;');
 
            // Do any additional work,
            // For example - generate the site navigation menu from the site structure
 
            // return the compiled page
            resolve(compiledPage);
        });
    }
}

Page Compiler Performance

The page compiler is run for each page that will be compiled. Typically, the result produced by the page compiler will be the same for each page that it’s used on. Rather than re-running the page compiler for each page, you should look at whether you can cache the output so that it’s only run it once. If you have multiple languages, you can consider using once per locale. For example, the *-compile.mjs file could add caching as follows:

const compiledPageCache {};
  
export default class {
    constructor () {}
 
    compile (args) {
        const SCSCompileAPI = args.SCSCompileAPI;
        let compiledPage = args.layoutMarkup;
        const pageLocale = SCSCompileAPI.pageLocale;
 
        compiledPageCache[pageLocale] = compiledPageCache[pageLocale} || new Promise((resolve, reject) => {
            // Example: use string replace on the page layout to convert it to runtime values
            compiledPage = compiledPage.replace('opacity: 0;', 'opacity: 1;');
 
            // Do any additional work,
            // For example - generate the site navigation menu from the site structure
 
            // return the compiled page
            resolve(compiledPage);
        });
         
        return compiledPageCache[pageLocale];
    }
}

Note: Make sure you clean up the cache as the locale changes. Also, for larger cache entries, you may want to store it on the file system.

Runtime Page Optimization

The objective of site compilation is to reduce the cost of loading a page at runtime. You may have several separate JavaScript files included in the page layout to support functionality that may no longer be required after the page is compiled. If you can identify libraries that are no longer used, you should look at whether you can remove them in the page compiler so that they aren’t downloaded at runtime unnecessarily.

Post-Processing Pages

An additional Page Compiler API is afterPageCompile(). This takes the same parameters as the original compile(), but with the page containing all the content from all the components inserted into the page.

export default class {
    constructor () {}
 
    compile (args) {
        ...
    }
  
    afterPageCompile (args) {
        const SCSCompileAPI = args.SCSCompileAPI;
        let compiledPage = args.layoutMarkup;
 
        return new Promise((resolve, reject) => {
            // Example: use string replace on the page layout to convert it to runtime values
            compiledPage = compiledPage.replace('<!-- preload images -->', '<link rel="preload" href="sampleimage.png" as="image" media="(min-width: 580px)">');
 
            // return the compiled page
            resolve(compiledPage);
        });
    }
}

Preloading Resources

One use of post-processing of pages may be to indicate to the browser important resources that need to be loaded as early as possible (for example, banner images that you want to appear immediately). You should look at preloading these resources in the <head> of the generated HTML:

<link rel="preload" href="sampleimage.png" as="image" media="(min-width: 580px)">

Oracle Content Management Libraries and Resources

Oracle Content Management itself will insert JavaScript files and objects into the compiled page, including the main renderer.js file. It’s possible to remove these resources to further improve the page performance. If you do remove these resources, the page will be rendered simply as a standard HTML page, so that none of the resources below will function correctly. Therefore, this is only an option if your page does not require any of the following:

As you can see, you need to have a very controlled environment to make sure your page will run correctly after removing the Oracle Content Management artifacts from the page, but doing so will give you complete control over the performance of your page. If your site can run with these constraints, the strings that would be removed from your page layout by the custom page compiler are:

<!--$SCS_RENDER_INFO-->
<!--$SCS_SITE_HEADER-->
<!--$SCS_PAGE_HEADER-->
<script data-main="/_sitescloud/renderer/renderer.js" src="/_sitescloud/renderer/require.js"></script>
<!--$SCS_PAGE_FOOTER-->
<!--$SCS_SITE_FOOTER-->