|
1 | 1 | --- |
| 2 | +path: '/perf' |
| 3 | +date: '2020-06-26' |
| 4 | +title: 'Performance Optimization Tips & Tricks' |
| 5 | +tags: ['nunjucks', '11ty', 'mozilla'] |
| 6 | +excerpt: 'From a Twitter thread by Ivan Akulov' |
| 7 | +link: 'https://twitter.com/iamakulov/status/1275771832386441216' |
| 8 | +--- |
2 | 9 |
|
3 | | -path: "/nunjucks" |
4 | | -date: "2020-06-23" |
5 | | -title: "Hey, What's Nunjucks?" |
6 | | -tags: ["nunjucks", "11ty", "mozilla"] |
7 | | -excerpt: "Nunjucks was made by Mozilla ❤️" |
8 | | -link: "https://mozilla.github.io/nunjucks/templating.html" |
| 10 | +Note: I'm not a very familiar with `webpack`, so I skipped most of the tips concering `webpack` configuration. |
9 | 11 |
|
10 | | ---- |
| 12 | +## React |
| 13 | + |
| 14 | +### Debugging: |
| 15 | + |
| 16 | +- In Performance, once you've recorded a profile, go to **Timings** too see which components were rendered and when (good for debugging) - unfortunately this will be removed from React [link](https://github.com/facebook/react/pull/18417). |
| 17 | + |
| 18 | +- Component renders: Go to React DevTools settings and check "**Highlight updates...**". Now, whenever you do something, every component that re-renders will flash for a bit. |
| 19 | + |
| 20 | +- Another way to figure out why a component re-renders is to use [`why-did-you-render`](https://github.com/welldone-software/why-did-you-render) . |
| 21 | + |
| 22 | +### Preact |
| 23 | + |
| 24 | +- Replace it with `preact` + `preact-compat` (`react-dom` is the single largest dependency. Just by removing it, you can reduce your load time quite significantly). |
11 | 25 |
|
12 | | -## What is Nunjucks? |
| 26 | +## Images |
13 | 27 |
|
14 | | -Nunjucks is a templating language by Mozilla ❤️. |
| 28 | +- Compress them using Cloudflare (\$20/month), use **Polish** option. |
15 | 29 |
|
16 | | -A templating language is like a preprocessor for HTML (what SASS is to CSS) 👍. |
| 30 | +- Optimize image sizes with `<img srcset>` (don't serve gigantic images for tiny screens). |
17 | 31 |
|
18 | | -Template engines are tools that help us break HTML code into smaller pieces that we can reuse across multiple HTML files. |
| 32 | +## Fonts |
19 | 33 |
|
20 | | -They also give you the power to feed data into variables that help you simplify your code ([from](https://zellwk.com/blog/nunjucks-with-gulp/)). |
| 34 | +- Subset fonts for loading the fonts faster with [subfont](https://www.npmjs.com/package/subfont) or [glyphhanger](https://github.com/filamentgroup/glyphhanger). |
21 | 35 |
|
22 | | -Why use it? |
| 36 | +- If you’re preloading fonts, make sure you use the `crossorigin="anonymous"` attribute (without that attribute, preloaded fonts will be ignored). |
23 | 37 |
|
24 | | -- It lets you break HTML code into smaller files |
25 | | -- It lets you use data to populate your markup (DRY code baby) |
26 | | -- I'm learning 11ty, where Nunjucks is the preferred templating language. |
| 38 | +- A great way to speed up custom fonts is to use `font-display`([more details](https://font-display.glitch.me/)). |
27 | 39 |
|
28 | | -## File extension |
| 40 | +- For older websites add `&display=swap` (or another value) parameter to get `font-display` benefits. |
29 | 41 |
|
30 | | -Can be `.njk` but also just `.html`. |
| 42 | +## Other DevTools Magic |
31 | 43 |
|
32 | | -## Variables |
| 44 | +### Debugging |
33 | 45 |
|
34 | | -This is how you write variables: |
| 46 | +- If your app is lagging, that might be due to "repainting too much on the screen": **Dev tools → More tools → Rendering → Paint Flashing** |
35 | 47 |
|
36 | | -- `{{ username }}` also `{{ username.name }}` |
| 48 | +### Code splitting |
37 | 49 |
|
38 | | -You can also do `if` and `for` and other stuff (just like in JavaScript). |
| 50 | +- To see how much of your CSS and JS has been used to render a page: **DevTools → Ctrl/⌘+P → Coverage → "Start instrumenting...".** |
39 | 51 |
|
40 | | -## Filters |
| 52 | +- [bundle buddy](https://www.npmjs.com/package/bundle-buddy) shows duplicated modules |
41 | 53 |
|
42 | | -Filters are functions (note the `|` ). Filters can be builtin or made by you. |
| 54 | +- also [bundle wizard](https://www.npmjs.com/package/bundle-wizard) |
43 | 55 |
|
44 | | -- `{{ name | title }}` |
45 | | -- `{{ name | join(",") }}` |
| 56 | +## Libraries |
46 | 57 |
|
47 | | -Some built-in filters: |
| 58 | +- Moments.js: [day.js](https://github.com/iamkun/dayjs) is similar but smaller. |
48 | 59 |
|
49 | | -- capitalize |
50 | | -- lower |
51 | | -- random |
52 | | -- replace |
53 | | -- reverse |
54 | | -- safe |
55 | | -- trim |
56 | | -- urlize (Convert URLs in plain text into clickable links:) |
| 60 | +- `lodash`: babel-plugin-lodash transforms your Lodash imports to make sure you’re only bundling methods that you actually use (= 10-20 functions instead of 300). |
57 | 61 |
|
58 | | -## Template inheritance |
| 62 | +- Try aliasing `lodash-es` to `lodash` (to avoid lodash being bundled multiple times). |
59 | 63 |
|
60 | | -Template inheritance is where nunjucks really shines! |
| 64 | +- Check how much they are affecting your loading speed: **Network → Sort by domain → Right-click each third-party → Select "Block request domain"**. Then run lighthouse audit to compare. |
61 | 65 |
|
62 | | -### Includes |
| 66 | +### Defer 3rd parties: |
63 | 67 |
|
64 | | -include pulls in other templates in place (especially partials) |
| 68 | +- More details [here](https://3perf.com/blog/notion/#defer-third-parties), or just wrap your third party loading code with `setTimeout`. |
65 | 69 |
|
66 | | -```HTML |
67 | | -<body> |
68 | | - {% include partials "nav" %} |
69 | | - <div class="content"> ... </div> |
70 | | - {% include partials "footer" %} |
71 | | -</body> |
72 | | -``` |
| 70 | +## Critical CSS |
73 | 71 |
|
74 | | -- filenames that begin with \_ are not built so they are ideal for partials. |
| 72 | +- more [here](https://github.com/addyosmani/critical) and [here](https://3perf.com/talks/web-perf-101/#critical-css) |
75 | 73 |
|
76 | | -### Extends |
| 74 | +## Speed tests |
77 | 75 |
|
78 | | -- extends allow you to define a template document with “blocks” inside of it that are meant to take chunks of content. |
| 76 | +- [Lighthosue from CLI](https://www.npmjs.com/package/lighthouse) |
79 | 77 |
|
80 | | -- this allows us to define a base template, and then override parts of it within the child template. This is known as template inheritance. |
| 78 | +- [webpage test](https://webpagetest.org/) |
81 | 79 |
|
82 | | -## Macros (import) |
| 80 | +## Misc Optimizations |
83 | 81 |
|
84 | | -- macros are imports with parameters - a.k.a. functions! |
| 82 | +- Type `-has-response-header: Content-Encoding` into the filter in the Network panel to see if resources are missing gzip/Brotli compression. |
85 | 83 |
|
86 | | -## Whitespace |
| 84 | +- Speedier navigation: [getquick](https://getquick.link/) (preloads links when the visitor hovers them. this gives a 100-300 ms head start), [instantclick](http://instantclick.io/) (goes further and preloads all links within the viewport). |
87 | 85 |
|
88 | | -- You can tell the engine to strip all leading or trailing whitespace by adding a minus sign (-) to the start or end block or a variable. |
| 86 | +- To check whether all requests use a single HTTP/2 connection, or something’s misconfigured, enable the **"Connection ID"** column in **DevTools → Network**. |
89 | 87 |
|
90 | | -## Autoescaping |
| 88 | +- Use [polyfill.io](https://polyfill.io/v3/) to reduce the amount of polyfills. |
91 | 89 |
|
92 | | -- If autoescaping is turned on in the environment, all output will automatically be escaped for safe output. To manually mark the output as safe, use the safe filter. Nunjucks will not escape this output. |
| 90 | +- If you have any `scroll` or `touch*` listeners, make sure to pass `passive: true` to addEventListener, more [here](https://developers.google.com/web/updates/2016/06/passive-event-listeners). |
0 commit comments