Add forntend performance content

best-practices
Kamran Ahmed 2 years ago
parent b7237cc2dc
commit 17ad153583
  1. 163
      bin/best-practice-content.cjs
  2. 28
      bin/readme.md
  3. 1
      package.json
  4. 2596
      public/jsons/best-practices/frontend-performance.json
  5. 1
      src/best-practices/frontend-performance/content/100-minimize-iframe-count.md
  6. 1
      src/best-practices/frontend-performance/content/101-minify-css.md
  7. 1
      src/best-practices/frontend-performance/content/102-make-css-files-non-blocking.md
  8. 1
      src/best-practices/frontend-performance/content/103-inline-critical-css.md
  9. 1
      src/best-practices/frontend-performance/content/104-avoid-inline-css.md
  10. 1
      src/best-practices/frontend-performance/content/105-analyse-stylesheets-complexity.md
  11. 1
      src/best-practices/frontend-performance/content/106-compress-your-images.md
  12. 1
      src/best-practices/frontend-performance/content/107-choose-image-format-approprietly.md
  13. 1
      src/best-practices/frontend-performance/content/108-minify-your-javascript.md
  14. 1
      src/best-practices/frontend-performance/content/109-use-non-blocking-javascript.md
  15. 1
      src/best-practices/frontend-performance/content/110-use-https-on-your-website.md
  16. 1
      src/best-practices/frontend-performance/content/111-page-weight-below-1500.md
  17. 1
      src/best-practices/frontend-performance/content/112-page-load-time-below-3s.md
  18. 1
      src/best-practices/frontend-performance/content/113-keep-ttfb-less-1-3s.md
  19. 1
      src/best-practices/frontend-performance/content/114-minimize-http-requests.md
  20. 1
      src/best-practices/frontend-performance/content/115-use-same-protocol.md
  21. 1
      src/best-practices/frontend-performance/content/116-avoid-404-files.md
  22. 1
      src/best-practices/frontend-performance/content/117-use-http-cache-headers.md
  23. 1
      src/best-practices/frontend-performance/content/118-enable-compression.md
  24. 1
      src/best-practices/frontend-performance/content/119-minify-html.md
  25. 1
      src/best-practices/frontend-performance/content/120-use-cdn.md
  26. 1
      src/best-practices/frontend-performance/content/121-prefer-vector-images.md
  27. 1
      src/best-practices/frontend-performance/content/122-set-width-height-images.md
  28. 1
      src/best-practices/frontend-performance/content/123-avoid-base64-images.md
  29. 1
      src/best-practices/frontend-performance/content/124-load-offscreen-images-lazily.md
  30. 1
      src/best-practices/frontend-performance/content/125-serve-exact-size-images.md
  31. 1
      src/best-practices/frontend-performance/content/126-avoid-multiple-inline-js-snippets.md
  32. 1
      src/best-practices/frontend-performance/content/127-keep-dependencies-up-to-date.md
  33. 1
      src/best-practices/frontend-performance/content/128-analyze-js-for-perf-issues.md
  34. 1
      src/best-practices/frontend-performance/content/129-use-service-workers-for-caching.md
  35. 1
      src/best-practices/frontend-performance/content/130-cookie-size-less-4096-bytes.md
  36. 1
      src/best-practices/frontend-performance/content/131-keep-cookie-count-below-20.md
  37. 1
      src/best-practices/frontend-performance/content/132-pre-load-urls-where-possible.md
  38. 1
      src/best-practices/frontend-performance/content/133-concatenate-css-single-file.md
  39. 1
      src/best-practices/frontend-performance/content/134-remove-unused-css.md
  40. 1
      src/best-practices/frontend-performance/content/135-use-woff2-font-format.md
  41. 1
      src/best-practices/frontend-performance/content/136-use-preconnect-to-load-fonts.md
  42. 1
      src/best-practices/frontend-performance/content/137-keep-web-font-under-300k.md
  43. 1
      src/best-practices/frontend-performance/content/138-prevent-flash-text.md
  44. 1
      src/best-practices/frontend-performance/content/139-check-dependency-size.md
  45. 1
      src/best-practices/frontend-performance/content/140-page-speed-insights.md
  46. 1
      src/best-practices/frontend-performance/content/141-lighthouse.md
  47. 1
      src/best-practices/frontend-performance/content/142-web-page-test.md
  48. 1
      src/best-practices/frontend-performance/content/143-chrome-dev-tools.md
  49. 1
      src/best-practices/frontend-performance/content/144-bundlephobia.md
  50. 1
      src/best-practices/frontend-performance/content/145-squoosh-ap.md
  51. 1
      src/best-practices/frontend-performance/content/146-framework-guides.md
  52. 1
      src/best-practices/frontend-performance/content/147-recommended-guides.md
  53. 1
      src/best-practices/frontend-performance/content/index.md
  54. 1
      src/best-practices/frontend-performance/content/minimize-iframes.md

@ -0,0 +1,163 @@
const fs = require('fs');
const path = require('path');
const CONTENT_DIR = path.join(__dirname, '../content');
// Directory containing the best-practices
const BEST_PRACTICE_CONTENT_DIR = path.join(__dirname, '../src/best-practices');
const bestPracticeId = process.argv[2];
const allowedBestPracticeId = fs.readdirSync(BEST_PRACTICE_CONTENT_DIR);
if (!bestPracticeId) {
console.error('bestPractice is required');
process.exit(1);
}
if (!allowedBestPracticeId.includes(bestPracticeId)) {
console.error(`Invalid best practice key ${bestPracticeId}`);
console.error(`Allowed keys are ${allowedBestPracticeId.join(', ')}`);
process.exit(1);
}
// Directory holding the best parctice content files
const bestPracticeDirName = fs
.readdirSync(BEST_PRACTICE_CONTENT_DIR)
.find((dirName) => dirName.replace(/\d+-/, '') === bestPracticeId);
if (!bestPracticeDirName) {
console.error('Best practice directory not found');
process.exit(1);
}
const bestPracticeDirPath = path.join(BEST_PRACTICE_CONTENT_DIR, bestPracticeDirName);
const bestPracticeContentDirPath = path.join(
BEST_PRACTICE_CONTENT_DIR,
bestPracticeDirName,
'content'
);
// If best practice content already exists do not proceed as it would override the files
if (fs.existsSync(bestPracticeContentDirPath)) {
console.error(`Best Practice content already exists @ ${bestPracticeContentDirPath}`);
process.exit(1);
}
function prepareDirTree(control, dirTree, dirSortOrders) {
// Directories are only created for groups
if (control.typeID !== '__group__') {
return;
}
// e.g. 104-testing-your-apps:other-options
const controlName = control?.properties?.controlName || '';
// e.g. 104
const sortOrder = controlName.match(/^\d+/)?.[0];
// No directory for a group without control name
if (!controlName || !sortOrder) {
return;
}
// e.g. testing-your-apps:other-options
const controlNameWithoutSortOrder = controlName.replace(/^\d+-/, '');
// e.g. ['testing-your-apps', 'other-options']
const dirParts = controlNameWithoutSortOrder.split(':');
// Nest the dir path in the dirTree
let currDirTree = dirTree;
dirParts.forEach((dirPart) => {
currDirTree[dirPart] = currDirTree[dirPart] || {};
currDirTree = currDirTree[dirPart];
});
dirSortOrders[controlNameWithoutSortOrder] = Number(sortOrder);
const childrenControls = control.children.controls.control;
// No more children
if (childrenControls.length) {
childrenControls.forEach((childControl) => {
prepareDirTree(childControl, dirTree, dirSortOrders);
});
}
return { dirTree, dirSortOrders };
}
const bestPractice = require(path.join(__dirname, `../public/jsons/best-practices/${bestPracticeId}`));
const controls = bestPractice.mockup.controls.control;
// Prepare the dir tree that we will be creating and also calculate the sort orders
const dirTree = {};
const dirSortOrders = {};
controls.forEach((control) => {
prepareDirTree(control, dirTree, dirSortOrders);
});
/**
* @param parentDir Parent directory in which directory is to be created
* @param dirTree Nested dir tree to be created
* @param sortOrders Mapping from groupName to sort order
* @param filePaths The mapping from groupName to file path
*/
function createDirTree(parentDir, dirTree, sortOrders, filePaths = {}) {
const childrenDirNames = Object.keys(dirTree);
const hasChildren = childrenDirNames.length !== 0;
// @todo write test for this, yolo for now
const groupName = parentDir
.replace(bestPracticeContentDirPath, '') // Remove base dir path
.replace(/(^\/)|(\/$)/g, '') // Remove trailing slashes
.replace(/(^\d+?-)/g, '') // Remove sorting information
.replaceAll('/', ':') // Replace slashes with `:`
.replace(/:\d+-/, ':');
const humanizedGroupName = groupName
.split(':')
.pop()
?.replaceAll('-', ' ')
.replace(/^\w/, ($0) => $0.toUpperCase());
const sortOrder = sortOrders[groupName] || '';
// Attach sorting information to dirname
// e.g. /best-practices/frontend-performance/content/internet
// ———> /best-practices/frontend-performance/content/103-internet
if (sortOrder) {
parentDir = parentDir.replace(/(.+?)([^\/]+)?$/, `$1${sortOrder}-$2`);
}
// If no children, create a file for this under the parent directory
if (!hasChildren) {
let fileName = `${parentDir}.md`;
fs.writeFileSync(fileName, `# ${humanizedGroupName}`);
filePaths[groupName || 'home'] = fileName.replace(CONTENT_DIR, '');
return filePaths;
}
// There *are* children, so create the parent as a directory
// and create `index.md` as the content file for this
fs.mkdirSync(parentDir);
let readmeFilePath = path.join(parentDir, 'index.md');
fs.writeFileSync(readmeFilePath, `# ${humanizedGroupName}`);
filePaths[groupName || 'home'] = readmeFilePath.replace(CONTENT_DIR, '');
// For each of the directory names, create a
// directory inside the given directory
childrenDirNames.forEach((dirName) => {
createDirTree(
path.join(parentDir, dirName),
dirTree[dirName],
dirSortOrders,
filePaths
);
});
return filePaths;
}
// Create directories and get back the paths for created directories
createDirTree(bestPracticeContentDirPath, dirTree, dirSortOrders);
console.log('Created best practice content directory structure');

@ -0,0 +1,28 @@
## CLI Tools
> A bunch of CLI scripts to make the development easier
## `roadmap-links.cjs`
Generates a list of all the resources links in any roadmap file.
## `compress-jsons.cjs`
Compresses all the JSON files in the `public/jsons` folder
## `roadmap-content.cjs`
This command is used to create the content folders and files for the interactivity of the roadmap. You can use the below command to generate the roadmap skeletons inside a roadmap directory:
```bash
npm run roadmap-content [frontend|backend|devops|...]
```
For the content skeleton to be generated, we should have proper grouping, and the group names in the project files. You can follow the steps listed below in order to add the meta information to the roadmap.
- Remove all the groups from the roadmaps through the project editor. Select all and press `cmd+shift+g`
- Identify the boxes that should be clickable and group them together with `cmd+shift+g`
- Assign the name to the groups.
- Group names have the format of `[sort]-[slug]` e.g. `100-internet`. Each group name should start with a number starting from 100 which helps with sorting of the directories and the files. Groups at the same level have the sequential sorting information.
- Each groups children have a separate group and have the name similar to `[sort]-[parent-slug]:[child-slug]` where sort refers to the sorting of the `child-slug` and not the parent. Also parent-slug does not need to have the sorting information as a part of slug e.g. if parent was `100-internet` the children would be `100-internet:how-does-the-internet-work`, `101-internet:what-is-http`, `102-internet:browsers`.

@ -14,6 +14,7 @@
"upgrade": "ncu -u",
"roadmap-links": "node bin/roadmap-links.cjs",
"roadmap-content": "node bin/roadmap-content.cjs",
"best-practice-content": "node bin/best-practice-content.cjs",
"test:e2e": "playwright test"
},
"dependencies": {

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save