@@ -6,8 +6,43 @@ const getPremberUrls = require('./prember-urls');
66const BASE_URL = 'http://127.0.0.1:8080' ;
77const PRERENDER_DIR = 'prerender' ;
88
9- async function prerenderVersion ( urls ) {
10- const browser = await chromium . launch ( ) ;
9+ async function prerenderPage ( page , url ) {
10+ try {
11+ // Use router transition
12+ await page . evaluate ( ( path ) => {
13+ return window . __router ?. transitionTo ( path ) ;
14+ } , url ) ;
15+
16+ // Check if we got a 404 by looking for common error indicators
17+ const is404 = await page . evaluate ( ( ) => {
18+ return document . title . includes ( 'Page Not Found' ) ;
19+ } ) ;
20+
21+ if ( is404 ) {
22+ return { url, status : 'not-found' } ;
23+ }
24+
25+ // Get the HTML content
26+ const html = await page . content ( ) ;
27+
28+ // Convert URL to file path
29+ // e.g., /ember/release/classes/ApplicationInstance -> prerender/ember/release/classes/ApplicationInstance/index.html
30+ const filePath = join ( PRERENDER_DIR , url , 'index.html' ) ;
31+ const dir = dirname ( filePath ) ;
32+
33+ // Create directory structure
34+ mkdirSync ( dir , { recursive : true } ) ;
35+
36+ // Write HTML file
37+ writeFileSync ( filePath , html , 'utf-8' ) ;
38+
39+ return { url, status : 'success' } ;
40+ } catch ( error ) {
41+ return { url, status : 'error' , error : error . message } ;
42+ }
43+ }
44+
45+ async function initializePage ( browser ) {
1146 const page = await browser . newPage ( ) ;
1247
1348 await page . addInitScript ( ( ) => {
@@ -26,57 +61,50 @@ async function prerenderVersion(urls) {
2661 return router && ! router . currentRouteName ?. includes ( 'loading' ) ;
2762 } ) ;
2863
29- let successCount = 0 ;
30- let notFoundCount = 0 ;
64+ return page ;
65+ }
3166
32- for ( let i = 0 ; i < urls . length ; i ++ ) {
33- const url = urls [ i ] ;
67+ async function prerenderVersion ( urls ) {
68+ const browser = await chromium . launch ( ) ;
69+ const CONCURRENCY = 5 ; // Number of parallel pages
3470
35- try {
36- // Subsequent URLs: use router transition
37- await page . evaluate ( ( path ) => {
38- return window . __router ?. transitionTo ( path ) ;
39- } , url ) ;
71+ // Initialize multiple pages
72+ const pages = await Promise . all (
73+ Array . from ( { length : CONCURRENCY } , ( ) => initializePage ( browser ) ) ,
74+ ) ;
4075
41- // Wait for network to be idle after transition
42- await page . waitForLoadState ( 'networkidle' ) ;
76+ let successCount = 0 ;
77+ let notFoundCount = 0 ;
78+ let errorCount = 0 ;
79+ let urlIndex = 0 ;
80+
81+ // Process URLs in parallel using a worker pool pattern
82+ const workers = pages . map ( async ( page ) => {
83+ while ( urlIndex < urls . length ) {
84+ const currentIndex = urlIndex ++ ;
85+ const url = urls [ currentIndex ] ;
4386
44- // Check if we got a 404 by looking for common error indicators
45- const is404 = await page . evaluate ( ( ) => {
46- return document . title . includes ( 'Page Not Found' ) ;
47- } ) ;
87+ const result = await prerenderPage ( page , url ) ;
4888
49- if ( is404 ) {
89+ if ( result . status === 'success' ) {
90+ successCount ++ ;
91+ } else if ( result . status === 'not-found' ) {
5092 console . log ( `Not Found: ${ url } ` ) ;
5193 notFoundCount ++ ;
52- continue ;
94+ } else {
95+ console . error ( `Error processing ${ url } :` , result . error ) ;
96+ errorCount ++ ;
5397 }
5498
55- // Get the HTML content
56- const html = await page . content ( ) ;
57-
58- // Convert URL to file path
59- // e.g., /ember/release/classes/ApplicationInstance -> prerender/ember/release/classes/ApplicationInstance/index.html
60- const filePath = join ( PRERENDER_DIR , url , 'index.html' ) ;
61- const dir = dirname ( filePath ) ;
62-
63- // Create directory structure
64- mkdirSync ( dir , { recursive : true } ) ;
65-
66- // Write HTML file
67- writeFileSync ( filePath , html , 'utf-8' ) ;
68-
69- successCount ++ ;
70- if ( ( i + 1 ) % 100 === 0 ) {
99+ if ( ( currentIndex + 1 ) % 100 === 0 ) {
71100 console . log (
72- `Progress: ${ i + 1 } /${ urls . length } (${ successCount } saved, ${ notFoundCount } not found)` ,
101+ `Progress: ${ currentIndex + 1 } /${ urls . length } (${ successCount } saved, ${ notFoundCount } not found, ${ errorCount } errors )` ,
73102 ) ;
74103 }
75- } catch ( error ) {
76- console . error ( `Error processing ${ url } :` , error . message ) ;
77104 }
78- }
105+ } ) ;
79106
107+ await Promise . all ( workers ) ;
80108 await browser . close ( ) ;
81109}
82110async function prerender ( ) {
@@ -86,7 +114,9 @@ async function prerender() {
86114 0 ,
87115 ) ;
88116
89- console . log ( `Prerendering ${ totalUrls } URLs...` ) ;
117+ console . log (
118+ `Prerendering ${ totalUrls } URLs across ${ urlsByVersion . size } versions...` ,
119+ ) ;
90120
91121 for ( const [ version , urls ] of urlsByVersion . entries ( ) ) {
92122 await prerenderVersion ( urls ) ;
0 commit comments