ಪರಿಪೂರ್ಣ Lighthouse ಸ್ಕೋರ್‌ನ ಹಿಂದಿರುವ ಪ್ರತಿಯೊಂದು ಆಪ್ಟಿಮೈಸೇಶನ್

ನಾನು ನನ್ನ ಸೈಟ್‌ನಲ್ಲಿ ನಿರಂತರವಾಗಿ Lighthouse ಅನ್ನು ರನ್ ಮಾಡುತ್ತೇನೆ. ಇದು ಪ್ರತಿ ಲೋಕಲ್ ರನ್‌ನಲ್ಲಿ ಮತ್ತು Vercel ನ Real Experience Score ನಲ್ಲಿ 100 ರಲ್ಲೇ ಇರುತ್ತದೆ.

ಈ ಸ್ಕೋರ್‌ಗಳು ಕೇವಲ ಸಾಮಾನ್ಯ ಚೆಕ್‌ಲಿಸ್ಟ್‌ನಿಂದ ಬರುವುದಿಲ್ಲ. ಕೆಲಸವನ್ನು ಬ್ರೌಸರ್‌ನಿಂದ ಬಿಲ್ಡ್ (build) ಹಂತಕ್ಕೆ ವರ್ಗಾಯಿಸುವ ಮೂಲಕ ನಾನು ಇವುಗಳನ್ನು ಸಾಧಿಸುತ್ತೇನೆ.

ನಾನು ಇದನ್ನು ಮಾಡುವ ನಿಖರವಾದ ವಿಧಾನ ಇಲ್ಲಿದೆ.

ಕೆಲಸವನ್ನು ಬಿಲ್ಡ್ ಟೈಮ್‌ಗೆ (build time) ವರ್ಗಾಯಿಸಿ

ಹೆಚ್ಚಿನ ಗೈಡ್‌ಗಳು ಎಲ್ಲವನ್ನೂ lazy-load ಮಾಡಲು ಹೇಳುತ್ತವೆ. ಆದರೆ ನಾನು prerender ಮಾಡುವುದನ್ನು ಇಷ್ಟಪಡುತ್ತೇನೆ. ನಾನು prerendering ಅನ್ನು ಎನೇಬಲ್ ಮಾಡಿರುವ TanStack Start ಅನ್ನು ಬಳಸುತ್ತೇನೆ.

ಇದು ಬಿಲ್ಡ್ ಸಮಯದಲ್ಲಿ ಇಡೀ ಸೈಟ್ ಅನ್ನು ಸ್ಟ್ಯಾಟಿಕ್ HTML ಆಗಿ ಪರಿವರ್ತಿಸುತ್ತದೆ. ಮೊದಲ ಪುಟವನ್ನು ತೋರಿಸಲು ಬ್ರೌಸರ್ ಭಾರವಾದ JavaScript ಅನ್ನು ಎಕ್ಸಿಕ್ಯೂಟ್ ಮಾಡಬೇಕಾಗಿಲ್ಲ. ಬಳಕೆದಾರರು ಎಂಟರ್ ಒತ್ತಿದಾಗ HTML ಈಗಾಗಲೇ ಅಲ್ಲಿರುತ್ತದೆ.

ಸಂಕೀರ್ಣ ಲಾಜಿಕ್ ಅನ್ನು ಮೊದಲೇ ಲೆಕ್ಕಹಾಕಿ (Precompute)

ನನ್ನ ಹೋಮ್‌ಪೇಜ್‌ನಲ್ಲಿ 5,000 ಚುಕ್ಕೆಗಳಿರುವ ವಿಶ್ವ ಭೂಪಟವಿದೆ. ಸಾಮಾನ್ಯವಾಗಿ, ಒಂದು ಲೈಬ್ರರಿಯು GeoJSON ಅನ್ನು ಪಾರ್ಸ್ ಮಾಡಿ ಮೇನ್ ಥ್ರೆಡ್‌ನಲ್ಲಿ (main thread) ಗಣಿತದ ಲೆಕ್ಕಾಚಾರಗಳನ್ನು ಮಾಡುತ್ತದೆ. ಇದು ಪುಟವನ್ನು 1,000ms ಕಾಲ ಬ್ಲಾಕ್ ಮಾಡುತ್ತದೆ.

ನಾನು ಈ ಗಣಿತದ ಕೆಲಸವನ್ನು ಬಿಲ್ಡ್ ಸ್ಕ್ರಿಪ್ಟ್‌ಗೆ ವರ್ಗಾಯಿಸುವ ಮೂಲಕ ಇದನ್ನು ಪರಿಹರಿಸಿದೆ.

  • ನಾನು ಎಲ್ಲಾ 5,000 ಚುಕ್ಕೆಗಳಿಗಾಗಿ ಒಂದೇ SVG path ಸ್ಟ್ರಿಂಗ್ ಅನ್ನು ಜನರೇಟ್ ಮಾಡುತ್ತೇನೆ.
  • 5,000 ಪ್ರತ್ಯೇಕ ಸರ್ಕಲ್‌ಗಳಿಗಿಂತ ಒಂದೇ ಪಥವನ್ನು (path) ಬ್ರೌಸರ್ ರೆಂಡರ್ ಮಾಡುವುದು ಹೆಚ್ಚು ವೇಗವಾಗಿರುತ್ತದೆ.
  • ನಾನು ಕೋಆರ್ಡಿನೇಟ್ ಲುಕ್‌ಅಪ್ ಟೇಬಲ್‌ಗಳನ್ನು ಮೊದಲೇ ಲೆಕ್ಕಹಾಕುತ್ತೇನೆ, ಇದರಿಂದ ರನ್‌ಟೈಮ್‌ನಲ್ಲಿ ಬ್ರೌಸರ್ ಯಾವುದೇ ಗಣಿತದ ಕೆಲಸ ಮಾಡಬೇಕಾಗಿಲ್ಲ.

ಆ 1,000ms ವಿಳಂಬವು ಒಂದೇ ಕ್ಷಣದಲ್ಲಿ ನಡೆಯುವ ಪೇಂಟ್ (paint) ಆಗಿ ಬದಲಾಗುತ್ತದೆ.

ಫಾಂಟ್ ಲೋಡಿಂಗ್ ಅನ್ನು ಆಪ್ಟಿಮೈಸ್ ಮಾಡಿ

ನಾನು ನನ್ನ ಪ್ರೈಮರಿ ಫಾಂಟ್‌ಗಳಿಗಾಗಿ rel="preload" ಬಳಸುತ್ತೇನೆ.

crossOrigin ಅಟ್ರಿಬ್ಯೂಟ್ ಅನ್ನು ಮರೆಯುವುದು ಒಂದು ಸಾಮಾನ್ಯ ತಪ್ಪು. ನೀವು ಅದನ್ನು ಬಿಟ್ಟರೆ, ಬ್ರೌಸರ್ ಫಾಂಟ್ ಅನ್ನು ಎರಡು ಬಾರಿ ಫೆಚ್ ಮಾಡುತ್ತದೆ. ಇದು ನಿಮ್ಮ Largest Contentful Paint (LCP) ಅನ್ನು ಹಾಳುಮಾಡುತ್ತದೆ. ನಾನು 'above the fold' ಭಾಗದಲ್ಲಿ ಬಳಸುವ ಮೂರು ಫಾಂಟ್‌ಗಳನ್ನು ಮಾತ್ರ ಪ್ರೀಲೋಡ್ ಮಾಡುತ್ತೇನೆ.

ಅನಿಮೇಷನ್‌ಗಾಗಿ ಸರಿಯಾದ ಪರಿಕರಗಳನ್ನು ಬಳಸಿ

ನನ್ನ ಮ್ಯಾಪ್ ಮಾರ್ಕರ್ಸ್‌ಗಳ ಮೇಲಿನ ಸರಳ ಪಲ್ಸ್ ಅನಿಮೇಷನ್‌ಗಳಿಗಾಗಿ ನಾನು SMIL ಬಳಸುತ್ತೇನೆ. ಅನಿಮೇಷನ್ ಲೂಪ್ ಅನ್ನು ಚಲಾಯಿಸಲು React state ಬಳಸುವುದಕ್ಕಿಂತ ಇದು ಹೆಚ್ಚು ಹಗುರವಾಗಿದೆ. ಇದು ಬ್ರೌಸರ್ ಕೆಲಸವನ್ನು ಕಂಪೊಸಿಟರ್ ಥ್ರೆಡ್‌ನಲ್ಲಿ (compositor thread) ನಿರ್ವಹಿಸಲು ಅನುಮತಿಸುತ್ತದೆ.

ಸಂಕೀರ್ಣ ಪಥಗಳಿಗಾಗಿ, ನಾನು motion ಬಳಸುತ್ತೇನೆ. ನಾನು ಅದನ್ನು ಸರಳವಾಗಿಡುತ್ತೇನೆ. ನಾನು ಮೌಂಟ್ (mount) ಆದಾಗ ಒಮ್ಮೆ ಅನಿಮೇಟ್ ಮಾಡುತ್ತೇನೆ ಮತ್ತು ಸ್ಕ್ರೋಲ್ ಪೊಸಿಷನ್‌ಗಳನ್ನು (scroll positions) ಗಮನಿಸುವುದನ್ನು ತಪ್ಪಿಸುತ್ತೇನೆ.

ವೆಕ್ಟರ್‌ಗಳು ಮತ್ತು WebP ಬಳಸಿ

ಅದು ಲೋಗೋ ಅಥವಾ ಆಕಾರವಾಗಿದ್ದರೆ, SVG ಬಳಸಿ. ಅದು ಫೋಟೋ ಆಗಿದ್ದರೆ, WebP ಬಳಸಿ. ಇದು ಫೈಲ್ ಗಾತ್ರವನ್ನು ಕಡಿಮೆ ಇರಿಸುತ್ತದೆ ಮತ್ತು ಲೇಔಟ್ ಶಿಫ್ಟ್‌ಗಳನ್ನು (layout shifts) ತಡೆಯುತ್ತದೆ.

ಓವರ್-ಇಂಜಿನಿಯರಿಂಗ್ ತಪ್ಪಿಸಿ

ನಾನು ಇಮೇಜ್ CDN ಅನ್ನು ಬಳಸುವುದಿಲ್ಲ. ನಾನು ಸಂಕೀರ್ಣವಾದ ಕೋಡ್-ಸ್ಪ್ಲಿಟಿಂಗ್ ಅನ್ನು ಬಳಸುವುದಿಲ್ಲ. ನನ್ನ ಸೈಟ್ ಚಿಕ್ಕದಾಗಿದೆ, ಆದ್ದರಿಂದ ರೂಟ್-ಲೆವೆಲ್ ಸ್ಪ್ಲಿಟಿಂಗ್ (route-level splitting) ಸಾಕಾಗುತ್ತದೆ.

ಪರಿಪೂರ್ಣ ಸ್ಕೋರ್ ಎಂಬುದು ಕೇವಲ ಒಂದು ವ್ಯಾನಿಟಿ ಮೆಟ್ರಿಕ್ (vanity metric) ಆಗಿರಬಹುದು. ನಿಮ್ಮ ಕಾರ್ಯಕ್ಷಮತೆಯನ್ನು ಅಳೆಯುವುದು ಮತ್ತು ಸಾಧ್ಯವಾದಷ್ಟು ಹೆಚ್ಚಿನ ಕೆಲಸವನ್ನು ಬಳಕೆದಾರರ ಸಾಧನದಿಂದ ದೂರವಿಡುವುದು ನಿಜವಾದ ಗುರಿಯಾಗಿದೆ.

ನನ್ನ ಪೋರ್ಟ್‌ಫೋಲಿಯೋ: brodin.dev

ಸೋರ್ಸ್ ಕೋಡ್: github.com/NathanBrodin/Portfolio

TanStack Start prerendering: tanstack.com/start

Paper Shaders: shaders.paper.design

ಪೂರ್ಣ ಪೋಸ್ಟ್: https://dev.to/nathan-brodin/every-optimization-behind-a-perfect-lighthouse-score-283n