Upgrade to Pro — share decks privately, control downloads, hide ads and more …

How2ImproveFrontendPerformance

 How2ImproveFrontendPerformance

Taiga Mikami

June 19, 2023
Tweet

More Decks by Taiga Mikami

Other Decks in Technology

Transcript

  1. https://web.dev/why-speed-matters/ “Performance has directly impacted the company's bottom line.” by

    Pinterest > Pinterest reduced perceived wait times by 40% and this increased search engine traffic and sign-ups by 15%. Performance is about improving conversions Performance is about user experience Performance is about people
  2. In Shippio⛴ ? ⭕ Good experience makes customers pay for

    Shippio app ❌ Bad experience makes customers leave
  3. FCP https://web.dev/i18n/en/lcp/ First Contentful Paint (FCP) metric measures the time

    from when the page starts loading to when any part of the page's content is rendered on the screen. https://web.dev/i18n/en/fcp/ SI Speed Index (SI) is a page load performance metric that shows you how quickly the contents of a page are visibly populated. https://developer.mozilla.org/en-US/docs/Glossary/Speed_index https://developer.chrome.com/docs/lighthouse/performance/speed-index/ LCP Largest Contentful Paint (LCP) metric reports the render time of the largest image or text block visible within the viewport, relative to when the page first started loading.
  4. TTI https://web.dev/i18n/en/cls/ https://web.dev/evolving-cls/ TTI metric measures the time from when

    the page starts loading to when its main sub-resources have loaded and it is capable of reliably responding to user input quickly. https://web.dev/i18n/en/tti/ TBT Total Blocking Time (TBT) metric measures the total amount of time between First Contentful Paint (FCP) and Time to Interactive (TTI) where the main thread was blocked for long enough to prevent input responsiveness. https://web.dev/i18n/en/tbt/ CLS CLS is a measure of the largest burst of layout shift scores for every unexpected layout shift that occurs during the entire lifespan of a page.
  5. Performance.now() Focus on the specific process const t0 = performance.now();

    doSomething(); ← Target const t1 = performance.now(); console.log(`Call to doSomething took ${t1 - t0} milliseconds.`); Call to doSomething took 11088.40000000596 milliseconds. Code Output (console.log)
  6. Request Web page GET HTML Build DOM GET CSS GET

    JavaScript Build CSSOM Run JavaScript Render Page Idle Block Critical Rendering Path Network Process Rendering Process Start Goal Load HTML Documents Load Subresources Rendering
  7. ① To transfer as little data as possible ② To

    transfer data as few times as possible ③ To keep the data transfer distance as short as possible Principles of optimisation of network part ① request ② request ③ data data far close
  8. Lighthouse tells us what to improve • Enable text compresion

    • Reduce unused JavaScript • Reduce unused CSS
  9. ✅ Using other packages ✅ Not Using packages Remove too

    big packages eg.) Lodash → Rewriting to Vanilla JavaScript icons package → Rewriting to SVG (Import only you need) css-ui package → Rewriting to Pure CSS eg.) moment.js → change to other package (day.js, date-fns) react-router → wouter
  10. Compression of the image Converting images to WebP or AVIF

    etc… Converting font to WOFF2 Assets Optimization https://github.com/GoogleChromeLabs/squoosh 🖼 Images ✏ Fonts https://github.com/papandreou/subset-font ※Some browsers are still not supported. Our clients may be using even older browsers 😩 https://github.com/imagemin/imagemin-cli
  11. HTTP3 is even faster with QUIC and UDP instead of

    TCP protocol. HTTP1 ✕ / HTTP2 ◯ / HTTP3 ◎ (depending on the browser)
  12. Apps should be compressed by Brotil algorithm. Content encoding https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding

    https://firebase.blog/posts/2020/08/firebase-hosting-new-features Firebase hosting does everything automatically. 👏👏
  13. Server-Side Rendering Client Server Client Server Initial request <html />

    Request (resouces and data) Data payload Initial request <html /> SPA SSR SSR is shorter TTI (Time to Interactive) 🚀 Interactive Interactive Server-Side Rendering might be overkill for our service…
  14. Parallel Request async function notUsePromiseAll() { console.log('Start!!'); const response1 =

    await fetch("https://example.com/api/1"); const response2 = await fetch("https://example.com/api/2"); console.log('End!!'); } async function usePromiseAll() { console.log('Start!!'); const [response1, response2] = await Promise.all([ fetch("https://example.com/api/1"), fetch("https://example.com/api/2"), ]); console.log('End!!'); } Good 👍 Bad 👎 fetch 1 fetch 2 fetch 1 fetch 2 Use Promise.all() time time
  15. Using Skeleton Improve the score for CLS You can create

    the frame for the data after loading in advance Make for great user experiences To make the page loading speed feel faster for users
  16. Reduce Chunk Size Per Page React.lazy + Suspence import React,

    { Suspense, lazy } from 'react'; import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; const Home = lazy(() => import('./routes/Home')); const About = lazy(() => import('./routes/About')); const App = () => ( <Router> <Suspense fallback={<div>Loading...</div>}> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> </Routes> </Suspense> </Router> ); File sizes after gzip: 322.74 KB (+180.2 KB) build/static/js/18.aa12ce15.chunk.js 235.25 KB (+231.59 KB) build/static/js/28.a0c7e83f.chunk.js Home Component About Component Can download the required JS for each page. 😎 FYI: Similar solution
  17. Reduce Chunk Size Per Page import { lazy } from

    'react'; ... { path: '/dashboard', component: lazy(() => import('../pages/dashboard/Dashboard')), }, { path: '/shipment', component: lazy(() => import('../pages/shipments/ShipmentsContainer')), }, { path: '/shipments', component: lazy(() => import('../pages/shipments/ShipmentsContainer')), }, { path: '/quote', component: lazy(() => import('../../pages/quote/RoutesContainer/RoutesContainer')), }, ... File sizes after gzip: 322.74 KB (+180.2 KB) build/static/js/18.aa12ce15.chunk.js 235.25 KB (+231.59 KB) build/static/js/28.a0c7e83f.chunk.js 229.81 KB (-107 B) build/static/css/11.c8964559.chunk.css 154.53 KB (-14.75 KB) build/static/js/11.183c1d8c.chunk.js 132.47 KB (-211.45 KB) build/static/js/16.828d24e0.chunk.js 132.47 KB (-10.07 KB) build/static/js/17.96b0ee45.chunk.js 119.37 KB (-10.42 KB) build/static/js/12.59c03137.chunk.js Router file Build Output https://webpack.js.org/plugins/split-chunks-plugin/#optimizationsplitchunks SplitChunksPlugin Improve bit more…🤔?
  18. (to get backend response faster.) • Scaling Sever • SQL

    optimisation • Thread handling • Giving more detail properties to html tags • Tuning Contents Cache-Policy • Tuning Graphql Client Cache-Policy (Apollo-Client) • Prefetch resources: preconnect, dns-prefetch, preload • Using ServiceWorker • WebAssembly Other Tips Improve Backend