ఒక పరిపూర్ణ Lighthouse స్కోర్ వెనుక ఉన్న ప్రతి ఆప్టిమైజేషన్

నేను నా సైట్‌లో నిరంతరం Lighthouseని రన్ చేస్తూ ఉంటాను. ప్రతి లోకల్ రన్‌లోనూ మరియు Vercel యొక్క Real Experience Scoreలోనూ ఇది 100 వద్దే ఉంటుంది.

ఈ స్కోర్లు ఏదో సాధారణ చెక్‌లిస్ట్ ద్వారా వచ్చినవి కావు. బ్రౌజర్ నుండి పనిని బిల్డ్ స్టేజ్ (build stage)కి మార్చడం ద్వారా నేను వీటిని సాధిస్తాను.

నేను దీనిని ఖచ్చితంగా ఎలా చేస్తానో ఇక్కడ ఉంది.

పనిని బిల్డ్ టైమ్‌కి మార్చండి

చాలా గైడ్‌లు ప్రతిదీ lazy-load చేయమని చెబుతాయి. నేను prerender చేయడానికే మొగ్గు చూపుతాను. నేను prerendering ఎనేబుల్ చేసిన TanStack Startని ఉపయోగిస్తాను.

ఇది బిల్డ్ సమయంలో మొత్తం సైట్‌ను static HTMLగా మారుస్తుంది. మొదటి పేజీని చూపించడానికి బ్రౌజర్ భారీ JavaScriptని ఎగ్జిక్యూట్ చేయాల్సిన అవసరం లేదు. యూజర్ ఎంటర్ చేసినప్పుడు HTML ఇప్పటికే సిద్ధంగా ఉంటుంది.

సంక్లిష్టమైన లాజిక్‌ను ముందే లెక్కించండి (Precompute)

నా హోమ్‌పేజీలో 5,000 చుక్కలతో కూడిన ప్రపంచ పటం (world map) ఉంది. సాధారణంగా, ఒక లైబ్రరీ GeoJSONని పార్స్ చేసి, మెయిన్ థ్రెడ్‌లో గణిత ప్రక్రియలను (math) నిర్వహిస్తుంది. ఇది పేజీని 1,000ms పాటు బ్లాక్ చేస్తుంది.

ఈ గణిత ప్రక్రియను బిల్డ్ స్క్రిప్ట్‌కి మార్చడం ద్వారా నేను దీనిని పరిష్కరించాను.

  • నేను 5,000 చుక్కలన్నింటికీ ఒకే ఒక SVG path stringని జనరేట్ చేస్తాను.
  • 5,000 విడివిడి సర్కిల్స్ కంటే ఒకే పాత్ (path) బ్రౌజర్ రెండర్ చేయడానికి చాలా వేగంగా ఉంటుంది.
  • నేను కోఆర్డినేట్ లుకప్ టేబుల్స్‌ను (coordinate lookup tables) ముందే లెక్కించి ఉంచుతాను, తద్వారా రన్‌టైమ్‌లో బ్రౌజర్ ఎలాంటి గణిత ప్రక్రియలు చేయాల్సిన అవసరం ఉండదు.

ఆ 1,000ms ఆలస్యం ఒకేసారి, తక్షణమే కనిపించే (instant 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ని ఉపయోగించను. నేను సంక్లిష్టమైన code-splittingని ఉపయోగించను. నా సైట్ చిన్నది, కాబట్టి route-level splitting సరిపోతుంది.

పరిపూర్ణ స్కోరు అనేది కేవలం ఒక vanity metric మాత్రమే కావచ్చు. మీ పనితీరును (performance) కొలవడం మరియు వీలైనంత ఎక్కువ పనిని యూజర్ పరికరం (user's device) నుండి దూరంగా తరలించడమే అసలైన లక్ష్యం.

నా పోర్ట్‌ఫోలియో: 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