@@ -235,10 +235,7 @@ const config = {
235235 theme : {
236236 customCss : require . resolve ( './src/css/custom.css' ) ,
237237 } ,
238- gtag : {
239- trackingID : 'UA-109059578-7' ,
240- anonymizeIP : true ,
241- } ,
238+ // gtag disabled - using optimized custom loading in performancePlugin
242239 sitemap : {
243240 changefreq : 'weekly' ,
244241 priority : 0.5 ,
@@ -251,62 +248,121 @@ const config = {
251248 // Bundle analyzer for optimization monitoring
252249
253250 plugins : [
254- // Custom webpack plugin for source maps and performance
251+ // Enhanced webpack optimization plugin for better bundle splitting
255252 function webpackOptimizationPlugin ( ) {
256253 return {
257254 name : 'webpack-optimization-plugin' ,
258255 configureWebpack ( config , isServer ) {
259256 if ( ! isServer ) {
260257 return {
261- devtool : 'source-map' ,
258+ devtool : process . env . NODE_ENV === 'production' ? false : 'source-map' ,
262259 optimization : {
263260 splitChunks : {
264261 chunks : 'all' ,
262+ maxInitialRequests : 5 ,
263+ maxAsyncRequests : 10 ,
265264 cacheGroups : {
265+ // Separate heavy libraries
266+ algolia : {
267+ test : / [ \\ / ] n o d e _ m o d u l e s [ \\ / ] ( @ d o c s e a r c h | a l g o l i a s e a r c h ) / ,
268+ name : 'algolia' ,
269+ chunks : 'all' ,
270+ priority : 30 ,
271+ } ,
272+ prism : {
273+ test : / [ \\ / ] n o d e _ m o d u l e s [ \\ / ] p r i s m j s / ,
274+ name : 'prism' ,
275+ chunks : 'async' ,
276+ priority : 25 ,
277+ } ,
278+ react : {
279+ test : / [ \\ / ] n o d e _ m o d u l e s [ \\ / ] ( r e a c t | r e a c t - d o m ) / ,
280+ name : 'react' ,
281+ chunks : 'all' ,
282+ priority : 20 ,
283+ } ,
266284 vendor : {
267285 test : / [ \\ / ] n o d e _ m o d u l e s [ \\ / ] / ,
268286 name : 'vendors' ,
269287 chunks : 'all' ,
270288 priority : 10 ,
289+ maxSize : 200000 , // Split large vendor chunks
271290 } ,
272291 common : {
273292 name : 'common' ,
274293 minChunks : 2 ,
275294 chunks : 'all' ,
276295 priority : 5 ,
277296 reuseExistingChunk : true ,
297+ maxSize : 100000 ,
278298 } ,
279299 } ,
280300 } ,
301+ usedExports : true ,
302+ sideEffects : false ,
281303 } ,
282304 } ;
283305 }
284306 } ,
285307 } ;
286308 } ,
287- // Performance optimization plugin
309+ // Enhanced performance optimization plugin
288310 function performancePlugin ( ) {
289311 return {
290312 name : 'performance-plugin' ,
291313 injectHtmlTags ( ) {
292314 return {
293315 headTags : [
316+ // Critical CSS inlining hint
317+ {
318+ tagName : 'script' ,
319+ innerHTML : `
320+ // Optimize font loading
321+ if ('fonts' in document) {
322+ document.fonts.ready.then(() => {
323+ document.documentElement.classList.add('fonts-loaded');
324+ });
325+ }
326+ ` ,
327+ } ,
328+ // Optimized analytics loading
294329 {
295330 tagName : 'script' ,
296331 innerHTML : `
297332 (function() {
298- var script = document.createElement('script');
299- script.async = true;
300- script.src = 'https://www.googletagmanager.com/gtag/js?id=UA-109059578-7';
301- script.onload = function() {
302- window.dataLayer = window.dataLayer || [];
303- function gtag(){dataLayer.push(arguments);}
304- gtag('js', new Date());
305- gtag('config', 'UA-109059578-7', {anonymize_ip: true});
306- };
307- setTimeout(function() {
333+ // Only load analytics after user interaction or page idle
334+ var loaded = false;
335+ function loadGA() {
336+ if (loaded) return;
337+ loaded = true;
338+
339+ var script = document.createElement('script');
340+ script.async = true;
341+ script.src = 'https://www.googletagmanager.com/gtag/js?id=UA-109059578-7';
342+ script.onload = function() {
343+ window.dataLayer = window.dataLayer || [];
344+ function gtag(){dataLayer.push(arguments);}
345+ gtag('js', new Date());
346+ gtag('config', 'UA-109059578-7', {
347+ anonymize_ip: true,
348+ send_page_view: false // Prevent duplicate page views
349+ });
350+ // Send initial page view
351+ gtag('event', 'page_view', {
352+ page_title: document.title,
353+ page_location: window.location.href
354+ });
355+ };
308356 document.head.appendChild(script);
309- }, 3000);
357+ }
358+
359+ // Load on user interaction
360+ ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart', 'click'].forEach(function(event) {
361+ window.addEventListener(event, loadGA, {once: true, passive: true});
362+ });
363+
364+ // Fallback: load after 5 seconds
365+ setTimeout(loadGA, 5000);
310366 })();
311367 ` ,
312368 } ,
@@ -315,6 +371,103 @@ const config = {
315371 } ,
316372 } ;
317373 } ,
374+ // Critical CSS optimization plugin
375+ function criticalCSSPlugin ( ) {
376+ return {
377+ name : 'critical-css-plugin' ,
378+ injectHtmlTags ( ) {
379+ return {
380+ headTags : [
381+ // Critical CSS inlining
382+ {
383+ tagName : 'style' ,
384+ innerHTML : `
385+ /* Critical above-the-fold styles */
386+ :root {
387+ --ifm-color-primary: #25c2a0;
388+ --ifm-color-primary-dark: #21af90;
389+ --ifm-color-primary-darker: #1fa588;
390+ --ifm-color-primary-darkest: #1a8870;
391+ --ifm-color-primary-light: #29d5b0;
392+ --ifm-color-primary-lighter: #32d8b4;
393+ --ifm-color-primary-lightest: #4fddbf;
394+ --ifm-code-font-size: 95%;
395+ }
396+
397+ /* Critical layout styles */
398+ html { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; }
399+ body { margin: 0; background: #fff; color: #1c1e21; }
400+ .navbar { background: #fff; box-shadow: 0 1px 2px 0 rgba(0,0,0,0.1); }
401+ .main-wrapper { display: flex; flex: 1 0 auto; }
402+
403+ /* Loading state optimization */
404+ .theme-doc-sidebar-container { will-change: transform; }
405+ .pagination-nav { will-change: transform; }
406+
407+ /* Font display optimization */
408+ @font-face {
409+ font-family: system-ui;
410+ font-display: swap;
411+ }
412+ ` ,
413+ } ,
414+ // Preload critical fonts
415+ {
416+ tagName : 'link' ,
417+ attributes : {
418+ rel : 'preload' ,
419+ href : 'data:font/woff2;charset=utf-8;base64,' ,
420+ as : 'font' ,
421+ type : 'font/woff2' ,
422+ crossorigin : 'anonymous' ,
423+ } ,
424+ } ,
425+ ] ,
426+ postBodyTags : [
427+ // Defer non-critical CSS with dynamic hash detection
428+ {
429+ tagName : 'script' ,
430+ innerHTML : `
431+ // Load non-critical CSS asynchronously
432+ (function() {
433+ // Find the actual CSS file name dynamically
434+ var cssFiles = document.querySelectorAll('link[rel="stylesheet"]');
435+ var mainCssFile = null;
436+ cssFiles.forEach(function(css) {
437+ if (css.href.includes('/assets/css/styles.') && css.href.includes('.css')) {
438+ mainCssFile = css.href;
439+ css.media = 'print'; // Initially load as print to avoid blocking
440+ }
441+ });
442+
443+ if (mainCssFile) {
444+ // Load after critical content is painted
445+ setTimeout(function() {
446+ cssFiles.forEach(function(css) {
447+ if (css.href === mainCssFile) {
448+ css.media = 'all';
449+ }
450+ });
451+ }, 100);
452+ }
453+ })();
454+
455+ // Load background image after everything else
456+ window.addEventListener('load', function() {
457+ setTimeout(function() {
458+ var mainWrapper = document.querySelector('.main-wrapper');
459+ if (mainWrapper) {
460+ mainWrapper.classList.add('bg-loaded');
461+ }
462+ }, 1000);
463+ });
464+ ` ,
465+ } ,
466+ ] ,
467+ } ;
468+ } ,
469+ } ;
470+ } ,
318471 [
319472 '@docusaurus/plugin-ideal-image' ,
320473 {
0 commit comments