├── .gitignore
├── lazy-loading-dynamic-import
├── src
│ ├── views
│ │ ├── about.mjs
│ │ ├── help.mjs
│ │ ├── home.mjs
│ │ └── contact.mjs
│ ├── index.js
│ ├── routerConfig.mjs
│ └── router.mjs
├── readme.md
├── package.json
└── index.html
├── .github
├── workflows
│ └── set-default-labels.yml
└── labels.json
├── README.md
├── CODE_OF_CONDUCT.md
└── LICENSE
/.gitignore:
--------------------------------------------------------------------------------
1 | .vscode
2 | .DS_Store
3 | build
4 | dist
5 | node_modules
6 | .cache
--------------------------------------------------------------------------------
/lazy-loading-dynamic-import/src/views/about.mjs:
--------------------------------------------------------------------------------
1 | export default `
2 |
About
3 | `;
--------------------------------------------------------------------------------
/lazy-loading-dynamic-import/src/views/help.mjs:
--------------------------------------------------------------------------------
1 | export default `
2 | Help
3 | `;
--------------------------------------------------------------------------------
/lazy-loading-dynamic-import/src/views/home.mjs:
--------------------------------------------------------------------------------
1 | export default `
2 | Home
3 | `;
--------------------------------------------------------------------------------
/lazy-loading-dynamic-import/src/views/contact.mjs:
--------------------------------------------------------------------------------
1 | export default `
2 | Contact
3 | `;
--------------------------------------------------------------------------------
/.github/workflows/set-default-labels.yml:
--------------------------------------------------------------------------------
1 | name: set-default-labels
2 | on: [workflow_dispatch]
3 |
4 | jobs:
5 | set-default-labels:
6 | uses: mdn/workflows/.github/workflows/set-default-labels.yml@main
7 | with:
8 | target-repo: "mdn/perf-examples"
9 | should-delete-labels: true
10 |
--------------------------------------------------------------------------------
/lazy-loading-dynamic-import/readme.md:
--------------------------------------------------------------------------------
1 | # Lazy Loading - Dynamic Import
2 |
3 | This demo includes a simple router implementation that lazy loads the different views as they are accessed.
4 |
5 | ## To run the demo
6 |
7 | Get the demo
8 |
9 | ```
10 | git clone https://github.com/garyvh2/perf-examples.git
11 | cd Lazy Loading - Dynamic Import
12 | ```
13 |
14 | Run the demo
15 |
16 | ```
17 | npm install
18 | npm start
19 | ```
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Performance examples
2 |
3 | > [!NOTE]
4 | > This repository is archived as of December 2023.
5 | > Many thanks to everyone who contributed! 🎉
6 | >
7 | > For MDN documentation about performance, see https://developer.mozilla.org/en-US/docs/web/Performance.
8 |
9 | ## Demos included
10 |
11 | - [Lazy Loading Demo](https://garyvh2.github.io/perf-examples/lazy-loading-dynamic-import/) from [Lazy-loading JavaScript with import()]()
12 |
--------------------------------------------------------------------------------
/lazy-loading-dynamic-import/src/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | import { Router } from './router.mjs';
3 |
4 | /** Elements */
5 | const routerOutlet = document.getElementById('outlet');
6 |
7 | /** Router */
8 | import('./routerConfig.mjs').then(({
9 | routerConfig
10 | }) => {
11 | const routerInstance = new Router(routerConfig, routerOutlet);
12 | routerInstance.renderPage(location.pathname || '/perf-examples/lazy-loading-dynamic-import/');
13 | });
--------------------------------------------------------------------------------
/lazy-loading-dynamic-import/src/routerConfig.mjs:
--------------------------------------------------------------------------------
1 | export const routerConfig = {
2 | '/': () => import('./views/home.mjs'),
3 | '/perf-examples/lazy-loading-dynamic-import/': () => import('./views/home.mjs'),
4 | '/perf-examples/lazy-loading-dynamic-import/help': () => import('./views/help.mjs'),
5 | '/perf-examples/lazy-loading-dynamic-import/about': () => import('./views/about.mjs'),
6 | '/perf-examples/lazy-loading-dynamic-import/contact': () => import('./views/contact.mjs')
7 | }
--------------------------------------------------------------------------------
/lazy-loading-dynamic-import/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "lazy-loading-dynamic-import",
3 | "version": "1.0.0",
4 | "description": "Lazy Loading example with dynamic import",
5 | "main": "index.html",
6 | "scripts": {
7 | "start": "parcel index.html --open",
8 | "build": "parcel build index.html"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git+https://github.com/mdn/perf-examples.git"
13 | },
14 | "author": "garyvh2",
15 | "license": "CC0-1.0",
16 | "bugs": {
17 | "url": "https://github.com/mdn/perf-examples/issues"
18 | },
19 | "homepage": "https://github.com/mdn/perf-examples#readme",
20 | "dependencies": {
21 | "parcel": "^1.12.3"
22 | }
23 | }
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Community Participation Guidelines
2 |
3 | This repository is governed by Mozilla's code of conduct and etiquette guidelines.
4 | For more details, please read the
5 | [Mozilla Community Participation Guidelines](https://www.mozilla.org/about/governance/policies/participation/).
6 |
7 | ## How to Report
8 | For more information on how to report violations of the Community Participation Guidelines, please read our [How to Report](https://www.mozilla.org/about/governance/policies/participation/reporting/) page.
9 |
10 |
16 |
--------------------------------------------------------------------------------
/lazy-loading-dynamic-import/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Lazy Loading - Dynamic Import
9 |
10 |
11 |
12 |
13 | Home
14 | About
15 | Help
16 | Contact
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/lazy-loading-dynamic-import/src/router.mjs:
--------------------------------------------------------------------------------
1 | export class Router {
2 | constructor(config, outlet) {
3 | /** Store Properties locally */
4 | this.config = config;
5 | this.outlet = outlet;
6 |
7 | /** Add Listener to links */
8 | document.addEventListener('click', (event) => this.linkListener(event), true);
9 | window.addEventListener('popstate', (event) => this.popstateListener(event), true);
10 | }
11 |
12 | /**
13 | * Listener for window popstate events
14 | * @param event popstate event
15 | */
16 | popstateListener(event) {
17 | if (this.config[location.pathname]) {
18 | this.renderPage(location.pathname);
19 | }
20 | }
21 |
22 | /**
23 | * Listener for anchor elements click
24 | * @param event
25 | */
26 | linkListener(event) {
27 | /** If the element clicked is an anchor */
28 | if (event.target instanceof HTMLAnchorElement) {
29 | const {
30 | pathname
31 | } = event.target;
32 | /** If the path of the link is in the configuration */
33 | if (this.config[pathname]) {
34 | event.preventDefault();
35 | this.renderPage(pathname);
36 | }
37 | }
38 | }
39 |
40 | /**
41 | * Fetches and renders a view based on the url
42 | * The router takes the configuration with the format
43 | *
44 | * {
45 | * '/pathname': () => import('./view/filename')
46 | * }
47 | *
48 | * So whenever a route event is triggered, the location is pushed into the history
49 | * and the dynamic import of the view is executed
50 | *
51 | * Then the outlet innerHTML is set to the view content
52 | *
53 | * @param href url
54 | */
55 | renderPage(href) {
56 | /** Fetch and render, dynamically */
57 | this.config[href]().then((view) => {
58 | this.setOutletContent(view.default);
59 | /** Push new state */
60 | history.pushState(null, null, href);
61 | });
62 | }
63 |
64 | /**
65 | * sets the HTML content
66 | * @param content html content
67 | */
68 | setOutletContent(content) {
69 | this.outlet.innerHTML = content;
70 | }
71 | }
--------------------------------------------------------------------------------
/.github/labels.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "good first issue",
4 | "color": "028c46",
5 | "description": "A good issue for newcomers to get started with."
6 | },
7 | {
8 | "name": "help wanted",
9 | "color": "028c46",
10 | "description": "If you know something about this, we would love your help!"
11 | },
12 | {
13 | "name": "needs info",
14 | "color": "028c46",
15 | "description": "This needs more information to review or act on."
16 | },
17 | {
18 | "name": "needs triage",
19 | "color": "028c46",
20 | "description": "Triage needed by staff and/or partners. Automatically applied when an issue is opened."
21 | },
22 | {
23 | "name": "expert help needed",
24 | "color": "028c46",
25 | "description": "This needs more information from a subject matter expert (SME)."
26 | },
27 | {
28 | "name": "idle",
29 | "color": "028c46",
30 | "description": "Issues and pull requests with no activity for three months."
31 | },
32 | {
33 | "name": "on hold",
34 | "color": "028c46",
35 | "description": "Waiting on something else before this can be moved forward."
36 | },
37 | {
38 | "name": "for later",
39 | "color": "028c46",
40 | "description": "Not planned at this time."
41 | },
42 | {
43 | "name": "needs content update",
44 | "color": "028c46",
45 | "description": "Needs update to the content to support this change."
46 | },
47 | {
48 | "name": "chore",
49 | "color": "028c46",
50 | "description": "A routine task."
51 | },
52 | {
53 | "name": "enhancement",
54 | "color": "028c46",
55 | "description": "Improves an existing feature."
56 | },
57 | {
58 | "name": "bug",
59 | "color": "c05964",
60 | "description": "Indicates an unexpected problem or unintended behavior."
61 | },
62 | {
63 | "name": "wontfix",
64 | "color": "c05964",
65 | "description": "Deemed to be outside the scope of the project or would require significant time and resources to fix."
66 | },
67 | {
68 | "name": "effort: small",
69 | "color": "866dc1",
70 | "description": "Task is a small effort."
71 | },
72 | {
73 | "name": "effort: medium",
74 | "color": "866dc1",
75 | "description": "Task is a medium effort."
76 | },
77 | {
78 | "name": "effort: large",
79 | "color": "866dc1",
80 | "description": "Task is large effort."
81 | },
82 | {
83 | "name": "p0",
84 | "color": "6e8bc1",
85 | "description": "Urgent. We will address this as soon as possible."
86 | },
87 | {
88 | "name": "p1",
89 | "color": "6e8bc1",
90 | "description": "We will address this soon and will provide capacity from our team for it in the next few releases."
91 | },
92 | {
93 | "name": "p2",
94 | "color": "6e8bc1",
95 | "description": "We want to address this but may have other higher priority items."
96 | },
97 | {
98 | "name": "p3",
99 | "color": "6e8bc1",
100 | "description": "We don't have visibility when this will be addressed."
101 | }
102 | ]
103 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | CC0 1.0 Universal
2 |
3 | Statement of Purpose
4 |
5 | The laws of most jurisdictions throughout the world automatically confer
6 | exclusive Copyright and Related Rights (defined below) upon the creator and
7 | subsequent owner(s) (each and all, an "owner") of an original work of
8 | authorship and/or a database (each, a "Work").
9 |
10 | Certain owners wish to permanently relinquish those rights to a Work for the
11 | purpose of contributing to a commons of creative, cultural and scientific
12 | works ("Commons") that the public can reliably and without fear of later
13 | claims of infringement build upon, modify, incorporate in other works, reuse
14 | and redistribute as freely as possible in any form whatsoever and for any
15 | purposes, including without limitation commercial purposes. These owners may
16 | contribute to the Commons to promote the ideal of a free culture and the
17 | further production of creative, cultural and scientific works, or to gain
18 | reputation or greater distribution for their Work in part through the use and
19 | efforts of others.
20 |
21 | For these and/or other purposes and motivations, and without any expectation
22 | of additional consideration or compensation, the person associating CC0 with a
23 | Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
24 | and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
25 | and publicly distribute the Work under its terms, with knowledge of his or her
26 | Copyright and Related Rights in the Work and the meaning and intended legal
27 | effect of CC0 on those rights.
28 |
29 | 1. Copyright and Related Rights. A Work made available under CC0 may be
30 | protected by copyright and related or neighboring rights ("Copyright and
31 | Related Rights"). Copyright and Related Rights include, but are not limited
32 | to, the following:
33 |
34 | i. the right to reproduce, adapt, distribute, perform, display, communicate,
35 | and translate a Work;
36 |
37 | ii. moral rights retained by the original author(s) and/or performer(s);
38 |
39 | iii. publicity and privacy rights pertaining to a person's image or likeness
40 | depicted in a Work;
41 |
42 | iv. rights protecting against unfair competition in regards to a Work,
43 | subject to the limitations in paragraph 4(a), below;
44 |
45 | v. rights protecting the extraction, dissemination, use and reuse of data in
46 | a Work;
47 |
48 | vi. database rights (such as those arising under Directive 96/9/EC of the
49 | European Parliament and of the Council of 11 March 1996 on the legal
50 | protection of databases, and under any national implementation thereof,
51 | including any amended or successor version of such directive); and
52 |
53 | vii. other similar, equivalent or corresponding rights throughout the world
54 | based on applicable law or treaty, and any national implementations thereof.
55 |
56 | 2. Waiver. To the greatest extent permitted by, but not in contravention of,
57 | applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
58 | unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
59 | and Related Rights and associated claims and causes of action, whether now
60 | known or unknown (including existing as well as future claims and causes of
61 | action), in the Work (i) in all territories worldwide, (ii) for the maximum
62 | duration provided by applicable law or treaty (including future time
63 | extensions), (iii) in any current or future medium and for any number of
64 | copies, and (iv) for any purpose whatsoever, including without limitation
65 | commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes
66 | the Waiver for the benefit of each member of the public at large and to the
67 | detriment of Affirmer's heirs and successors, fully intending that such Waiver
68 | shall not be subject to revocation, rescission, cancellation, termination, or
69 | any other legal or equitable action to disrupt the quiet enjoyment of the Work
70 | by the public as contemplated by Affirmer's express Statement of Purpose.
71 |
72 | 3. Public License Fallback. Should any part of the Waiver for any reason be
73 | judged legally invalid or ineffective under applicable law, then the Waiver
74 | shall be preserved to the maximum extent permitted taking into account
75 | Affirmer's express Statement of Purpose. In addition, to the extent the Waiver
76 | is so judged Affirmer hereby grants to each affected person a royalty-free,
77 | non transferable, non sublicensable, non exclusive, irrevocable and
78 | unconditional license to exercise Affirmer's Copyright and Related Rights in
79 | the Work (i) in all territories worldwide, (ii) for the maximum duration
80 | provided by applicable law or treaty (including future time extensions), (iii)
81 | in any current or future medium and for any number of copies, and (iv) for any
82 | purpose whatsoever, including without limitation commercial, advertising or
83 | promotional purposes (the "License"). The License shall be deemed effective as
84 | of the date CC0 was applied by Affirmer to the Work. Should any part of the
85 | License for any reason be judged legally invalid or ineffective under
86 | applicable law, such partial invalidity or ineffectiveness shall not
87 | invalidate the remainder of the License, and in such case Affirmer hereby
88 | affirms that he or she will not (i) exercise any of his or her remaining
89 | Copyright and Related Rights in the Work or (ii) assert any associated claims
90 | and causes of action with respect to the Work, in either case contrary to
91 | Affirmer's express Statement of Purpose.
92 |
93 | 4. Limitations and Disclaimers.
94 |
95 | a. No trademark or patent rights held by Affirmer are waived, abandoned,
96 | surrendered, licensed or otherwise affected by this document.
97 |
98 | b. Affirmer offers the Work as-is and makes no representations or warranties
99 | of any kind concerning the Work, express, implied, statutory or otherwise,
100 | including without limitation warranties of title, merchantability, fitness
101 | for a particular purpose, non infringement, or the absence of latent or
102 | other defects, accuracy, or the present or absence of errors, whether or not
103 | discoverable, all to the greatest extent permissible under applicable law.
104 |
105 | c. Affirmer disclaims responsibility for clearing rights of other persons
106 | that may apply to the Work or any use thereof, including without limitation
107 | any person's Copyright and Related Rights in the Work. Further, Affirmer
108 | disclaims responsibility for obtaining any necessary consents, permissions
109 | or other rights required for any use of the Work.
110 |
111 | d. Affirmer understands and acknowledges that Creative Commons is not a
112 | party to this document and has no duty or obligation with respect to this
113 | CC0 or use of the Work.
114 |
115 | For more information, please see
116 |
117 |
--------------------------------------------------------------------------------