ЁЯЪА рдзрдбрд╛ 09 тАФ Performance: рдлрд▓рдХ рдкрдЯрдХрди рдЙрдШрдбрддреЛ
ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 09 ┬╖ рдорд╛рдЧреАрд▓: lesson-08-design-tokens ┬╖ рдкреБрдвреАрд▓: lesson-10-testing
ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ
рдзрдбреЗ 01тАУ08, рдЖрдгрд┐ рддреНрдпрд╛рд╕реЛрдмрдд рдлрд▓рдХ рдордВрдж рдХрд╛ рд╡рд╛рдЯрддрд╛рдд рдЖрдгрд┐ рдЦрд░реЛрдЦрд░ рдХрд╛рдп рджреБрд░реБрд╕реНрдд рдХрд░рддреЗ: рдХрдореА bytes, рдкреНрд░рд╛рдорд╛рдгрд┐рдХ images, caching, рдЖрдгрд┐ рдорд╛рдгрд╕рд╛рд▓рд╛ рдЬрд╛рдгрд╡рдгрд╛рд░рд╛ рд╡реЗрдЧ рд╕рд╛рдВрдЧрдгрд╛рд░реЗ рддреАрди рдЖрдХрдбреЗ тАФ Core Web Vitals.
ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ
рдлрд▓рдХ рдХрдВрдЯрд╛рд│рд╡рд╛рдгреНрдпрд╛ рдХрд╛рд░рдгрд╛рдВрдиреА рдордВрдж рдЕрд╕рддреЛ: рддреЛ рдЬрдб рдЕрд╕рддреЛ (download рдХрд░рд╛рдпрд▓рд╛ рдЦреВрдк рдХрд╛рд╣реА), рддреЛ рдерд╛рдВрдмрддреЛ (рдПрдХ file рдкреБрдврдЪреНрдпрд╛ file рд▓рд╛ рдЕрдбрд╡рддреЗ), рдХрд┐рдВрд╡рд╛ load рд╣реЛрддрд╛рдирд╛ рддреЛ рдЙрдбреНрдпрд╛ рдорд╛рд░рддреЛ. рдкреНрд░рддреНрдпреЗрдХрд╛рд╡рд░ рдПрдХ рдХрдВрдЯрд╛рд│рд╡рд╛рдгрд╛ рдЙрдкрд╛рдп рдЖрд╣реЗ:
- рд╡рдЬрди тЪЦя╕П тАФ рдХрдореА рдкрд╛рдард╡рд╛. Minify рдЖрдгрд┐ compress рдХрд░рд╛ (gzip/brotli), code рдЕрд╕рд╛ рд╡рд┐рднрд╛рдЧрд╛ рдХреА page рд▓рд╛ рдлрдХреНрдд рд▓рд╛рдЧреЗрд▓ рддреЗрд╡рдвреЗрдЪ load рд╣реЛрдИрд▓, рдЖрдгрд┐ рдПрдХрджрд╛рдЪ рд╡рд╛рдкрд░рд▓реЗрд▓реА library рдХрд╛рдвреВрди рдЯрд╛рдХрд╛. рддреБрдордЪреНрдпрд╛ code рдЖрдзреАрдЪ framework ~140 KB рдЕрд╕рддреЛ; рдЖрдкрд▓рд╛ рд╕рдВрдкреВрд░реНрдг рдлрд▓рдХ ~9 KB рдЖрд╣реЗ.
- Images ЁЯЦ╝я╕П тАФ рдХреЛрдгрддреНрдпрд╛рд╣реА рдлрд▓рдХрд╛рд╡рд░рдЪреА рдмрд╣реБрддреЗрдХ рд╡реЗрд│рд╛ рд╕рдЧрд│реНрдпрд╛рдд рдЬрдб рдЧреЛрд╖реНрдЯ. рдпреЛрдЧреНрдп
рдЖрдХрд╛рд░ (200px card рдордзреНрдпреЗ 4000px photo рдирдХреЛ), рдЖрдзреБрдирд┐рдХ format (WebP/AVIF),
fold рдЪреНрдпрд╛ рдЦрд╛рд▓рдЪреНрдпрд╛ рдкреНрд░рддреНрдпреЗрдХ рдЧреЛрд╖реНрдЯреАрд╕рд╛рдареА
loading="lazy", рдЖрдгрд┐ рдиреЗрд╣рдореАwidth/height, рдореНрд╣рдгрдЬреЗ рддреНрдпрд╛ рдЖрд▓реНрдпрд╛рд╡рд░ layout рдЙрдбреА рдорд╛рд░рдд рдирд╛рд╣реА. - Caching ЁЯзК тАФ рд╕рдЧрд│реНрдпрд╛рдд рдЬрд▓рдж file рдореНрд╣рдгрдЬреЗ рдЬреА рдЖрдзреАрдЪ рд╡рд╛рдЪрдХрд╛рдЪреНрдпрд╛ machine рд╡рд░
рдЖрд╣реЗ. Filename рд▓рд╛ hash рд▓рд╛рд╡рд╛ (
app.7f3c2a.js), рд╡рд░реНрд╖рднрд░ cache рдХрд░рд╛, рдЖрдгрд┐ content рдмрджрд▓рд▓рд╛ рдХреА рдирд╛рд╡ рдмрджрд▓рд╛. CDN рддреА рд╡рд╛рдЪрдХрд╛рдЬрд╡рд│ рдареЗрд╡рддреЛ.
рдордЧ рдорд╛рдгрд╕рд╛рд▓рд╛ рдХрд╛рдп рдЬрд╛рдгрд╡рддреЗ рддреЗ рдореЛрдЬрд╛ тАФ Core Web Vitals: LCP (рд╕рдЧрд│реНрдпрд╛рдд рдореЛрдареА рдЧреЛрд╖реНрдЯ рдХрд┐рддреА рд▓рд╡рдХрд░ рджрд┐рд╕рддреЗ), INP (taps рдирд╛ рдХрд┐рддреА рдкрдЯрдХрди рдкреНрд░рддрд┐рд╕рд╛рдж рдорд┐рд│рддреЛ), CLS (рдЧреЛрд╖реНрдЯреА рдХрд┐рддреА рдЙрдбреНрдпрд╛ рдорд╛рд░рддрд╛рдд). рддреБрдордЪреНрдпрд╛ laptop рд╡рд░ рдирд╛рд╣реА, рддрд░ throttled phone рд╡рд░ рдореЛрдЬрд╛.
ЁЯЧ║я╕П рдЖрдХреГрддреА
flowchart LR
w["тЪЦя╕П weight<br/>minify ┬╖ compress ┬╖ split ┬╖ delete"]
i["ЁЯЦ╝я╕П images<br/>right size ┬╖ webp/avif ┬╖ lazy ┬╖ width+height"]
c["ЁЯзК caching<br/>hashed names + long max-age ┬╖ CDN"]
m["ЁЯУП measure<br/>LCP ┬╖ INP ┬╖ CLS on a slow phone"]
w --> i --> c --> m
m -->|"the number that moved"| w
тЭУ рдХрд╛рдп
- Critical path: HTML тЖТ CSS (render-blocking) тЖТ JS. CSS рдЫреЛрдЯреА рдЖрдгрд┐ рд▓рд╡рдХрд░
рдареЗрд╡рд╛; JS
defer/type=moduleрдиреЗ load рдХрд░рд╛ рдореНрд╣рдгрдЬреЗ parsing рдЕрдбрдд рдирд╛рд╣реА. - LCP тЙд 2.5 s: рдмрд╣реБрддреЗрдХ рд╡реЗрд│рд╛ hero image рдХрд┐рдВрд╡рд╛ heading тАФ рддреА preload рдХрд░рд╛, lazy load рдХрд░реВ рдирдХрд╛. INP тЙд 200 ms: main thread рд╡рд░рдЪреЗ рдХрд╛рдо рдЫреЛрдЯреЗ рдареЗрд╡рд╛ (рд▓рд╛рдВрдм tasks taps рдЕрдбрд╡рддрд╛рдд). CLS тЙд 0.1: images, ads рдЖрдгрд┐ рдЙрд╢рд┐рд░рд╛ рдпреЗрдгрд╛рд▒реНрдпрд╛ fonts рд╕рд╛рдареА рдЬрд╛рдЧрд╛ рд░рд╛рдЦреВрди рдареЗрд╡рд╛.
- Fonts:
font-display: swap, subset, self-host рдХрд┐рдВрд╡рд╛ preconnect; рдЙрд╢рд┐рд░рд╛ рдпреЗрдгрд╛рд░рд╛ webfont рд╣реА CLS рдЖрдгрд┐ LCP рдЪреА рдиреЗрд╣рдореАрдЪреА рдЕрдбрдЪрдг рдЖрд╣реЗ. (рдЖрдкрд▓рд╛ рдлрд▓рдХ system fonts рд╡рд╛рдкрд░рддреЛ тАФ рд╢реВрдиреНрдп bytes, рд▓рдЧреЗрдЪ.) - Caching headers: hashed assets рд╕рд╛рдареА
Cache-Control: max-age=31536000, immutable; HTML рд╕рд╛рдареА рдЫреЛрдЯрд╛ рдХрд┐рдВрд╡рд╛no-cache. рд╣рд╛ API рд╢рд╛рд│реЗрдЪрд╛ рдзрдбрд╛ 10 рдЖрд╣реЗ, browser рдЪреНрдпрд╛ рдмрд╛рдЬреВрдиреЗ рдкрд╛рд╣рд┐рд▓реЗрд▓рд╛. - рдореЛрдЬрд╛: DevTools тЖТ Lighthouse (lab) рдЖрдгрд┐ CPU/network throttling рд╕рд╣
Performance panel; рдЦрд▒реНрдпрд╛ users рд╕рд╛рдареА
PerformanceObserverрдХрд┐рдВрд╡рд╛ RUM tool (рдзрдбрд╛ 12). - рдЕрдВрджрд╛рдЬ рдХрд░реВ рдирдХрд╛: рдЬреЛ рдЖрдХрдбрд╛ рд╡рд╛рдИрдЯ рдЖрд╣реЗ рддреЛрдЪ рдЙрдкрд╛рдп рдард░рд╡рддреЛ. 2 MB hero image load рд╣реЛрдд рдЕрд╕рддрд╛рдирд╛ 9 KB bundle optimise рдХрд░рдгреЗ рдореНрд╣рдгрдЬреЗ рдирд╛рдЯрдХ.
ЁЯдФ рдХрд╛
рдХрд╛рд░рдг рд╡реЗрдЧ рд╣реЗ рдЕрд╕реЗ рд╡реИрд╢рд┐рд╖реНрдЯреНрдп рдЖрд╣реЗ рдЬреЗ рд▓реЛрдХрд╛рдВрдирд╛ рдЗрддрд░ рдХреЛрдгрддреЗрд╣реА рд▓рдХреНрд╖рд╛рдд рдпреЗрдгреНрдпрд╛рдЖрдзреА рдЬрд╛рдгрд╡рддреЗ, рдЖрдгрд┐ рдХрд╛рд░рдг рд╕рд░рд╛рд╕рд░реА network рд╡рд░рдЪрд╛ рд╕рд░рд╛рд╕рд░реА phone рддреБрдордЪреНрдпрд╛ machine рдкреЗрдХреНрд╖рд╛ рдЦреВрдкрдЪ рдордВрдж рдЕрд╕рддреЛ. рдХреЛрдгреАрд╣реА рдХреЗрд▓реЗрд▓реНрдпрд╛ рдкреНрд░рддреНрдпреЗрдХ рдЕрднреНрдпрд╛рд╕рд╛рдд load рдЪрд╛ рдкреНрд░рддреНрдпреЗрдХ рд╕реЗрдХрдВрдж conversions рдЧрдорд╛рд╡рддреЛ тАФ рдЖрдгрд┐ рд╢рд╛рд│реЗрдЪреНрдпрд╛ рдлрд▓рдХрд╛рд╡рд░, рддреЛ рдХрдВрдЯрд╛рд│реВрди рд╕реЛрдбреВрди рджреЗрдгрд╛рд░рд╛ рдкрд╛рд▓рдХ рдЧрдорд╛рд╡рддреЛ.
ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)
рдлрд▓рдХ рдХрдореА рдЧреЛрд╖реНрдЯреА рдЕрд╕рд▓реНрдпрд╛рдореБрд│реЗ рдЬрд▓рдж рдЖрд╣реЗ: рддреАрди files, system fonts, inline SVG avatars (image requests рдЕрдЬрд┐рдмрд╛рдд рдирд╛рд╣реАрдд), framework рдирд╛рд╣реА, build рдирд╛рд╣реА. рд╣реА рд╕рдЧрд│реНрдпрд╛рдд рд╕реНрд╡рд╕реНрдд performance рд░рдгрдиреАрддреА рдЖрд╣реЗ тАФ рдЖрдгрд┐ рдЦрд░рд╛ project рдЬрдб рдЭрд╛рд▓реНрдпрд╛рд╡рд░ рдЬреНрдпрд╛рдЪреНрдпрд╛рд╢реА рддреБрд▓рдирд╛ рдХрд░рд╛рдпрдЪреА рддреЛ рдкрд╛рдпрд╛.
ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛
python3 ui/mock_api.py
# 1) the honest baseline:
wc -c ui/index.html ui/styles.css ui/app.js # ~9 KB total, uncompressed
# 2) Lighthouse: DevTools тЖТ Lighthouse тЖТ Mobile тЖТ Analyze. Note LCP, CLS, and the score.
# 3) feel a slow network: DevTools тЖТ Network тЖТ throttle to "Slow 4G", reload. Then Performance тЖТ CPU 4├Ч slowdown.
# 4) create CLS on purpose: remove width="40" height="40" from the card <img> in index.html, reload on Slow 4G тАФ
# watch the cards shift as avatars arrive. Put them back.
# 5) create a long task: in the Console run let t=Date.now(); while(Date.now()-t<800){} and try clicking during it тАФ that is bad INP.
тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ
Lighthouse рдлрд▓рдХрд╛рд▓рд╛ рдЙрдЪреНрдЪ performance score рджреЗрддреЛ, рдЖрдгрд┐ LCP 2.5 s рдЪреНрдпрд╛ рдмрд░реАрдЪ рдЦрд╛рд▓реА рдЕрд╕рддреЗ. Image dimensions рдХрд╛рдврд▓реНрдпрд╛рд╡рд░ рдордВрдж connection рд╡рд░ layout рд╕реНрдкрд╖реНрдЯрдкрдгреЗ рдЙрдбреА рдорд╛рд░рддреЛ (рдЖрдгрд┐ CLS рд╡рд╛рдврддреЛ); рддреЗ рдкрд░рдд рд▓рд╛рд╡рд▓реНрдпрд╛рд╡рд░ рддреЗ рджреБрд░реБрд╕реНрдд рд╣реЛрддреЗ. Busy-loop рдореБрд│реЗ page рдЬрд╡рд│рдЬрд╡рд│ рдПрдХ рд╕реЗрдХрдВрдж рдкреНрд░рддрд┐рд╕рд╛рдж рджреЗрдд рдирд╛рд╣реА тАФ рд╣реЗрдЪ INP рдореЛрдЬрддреЛ.
ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ
User рд▓рд╛ рдЬрд╕рд╛ рдЕрдиреБрднрд╡ рдпреЗрддреЛ рддрд╕рд╛ рддреБрдореНрд╣реА рдлрд▓рдХ рдореЛрдЬрд▓рд╛рдд, рдЖрдгрд┐ layout shift рдЖрдгрд┐ рдЕрдбрд▓реЗрд▓рд╛ main thread рдореБрджреНрджрд╛рдо рдШрдбрд╡реВрди рджреБрд░реБрд╕реНрддрд╣реА рдХреЗрд▓рд╛.
тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛
- рдореЛрдареА, optimise рди рдХреЗрд▓реЗрд▓реА image LCP рд╡рд░ рд░рд╛рдЬреНрдп рдХрд░рдд рдЕрд╕рддрд╛рдирд╛ bundle size optimise рдХрд░рдгреЗ
- hero image lazy-load рдХрд░рдгреЗ (рддреЛрдЪ LCP element рдЖрд╣реЗ тАФ рддреЛ рд▓рдЧреЗрдЪ load рдХрд░рд╛)
- images рд╡рд░
width/heightрдирд╕рдгреЗ (CLS) - HTML рд╡рд░реНрд╖рднрд░ cache рдХрд░рдгреЗ (рдирд╡реАрди version рдХреЛрдгрд╛рд▓рд╛рдЪ рдХрдзреАрдЪ рджрд┐рд╕рдд рдирд╛рд╣реА)
- рдлрдХреНрдд office wifi рд╡рд░рдЪреНрдпрд╛ рдЬрд▓рдж laptop рд╡рд░ test рдХрд░рдгреЗ
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: Core Web Vitals browsers рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рддреВрди рдореЛрдЬрддрд╛рдд рдЖрдгрд┐ search ranking рд╕рд╛рдареА рд╡рд╛рдкрд░рд▓реНрдпрд╛ рдЬрд╛рддрд╛рдд; рддреНрдпрд╛рд╣реВрди рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ рдореНрд╣рдгрдЬреЗ рд▓реЛрдХ рдЬреНрдпрд╛рдмрджреНрджрд▓ рддрдХреНрд░рд╛рд░ рдХрд░рддрд╛рдд рддреНрдпрд╛рдЪреНрдпрд╛рд╢реА рддреНрдпрд╛ рдЬреБрд│рддрд╛рдд. рдпрд╛ рдзрдбреНрдпрд╛рдд "рд╣реЗ рдордВрдж рд╡рд╛рдЯрддреЗ" рд╣реЗ рдХреГрддреА рдХрд░рддрд╛ рдпреЗрдгрд╛рд░рд╛ рдЖрдХрдбрд╛ рдмрдирддреЗ.
тПня╕П рдкреБрдвреЗ
рдкреБрдврдЪреНрдпрд╛ рдмрджрд▓рд╛рдд рдореЛрдбрдд рдЕрд╕реЗрд▓ рддрд░ рдЬрд▓рдж рдЖрдгрд┐ рд╕реБрдВрджрд░ рдЕрд╕рдгреЗ рдкреБрд░реЗрд╕реЗ рдирд╛рд╣реА: UI testing тАФ unit, component, end-to-end рдЖрдгрд┐ рддреБрдордЪреНрдпрд╛рдХрдбреЗ рдЖрдзреАрдЪ рдЕрд╕рд▓реЗрд▓рд╛ smoke test.
git checkout lesson-10-testing