From e5a5cbed5c2ab959ace8d019fdb0fdc3f1249412 Mon Sep 17 00:00:00 2001 From: enson0131 Date: Thu, 8 Feb 2024 02:20:05 +0000 Subject: [PATCH] deploy: c67dcfc20d9f0472024f0f82c68c2d595dd4ed02 --- 404.html | 2 +- ...270\345\205\263_\346\246\202\350\246\201.md.632ffa2f.js" | 2 +- ...45\205\263_\346\246\202\350\246\201.md.632ffa2f.lean.js" | 2 +- ...6Vue\347\232\204\345\214\272\345\210\253.md.5fd109fc.js" | 2 +- ...347\232\204\345\214\272\345\210\253.md.5fd109fc.lean.js" | 2 +- ...\213\344\273\266\346\234\272\345\210\266.md.9d3f4079.js" | 2 +- ...344\273\266\346\234\272\345\210\266.md.9d3f4079.lean.js" | 2 +- ...\202\345\270\270\346\234\272\345\210\266.md.67ec8db4.js" | 2 +- ...345\270\270\346\234\272\345\210\266.md.67ec8db4.lean.js" | 2 +- ...\247\350\203\275\344\274\230\345\214\226.md.8eb2e33c.js" | 2 +- ...350\203\275\344\274\230\345\214\226.md.8eb2e33c.lean.js" | 2 +- ...0\350\246\201\344\275\277\347\224\250JSX.md.d1fcafa8.js" | 2 +- ...\246\201\344\275\277\347\224\250JSX.md.d1fcafa8.lean.js" | 2 +- ...eact\346\230\257\344\273\200\344\271\210.md.6fb31cb5.js" | 2 +- ...346\230\257\344\273\200\344\271\210.md.6fb31cb5.lean.js" | 2 +- ...\225\346\270\262\346\237\223\347\232\204.md.b469a419.js" | 2 +- ...346\270\262\346\237\223\347\232\204.md.b469a419.lean.js" | 2 +- ...\225\351\200\232\344\277\241\347\232\204.md.72c5ac4e.js" | 2 +- ...351\200\232\344\277\241\347\232\204.md.72c5ac4e.lean.js" | 2 +- ...guide_React_diff\347\256\227\346\263\225.md.926d46b2.js" | 2 +- ..._React_diff\347\256\227\346\263\225.md.926d46b2.lean.js" | 2 +- ...\202\345\270\270\346\234\272\345\210\266.md.6a032df0.js" | 2 +- ...345\270\270\346\234\272\345\210\266.md.6a032df0.lean.js" | 2 +- ...\257\345\274\202\346\255\245\347\232\204.md.89186477.js" | 2 +- ...345\274\202\346\255\245\347\232\204.md.89186477.lean.js" | 2 +- ...344\273\200\344\271\210\346\230\257Fiber.md.ec244869.js" | 2 +- ...73\200\344\271\210\346\230\257Fiber.md.ec244869.lean.js" | 2 +- ...350\256\241React\347\273\204\344\273\266.md.195ded5e.js" | 2 +- ...56\241React\347\273\204\344\273\266.md.195ded5e.lean.js" | 2 +- ...\201\347\232\204\351\227\256\351\242\230.md.4f1f1ac9.js" | 2 +- ...347\232\204\351\227\256\351\242\230.md.4f1f1ac9.lean.js" | 2 +- ...\220\347\240\201\350\247\243\350\257\273.md.dc2eca87.js" | 2 +- ...347\240\201\350\247\243\350\257\273.md.dc2eca87.lean.js" | 2 +- ...\276\350\256\241\347\220\206\345\277\265.md.b1a2b96a.js" | 2 +- ...350\256\241\347\220\206\345\277\265.md.b1a2b96a.lean.js" | 2 +- ...\250\347\216\207\347\237\253\346\255\243.md.a8665ee4.js" | 2 +- ...347\216\207\347\237\253\346\255\243.md.a8665ee4.lean.js" | 2 +- ...\246\345\206\231\346\200\247\350\203\275.md.419e5315.js" | 2 +- ...345\206\231\346\200\247\350\203\275.md.419e5315.lean.js" | 2 +- ...\252\347\224\261\344\271\246\345\206\231.md.b9949f49.js" | 2 +- ...347\224\261\344\271\246\345\206\231.md.b9949f49.lean.js" | 2 +- ...\246\345\206\231\346\200\247\350\203\275.md.10b7092a.js" | 2 +- ...345\206\231\346\200\247\350\203\275.md.10b7092a.lean.js" | 2 +- ...\246\345\206\231\346\200\247\350\203\275.md.2eca7891.js" | 2 +- ...345\206\231\346\200\247\350\203\275.md.2eca7891.lean.js" | 2 +- ...\246\345\206\231\346\200\247\350\203\275.md.af60bf99.js" | 2 +- ...345\206\231\346\200\247\350\203\275.md.af60bf99.lean.js" | 2 +- ...\246\345\206\231\346\200\247\350\203\275.md.c136fb49.js" | 2 +- ...345\206\231\346\200\247\350\203\275.md.c136fb49.lean.js" | 2 +- .../guide_css\347\233\270\345\205\263_BFC.md.0cc3082f.js" | 2 +- ...ide_css\347\233\270\345\205\263_BFC.md.0cc3082f.lean.js" | 2 +- ...uide_css\347\233\270\345\205\263_display.md.24ba2b32.js" | 2 +- ...css\347\233\270\345\205\263_display.md.24ba2b32.lean.js" | 2 +- ...tion\347\232\204\345\205\263\347\263\273.md.1a5ef489.js" | 2 +- ...347\232\204\345\205\263\347\263\273.md.1a5ef489.lean.js" | 2 +- ...3\200\201opacity\345\214\272\345\210\253.md.5aec2cb5.js" | 2 +- ...\201opacity\345\214\272\345\210\253.md.5aec2cb5.lean.js" | 2 +- ...ide_css\347\233\270\345\205\263_position.md.f6e57cb3.js" | 2 +- ...ss\347\233\270\345\205\263_position.md.f6e57cb3.lean.js" | 2 +- ...\213\345\200\274\346\226\271\345\274\217.md.7b9b530a.js" | 2 +- ...345\200\274\346\226\271\345\274\217.md.7b9b530a.lean.js" | 2 +- ...270\345\205\263_\346\246\202\350\246\201.md.20b96226.js" | 2 +- ...45\205\263_\346\246\202\350\246\201.md.20b96226.lean.js" | 2 +- ...\240\347\232\204\346\226\271\346\263\225.md.49a19e25.js" | 2 +- ...347\232\204\346\226\271\346\263\225.md.49a19e25.lean.js" | 2 +- ...\345\205\263_DOM\347\233\270\345\205\263.md.bd7d10f3.js" | 2 +- ...205\263_DOM\347\233\270\345\205\263.md.bd7d10f3.lean.js" | 2 +- ...\345\205\263_ES6\347\233\270\345\205\263.md.98a38a5e.js" | 2 +- ...205\263_ES6\347\233\270\345\205\263.md.98a38a5e.lean.js" | 2 +- ...\225\350\216\267\346\234\272\345\210\266.md.1e9b4755.js" | 2 +- ...350\216\267\346\234\272\345\210\266.md.1e9b4755.lean.js" | 2 +- ...\247\350\241\214\346\234\272\345\210\266.md.8aebbf95.js" | 2 +- ...350\241\214\346\234\272\345\210\266.md.8aebbf95.lean.js" | 2 +- ...\226\350\257\221\346\234\272\345\210\266.md.6b3e2f0d.js" | 2 +- ...350\257\221\346\234\272\345\210\266.md.6b3e2f0d.lean.js" | 2 +- ...vaScript\347\233\270\345\205\263_Promise.md.adc6aed9.js" | 2 +- ...ipt\347\233\270\345\205\263_Promise.md.adc6aed9.lean.js" | 2 +- ...javaScript\347\233\270\345\205\263_index.md.ff95dc7a.js" | 2 +- ...cript\347\233\270\345\205\263_index.md.ff95dc7a.lean.js" | 2 +- ...\252\347\216\257\346\234\272\345\210\266.md.4ff87ac5.js" | 2 +- ...347\216\257\346\234\272\345\210\266.md.4ff87ac5.lean.js" | 2 +- ...\236\346\224\266\346\234\272\345\210\266.md.6755966f.js" | 2 +- ...346\224\266\346\234\272\345\210\266.md.6755966f.lean.js" | 2 +- ...\272\347\241\200\346\246\202\345\277\265.md.dcfd312c.js" | 2 +- ...347\241\200\346\246\202\345\277\265.md.dcfd312c.lean.js" | 2 +- ...2\345\270\270\350\247\201\347\232\204API.md.19aad48b.js" | 2 +- ...\270\270\350\247\201\347\232\204API.md.19aad48b.lean.js" | 2 +- ...270\345\205\263_\345\256\232\344\271\211.md.c58c5632.js" | 2 +- ...45\205\263_\345\256\232\344\271\211.md.c58c5632.lean.js" | 2 +- ...1\345\270\270\350\247\201\347\232\204API.md.4eca8a1e.js" | 2 +- ...\270\270\350\247\201\347\232\204API.md.4eca8a1e.lean.js" | 2 +- ...\260\346\215\256\347\261\273\345\236\213.md.d9e46f31.js" | 2 +- ...346\215\256\347\261\273\345\236\213.md.d9e46f31.lean.js" | 2 +- ...4\345\270\270\350\247\201\347\232\204API.md.2dc845e4.js" | 2 +- ...\270\270\350\247\201\347\232\204API.md.2dc845e4.lean.js" | 2 +- ...\204\350\277\220\347\256\227\347\254\246.md.d9d1e0c1.js" | 2 +- ...350\277\220\347\256\227\347\254\246.md.d9d1e0c1.lean.js" | 2 +- ...\231\350\241\250\350\276\276\345\274\217.md.37761b31.js" | 2 +- ...350\241\250\350\276\276\345\274\217.md.37761b31.lean.js" | 2 +- ...\247\346\211\277\347\233\270\345\205\263.md.0b549acd.js" | 2 +- ...346\211\277\347\233\270\345\205\263.md.0b549acd.lean.js" | 2 +- ...ex.md.e15e3d26.js => guide_webpack_index.md.f2414c6a.js} | 2 +- ...3d26.lean.js => guide_webpack_index.md.f2414c6a.lean.js} | 2 +- ...\204\345\273\272\346\265\201\347\250\213.md.07f4ea79.js" | 2 +- ...345\273\272\346\265\201\347\250\213.md.07f4ea79.lean.js" | 2 +- ...270\345\205\263_\346\246\202\350\246\201.md.f313a7ec.js" | 2 +- ...45\205\263_\346\246\202\350\246\201.md.f313a7ec.lean.js" | 2 +- ...\210\345\231\250\345\206\205\346\240\270.md.9cd84d74.js" | 2 +- ...345\231\250\345\206\205\346\240\270.md.9cd84d74.lean.js" | 2 +- ...\210\345\231\250\345\256\211\345\205\250.md.cda4119d.js" | 2 +- ...345\231\250\345\256\211\345\205\250.md.cda4119d.lean.js" | 2 +- ...\262\346\237\223\346\265\201\347\250\213.md.1331606e.js" | 2 +- ...346\237\223\346\265\201\347\250\213.md.1331606e.lean.js" | 2 +- ...\210\345\231\250\347\274\223\345\255\230.md.88373219.js" | 2 +- ...345\231\250\347\274\223\345\255\230.md.88373219.lean.js" | 2 +- ...\233\347\250\213\346\236\266\346\236\204.md.1b1db83e.js" | 2 +- ...347\250\213\346\236\266\346\236\204.md.1b1db83e.lean.js" | 2 +- ...\347\273\234\347\233\270\345\205\263_CDN.md.e85fe02e.js" | 2 +- ...273\234\347\233\270\345\205\263_CDN.md.e85fe02e.lean.js" | 2 +- ...\347\273\234\347\233\270\345\205\263_DNS.md.3f43cbe6.js" | 2 +- ...273\234\347\233\270\345\205\263_DNS.md.3f43cbe6.lean.js" | 2 +- ...\202\347\232\204\345\214\272\345\210\253.md.5b02925b.js" | 2 +- ...347\232\204\345\214\272\345\210\253.md.5b02925b.lean.js" | 2 +- ...347\273\234\347\233\270\345\205\263_HTTP.md.3d19dae2.js" | 2 +- ...73\234\347\233\270\345\205\263_HTTP.md.3d19dae2.lean.js" | 2 +- ...47\273\234\347\233\270\345\205\263_HTTPS.md.4c7346fd.js" | 2 +- ...3\234\347\233\270\345\205\263_HTTPS.md.4c7346fd.lean.js" | 2 +- ...\215\345\272\224\346\212\245\346\226\207.md.e9c73579.js" | 2 +- ...345\272\224\346\212\245\346\226\207.md.e9c73579.lean.js" | 2 +- ...\201\347\232\204\351\227\256\351\242\230.md.3b584d49.js" | 2 +- ...347\232\204\351\227\256\351\242\230.md.3b584d49.lean.js" | 2 +- ...270\345\205\263_\346\246\202\350\246\201.md.3b48bb07.js" | 2 +- ...45\205\263_\346\246\202\350\246\201.md.3b48bb07.lean.js" | 2 +- ...\267\346\261\202\346\212\245\346\226\207.md.715db4fc.js" | 2 +- ...346\261\202\346\212\245\346\226\207.md.715db4fc.lean.js" | 2 +- ...\250\345\237\237\350\257\267\346\261\202.md.f2530ac2.js" | 2 +- ...345\237\237\350\257\267\346\261\202.md.f2530ac2.lean.js" | 2 +- assets/{index.md.57af2e65.js => index.md.a6c2532f.js} | 2 +- ...{index.md.57af2e65.lean.js => index.md.a6c2532f.lean.js} | 2 +- ..._ISO\346\204\237\345\205\211\345\272\246.md.1470d204.js" | 2 +- ...346\204\237\345\205\211\345\272\246.md.1470d204.lean.js" | 2 +- ...202\345\277\265_\345\205\211\345\234\210.md.ae3bc87c.js" | 2 +- ...45\277\265_\345\205\211\345\234\210.md.ae3bc87c.lean.js" | 2 +- ...\253\351\227\250\351\200\237\345\272\246.md.9e05d8bb.js" | 2 +- ...351\227\250\351\200\237\345\272\246.md.9e05d8bb.lean.js" | 2 +- ...\204\351\273\221\350\203\214\346\231\257.md.013683af.js" | 2 +- ...351\273\221\350\203\214\346\231\257.md.013683af.lean.js" | 2 +- ...\225\346\213\215\351\233\250\344\270\235.md.5a2c1fb7.js" | 1 + ...346\213\215\351\233\250\344\270\235.md.5a2c1fb7.lean.js" | 2 +- ...\225\346\213\215\351\233\250\344\270\235.md.c8378969.js" | 1 - ...\246\345\271\273\345\205\211\346\226\221.md.345608b9.js" | 2 +- ...345\271\273\345\205\211\346\226\221.md.345608b9.lean.js" | 2 +- .../\346\246\202\350\246\201.html" | 6 +++--- ...344\270\216Vue\347\232\204\345\214\272\345\210\253.html" | 6 +++--- ...04\344\272\213\344\273\266\346\234\272\345\210\266.html" | 6 +++--- ...04\345\274\202\345\270\270\346\234\272\345\210\266.html" | 6 +++--- ...04\346\200\247\350\203\275\344\274\230\345\214\226.html" | 6 +++--- ...344\271\210\350\246\201\344\275\277\347\224\250JSX.html" | 6 +++--- .../React/React\346\230\257\344\273\200\344\271\210.html" | 6 +++--- ...02\344\275\225\346\270\262\346\237\223\347\232\204.html" | 6 +++--- ...02\344\275\225\351\200\232\344\277\241\347\232\204.html" | 6 +++--- "guide/React/diff\347\256\227\346\263\225.html" | 6 +++--- ...ct\345\274\202\345\270\270\346\234\272\345\210\266.html" | 6 +++--- ...30\346\230\257\345\274\202\346\255\245\347\232\204.html" | 6 +++--- .../React/\344\273\200\344\271\210\346\230\257Fiber.html" | 6 +++--- ...0\256\276\350\256\241React\347\273\204\344\273\266.html" | 6 +++--- ...70\350\247\201\347\232\204\351\227\256\351\242\230.html" | 6 +++--- .../\346\272\220\347\240\201\350\247\243\350\257\273.html" | 6 +++--- .../\350\256\276\350\256\241\347\220\206\345\277\265.html" | 6 +++--- ...06\350\276\250\347\216\207\347\237\253\346\255\243.html" | 6 +++--- ...as\344\271\246\345\206\231\346\200\247\350\203\275.html" | 6 +++--- ...12\350\207\252\347\224\261\344\271\246\345\206\231.html" | 6 +++--- ...30\344\271\246\345\206\231\346\200\247\350\203\275.html" | 6 +++--- ...as\344\271\246\345\206\231\346\200\247\350\203\275.html" | 6 +++--- ...as\344\271\246\345\206\231\346\200\247\350\203\275.html" | 6 +++--- ...as\344\271\246\345\206\231\346\200\247\350\203\275.html" | 6 +++--- "guide/css\347\233\270\345\205\263/BFC.html" | 6 +++--- "guide/css\347\233\270\345\205\263/display.html" | 6 +++--- ...00\201position\347\232\204\345\205\263\347\263\273.html" | 6 +++--- ...ibility\343\200\201opacity\345\214\272\345\210\253.html" | 6 +++--- "guide/css\347\233\270\345\205\263/position.html" | 6 +++--- ...66\350\265\213\345\200\274\346\226\271\345\274\217.html" | 6 +++--- .../\346\246\202\350\246\201.html" | 6 +++--- ...03\347\264\240\347\232\204\346\226\271\346\263\225.html" | 6 +++--- .../DOM\347\233\270\345\205\263.html" | 6 +++--- .../ES6\347\233\270\345\205\263.html" | 6 +++--- ...70\346\215\225\350\216\267\346\234\272\345\210\266.html" | 6 +++--- ...pt\346\211\247\350\241\214\346\234\272\345\210\266.html" | 6 +++--- ...pt\347\274\226\350\257\221\346\234\272\345\210\266.html" | 6 +++--- "guide/javaScript\347\233\270\345\205\263/Promise.html" | 6 +++--- "guide/javaScript\347\233\270\345\205\263/index.html" | 6 +++--- ...66\345\276\252\347\216\257\346\234\272\345\210\266.html" | 6 +++--- ...76\345\233\236\346\224\266\346\234\272\345\210\266.html" | 6 +++--- .../\345\237\272\347\241\200\346\246\202\345\277\265.html" | 6 +++--- ...344\270\262\345\270\270\350\247\201\347\232\204API.html" | 6 +++--- .../\345\256\232\344\271\211.html" | 6 +++--- ...350\261\241\345\270\270\350\247\201\347\232\204API.html" | 6 +++--- .../\346\225\260\346\215\256\347\261\273\345\236\213.html" | 6 +++--- ...347\273\204\345\270\270\350\247\201\347\232\204API.html" | 6 +++--- ...60\347\232\204\350\277\220\347\256\227\347\254\246.html" | 6 +++--- ...43\345\210\231\350\241\250\350\276\276\345\274\217.html" | 6 +++--- .../\347\273\247\346\211\277\347\233\270\345\205\263.html" | 6 +++--- guide/webpack/index.html | 6 +++--- .../\346\236\204\345\273\272\346\265\201\347\250\213.html" | 6 +++--- .../\346\246\202\350\246\201.html" | 6 +++--- ...17\350\247\210\345\231\250\345\206\205\346\240\270.html" | 6 +++--- ...17\350\247\210\345\231\250\345\256\211\345\205\250.html" | 6 +++--- ...50\346\270\262\346\237\223\346\265\201\347\250\213.html" | 6 +++--- ...17\350\247\210\345\231\250\347\274\223\345\255\230.html" | 6 +++--- ...50\350\277\233\347\250\213\346\236\266\346\236\204.html" | 6 +++--- .../CDN.html" | 6 +++--- .../DNS.html" | 6 +++--- ...67\346\261\202\347\232\204\345\214\272\345\210\253.html" | 6 +++--- .../HTTP.html" | 6 +++--- .../HTTPS.html" | 6 +++--- .../\345\223\215\345\272\224\346\212\245\346\226\207.html" | 6 +++--- ...70\350\247\201\347\232\204\351\227\256\351\242\230.html" | 6 +++--- .../\346\246\202\350\246\201.html" | 6 +++--- .../\350\257\267\346\261\202\346\212\245\346\226\207.html" | 6 +++--- .../\350\267\250\345\237\237\350\257\267\346\261\202.html" | 6 +++--- hashmap.json | 2 +- index.html | 6 +++--- .../ISO\346\204\237\345\205\211\345\272\246.html" | 6 +++--- .../\345\205\211\345\234\210.html" | 6 +++--- .../\345\277\253\351\227\250\351\200\237\345\272\246.html" | 6 +++--- ...61\347\232\204\351\273\221\350\203\214\346\231\257.html" | 6 +++--- ...02\344\275\225\346\213\215\351\233\250\344\270\235.html" | 6 +++--- ...04\346\242\246\345\271\273\345\205\211\346\226\221.html" | 6 +++--- 228 files changed, 377 insertions(+), 377 deletions(-) rename "assets/guide_Node\347\233\270\345\205\263_\346\246\202\350\246\201.md.914ab426.js" => "assets/guide_Node\347\233\270\345\205\263_\346\246\202\350\246\201.md.632ffa2f.js" (84%) rename "assets/guide_Node\347\233\270\345\205\263_\346\246\202\350\246\201.md.914ab426.lean.js" => "assets/guide_Node\347\233\270\345\205\263_\346\246\202\350\246\201.md.632ffa2f.lean.js" (84%) rename "assets/guide_React_React\344\270\216Vue\347\232\204\345\214\272\345\210\253.md.a4cc8156.js" => "assets/guide_React_React\344\270\216Vue\347\232\204\345\214\272\345\210\253.md.5fd109fc.js" (85%) rename "assets/guide_React_React\344\270\216Vue\347\232\204\345\214\272\345\210\253.md.a4cc8156.lean.js" => "assets/guide_React_React\344\270\216Vue\347\232\204\345\214\272\345\210\253.md.5fd109fc.lean.js" (85%) rename "assets/guide_React_React\344\270\255\347\232\204\344\272\213\344\273\266\346\234\272\345\210\266.md.125ce9e6.js" => "assets/guide_React_React\344\270\255\347\232\204\344\272\213\344\273\266\346\234\272\345\210\266.md.9d3f4079.js" (95%) rename "assets/guide_React_React\344\270\255\347\232\204\344\272\213\344\273\266\346\234\272\345\210\266.md.125ce9e6.lean.js" => "assets/guide_React_React\344\270\255\347\232\204\344\272\213\344\273\266\346\234\272\345\210\266.md.9d3f4079.lean.js" (86%) rename "assets/guide_React_React\344\270\255\347\232\204\345\274\202\345\270\270\346\234\272\345\210\266.md.44ac2de8.js" => "assets/guide_React_React\344\270\255\347\232\204\345\274\202\345\270\270\346\234\272\345\210\266.md.67ec8db4.js" (85%) rename "assets/guide_React_React\344\270\255\347\232\204\345\274\202\345\270\270\346\234\272\345\210\266.md.44ac2de8.lean.js" => "assets/guide_React_React\344\270\255\347\232\204\345\274\202\345\270\270\346\234\272\345\210\266.md.67ec8db4.lean.js" (85%) rename "assets/guide_React_React\344\270\255\347\232\204\346\200\247\350\203\275\344\274\230\345\214\226.md.581ed9f6.js" => "assets/guide_React_React\344\270\255\347\232\204\346\200\247\350\203\275\344\274\230\345\214\226.md.8eb2e33c.js" (99%) rename "assets/guide_React_React\344\270\255\347\232\204\346\200\247\350\203\275\344\274\230\345\214\226.md.581ed9f6.lean.js" => "assets/guide_React_React\344\270\255\347\232\204\346\200\247\350\203\275\344\274\230\345\214\226.md.8eb2e33c.lean.js" (87%) rename "assets/guide_React_React\344\270\272\344\273\200\344\271\210\350\246\201\344\275\277\347\224\250JSX.md.917208ca.js" => "assets/guide_React_React\344\270\272\344\273\200\344\271\210\350\246\201\344\275\277\347\224\250JSX.md.d1fcafa8.js" (88%) rename "assets/guide_React_React\344\270\272\344\273\200\344\271\210\350\246\201\344\275\277\347\224\250JSX.md.917208ca.lean.js" => "assets/guide_React_React\344\270\272\344\273\200\344\271\210\350\246\201\344\275\277\347\224\250JSX.md.d1fcafa8.lean.js" (88%) rename "assets/guide_React_React\346\230\257\344\273\200\344\271\210.md.bd2dae02.js" => "assets/guide_React_React\346\230\257\344\273\200\344\271\210.md.6fb31cb5.js" (98%) rename "assets/guide_React_React\346\230\257\344\273\200\344\271\210.md.bd2dae02.lean.js" => "assets/guide_React_React\346\230\257\344\273\200\344\271\210.md.6fb31cb5.lean.js" (86%) rename "assets/guide_React_React\346\230\257\345\246\202\344\275\225\346\270\262\346\237\223\347\232\204.md.3113f4a0.js" => "assets/guide_React_React\346\230\257\345\246\202\344\275\225\346\270\262\346\237\223\347\232\204.md.b469a419.js" (99%) rename "assets/guide_React_React\346\230\257\345\246\202\344\275\225\346\270\262\346\237\223\347\232\204.md.3113f4a0.lean.js" => "assets/guide_React_React\346\230\257\345\246\202\344\275\225\346\270\262\346\237\223\347\232\204.md.b469a419.lean.js" (94%) rename "assets/guide_React_React\347\273\204\344\273\266\346\230\257\345\246\202\344\275\225\351\200\232\344\277\241\347\232\204.md.20eef01c.js" => "assets/guide_React_React\347\273\204\344\273\266\346\230\257\345\246\202\344\275\225\351\200\232\344\277\241\347\232\204.md.72c5ac4e.js" (91%) rename "assets/guide_React_React\347\273\204\344\273\266\346\230\257\345\246\202\344\275\225\351\200\232\344\277\241\347\232\204.md.20eef01c.lean.js" => "assets/guide_React_React\347\273\204\344\273\266\346\230\257\345\246\202\344\275\225\351\200\232\344\277\241\347\232\204.md.72c5ac4e.lean.js" (91%) rename "assets/guide_React_diff\347\256\227\346\263\225.md.e7fed7ec.js" => "assets/guide_React_diff\347\256\227\346\263\225.md.926d46b2.js" (98%) rename "assets/guide_React_diff\347\256\227\346\263\225.md.e7fed7ec.lean.js" => "assets/guide_React_diff\347\256\227\346\263\225.md.926d46b2.lean.js" (86%) rename "assets/guide_React_react\345\274\202\345\270\270\346\234\272\345\210\266.md.b97e740a.js" => "assets/guide_React_react\345\274\202\345\270\270\346\234\272\345\210\266.md.6a032df0.js" (84%) rename "assets/guide_React_react\345\274\202\345\270\270\346\234\272\345\210\266.md.b97e740a.lean.js" => "assets/guide_React_react\345\274\202\345\270\270\346\234\272\345\210\266.md.6a032df0.lean.js" (84%) rename "assets/guide_React_setState\346\230\257\345\220\214\346\255\245\350\277\230\346\230\257\345\274\202\346\255\245\347\232\204.md.181019e4.js" => "assets/guide_React_setState\346\230\257\345\220\214\346\255\245\350\277\230\346\230\257\345\274\202\346\255\245\347\232\204.md.89186477.js" (99%) rename "assets/guide_React_setState\346\230\257\345\220\214\346\255\245\350\277\230\346\230\257\345\274\202\346\255\245\347\232\204.md.181019e4.lean.js" => "assets/guide_React_setState\346\230\257\345\220\214\346\255\245\350\277\230\346\230\257\345\274\202\346\255\245\347\232\204.md.89186477.lean.js" (88%) rename "assets/guide_React_\344\273\200\344\271\210\346\230\257Fiber.md.3ee10b32.js" => "assets/guide_React_\344\273\200\344\271\210\346\230\257Fiber.md.ec244869.js" (96%) rename "assets/guide_React_\344\273\200\344\271\210\346\230\257Fiber.md.3ee10b32.lean.js" => "assets/guide_React_\344\273\200\344\271\210\346\230\257Fiber.md.ec244869.lean.js" (87%) rename "assets/guide_React_\345\246\202\344\275\225\350\256\276\350\256\241React\347\273\204\344\273\266.md.d49001fb.js" => "assets/guide_React_\345\246\202\344\275\225\350\256\276\350\256\241React\347\273\204\344\273\266.md.195ded5e.js" (95%) rename "assets/guide_React_\345\246\202\344\275\225\350\256\276\350\256\241React\347\273\204\344\273\266.md.d49001fb.lean.js" => "assets/guide_React_\345\246\202\344\275\225\350\256\276\350\256\241React\347\273\204\344\273\266.md.195ded5e.lean.js" (88%) rename "assets/guide_React_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.fc7d945a.js" => "assets/guide_React_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.4f1f1ac9.js" (91%) rename "assets/guide_React_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.fc7d945a.lean.js" => "assets/guide_React_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.4f1f1ac9.lean.js" (91%) rename "assets/guide_Redux_\346\272\220\347\240\201\350\247\243\350\257\273.md.b8a89f65.js" => "assets/guide_Redux_\346\272\220\347\240\201\350\247\243\350\257\273.md.dc2eca87.js" (89%) rename "assets/guide_Redux_\346\272\220\347\240\201\350\247\243\350\257\273.md.b8a89f65.lean.js" => "assets/guide_Redux_\346\272\220\347\240\201\350\247\243\350\257\273.md.dc2eca87.lean.js" (89%) rename "assets/guide_Redux_\350\256\276\350\256\241\347\220\206\345\277\265.md.ec673eba.js" => "assets/guide_Redux_\350\256\276\350\256\241\347\220\206\345\277\265.md.b1a2b96a.js" (89%) rename "assets/guide_Redux_\350\256\276\350\256\241\347\220\206\345\277\265.md.ec673eba.lean.js" => "assets/guide_Redux_\350\256\276\350\256\241\347\220\206\345\277\265.md.b1a2b96a.lean.js" (89%) rename "assets/guide_canvas_Canvas\345\260\272\345\257\270\345\217\212\345\210\206\350\276\250\347\216\207\347\237\253\346\255\243.md.5236c485.js" => "assets/guide_canvas_Canvas\345\260\272\345\257\270\345\217\212\345\210\206\350\276\250\347\216\207\347\237\253\346\255\243.md.a8665ee4.js" (99%) rename "assets/guide_canvas_Canvas\345\260\272\345\257\270\345\217\212\345\210\206\350\276\250\347\216\207\347\237\253\346\255\243.md.5236c485.lean.js" => "assets/guide_canvas_Canvas\345\260\272\345\257\270\345\217\212\345\210\206\350\276\250\347\216\207\347\237\253\346\255\243.md.a8665ee4.lean.js" (90%) rename "assets/guide_canvas_\345\217\257\350\247\206\345\214\272\345\237\237\345\206\205\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.3686d5ec.js" => "assets/guide_canvas_\345\217\257\350\247\206\345\214\272\345\237\237\345\206\205\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.419e5315.js" (99%) rename "assets/guide_canvas_\345\217\257\350\247\206\345\214\272\345\237\237\345\206\205\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.3686d5ec.lean.js" => "assets/guide_canvas_\345\217\257\350\247\206\345\214\272\345\237\237\345\206\205\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.419e5315.lean.js" (92%) rename "assets/guide_canvas_\345\246\202\344\275\225\345\234\250Canvas\347\224\273\346\235\277\344\270\212\350\207\252\347\224\261\344\271\246\345\206\231.md.984beaeb.js" => "assets/guide_canvas_\345\246\202\344\275\225\345\234\250Canvas\347\224\273\346\235\277\344\270\212\350\207\252\347\224\261\344\271\246\345\206\231.md.b9949f49.js" (99%) rename "assets/guide_canvas_\345\246\202\344\275\225\345\234\250Canvas\347\224\273\346\235\277\344\270\212\350\207\252\347\224\261\344\271\246\345\206\231.md.984beaeb.lean.js" => "assets/guide_canvas_\345\246\202\344\275\225\345\234\250Canvas\347\224\273\346\235\277\344\270\212\350\207\252\347\224\261\344\271\246\345\206\231.md.b9949f49.lean.js" (91%) rename "assets/guide_canvas_\351\200\232\350\277\207 OffscreenCanvas _ Worker \346\217\220\351\253\230\344\271\246\345\206\231\346\200\247\350\203\275.md.18a4aa5f.js" => "assets/guide_canvas_\351\200\232\350\277\207 OffscreenCanvas _ Worker \346\217\220\351\253\230\344\271\246\345\206\231\346\200\247\350\203\275.md.10b7092a.js" (99%) rename "assets/guide_canvas_\351\200\232\350\277\207 OffscreenCanvas _ Worker \346\217\220\351\253\230\344\271\246\345\206\231\346\200\247\350\203\275.md.18a4aa5f.lean.js" => "assets/guide_canvas_\351\200\232\350\277\207 OffscreenCanvas _ Worker \346\217\220\351\253\230\344\271\246\345\206\231\346\200\247\350\203\275.md.10b7092a.lean.js" (90%) rename "assets/guide_canvas_\351\200\232\350\277\207\344\270\212\344\270\213\345\210\206\345\261\202\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.ef016078.js" => "assets/guide_canvas_\351\200\232\350\277\207\344\270\212\344\270\213\345\210\206\345\261\202\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.2eca7891.js" (99%) rename "assets/guide_canvas_\351\200\232\350\277\207\344\270\212\344\270\213\345\210\206\345\261\202\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.ef016078.lean.js" => "assets/guide_canvas_\351\200\232\350\277\207\344\270\212\344\270\213\345\210\206\345\261\202\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.2eca7891.lean.js" (90%) rename "assets/guide_canvas_\351\200\232\350\277\207\347\246\273\345\261\217\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.c3dc05ff.js" => "assets/guide_canvas_\351\200\232\350\277\207\347\246\273\345\261\217\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.af60bf99.js" (99%) rename "assets/guide_canvas_\351\200\232\350\277\207\347\246\273\345\261\217\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.c3dc05ff.lean.js" => "assets/guide_canvas_\351\200\232\350\277\207\347\246\273\345\261\217\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.af60bf99.lean.js" (89%) rename "assets/guide_canvas_\351\200\232\350\277\207\350\264\235\345\241\236\345\260\224\346\233\262\347\272\277\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.acad2b6c.js" => "assets/guide_canvas_\351\200\232\350\277\207\350\264\235\345\241\236\345\260\224\346\233\262\347\272\277\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.c136fb49.js" (99%) rename "assets/guide_canvas_\351\200\232\350\277\207\350\264\235\345\241\236\345\260\224\346\233\262\347\272\277\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.acad2b6c.lean.js" => "assets/guide_canvas_\351\200\232\350\277\207\350\264\235\345\241\236\345\260\224\346\233\262\347\272\277\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.c136fb49.lean.js" (90%) rename "assets/guide_css\347\233\270\345\205\263_BFC.md.0b433659.js" => "assets/guide_css\347\233\270\345\205\263_BFC.md.0cc3082f.js" (96%) rename "assets/guide_css\347\233\270\345\205\263_BFC.md.0b433659.lean.js" => "assets/guide_css\347\233\270\345\205\263_BFC.md.0cc3082f.lean.js" (85%) rename "assets/guide_css\347\233\270\345\205\263_display.md.1eb7437c.js" => "assets/guide_css\347\233\270\345\205\263_display.md.24ba2b32.js" (99%) rename "assets/guide_css\347\233\270\345\205\263_display.md.1eb7437c.lean.js" => "assets/guide_css\347\233\270\345\205\263_display.md.24ba2b32.lean.js" (85%) rename "assets/guide_css\347\233\270\345\205\263_display\343\200\201float\343\200\201position\347\232\204\345\205\263\347\263\273.md.1fe9ac57.js" => "assets/guide_css\347\233\270\345\205\263_display\343\200\201float\343\200\201position\347\232\204\345\205\263\347\263\273.md.1a5ef489.js" (99%) rename "assets/guide_css\347\233\270\345\205\263_display\343\200\201float\343\200\201position\347\232\204\345\205\263\347\263\273.md.1fe9ac57.lean.js" => "assets/guide_css\347\233\270\345\205\263_display\343\200\201float\343\200\201position\347\232\204\345\205\263\347\263\273.md.1a5ef489.lean.js" (88%) rename "assets/guide_css\347\233\270\345\205\263_display\343\200\201visibility\343\200\201opacity\345\214\272\345\210\253.md.79a76e72.js" => "assets/guide_css\347\233\270\345\205\263_display\343\200\201visibility\343\200\201opacity\345\214\272\345\210\253.md.5aec2cb5.js" (96%) rename "assets/guide_css\347\233\270\345\205\263_display\343\200\201visibility\343\200\201opacity\345\214\272\345\210\253.md.79a76e72.lean.js" => "assets/guide_css\347\233\270\345\205\263_display\343\200\201visibility\343\200\201opacity\345\214\272\345\210\253.md.5aec2cb5.lean.js" (88%) rename "assets/guide_css\347\233\270\345\205\263_position.md.cc780e52.js" => "assets/guide_css\347\233\270\345\205\263_position.md.f6e57cb3.js" (99%) rename "assets/guide_css\347\233\270\345\205\263_position.md.cc780e52.lean.js" => "assets/guide_css\347\233\270\345\205\263_position.md.f6e57cb3.lean.js" (99%) rename "assets/guide_css\347\233\270\345\205\263_\345\257\271 line-height \347\232\204\347\220\206\350\247\243\345\217\212\345\205\266\350\265\213\345\200\274\346\226\271\345\274\217.md.91a29d6d.js" => "assets/guide_css\347\233\270\345\205\263_\345\257\271 line-height \347\232\204\347\220\206\350\247\243\345\217\212\345\205\266\350\265\213\345\200\274\346\226\271\345\274\217.md.7b9b530a.js" (97%) rename "assets/guide_css\347\233\270\345\205\263_\345\257\271 line-height \347\232\204\347\220\206\350\247\243\345\217\212\345\205\266\350\265\213\345\200\274\346\226\271\345\274\217.md.91a29d6d.lean.js" => "assets/guide_css\347\233\270\345\205\263_\345\257\271 line-height \347\232\204\347\220\206\350\247\243\345\217\212\345\205\266\350\265\213\345\200\274\346\226\271\345\274\217.md.7b9b530a.lean.js" (89%) rename "assets/guide_css\347\233\270\345\205\263_\346\246\202\350\246\201.md.28c775f1.js" => "assets/guide_css\347\233\270\345\205\263_\346\246\202\350\246\201.md.20b96226.js" (87%) rename "assets/guide_css\347\233\270\345\205\263_\346\246\202\350\246\201.md.28c775f1.lean.js" => "assets/guide_css\347\233\270\345\205\263_\346\246\202\350\246\201.md.20b96226.lean.js" (87%) rename "assets/guide_css\347\233\270\345\205\263_\351\232\220\350\227\217\345\205\203\347\264\240\347\232\204\346\226\271\346\263\225.md.b8d72453.js" => "assets/guide_css\347\233\270\345\205\263_\351\232\220\350\227\217\345\205\203\347\264\240\347\232\204\346\226\271\346\263\225.md.49a19e25.js" (94%) rename "assets/guide_css\347\233\270\345\205\263_\351\232\220\350\227\217\345\205\203\347\264\240\347\232\204\346\226\271\346\263\225.md.b8d72453.lean.js" => "assets/guide_css\347\233\270\345\205\263_\351\232\220\350\227\217\345\205\203\347\264\240\347\232\204\346\226\271\346\263\225.md.49a19e25.lean.js" (87%) rename "assets/guide_javaScript\347\233\270\345\205\263_DOM\347\233\270\345\205\263.md.016710fe.js" => "assets/guide_javaScript\347\233\270\345\205\263_DOM\347\233\270\345\205\263.md.bd7d10f3.js" (99%) rename "assets/guide_javaScript\347\233\270\345\205\263_DOM\347\233\270\345\205\263.md.016710fe.lean.js" => "assets/guide_javaScript\347\233\270\345\205\263_DOM\347\233\270\345\205\263.md.bd7d10f3.lean.js" (86%) rename "assets/guide_javaScript\347\233\270\345\205\263_ES6\347\233\270\345\205\263.md.bd6110d8.js" => "assets/guide_javaScript\347\233\270\345\205\263_ES6\347\233\270\345\205\263.md.98a38a5e.js" (99%) rename "assets/guide_javaScript\347\233\270\345\205\263_ES6\347\233\270\345\205\263.md.bd6110d8.lean.js" => "assets/guide_javaScript\347\233\270\345\205\263_ES6\347\233\270\345\205\263.md.98a38a5e.lean.js" (87%) rename "assets/guide_javaScript\347\233\270\345\205\263_JS\345\274\202\345\270\270\346\215\225\350\216\267\346\234\272\345\210\266.md.93a23d57.js" => "assets/guide_javaScript\347\233\270\345\205\263_JS\345\274\202\345\270\270\346\215\225\350\216\267\346\234\272\345\210\266.md.1e9b4755.js" (86%) rename "assets/guide_javaScript\347\233\270\345\205\263_JS\345\274\202\345\270\270\346\215\225\350\216\267\346\234\272\345\210\266.md.93a23d57.lean.js" => "assets/guide_javaScript\347\233\270\345\205\263_JS\345\274\202\345\270\270\346\215\225\350\216\267\346\234\272\345\210\266.md.1e9b4755.lean.js" (86%) rename "assets/guide_javaScript\347\233\270\345\205\263_JavaScript\346\211\247\350\241\214\346\234\272\345\210\266.md.912ab316.js" => "assets/guide_javaScript\347\233\270\345\205\263_JavaScript\346\211\247\350\241\214\346\234\272\345\210\266.md.8aebbf95.js" (92%) rename "assets/guide_javaScript\347\233\270\345\205\263_JavaScript\346\211\247\350\241\214\346\234\272\345\210\266.md.912ab316.lean.js" => "assets/guide_javaScript\347\233\270\345\205\263_JavaScript\346\211\247\350\241\214\346\234\272\345\210\266.md.8aebbf95.lean.js" (92%) rename "assets/guide_javaScript\347\233\270\345\205\263_JavaScript\347\274\226\350\257\221\346\234\272\345\210\266.md.1bf41186.lean.js" => "assets/guide_javaScript\347\233\270\345\205\263_JavaScript\347\274\226\350\257\221\346\234\272\345\210\266.md.6b3e2f0d.js" (92%) rename "assets/guide_javaScript\347\233\270\345\205\263_JavaScript\347\274\226\350\257\221\346\234\272\345\210\266.md.1bf41186.js" => "assets/guide_javaScript\347\233\270\345\205\263_JavaScript\347\274\226\350\257\221\346\234\272\345\210\266.md.6b3e2f0d.lean.js" (92%) rename "assets/guide_javaScript\347\233\270\345\205\263_Promise.md.fa3d3914.js" => "assets/guide_javaScript\347\233\270\345\205\263_Promise.md.adc6aed9.js" (99%) rename "assets/guide_javaScript\347\233\270\345\205\263_Promise.md.fa3d3914.lean.js" => "assets/guide_javaScript\347\233\270\345\205\263_Promise.md.adc6aed9.lean.js" (90%) rename "assets/guide_javaScript\347\233\270\345\205\263_index.md.b2d97d4d.js" => "assets/guide_javaScript\347\233\270\345\205\263_index.md.ff95dc7a.js" (88%) rename "assets/guide_javaScript\347\233\270\345\205\263_index.md.b2d97d4d.lean.js" => "assets/guide_javaScript\347\233\270\345\205\263_index.md.ff95dc7a.lean.js" (88%) rename "assets/guide_javaScript\347\233\270\345\205\263_\344\272\213\344\273\266\345\276\252\347\216\257\346\234\272\345\210\266.md.050f60d8.js" => "assets/guide_javaScript\347\233\270\345\205\263_\344\272\213\344\273\266\345\276\252\347\216\257\346\234\272\345\210\266.md.4ff87ac5.js" (93%) rename "assets/guide_javaScript\347\233\270\345\205\263_\344\272\213\344\273\266\345\276\252\347\216\257\346\234\272\345\210\266.md.050f60d8.lean.js" => "assets/guide_javaScript\347\233\270\345\205\263_\344\272\213\344\273\266\345\276\252\347\216\257\346\234\272\345\210\266.md.4ff87ac5.lean.js" (93%) rename "assets/guide_javaScript\347\233\270\345\205\263_\345\236\203\345\234\276\345\233\236\346\224\266\346\234\272\345\210\266.md.e3ad0c7a.js" => "assets/guide_javaScript\347\233\270\345\205\263_\345\236\203\345\234\276\345\233\236\346\224\266\346\234\272\345\210\266.md.6755966f.js" (95%) rename "assets/guide_javaScript\347\233\270\345\205\263_\345\236\203\345\234\276\345\233\236\346\224\266\346\234\272\345\210\266.md.e3ad0c7a.lean.js" => "assets/guide_javaScript\347\233\270\345\205\263_\345\236\203\345\234\276\345\233\236\346\224\266\346\234\272\345\210\266.md.6755966f.lean.js" (95%) rename "assets/guide_javaScript\347\233\270\345\205\263_\345\237\272\347\241\200\346\246\202\345\277\265.md.6cb63943.js" => "assets/guide_javaScript\347\233\270\345\205\263_\345\237\272\347\241\200\346\246\202\345\277\265.md.dcfd312c.js" (99%) rename "assets/guide_javaScript\347\233\270\345\205\263_\345\237\272\347\241\200\346\246\202\345\277\265.md.6cb63943.lean.js" => "assets/guide_javaScript\347\233\270\345\205\263_\345\237\272\347\241\200\346\246\202\345\277\265.md.dcfd312c.lean.js" (88%) rename "assets/guide_javaScript\347\233\270\345\205\263_\345\255\227\347\254\246\344\270\262\345\270\270\350\247\201\347\232\204API.md.f8114998.js" => "assets/guide_javaScript\347\233\270\345\205\263_\345\255\227\347\254\246\344\270\262\345\270\270\350\247\201\347\232\204API.md.19aad48b.js" (86%) rename "assets/guide_javaScript\347\233\270\345\205\263_\345\255\227\347\254\246\344\270\262\345\270\270\350\247\201\347\232\204API.md.f8114998.lean.js" => "assets/guide_javaScript\347\233\270\345\205\263_\345\255\227\347\254\246\344\270\262\345\270\270\350\247\201\347\232\204API.md.19aad48b.lean.js" (86%) rename "assets/guide_javaScript\347\233\270\345\205\263_\345\256\232\344\271\211.md.ede1ac70.js" => "assets/guide_javaScript\347\233\270\345\205\263_\345\256\232\344\271\211.md.c58c5632.js" (94%) rename "assets/guide_javaScript\347\233\270\345\205\263_\345\256\232\344\271\211.md.ede1ac70.lean.js" => "assets/guide_javaScript\347\233\270\345\205\263_\345\256\232\344\271\211.md.c58c5632.lean.js" (94%) rename "assets/guide_javaScript\347\233\270\345\205\263_\345\257\271\350\261\241\345\270\270\350\247\201\347\232\204API.md.fa4ed7c9.js" => "assets/guide_javaScript\347\233\270\345\205\263_\345\257\271\350\261\241\345\270\270\350\247\201\347\232\204API.md.4eca8a1e.js" (86%) rename "assets/guide_javaScript\347\233\270\345\205\263_\345\257\271\350\261\241\345\270\270\350\247\201\347\232\204API.md.fa4ed7c9.lean.js" => "assets/guide_javaScript\347\233\270\345\205\263_\345\257\271\350\261\241\345\270\270\350\247\201\347\232\204API.md.4eca8a1e.lean.js" (86%) rename "assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\346\215\256\347\261\273\345\236\213.md.78b17d35.js" => "assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\346\215\256\347\261\273\345\236\213.md.d9e46f31.js" (99%) rename "assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\346\215\256\347\261\273\345\236\213.md.78b17d35.lean.js" => "assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\346\215\256\347\261\273\345\236\213.md.d9e46f31.lean.js" (87%) rename "assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\347\273\204\345\270\270\350\247\201\347\232\204API.md.4cdc62b7.js" => "assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\347\273\204\345\270\270\350\247\201\347\232\204API.md.2dc845e4.js" (86%) rename "assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\347\273\204\345\270\270\350\247\201\347\232\204API.md.4cdc62b7.lean.js" => "assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\347\273\204\345\270\270\350\247\201\347\232\204API.md.2dc845e4.lean.js" (86%) rename "assets/guide_javaScript\347\233\270\345\205\263_\346\226\260\347\232\204\350\277\220\347\256\227\347\254\246.md.4ef7cdb7.js" => "assets/guide_javaScript\347\233\270\345\205\263_\346\226\260\347\232\204\350\277\220\347\256\227\347\254\246.md.d9d1e0c1.js" (85%) rename "assets/guide_javaScript\347\233\270\345\205\263_\346\226\260\347\232\204\350\277\220\347\256\227\347\254\246.md.4ef7cdb7.lean.js" => "assets/guide_javaScript\347\233\270\345\205\263_\346\226\260\347\232\204\350\277\220\347\256\227\347\254\246.md.d9d1e0c1.lean.js" (85%) rename "assets/guide_javaScript\347\233\270\345\205\263_\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217.md.9ee8e248.js" => "assets/guide_javaScript\347\233\270\345\205\263_\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217.md.37761b31.js" (85%) rename "assets/guide_javaScript\347\233\270\345\205\263_\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217.md.9ee8e248.lean.js" => "assets/guide_javaScript\347\233\270\345\205\263_\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217.md.37761b31.lean.js" (85%) rename "assets/guide_javaScript\347\233\270\345\205\263_\347\273\247\346\211\277\347\233\270\345\205\263.md.237c7c62.js" => "assets/guide_javaScript\347\233\270\345\205\263_\347\273\247\346\211\277\347\233\270\345\205\263.md.0b549acd.js" (99%) rename "assets/guide_javaScript\347\233\270\345\205\263_\347\273\247\346\211\277\347\233\270\345\205\263.md.237c7c62.lean.js" => "assets/guide_javaScript\347\233\270\345\205\263_\347\273\247\346\211\277\347\233\270\345\205\263.md.0b549acd.lean.js" (86%) rename assets/{guide_webpack_index.md.e15e3d26.js => guide_webpack_index.md.f2414c6a.js} (94%) rename assets/{guide_webpack_index.md.e15e3d26.lean.js => guide_webpack_index.md.f2414c6a.lean.js} (94%) rename "assets/guide_webpack_\346\236\204\345\273\272\346\265\201\347\250\213.md.379b02b0.js" => "assets/guide_webpack_\346\236\204\345\273\272\346\265\201\347\250\213.md.07f4ea79.js" (99%) rename "assets/guide_webpack_\346\236\204\345\273\272\346\265\201\347\250\213.md.379b02b0.lean.js" => "assets/guide_webpack_\346\236\204\345\273\272\346\265\201\347\250\213.md.07f4ea79.lean.js" (86%) rename "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\246\202\350\246\201.md.1965a3c6.js" => "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\246\202\350\246\201.md.f313a7ec.js" (88%) rename "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\246\202\350\246\201.md.1965a3c6.lean.js" => "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\246\202\350\246\201.md.f313a7ec.lean.js" (88%) rename "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\206\205\346\240\270.md.ac5651f8.js" => "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\206\205\346\240\270.md.9cd84d74.js" (92%) rename "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\206\205\346\240\270.md.ac5651f8.lean.js" => "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\206\205\346\240\270.md.9cd84d74.lean.js" (92%) rename "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\256\211\345\205\250.md.0e2ad803.js" => "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\256\211\345\205\250.md.cda4119d.js" (99%) rename "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\256\211\345\205\250.md.0e2ad803.lean.js" => "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\256\211\345\205\250.md.cda4119d.lean.js" (90%) rename "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\346\265\201\347\250\213.md.a1f24938.js" => "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\346\265\201\347\250\213.md.1331606e.js" (99%) rename "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\346\265\201\347\250\213.md.a1f24938.lean.js" => "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\346\265\201\347\250\213.md.1331606e.lean.js" (90%) rename "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\347\274\223\345\255\230.md.8cddcc95.js" => "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\347\274\223\345\255\230.md.88373219.js" (99%) rename "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\347\274\223\345\255\230.md.8cddcc95.lean.js" => "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\347\274\223\345\255\230.md.88373219.lean.js" (87%) rename "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\350\277\233\347\250\213\346\236\266\346\236\204.md.13fb4bd1.js" => "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\350\277\233\347\250\213\346\236\266\346\236\204.md.1b1db83e.js" (97%) rename "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\350\277\233\347\250\213\346\236\266\346\236\204.md.13fb4bd1.lean.js" => "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\350\277\233\347\250\213\346\236\266\346\236\204.md.1b1db83e.lean.js" (87%) rename "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_CDN.md.c26e601b.js" => "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_CDN.md.e85fe02e.js" (98%) rename "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_CDN.md.c26e601b.lean.js" => "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_CDN.md.e85fe02e.lean.js" (86%) rename "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_DNS.md.e56a26c8.js" => "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_DNS.md.3f43cbe6.js" (96%) rename "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_DNS.md.e56a26c8.lean.js" => "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_DNS.md.3f43cbe6.lean.js" (85%) rename "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_GET\350\257\267\346\261\202\345\222\214POST\350\257\267\346\261\202\347\232\204\345\214\272\345\210\253.md.5e98e509.js" => "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_GET\350\257\267\346\261\202\345\222\214POST\350\257\267\346\261\202\347\232\204\345\214\272\345\210\253.md.5b02925b.js" (95%) rename "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_GET\350\257\267\346\261\202\345\222\214POST\350\257\267\346\261\202\347\232\204\345\214\272\345\210\253.md.5e98e509.lean.js" => "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_GET\350\257\267\346\261\202\345\222\214POST\350\257\267\346\261\202\347\232\204\345\214\272\345\210\253.md.5b02925b.lean.js" (95%) rename "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTP.md.22d66eca.js" => "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTP.md.3d19dae2.js" (99%) rename "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTP.md.22d66eca.lean.js" => "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTP.md.3d19dae2.lean.js" (88%) rename "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTPS.md.24fcb37f.js" => "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTPS.md.4c7346fd.js" (98%) rename "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTPS.md.24fcb37f.lean.js" => "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTPS.md.4c7346fd.lean.js" (90%) rename "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\223\215\345\272\224\346\212\245\346\226\207.md.2f7e04b4.js" => "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\223\215\345\272\224\346\212\245\346\226\207.md.e9c73579.js" (99%) rename "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\223\215\345\272\224\346\212\245\346\226\207.md.2f7e04b4.lean.js" => "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\223\215\345\272\224\346\212\245\346\226\207.md.e9c73579.lean.js" (98%) rename "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.e25938b4.js" => "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.3b584d49.js" (85%) rename "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.e25938b4.lean.js" => "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.3b584d49.lean.js" (85%) rename "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\346\246\202\350\246\201.md.3cfbfdfd.js" => "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\346\246\202\350\246\201.md.3b48bb07.js" (88%) rename "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\346\246\202\350\246\201.md.3cfbfdfd.lean.js" => "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\346\246\202\350\246\201.md.3b48bb07.lean.js" (88%) rename "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\257\267\346\261\202\346\212\245\346\226\207.md.ccdffe1b.js" => "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\257\267\346\261\202\346\212\245\346\226\207.md.715db4fc.js" (98%) rename "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\257\267\346\261\202\346\212\245\346\226\207.md.ccdffe1b.lean.js" => "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\257\267\346\261\202\346\212\245\346\226\207.md.715db4fc.lean.js" (88%) rename "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\267\250\345\237\237\350\257\267\346\261\202.md.2626dc46.js" => "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\267\250\345\237\237\350\257\267\346\261\202.md.f2530ac2.js" (99%) rename "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\267\250\345\237\237\350\257\267\346\261\202.md.2626dc46.lean.js" => "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\267\250\345\237\237\350\257\267\346\261\202.md.f2530ac2.lean.js" (90%) rename assets/{index.md.57af2e65.js => index.md.a6c2532f.js} (92%) rename assets/{index.md.57af2e65.lean.js => index.md.a6c2532f.lean.js} (92%) rename "assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_ISO\346\204\237\345\205\211\345\272\246.md.f82c77cc.js" => "assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_ISO\346\204\237\345\205\211\345\272\246.md.1470d204.js" (91%) rename "assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_ISO\346\204\237\345\205\211\345\272\246.md.f82c77cc.lean.js" => "assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_ISO\346\204\237\345\205\211\345\272\246.md.1470d204.lean.js" (91%) rename "assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\205\211\345\234\210.md.6fcc955a.js" => "assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\205\211\345\234\210.md.ae3bc87c.js" (92%) rename "assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\205\211\345\234\210.md.6fcc955a.lean.js" => "assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\205\211\345\234\210.md.ae3bc87c.lean.js" (92%) rename "assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\277\253\351\227\250\351\200\237\345\272\246.md.0fea1225.js" => "assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\277\253\351\227\250\351\200\237\345\272\246.md.9e05d8bb.js" (93%) rename "assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\277\253\351\227\250\351\200\237\345\272\246.md.0fea1225.lean.js" => "assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\277\253\351\227\250\351\200\237\345\272\246.md.9e05d8bb.lean.js" (93%) rename "assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\350\212\261\347\232\204\351\273\221\350\203\214\346\231\257.md.647a17e0.js" => "assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\350\212\261\347\232\204\351\273\221\350\203\214\346\231\257.md.013683af.js" (92%) rename "assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\350\212\261\347\232\204\351\273\221\350\203\214\346\231\257.md.647a17e0.lean.js" => "assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\350\212\261\347\232\204\351\273\221\350\203\214\346\231\257.md.013683af.lean.js" (92%) create mode 100644 "assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\351\233\250\344\270\235.md.5a2c1fb7.js" rename "assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\351\233\250\344\270\235.md.c8378969.lean.js" => "assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\351\233\250\344\270\235.md.5a2c1fb7.lean.js" (51%) delete mode 100644 "assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\351\233\250\344\270\235.md.c8378969.js" rename "assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\346\213\215\346\221\204\346\242\246\345\271\273\345\205\211\346\226\221.md.ab138890.js" => "assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\346\213\215\346\221\204\346\242\246\345\271\273\345\205\211\346\226\221.md.345608b9.js" (93%) rename "assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\346\213\215\346\221\204\346\242\246\345\271\273\345\205\211\346\226\221.md.ab138890.lean.js" => "assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\346\213\215\346\221\204\346\242\246\345\271\273\345\205\211\346\226\221.md.345608b9.lean.js" (93%) diff --git a/404.html b/404.html index 9610df31..60bb5a96 100644 --- a/404.html +++ b/404.html @@ -21,7 +21,7 @@
Skip to content

404

PAGE NOT FOUND

But if you don't change your direction, and if you keep looking, you may end up where you are heading.
- + \ No newline at end of file diff --git "a/assets/guide_Node\347\233\270\345\205\263_\346\246\202\350\246\201.md.914ab426.js" "b/assets/guide_Node\347\233\270\345\205\263_\346\246\202\350\246\201.md.632ffa2f.js" similarity index 84% rename from "assets/guide_Node\347\233\270\345\205\263_\346\246\202\350\246\201.md.914ab426.js" rename to "assets/guide_Node\347\233\270\345\205\263_\346\246\202\350\246\201.md.632ffa2f.js" index f38d4612..1d21037a 100644 --- "a/assets/guide_Node\347\233\270\345\205\263_\346\246\202\350\246\201.md.914ab426.js" +++ "b/assets/guide_Node\347\233\270\345\205\263_\346\246\202\350\246\201.md.632ffa2f.js" @@ -1 +1 @@ -import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/Node相关/概要.md","filePath":"guide/Node相关/概要.md","lastUpdated":1707358495000}'),o={name:"guide/Node相关/概要.md"};function d(r,s,c,n,i,_){return t(),a("div")}const f=e(o,[["render",d]]);export{m as __pageData,f as default}; +import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/Node相关/概要.md","filePath":"guide/Node相关/概要.md","lastUpdated":1707358769000}'),o={name:"guide/Node相关/概要.md"};function d(r,s,c,n,i,_){return t(),a("div")}const f=e(o,[["render",d]]);export{m as __pageData,f as default}; diff --git "a/assets/guide_Node\347\233\270\345\205\263_\346\246\202\350\246\201.md.914ab426.lean.js" "b/assets/guide_Node\347\233\270\345\205\263_\346\246\202\350\246\201.md.632ffa2f.lean.js" similarity index 84% rename from "assets/guide_Node\347\233\270\345\205\263_\346\246\202\350\246\201.md.914ab426.lean.js" rename to "assets/guide_Node\347\233\270\345\205\263_\346\246\202\350\246\201.md.632ffa2f.lean.js" index f38d4612..1d21037a 100644 --- "a/assets/guide_Node\347\233\270\345\205\263_\346\246\202\350\246\201.md.914ab426.lean.js" +++ "b/assets/guide_Node\347\233\270\345\205\263_\346\246\202\350\246\201.md.632ffa2f.lean.js" @@ -1 +1 @@ -import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/Node相关/概要.md","filePath":"guide/Node相关/概要.md","lastUpdated":1707358495000}'),o={name:"guide/Node相关/概要.md"};function d(r,s,c,n,i,_){return t(),a("div")}const f=e(o,[["render",d]]);export{m as __pageData,f as default}; +import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/Node相关/概要.md","filePath":"guide/Node相关/概要.md","lastUpdated":1707358769000}'),o={name:"guide/Node相关/概要.md"};function d(r,s,c,n,i,_){return t(),a("div")}const f=e(o,[["render",d]]);export{m as __pageData,f as default}; diff --git "a/assets/guide_React_React\344\270\216Vue\347\232\204\345\214\272\345\210\253.md.a4cc8156.js" "b/assets/guide_React_React\344\270\216Vue\347\232\204\345\214\272\345\210\253.md.5fd109fc.js" similarity index 85% rename from "assets/guide_React_React\344\270\216Vue\347\232\204\345\214\272\345\210\253.md.a4cc8156.js" rename to "assets/guide_React_React\344\270\216Vue\347\232\204\345\214\272\345\210\253.md.5fd109fc.js" index 640fda56..e125bbb4 100644 --- "a/assets/guide_React_React\344\270\216Vue\347\232\204\345\214\272\345\210\253.md.a4cc8156.js" +++ "b/assets/guide_React_React\344\270\216Vue\347\232\204\345\214\272\345\210\253.md.5fd109fc.js" @@ -1 +1 @@ -import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const u=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React与Vue的区别.md","filePath":"guide/React/React与Vue的区别.md","lastUpdated":1707358495000}'),c={name:"guide/React/React与Vue的区别.md"};function r(o,s,d,n,_,i){return t(),a("div")}const m=e(c,[["render",r]]);export{u as __pageData,m as default}; +import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const u=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React与Vue的区别.md","filePath":"guide/React/React与Vue的区别.md","lastUpdated":1707358769000}'),c={name:"guide/React/React与Vue的区别.md"};function r(o,s,d,n,_,i){return t(),a("div")}const m=e(c,[["render",r]]);export{u as __pageData,m as default}; diff --git "a/assets/guide_React_React\344\270\216Vue\347\232\204\345\214\272\345\210\253.md.a4cc8156.lean.js" "b/assets/guide_React_React\344\270\216Vue\347\232\204\345\214\272\345\210\253.md.5fd109fc.lean.js" similarity index 85% rename from "assets/guide_React_React\344\270\216Vue\347\232\204\345\214\272\345\210\253.md.a4cc8156.lean.js" rename to "assets/guide_React_React\344\270\216Vue\347\232\204\345\214\272\345\210\253.md.5fd109fc.lean.js" index 640fda56..e125bbb4 100644 --- "a/assets/guide_React_React\344\270\216Vue\347\232\204\345\214\272\345\210\253.md.a4cc8156.lean.js" +++ "b/assets/guide_React_React\344\270\216Vue\347\232\204\345\214\272\345\210\253.md.5fd109fc.lean.js" @@ -1 +1 @@ -import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const u=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React与Vue的区别.md","filePath":"guide/React/React与Vue的区别.md","lastUpdated":1707358495000}'),c={name:"guide/React/React与Vue的区别.md"};function r(o,s,d,n,_,i){return t(),a("div")}const m=e(c,[["render",r]]);export{u as __pageData,m as default}; +import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const u=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React与Vue的区别.md","filePath":"guide/React/React与Vue的区别.md","lastUpdated":1707358769000}'),c={name:"guide/React/React与Vue的区别.md"};function r(o,s,d,n,_,i){return t(),a("div")}const m=e(c,[["render",r]]);export{u as __pageData,m as default}; diff --git "a/assets/guide_React_React\344\270\255\347\232\204\344\272\213\344\273\266\346\234\272\345\210\266.md.125ce9e6.js" "b/assets/guide_React_React\344\270\255\347\232\204\344\272\213\344\273\266\346\234\272\345\210\266.md.9d3f4079.js" similarity index 95% rename from "assets/guide_React_React\344\270\255\347\232\204\344\272\213\344\273\266\346\234\272\345\210\266.md.125ce9e6.js" rename to "assets/guide_React_React\344\270\255\347\232\204\344\272\213\344\273\266\346\234\272\345\210\266.md.9d3f4079.js" index 3ef38710..7f2bfbe0 100644 --- "a/assets/guide_React_React\344\270\255\347\232\204\344\272\213\344\273\266\346\234\272\345\210\266.md.125ce9e6.js" +++ "b/assets/guide_React_React\344\270\255\347\232\204\344\272\213\344\273\266\346\234\272\345\210\266.md.9d3f4079.js" @@ -1 +1 @@ -import{_ as a,o as e,c as t,Q as c}from"./chunks/framework.b6910bb2.js";const p=JSON.parse('{"title":"React 事件机制","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React中的事件机制.md","filePath":"guide/React/React中的事件机制.md","lastUpdated":1707358495000}'),r={name:"guide/React/React中的事件机制.md"},o=c('

React 事件机制

概要

为了抹平各个浏览器之间的差异以及统一维护和管理事件,React 自行实现了合成事件,用来模拟原生事件的行为 在 React 16 之前,React 的合成事件放在了 document 的冒泡阶段 在 React 16 之后,为了兼容各个版本,React 的合成事件放在了 根节点 的捕获和冒泡阶段

具体实现

',4),_=[o];function d(i,n,s,l,h,R){return e(),t("div",null,_)}const m=a(r,[["render",d]]);export{p as __pageData,m as default}; +import{_ as a,o as e,c as t,Q as c}from"./chunks/framework.b6910bb2.js";const p=JSON.parse('{"title":"React 事件机制","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React中的事件机制.md","filePath":"guide/React/React中的事件机制.md","lastUpdated":1707358769000}'),r={name:"guide/React/React中的事件机制.md"},o=c('

React 事件机制

概要

为了抹平各个浏览器之间的差异以及统一维护和管理事件,React 自行实现了合成事件,用来模拟原生事件的行为 在 React 16 之前,React 的合成事件放在了 document 的冒泡阶段 在 React 16 之后,为了兼容各个版本,React 的合成事件放在了 根节点 的捕获和冒泡阶段

具体实现

',4),_=[o];function d(i,n,s,l,h,R){return e(),t("div",null,_)}const m=a(r,[["render",d]]);export{p as __pageData,m as default}; diff --git "a/assets/guide_React_React\344\270\255\347\232\204\344\272\213\344\273\266\346\234\272\345\210\266.md.125ce9e6.lean.js" "b/assets/guide_React_React\344\270\255\347\232\204\344\272\213\344\273\266\346\234\272\345\210\266.md.9d3f4079.lean.js" similarity index 86% rename from "assets/guide_React_React\344\270\255\347\232\204\344\272\213\344\273\266\346\234\272\345\210\266.md.125ce9e6.lean.js" rename to "assets/guide_React_React\344\270\255\347\232\204\344\272\213\344\273\266\346\234\272\345\210\266.md.9d3f4079.lean.js" index bf0528ed..c95e19ec 100644 --- "a/assets/guide_React_React\344\270\255\347\232\204\344\272\213\344\273\266\346\234\272\345\210\266.md.125ce9e6.lean.js" +++ "b/assets/guide_React_React\344\270\255\347\232\204\344\272\213\344\273\266\346\234\272\345\210\266.md.9d3f4079.lean.js" @@ -1 +1 @@ -import{_ as a,o as e,c as t,Q as c}from"./chunks/framework.b6910bb2.js";const p=JSON.parse('{"title":"React 事件机制","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React中的事件机制.md","filePath":"guide/React/React中的事件机制.md","lastUpdated":1707358495000}'),r={name:"guide/React/React中的事件机制.md"},o=c("",4),_=[o];function d(i,n,s,l,h,R){return e(),t("div",null,_)}const m=a(r,[["render",d]]);export{p as __pageData,m as default}; +import{_ as a,o as e,c as t,Q as c}from"./chunks/framework.b6910bb2.js";const p=JSON.parse('{"title":"React 事件机制","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React中的事件机制.md","filePath":"guide/React/React中的事件机制.md","lastUpdated":1707358769000}'),r={name:"guide/React/React中的事件机制.md"},o=c("",4),_=[o];function d(i,n,s,l,h,R){return e(),t("div",null,_)}const m=a(r,[["render",d]]);export{p as __pageData,m as default}; diff --git "a/assets/guide_React_React\344\270\255\347\232\204\345\274\202\345\270\270\346\234\272\345\210\266.md.44ac2de8.js" "b/assets/guide_React_React\344\270\255\347\232\204\345\274\202\345\270\270\346\234\272\345\210\266.md.67ec8db4.js" similarity index 85% rename from "assets/guide_React_React\344\270\255\347\232\204\345\274\202\345\270\270\346\234\272\345\210\266.md.44ac2de8.js" rename to "assets/guide_React_React\344\270\255\347\232\204\345\274\202\345\270\270\346\234\272\345\210\266.md.67ec8db4.js" index ffb3a493..a312f6cb 100644 --- "a/assets/guide_React_React\344\270\255\347\232\204\345\274\202\345\270\270\346\234\272\345\210\266.md.44ac2de8.js" +++ "b/assets/guide_React_React\344\270\255\347\232\204\345\274\202\345\270\270\346\234\272\345\210\266.md.67ec8db4.js" @@ -1 +1 @@ -import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React中的异常机制.md","filePath":"guide/React/React中的异常机制.md","lastUpdated":1707358495000}'),c={name:"guide/React/React中的异常机制.md"};function r(o,s,_,d,n,i){return t(),a("div")}const f=e(c,[["render",r]]);export{m as __pageData,f as default}; +import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React中的异常机制.md","filePath":"guide/React/React中的异常机制.md","lastUpdated":1707358769000}'),c={name:"guide/React/React中的异常机制.md"};function r(o,s,_,d,n,i){return t(),a("div")}const f=e(c,[["render",r]]);export{m as __pageData,f as default}; diff --git "a/assets/guide_React_React\344\270\255\347\232\204\345\274\202\345\270\270\346\234\272\345\210\266.md.44ac2de8.lean.js" "b/assets/guide_React_React\344\270\255\347\232\204\345\274\202\345\270\270\346\234\272\345\210\266.md.67ec8db4.lean.js" similarity index 85% rename from "assets/guide_React_React\344\270\255\347\232\204\345\274\202\345\270\270\346\234\272\345\210\266.md.44ac2de8.lean.js" rename to "assets/guide_React_React\344\270\255\347\232\204\345\274\202\345\270\270\346\234\272\345\210\266.md.67ec8db4.lean.js" index ffb3a493..a312f6cb 100644 --- "a/assets/guide_React_React\344\270\255\347\232\204\345\274\202\345\270\270\346\234\272\345\210\266.md.44ac2de8.lean.js" +++ "b/assets/guide_React_React\344\270\255\347\232\204\345\274\202\345\270\270\346\234\272\345\210\266.md.67ec8db4.lean.js" @@ -1 +1 @@ -import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React中的异常机制.md","filePath":"guide/React/React中的异常机制.md","lastUpdated":1707358495000}'),c={name:"guide/React/React中的异常机制.md"};function r(o,s,_,d,n,i){return t(),a("div")}const f=e(c,[["render",r]]);export{m as __pageData,f as default}; +import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React中的异常机制.md","filePath":"guide/React/React中的异常机制.md","lastUpdated":1707358769000}'),c={name:"guide/React/React中的异常机制.md"};function r(o,s,_,d,n,i){return t(),a("div")}const f=e(c,[["render",r]]);export{m as __pageData,f as default}; diff --git "a/assets/guide_React_React\344\270\255\347\232\204\346\200\247\350\203\275\344\274\230\345\214\226.md.581ed9f6.js" "b/assets/guide_React_React\344\270\255\347\232\204\346\200\247\350\203\275\344\274\230\345\214\226.md.8eb2e33c.js" similarity index 99% rename from "assets/guide_React_React\344\270\255\347\232\204\346\200\247\350\203\275\344\274\230\345\214\226.md.581ed9f6.js" rename to "assets/guide_React_React\344\270\255\347\232\204\346\200\247\350\203\275\344\274\230\345\214\226.md.8eb2e33c.js" index 8b0e359c..79199d44 100644 --- "a/assets/guide_React_React\344\270\255\347\232\204\346\200\247\350\203\275\344\274\230\345\214\226.md.581ed9f6.js" +++ "b/assets/guide_React_React\344\270\255\347\232\204\346\200\247\350\203\275\344\274\230\345\214\226.md.8eb2e33c.js" @@ -1,4 +1,4 @@ -import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const u=JSON.parse('{"title":"React 中的性能优化","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React中的性能优化.md","filePath":"guide/React/React中的性能优化.md","lastUpdated":1707358495000}'),p={name:"guide/React/React中的性能优化.md"},o=l(`

React 中的性能优化

在 React 中当我们的父组件更新时,将渲染整个子组件树,这样会造成很大的性能开销,所以我们需要对组件进行优化,避免不必要的渲染。

常见的性能优化手段有:

  1. 减少不必要的渲染

    1. 使用 useMemo 缓存数据、使用 useCallback 缓存函数
    2. 使用 React.memo 缓存组件
    3. 合理的使用 Key
    4. 使用 Fragment 避免额外标记
    5. 通过 Suspense 和 Lazy 拆分组件
  2. 通用方案

    1. 在组件销毁的时候清除定时器/事件
    2. 频繁切换时使用 display: none; 避免不必要的性能开销
    3. 为组件创建错误边界

1 使用 useMemo 缓存数据、使用 useCallback 缓存函数

jsx
/**
+import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const u=JSON.parse('{"title":"React 中的性能优化","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React中的性能优化.md","filePath":"guide/React/React中的性能优化.md","lastUpdated":1707358769000}'),p={name:"guide/React/React中的性能优化.md"},o=l(`

React 中的性能优化

在 React 中当我们的父组件更新时,将渲染整个子组件树,这样会造成很大的性能开销,所以我们需要对组件进行优化,避免不必要的渲染。

常见的性能优化手段有:

  1. 减少不必要的渲染

    1. 使用 useMemo 缓存数据、使用 useCallback 缓存函数
    2. 使用 React.memo 缓存组件
    3. 合理的使用 Key
    4. 使用 Fragment 避免额外标记
    5. 通过 Suspense 和 Lazy 拆分组件
  2. 通用方案

    1. 在组件销毁的时候清除定时器/事件
    2. 频繁切换时使用 display: none; 避免不必要的性能开销
    3. 为组件创建错误边界

1 使用 useMemo 缓存数据、使用 useCallback 缓存函数

jsx
/**
  * 使用 useMemo 缓存数据,类似于 Vue 的 computed 计算属性
  * 使用 useCallback 缓存函数
  * @returns
diff --git "a/assets/guide_React_React\344\270\255\347\232\204\346\200\247\350\203\275\344\274\230\345\214\226.md.581ed9f6.lean.js" "b/assets/guide_React_React\344\270\255\347\232\204\346\200\247\350\203\275\344\274\230\345\214\226.md.8eb2e33c.lean.js"
similarity index 87%
rename from "assets/guide_React_React\344\270\255\347\232\204\346\200\247\350\203\275\344\274\230\345\214\226.md.581ed9f6.lean.js"
rename to "assets/guide_React_React\344\270\255\347\232\204\346\200\247\350\203\275\344\274\230\345\214\226.md.8eb2e33c.lean.js"
index 062ff9e6..d53d8afc 100644
--- "a/assets/guide_React_React\344\270\255\347\232\204\346\200\247\350\203\275\344\274\230\345\214\226.md.581ed9f6.lean.js"
+++ "b/assets/guide_React_React\344\270\255\347\232\204\346\200\247\350\203\275\344\274\230\345\214\226.md.8eb2e33c.lean.js"
@@ -1 +1 @@
-import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const u=JSON.parse('{"title":"React 中的性能优化","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React中的性能优化.md","filePath":"guide/React/React中的性能优化.md","lastUpdated":1707358495000}'),p={name:"guide/React/React中的性能优化.md"},o=l("",41),e=[o];function t(c,r,E,y,i,F){return n(),a("div",null,e)}const A=s(p,[["render",t]]);export{u as __pageData,A as default};
+import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const u=JSON.parse('{"title":"React 中的性能优化","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React中的性能优化.md","filePath":"guide/React/React中的性能优化.md","lastUpdated":1707358769000}'),p={name:"guide/React/React中的性能优化.md"},o=l("",41),e=[o];function t(c,r,E,y,i,F){return n(),a("div",null,e)}const A=s(p,[["render",t]]);export{u as __pageData,A as default};
diff --git "a/assets/guide_React_React\344\270\272\344\273\200\344\271\210\350\246\201\344\275\277\347\224\250JSX.md.917208ca.js" "b/assets/guide_React_React\344\270\272\344\273\200\344\271\210\350\246\201\344\275\277\347\224\250JSX.md.d1fcafa8.js"
similarity index 88%
rename from "assets/guide_React_React\344\270\272\344\273\200\344\271\210\350\246\201\344\275\277\347\224\250JSX.md.917208ca.js"
rename to "assets/guide_React_React\344\270\272\344\273\200\344\271\210\350\246\201\344\275\277\347\224\250JSX.md.d1fcafa8.js"
index 5409d7b8..e5e2efb2 100644
--- "a/assets/guide_React_React\344\270\272\344\273\200\344\271\210\350\246\201\344\275\277\347\224\250JSX.md.917208ca.js"
+++ "b/assets/guide_React_React\344\270\272\344\273\200\344\271\210\350\246\201\344\275\277\347\224\250JSX.md.d1fcafa8.js"
@@ -1 +1 @@
-import{_ as t,o as a,c,k as e,a as s}from"./chunks/framework.b6910bb2.js";const X=JSON.parse('{"title":"React 为什么要使用 JSX ?","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React为什么要使用JSX.md","filePath":"guide/React/React为什么要使用JSX.md","lastUpdated":1707358495000}'),r={name:"guide/React/React为什么要使用JSX.md"},o=e("h1",{id:"react-为什么要使用-jsx",tabindex:"-1"},[s("React 为什么要使用 JSX ? "),e("a",{class:"header-anchor",href:"#react-为什么要使用-jsx","aria-label":'Permalink to "React 为什么要使用 JSX ?"'},"​")],-1),n=e("p",null,"JSX 是 JavaScript 语法拓展,结构类似于 XML,它可以在 JavaScript 中直接使用 HTML 标签,这样可以方便开发者编写组件,提高开发效率。",-1),_=e("p",null,"没有JSX时,也可以使用 React.createElement 实现一个组件,但是这样的代码可读性很差,而且不方便复用,所以 React 推荐使用 JSX。",-1),d=[o,n,_];function i(l,p,J,S,h,R){return a(),c("div",null,d)}const u=t(r,[["render",i]]);export{X as __pageData,u as default};
+import{_ as t,o as a,c,k as e,a as s}from"./chunks/framework.b6910bb2.js";const X=JSON.parse('{"title":"React 为什么要使用 JSX ?","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React为什么要使用JSX.md","filePath":"guide/React/React为什么要使用JSX.md","lastUpdated":1707358769000}'),r={name:"guide/React/React为什么要使用JSX.md"},o=e("h1",{id:"react-为什么要使用-jsx",tabindex:"-1"},[s("React 为什么要使用 JSX ? "),e("a",{class:"header-anchor",href:"#react-为什么要使用-jsx","aria-label":'Permalink to "React 为什么要使用 JSX ?"'},"​")],-1),n=e("p",null,"JSX 是 JavaScript 语法拓展,结构类似于 XML,它可以在 JavaScript 中直接使用 HTML 标签,这样可以方便开发者编写组件,提高开发效率。",-1),_=e("p",null,"没有JSX时,也可以使用 React.createElement 实现一个组件,但是这样的代码可读性很差,而且不方便复用,所以 React 推荐使用 JSX。",-1),d=[o,n,_];function i(l,p,J,S,h,R){return a(),c("div",null,d)}const u=t(r,[["render",i]]);export{X as __pageData,u as default};
diff --git "a/assets/guide_React_React\344\270\272\344\273\200\344\271\210\350\246\201\344\275\277\347\224\250JSX.md.917208ca.lean.js" "b/assets/guide_React_React\344\270\272\344\273\200\344\271\210\350\246\201\344\275\277\347\224\250JSX.md.d1fcafa8.lean.js"
similarity index 88%
rename from "assets/guide_React_React\344\270\272\344\273\200\344\271\210\350\246\201\344\275\277\347\224\250JSX.md.917208ca.lean.js"
rename to "assets/guide_React_React\344\270\272\344\273\200\344\271\210\350\246\201\344\275\277\347\224\250JSX.md.d1fcafa8.lean.js"
index 5409d7b8..e5e2efb2 100644
--- "a/assets/guide_React_React\344\270\272\344\273\200\344\271\210\350\246\201\344\275\277\347\224\250JSX.md.917208ca.lean.js"
+++ "b/assets/guide_React_React\344\270\272\344\273\200\344\271\210\350\246\201\344\275\277\347\224\250JSX.md.d1fcafa8.lean.js"
@@ -1 +1 @@
-import{_ as t,o as a,c,k as e,a as s}from"./chunks/framework.b6910bb2.js";const X=JSON.parse('{"title":"React 为什么要使用 JSX ?","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React为什么要使用JSX.md","filePath":"guide/React/React为什么要使用JSX.md","lastUpdated":1707358495000}'),r={name:"guide/React/React为什么要使用JSX.md"},o=e("h1",{id:"react-为什么要使用-jsx",tabindex:"-1"},[s("React 为什么要使用 JSX ? "),e("a",{class:"header-anchor",href:"#react-为什么要使用-jsx","aria-label":'Permalink to "React 为什么要使用 JSX ?"'},"​")],-1),n=e("p",null,"JSX 是 JavaScript 语法拓展,结构类似于 XML,它可以在 JavaScript 中直接使用 HTML 标签,这样可以方便开发者编写组件,提高开发效率。",-1),_=e("p",null,"没有JSX时,也可以使用 React.createElement 实现一个组件,但是这样的代码可读性很差,而且不方便复用,所以 React 推荐使用 JSX。",-1),d=[o,n,_];function i(l,p,J,S,h,R){return a(),c("div",null,d)}const u=t(r,[["render",i]]);export{X as __pageData,u as default};
+import{_ as t,o as a,c,k as e,a as s}from"./chunks/framework.b6910bb2.js";const X=JSON.parse('{"title":"React 为什么要使用 JSX ?","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React为什么要使用JSX.md","filePath":"guide/React/React为什么要使用JSX.md","lastUpdated":1707358769000}'),r={name:"guide/React/React为什么要使用JSX.md"},o=e("h1",{id:"react-为什么要使用-jsx",tabindex:"-1"},[s("React 为什么要使用 JSX ? "),e("a",{class:"header-anchor",href:"#react-为什么要使用-jsx","aria-label":'Permalink to "React 为什么要使用 JSX ?"'},"​")],-1),n=e("p",null,"JSX 是 JavaScript 语法拓展,结构类似于 XML,它可以在 JavaScript 中直接使用 HTML 标签,这样可以方便开发者编写组件,提高开发效率。",-1),_=e("p",null,"没有JSX时,也可以使用 React.createElement 实现一个组件,但是这样的代码可读性很差,而且不方便复用,所以 React 推荐使用 JSX。",-1),d=[o,n,_];function i(l,p,J,S,h,R){return a(),c("div",null,d)}const u=t(r,[["render",i]]);export{X as __pageData,u as default};
diff --git "a/assets/guide_React_React\346\230\257\344\273\200\344\271\210.md.bd2dae02.js" "b/assets/guide_React_React\346\230\257\344\273\200\344\271\210.md.6fb31cb5.js"
similarity index 98%
rename from "assets/guide_React_React\346\230\257\344\273\200\344\271\210.md.bd2dae02.js"
rename to "assets/guide_React_React\346\230\257\344\273\200\344\271\210.md.6fb31cb5.js"
index d7907ea1..571d90d9 100644
--- "a/assets/guide_React_React\346\230\257\344\273\200\344\271\210.md.bd2dae02.js"
+++ "b/assets/guide_React_React\346\230\257\344\273\200\344\271\210.md.6fb31cb5.js"
@@ -1,4 +1,4 @@
-import{_ as s,o as a,c as o,Q as n}from"./chunks/framework.b6910bb2.js";const _=JSON.parse('{"title":"React 是什么?","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React是什么.md","filePath":"guide/React/React是什么.md","lastUpdated":1707358495000}'),e={name:"guide/React/React是什么.md"},l=n(`

React 是什么?

React 是一个用于构建用户界面的 JavaScript 库, 通过组件化的方式解决视图层复用的问题。

它的核心思路是: 声明式、组件化、通用型

声明式

相比 JQ 的命令式编程: $(body).css('color', 'red');, 声明式编程更加直观、便于复用:

jsx
const Body = (props) => {
+import{_ as s,o as a,c as o,Q as n}from"./chunks/framework.b6910bb2.js";const _=JSON.parse('{"title":"React 是什么?","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React是什么.md","filePath":"guide/React/React是什么.md","lastUpdated":1707358769000}'),e={name:"guide/React/React是什么.md"},l=n(`

React 是什么?

React 是一个用于构建用户界面的 JavaScript 库, 通过组件化的方式解决视图层复用的问题。

它的核心思路是: 声明式、组件化、通用型

声明式

相比 JQ 的命令式编程: $(body).css('color', 'red');, 声明式编程更加直观、便于复用:

jsx
const Body = (props) => {
    return <div style={{color: 'red'}}>{props.children}</div>
 }
const Body = (props) => {
    return <div style={{color: 'red'}}>{props.children}</div>
diff --git "a/assets/guide_React_React\346\230\257\344\273\200\344\271\210.md.bd2dae02.lean.js" "b/assets/guide_React_React\346\230\257\344\273\200\344\271\210.md.6fb31cb5.lean.js"
similarity index 86%
rename from "assets/guide_React_React\346\230\257\344\273\200\344\271\210.md.bd2dae02.lean.js"
rename to "assets/guide_React_React\346\230\257\344\273\200\344\271\210.md.6fb31cb5.lean.js"
index a2b28775..5bd5ff48 100644
--- "a/assets/guide_React_React\346\230\257\344\273\200\344\271\210.md.bd2dae02.lean.js"
+++ "b/assets/guide_React_React\346\230\257\344\273\200\344\271\210.md.6fb31cb5.lean.js"
@@ -1 +1 @@
-import{_ as s,o as a,c as o,Q as n}from"./chunks/framework.b6910bb2.js";const _=JSON.parse('{"title":"React 是什么?","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React是什么.md","filePath":"guide/React/React是什么.md","lastUpdated":1707358495000}'),e={name:"guide/React/React是什么.md"},l=n("",12),p=[l];function t(c,r,i,d,E,y){return a(),o("div",null,p)}const u=s(e,[["render",t]]);export{_ as __pageData,u as default};
+import{_ as s,o as a,c as o,Q as n}from"./chunks/framework.b6910bb2.js";const _=JSON.parse('{"title":"React 是什么?","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React是什么.md","filePath":"guide/React/React是什么.md","lastUpdated":1707358769000}'),e={name:"guide/React/React是什么.md"},l=n("",12),p=[l];function t(c,r,i,d,E,y){return a(),o("div",null,p)}const u=s(e,[["render",t]]);export{_ as __pageData,u as default};
diff --git "a/assets/guide_React_React\346\230\257\345\246\202\344\275\225\346\270\262\346\237\223\347\232\204.md.3113f4a0.js" "b/assets/guide_React_React\346\230\257\345\246\202\344\275\225\346\270\262\346\237\223\347\232\204.md.b469a419.js"
similarity index 99%
rename from "assets/guide_React_React\346\230\257\345\246\202\344\275\225\346\270\262\346\237\223\347\232\204.md.3113f4a0.js"
rename to "assets/guide_React_React\346\230\257\345\246\202\344\275\225\346\270\262\346\237\223\347\232\204.md.b469a419.js"
index 6d294a1e..c9a89198 100644
--- "a/assets/guide_React_React\346\230\257\345\246\202\344\275\225\346\270\262\346\237\223\347\232\204.md.3113f4a0.js"
+++ "b/assets/guide_React_React\346\230\257\345\246\202\344\275\225\346\270\262\346\237\223\347\232\204.md.b469a419.js"
@@ -1 +1 @@
-import{_ as e,o as r,c as o,Q as t}from"./chunks/framework.b6910bb2.js";const a="/vitePress-blob/assets/3.9b1f9060.png",i="/vitePress-blob/assets/4.f4dd49d0.png",n="/vitePress-blob/assets/5.34ee565e.png",s="/vitePress-blob/assets/12.ba19c2aa.png",c="/vitePress-blob/assets/6.121ea6f5.png",l="/vitePress-blob/assets/7.3f678f52.png",p="/vitePress-blob/assets/8.9d04f238.png",d="/vitePress-blob/assets/9.bae86652.png",b="/vitePress-blob/assets/11.07a5666c.png",h="/vitePress-blob/assets/13.5bf5bc75.png",m="/vitePress-blob/assets/14.f1d70f78.png",u="/vitePress-blob/assets/16.4d6f740b.png",_="/vitePress-blob/assets/15.254fe341.png",f="/vitePress-blob/assets/18.09fcc54c.png",k="/vitePress-blob/assets/17.625ac807.png",g="/vitePress-blob/assets/19.77c3b0a6.png",C=JSON.parse('{"title":"React 是如何渲染的","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React是如何渲染的.md","filePath":"guide/React/React是如何渲染的.md","lastUpdated":1707358495000}'),R={name:"guide/React/React是如何渲染的.md"},P=t('

React 是如何渲染的

概要

React 的渲染过程可以分成 2 大阶段, 分别是调和阶段和提交阶段。 调和阶段可以分成 beginWork 阶段、 completeWork 阶段。 在 beginWork 阶段中,React 会根据新生成的 ReactElement 对象和旧的 Fiber 节点进行对比,判断是否可以复用旧的 Fiber 节点并对 Fiber 进行标记。 在 completeWork 节点中,会自底向上构建副作用链表,用来记录需要更新的节点,生成的 DOM 节点会挂载在 Fiber 的 stateNode 属性上。

提交阶段主要分成:操作 DOM 前阶段、操作 DOM 阶段、操作 DOM 后阶段。

React 16 以前

在浏览器中 js 线程与渲染线程是互斥的,如果 js 线程长期占用着浏览器的主线程,那么界面将长时间不更新,在动画等一些场景下会造成卡顿效果。

因为 Stack Reconciler 是一个同步的递归过程,随着业务复杂度增加,Stack Reconciler 需要的调和时间会变长,

这意味着 js 将长时间占用浏览器,进而导致页面卡顿

Stack Reconciler

React 16 以后

将同步执行的 Stack Reconciler 替换成了异步可中断的 Fiber Reconciler

Fiber Reconciler

在更新时,每个任务会被赋予一个优先级,当任务抵达调度器时,高优先级的任务会更快抵达协调器,如有新的更高优先级的任务进入调度器时,当前协调器的任务就会被中断,更高优先级的任务将进入 reconciler

Fiber Reconciler

新的架构会导致部分生命周期重复执行:

  • componentWillMount
  • componentWillUpdate
  • showComponentUpdate
  • componentWillReceiveProps

Render Performance

从首次渲染的调用栈来看,React 的渲染过程主要分为以下几个步骤:

    1. Mount 阶段
    1. Render 阶段
    1. Commit 阶段

Mount 阶段

当执行 ReactDOM.render 时会直接调用 legacyRenderSubtreeIntoContainer 方法

legacyRenderSubtreeIntoContainer 方法

会创建 reactRootContainer 对象(也就是挂载的容器对象), reactRootContainer 对象的 _internalRoot 会指向 fiberRoot (FiberRootNode 类),也就是根节点对象。

legacyRenderSubtreeIntoContainer 最终返回挂载组件( App组件 )的实例对象。

Mount 渲染过程

FiberRootNode对象的描述

在 fiberRoot 对象( FiberRootNode类 )中的 current 属性将指向 rootFiber 对象 (根节点Fiber,即 FiberNode 实例)

fiberRoot对象指向 rootFiber 根节点Fiber

挂载创建关系图

updateContainer 函数

updateContainer 函数主要有以下 3 件事:

    1. 获取当前节点的优先级 lane
    1. 结合 lane 创建当前 Fiber 节点 update 对象,并将其入队
    1. 调度当前节点 (rootFiber 节点)

updateContainer

scheduleUpdateOnFiber 函数

scheduleUpdateOnFiber 函数中会获取 Fiber 节点的mode属性判断是否走同步渲染还是异步渲染的逻辑,在 React17 中首次渲染走的是同步渲染的逻辑

scheduleUpdateOnFiber

这里可能有小伙伴会问,Fiber架构不就是异步渲染的么? 我想说的是,Fiber架构的设计初衷确实是为了异步渲染而设计的,但是 Fiber 架构并不能和异步渲染画上等号,我们不难发现,Fiber 架构同时兼容了同步渲染和异步渲染,如下图,决定同步还是异步取决于 mode

mode 决定同步异步

Render 阶段

performSyncWorkOnRoot 函数

核心逻辑在 renderRootSync 函数中

renderRootSync 函数

核心方法有俩个 prepareFreshStackworkLoopSync 函数

renderRootSync 逻辑

prepareFreshStack 函数

主要是有个方法 createWorkInProgress , 用来构建 workInProgress 双缓冲树,通过 alternate 相互指向

createWorkInProgress 构建 work-in-progress 树

当建立好双缓冲树的关系后,我们不难得到以下的关系图

双缓冲树关系图

workLoopSync 函数

当我们构建完 workInProgress Tree 的根节点时,建立 current tree 和 workInProgess Tree 的关联关系后,将进入 workLoopSync 调和阶段。

反复判断 workInProgress 是否为空,如果不为空,就执行 performUnitOfWork 方法 workLoopSync 逻辑

performUnitOfWork 函数

performUnitOfWork 函数的作用是 beginWork 优先创建子节点。 completeUnitOfWork 创建完子节点后判断是否有兄弟节点,有则创建兄弟节点,无则继续向上遍历父节点,直到遍历到根节点为止

performUnitOfWork 逻辑

beginWork 函数

参考文档

1 https://zhuanlan.zhihu.com/p/385319664 2

',58),q=[P];function F(S,y,W,v,w,x){return r(),o("div",null,q)}const U=e(R,[["render",F]]);export{C as __pageData,U as default}; +import{_ as e,o as r,c as o,Q as t}from"./chunks/framework.b6910bb2.js";const a="/vitePress-blob/assets/3.9b1f9060.png",i="/vitePress-blob/assets/4.f4dd49d0.png",n="/vitePress-blob/assets/5.34ee565e.png",s="/vitePress-blob/assets/12.ba19c2aa.png",c="/vitePress-blob/assets/6.121ea6f5.png",l="/vitePress-blob/assets/7.3f678f52.png",p="/vitePress-blob/assets/8.9d04f238.png",d="/vitePress-blob/assets/9.bae86652.png",b="/vitePress-blob/assets/11.07a5666c.png",h="/vitePress-blob/assets/13.5bf5bc75.png",m="/vitePress-blob/assets/14.f1d70f78.png",u="/vitePress-blob/assets/16.4d6f740b.png",_="/vitePress-blob/assets/15.254fe341.png",f="/vitePress-blob/assets/18.09fcc54c.png",k="/vitePress-blob/assets/17.625ac807.png",g="/vitePress-blob/assets/19.77c3b0a6.png",C=JSON.parse('{"title":"React 是如何渲染的","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React是如何渲染的.md","filePath":"guide/React/React是如何渲染的.md","lastUpdated":1707358769000}'),R={name:"guide/React/React是如何渲染的.md"},P=t('

React 是如何渲染的

概要

React 的渲染过程可以分成 2 大阶段, 分别是调和阶段和提交阶段。 调和阶段可以分成 beginWork 阶段、 completeWork 阶段。 在 beginWork 阶段中,React 会根据新生成的 ReactElement 对象和旧的 Fiber 节点进行对比,判断是否可以复用旧的 Fiber 节点并对 Fiber 进行标记。 在 completeWork 节点中,会自底向上构建副作用链表,用来记录需要更新的节点,生成的 DOM 节点会挂载在 Fiber 的 stateNode 属性上。

提交阶段主要分成:操作 DOM 前阶段、操作 DOM 阶段、操作 DOM 后阶段。

React 16 以前

在浏览器中 js 线程与渲染线程是互斥的,如果 js 线程长期占用着浏览器的主线程,那么界面将长时间不更新,在动画等一些场景下会造成卡顿效果。

因为 Stack Reconciler 是一个同步的递归过程,随着业务复杂度增加,Stack Reconciler 需要的调和时间会变长,

这意味着 js 将长时间占用浏览器,进而导致页面卡顿

Stack Reconciler

React 16 以后

将同步执行的 Stack Reconciler 替换成了异步可中断的 Fiber Reconciler

Fiber Reconciler

在更新时,每个任务会被赋予一个优先级,当任务抵达调度器时,高优先级的任务会更快抵达协调器,如有新的更高优先级的任务进入调度器时,当前协调器的任务就会被中断,更高优先级的任务将进入 reconciler

Fiber Reconciler

新的架构会导致部分生命周期重复执行:

  • componentWillMount
  • componentWillUpdate
  • showComponentUpdate
  • componentWillReceiveProps

Render Performance

从首次渲染的调用栈来看,React 的渲染过程主要分为以下几个步骤:

    1. Mount 阶段
    1. Render 阶段
    1. Commit 阶段

Mount 阶段

当执行 ReactDOM.render 时会直接调用 legacyRenderSubtreeIntoContainer 方法

legacyRenderSubtreeIntoContainer 方法

会创建 reactRootContainer 对象(也就是挂载的容器对象), reactRootContainer 对象的 _internalRoot 会指向 fiberRoot (FiberRootNode 类),也就是根节点对象。

legacyRenderSubtreeIntoContainer 最终返回挂载组件( App组件 )的实例对象。

Mount 渲染过程

FiberRootNode对象的描述

在 fiberRoot 对象( FiberRootNode类 )中的 current 属性将指向 rootFiber 对象 (根节点Fiber,即 FiberNode 实例)

fiberRoot对象指向 rootFiber 根节点Fiber

挂载创建关系图

updateContainer 函数

updateContainer 函数主要有以下 3 件事:

    1. 获取当前节点的优先级 lane
    1. 结合 lane 创建当前 Fiber 节点 update 对象,并将其入队
    1. 调度当前节点 (rootFiber 节点)

updateContainer

scheduleUpdateOnFiber 函数

scheduleUpdateOnFiber 函数中会获取 Fiber 节点的mode属性判断是否走同步渲染还是异步渲染的逻辑,在 React17 中首次渲染走的是同步渲染的逻辑

scheduleUpdateOnFiber

这里可能有小伙伴会问,Fiber架构不就是异步渲染的么? 我想说的是,Fiber架构的设计初衷确实是为了异步渲染而设计的,但是 Fiber 架构并不能和异步渲染画上等号,我们不难发现,Fiber 架构同时兼容了同步渲染和异步渲染,如下图,决定同步还是异步取决于 mode

mode 决定同步异步

Render 阶段

performSyncWorkOnRoot 函数

核心逻辑在 renderRootSync 函数中

renderRootSync 函数

核心方法有俩个 prepareFreshStackworkLoopSync 函数

renderRootSync 逻辑

prepareFreshStack 函数

主要是有个方法 createWorkInProgress , 用来构建 workInProgress 双缓冲树,通过 alternate 相互指向

createWorkInProgress 构建 work-in-progress 树

当建立好双缓冲树的关系后,我们不难得到以下的关系图

双缓冲树关系图

workLoopSync 函数

当我们构建完 workInProgress Tree 的根节点时,建立 current tree 和 workInProgess Tree 的关联关系后,将进入 workLoopSync 调和阶段。

反复判断 workInProgress 是否为空,如果不为空,就执行 performUnitOfWork 方法 workLoopSync 逻辑

performUnitOfWork 函数

performUnitOfWork 函数的作用是 beginWork 优先创建子节点。 completeUnitOfWork 创建完子节点后判断是否有兄弟节点,有则创建兄弟节点,无则继续向上遍历父节点,直到遍历到根节点为止

performUnitOfWork 逻辑

beginWork 函数

参考文档

1 https://zhuanlan.zhihu.com/p/385319664 2

',58),q=[P];function F(S,y,W,v,w,x){return r(),o("div",null,q)}const U=e(R,[["render",F]]);export{C as __pageData,U as default}; diff --git "a/assets/guide_React_React\346\230\257\345\246\202\344\275\225\346\270\262\346\237\223\347\232\204.md.3113f4a0.lean.js" "b/assets/guide_React_React\346\230\257\345\246\202\344\275\225\346\270\262\346\237\223\347\232\204.md.b469a419.lean.js" similarity index 94% rename from "assets/guide_React_React\346\230\257\345\246\202\344\275\225\346\270\262\346\237\223\347\232\204.md.3113f4a0.lean.js" rename to "assets/guide_React_React\346\230\257\345\246\202\344\275\225\346\270\262\346\237\223\347\232\204.md.b469a419.lean.js" index 63b0fcd1..54bf9b99 100644 --- "a/assets/guide_React_React\346\230\257\345\246\202\344\275\225\346\270\262\346\237\223\347\232\204.md.3113f4a0.lean.js" +++ "b/assets/guide_React_React\346\230\257\345\246\202\344\275\225\346\270\262\346\237\223\347\232\204.md.b469a419.lean.js" @@ -1 +1 @@ -import{_ as e,o as r,c as o,Q as t}from"./chunks/framework.b6910bb2.js";const a="/vitePress-blob/assets/3.9b1f9060.png",i="/vitePress-blob/assets/4.f4dd49d0.png",n="/vitePress-blob/assets/5.34ee565e.png",s="/vitePress-blob/assets/12.ba19c2aa.png",c="/vitePress-blob/assets/6.121ea6f5.png",l="/vitePress-blob/assets/7.3f678f52.png",p="/vitePress-blob/assets/8.9d04f238.png",d="/vitePress-blob/assets/9.bae86652.png",b="/vitePress-blob/assets/11.07a5666c.png",h="/vitePress-blob/assets/13.5bf5bc75.png",m="/vitePress-blob/assets/14.f1d70f78.png",u="/vitePress-blob/assets/16.4d6f740b.png",_="/vitePress-blob/assets/15.254fe341.png",f="/vitePress-blob/assets/18.09fcc54c.png",k="/vitePress-blob/assets/17.625ac807.png",g="/vitePress-blob/assets/19.77c3b0a6.png",C=JSON.parse('{"title":"React 是如何渲染的","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React是如何渲染的.md","filePath":"guide/React/React是如何渲染的.md","lastUpdated":1707358495000}'),R={name:"guide/React/React是如何渲染的.md"},P=t("",58),q=[P];function F(S,y,W,v,w,x){return r(),o("div",null,q)}const U=e(R,[["render",F]]);export{C as __pageData,U as default}; +import{_ as e,o as r,c as o,Q as t}from"./chunks/framework.b6910bb2.js";const a="/vitePress-blob/assets/3.9b1f9060.png",i="/vitePress-blob/assets/4.f4dd49d0.png",n="/vitePress-blob/assets/5.34ee565e.png",s="/vitePress-blob/assets/12.ba19c2aa.png",c="/vitePress-blob/assets/6.121ea6f5.png",l="/vitePress-blob/assets/7.3f678f52.png",p="/vitePress-blob/assets/8.9d04f238.png",d="/vitePress-blob/assets/9.bae86652.png",b="/vitePress-blob/assets/11.07a5666c.png",h="/vitePress-blob/assets/13.5bf5bc75.png",m="/vitePress-blob/assets/14.f1d70f78.png",u="/vitePress-blob/assets/16.4d6f740b.png",_="/vitePress-blob/assets/15.254fe341.png",f="/vitePress-blob/assets/18.09fcc54c.png",k="/vitePress-blob/assets/17.625ac807.png",g="/vitePress-blob/assets/19.77c3b0a6.png",C=JSON.parse('{"title":"React 是如何渲染的","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React是如何渲染的.md","filePath":"guide/React/React是如何渲染的.md","lastUpdated":1707358769000}'),R={name:"guide/React/React是如何渲染的.md"},P=t("",58),q=[P];function F(S,y,W,v,w,x){return r(),o("div",null,q)}const U=e(R,[["render",F]]);export{C as __pageData,U as default}; diff --git "a/assets/guide_React_React\347\273\204\344\273\266\346\230\257\345\246\202\344\275\225\351\200\232\344\277\241\347\232\204.md.20eef01c.js" "b/assets/guide_React_React\347\273\204\344\273\266\346\230\257\345\246\202\344\275\225\351\200\232\344\277\241\347\232\204.md.72c5ac4e.js" similarity index 91% rename from "assets/guide_React_React\347\273\204\344\273\266\346\230\257\345\246\202\344\275\225\351\200\232\344\277\241\347\232\204.md.20eef01c.js" rename to "assets/guide_React_React\347\273\204\344\273\266\346\230\257\345\246\202\344\275\225\351\200\232\344\277\241\347\232\204.md.72c5ac4e.js" index 64bbab20..6a5bfafd 100644 --- "a/assets/guide_React_React\347\273\204\344\273\266\346\230\257\345\246\202\344\275\225\351\200\232\344\277\241\347\232\204.md.20eef01c.js" +++ "b/assets/guide_React_React\347\273\204\344\273\266\346\230\257\345\246\202\344\275\225\351\200\232\344\277\241\347\232\204.md.72c5ac4e.js" @@ -1 +1 @@ -import{_ as a,o as t,c,k as e,a as r}from"./chunks/framework.b6910bb2.js";const f=JSON.parse('{"title":"React 组件是如何通信的","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React组件是如何通信的.md","filePath":"guide/React/React组件是如何通信的.md","lastUpdated":1707358495000}'),s={name:"guide/React/React组件是如何通信的.md"},o=e("h1",{id:"react-组件是如何通信的",tabindex:"-1"},[r("React 组件是如何通信的 "),e("a",{class:"header-anchor",href:"#react-组件是如何通信的","aria-label":'Permalink to "React 组件是如何通信的"'},"​")],-1),_=[o];function d(n,i,l,p,h,m){return t(),c("div",null,_)}const u=a(s,[["render",d]]);export{f as __pageData,u as default}; +import{_ as a,o as t,c,k as e,a as r}from"./chunks/framework.b6910bb2.js";const f=JSON.parse('{"title":"React 组件是如何通信的","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React组件是如何通信的.md","filePath":"guide/React/React组件是如何通信的.md","lastUpdated":1707358769000}'),s={name:"guide/React/React组件是如何通信的.md"},o=e("h1",{id:"react-组件是如何通信的",tabindex:"-1"},[r("React 组件是如何通信的 "),e("a",{class:"header-anchor",href:"#react-组件是如何通信的","aria-label":'Permalink to "React 组件是如何通信的"'},"​")],-1),_=[o];function d(n,i,l,p,h,m){return t(),c("div",null,_)}const u=a(s,[["render",d]]);export{f as __pageData,u as default}; diff --git "a/assets/guide_React_React\347\273\204\344\273\266\346\230\257\345\246\202\344\275\225\351\200\232\344\277\241\347\232\204.md.20eef01c.lean.js" "b/assets/guide_React_React\347\273\204\344\273\266\346\230\257\345\246\202\344\275\225\351\200\232\344\277\241\347\232\204.md.72c5ac4e.lean.js" similarity index 91% rename from "assets/guide_React_React\347\273\204\344\273\266\346\230\257\345\246\202\344\275\225\351\200\232\344\277\241\347\232\204.md.20eef01c.lean.js" rename to "assets/guide_React_React\347\273\204\344\273\266\346\230\257\345\246\202\344\275\225\351\200\232\344\277\241\347\232\204.md.72c5ac4e.lean.js" index 64bbab20..6a5bfafd 100644 --- "a/assets/guide_React_React\347\273\204\344\273\266\346\230\257\345\246\202\344\275\225\351\200\232\344\277\241\347\232\204.md.20eef01c.lean.js" +++ "b/assets/guide_React_React\347\273\204\344\273\266\346\230\257\345\246\202\344\275\225\351\200\232\344\277\241\347\232\204.md.72c5ac4e.lean.js" @@ -1 +1 @@ -import{_ as a,o as t,c,k as e,a as r}from"./chunks/framework.b6910bb2.js";const f=JSON.parse('{"title":"React 组件是如何通信的","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React组件是如何通信的.md","filePath":"guide/React/React组件是如何通信的.md","lastUpdated":1707358495000}'),s={name:"guide/React/React组件是如何通信的.md"},o=e("h1",{id:"react-组件是如何通信的",tabindex:"-1"},[r("React 组件是如何通信的 "),e("a",{class:"header-anchor",href:"#react-组件是如何通信的","aria-label":'Permalink to "React 组件是如何通信的"'},"​")],-1),_=[o];function d(n,i,l,p,h,m){return t(),c("div",null,_)}const u=a(s,[["render",d]]);export{f as __pageData,u as default}; +import{_ as a,o as t,c,k as e,a as r}from"./chunks/framework.b6910bb2.js";const f=JSON.parse('{"title":"React 组件是如何通信的","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/React组件是如何通信的.md","filePath":"guide/React/React组件是如何通信的.md","lastUpdated":1707358769000}'),s={name:"guide/React/React组件是如何通信的.md"},o=e("h1",{id:"react-组件是如何通信的",tabindex:"-1"},[r("React 组件是如何通信的 "),e("a",{class:"header-anchor",href:"#react-组件是如何通信的","aria-label":'Permalink to "React 组件是如何通信的"'},"​")],-1),_=[o];function d(n,i,l,p,h,m){return t(),c("div",null,_)}const u=a(s,[["render",d]]);export{f as __pageData,u as default}; diff --git "a/assets/guide_React_diff\347\256\227\346\263\225.md.e7fed7ec.js" "b/assets/guide_React_diff\347\256\227\346\263\225.md.926d46b2.js" similarity index 98% rename from "assets/guide_React_diff\347\256\227\346\263\225.md.e7fed7ec.js" rename to "assets/guide_React_diff\347\256\227\346\263\225.md.926d46b2.js" index fe5aaf90..c1f3e6a9 100644 --- "a/assets/guide_React_diff\347\256\227\346\263\225.md.e7fed7ec.js" +++ "b/assets/guide_React_diff\347\256\227\346\263\225.md.926d46b2.js" @@ -1 +1 @@ -import{_ as e,o as a,c as t,Q as i}from"./chunks/framework.b6910bb2.js";const k=JSON.parse('{"title":"React 中的 Diff 算法","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/diff算法.md","filePath":"guide/React/diff算法.md","lastUpdated":1707358495000}'),d={name:"guide/React/diff算法.md"},r=i('

React 中的 Diff 算法

概要

React Diff 算法主要分单节点和多节点 Diff 算法 在单节点 Diff 算法中,会对比 key 和 tag 是否可以复用 如果 key 和 tag 都相同时,复用当前的 Fiber 节点,标记其他 Fiber 节点为删除 如果 key 不相同,标记删除当前的 Fiber 节点,对比下一个节点 如果 key 相同、tag 不同,则标记删除所有 Fiber 节点,生成新的 Fiber 节点

在多节点 Diff 中,有俩个 for 循环,第一个 for 循环判断可以复用的节点,记录最后可复用节点的 lastIndex 位置

通过 Map 建立节点和下标的对应关系,如果新节点的key可以在 Map 中找到,则复用旧节点,并判断新节点下标和 lastIndex 下标的关系, 如果新节点下标 > lastIndex 下标,说明只需要更新节点,不需要移动位置,更新 lastIndex。 如果新节点下标 < lastIndex,说明需要更新移动位置,不需要更新 lastIndex。

单节点diff算法 (render方法创建的element元素子节点只有一个)

1. 旧节点不存在

  1. 如果旧节点不存在,则直接新增节点

2. 旧节点存在

1 判断 key 和 tag 是否相同,相同则复用节点,更新属性 2 如果 key 相同但 tag 不相同,则删除所有节点 3 如果 key、tag 不同,则不需要复用,旧节点标记为删除

多节点diff算法 (render方法创建的element元素子节点有多个)

多节点diff有俩次 for 循环, 第一次 for 循环判断元素是否需要更新,第二次 for 循环判断元素是否需要移动位置

1 第一次 for 循环比较key和tag, 如果相同则复用, 并用 lastIndex 标记当前可以复用的节点位置

2 遇到不相同时, 跳出第一层 for 循环, 创建一个 Map 对象, 存储旧节点的 key 和 index

  • key不同导致不可复用,立即跳出整个遍历,第一轮遍历结束
  • key 相同 type 不同导致不可复用,会将 oldFiber 标记为 DELETION,并继续遍历

3 在 Map 对象中查找新节点的 key, 如果存在, 则说明新节点可以复用旧节点, 并且判断是否需要移动位置

4 如果 index > lastIndex, 则不需要移动位置, 更新 lastIndex

5 如果 index < lastIndex, 则需要移动位置, 不需要更新 lastIndex

',18),n=[r];function l(o,f,s,h,x,c){return a(),t("div",null,n)}const p=e(d,[["render",l]]);export{k as __pageData,p as default}; +import{_ as e,o as a,c as t,Q as i}from"./chunks/framework.b6910bb2.js";const k=JSON.parse('{"title":"React 中的 Diff 算法","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/diff算法.md","filePath":"guide/React/diff算法.md","lastUpdated":1707358769000}'),d={name:"guide/React/diff算法.md"},r=i('

React 中的 Diff 算法

概要

React Diff 算法主要分单节点和多节点 Diff 算法 在单节点 Diff 算法中,会对比 key 和 tag 是否可以复用 如果 key 和 tag 都相同时,复用当前的 Fiber 节点,标记其他 Fiber 节点为删除 如果 key 不相同,标记删除当前的 Fiber 节点,对比下一个节点 如果 key 相同、tag 不同,则标记删除所有 Fiber 节点,生成新的 Fiber 节点

在多节点 Diff 中,有俩个 for 循环,第一个 for 循环判断可以复用的节点,记录最后可复用节点的 lastIndex 位置

通过 Map 建立节点和下标的对应关系,如果新节点的key可以在 Map 中找到,则复用旧节点,并判断新节点下标和 lastIndex 下标的关系, 如果新节点下标 > lastIndex 下标,说明只需要更新节点,不需要移动位置,更新 lastIndex。 如果新节点下标 < lastIndex,说明需要更新移动位置,不需要更新 lastIndex。

单节点diff算法 (render方法创建的element元素子节点只有一个)

1. 旧节点不存在

  1. 如果旧节点不存在,则直接新增节点

2. 旧节点存在

1 判断 key 和 tag 是否相同,相同则复用节点,更新属性 2 如果 key 相同但 tag 不相同,则删除所有节点 3 如果 key、tag 不同,则不需要复用,旧节点标记为删除

多节点diff算法 (render方法创建的element元素子节点有多个)

多节点diff有俩次 for 循环, 第一次 for 循环判断元素是否需要更新,第二次 for 循环判断元素是否需要移动位置

1 第一次 for 循环比较key和tag, 如果相同则复用, 并用 lastIndex 标记当前可以复用的节点位置

2 遇到不相同时, 跳出第一层 for 循环, 创建一个 Map 对象, 存储旧节点的 key 和 index

  • key不同导致不可复用,立即跳出整个遍历,第一轮遍历结束
  • key 相同 type 不同导致不可复用,会将 oldFiber 标记为 DELETION,并继续遍历

3 在 Map 对象中查找新节点的 key, 如果存在, 则说明新节点可以复用旧节点, 并且判断是否需要移动位置

4 如果 index > lastIndex, 则不需要移动位置, 更新 lastIndex

5 如果 index < lastIndex, 则需要移动位置, 不需要更新 lastIndex

',18),n=[r];function l(o,f,s,h,x,c){return a(),t("div",null,n)}const p=e(d,[["render",l]]);export{k as __pageData,p as default}; diff --git "a/assets/guide_React_diff\347\256\227\346\263\225.md.e7fed7ec.lean.js" "b/assets/guide_React_diff\347\256\227\346\263\225.md.926d46b2.lean.js" similarity index 86% rename from "assets/guide_React_diff\347\256\227\346\263\225.md.e7fed7ec.lean.js" rename to "assets/guide_React_diff\347\256\227\346\263\225.md.926d46b2.lean.js" index 94738ff0..251d5373 100644 --- "a/assets/guide_React_diff\347\256\227\346\263\225.md.e7fed7ec.lean.js" +++ "b/assets/guide_React_diff\347\256\227\346\263\225.md.926d46b2.lean.js" @@ -1 +1 @@ -import{_ as e,o as a,c as t,Q as i}from"./chunks/framework.b6910bb2.js";const k=JSON.parse('{"title":"React 中的 Diff 算法","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/diff算法.md","filePath":"guide/React/diff算法.md","lastUpdated":1707358495000}'),d={name:"guide/React/diff算法.md"},r=i("",18),n=[r];function l(o,f,s,h,x,c){return a(),t("div",null,n)}const p=e(d,[["render",l]]);export{k as __pageData,p as default}; +import{_ as e,o as a,c as t,Q as i}from"./chunks/framework.b6910bb2.js";const k=JSON.parse('{"title":"React 中的 Diff 算法","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/diff算法.md","filePath":"guide/React/diff算法.md","lastUpdated":1707358769000}'),d={name:"guide/React/diff算法.md"},r=i("",18),n=[r];function l(o,f,s,h,x,c){return a(),t("div",null,n)}const p=e(d,[["render",l]]);export{k as __pageData,p as default}; diff --git "a/assets/guide_React_react\345\274\202\345\270\270\346\234\272\345\210\266.md.b97e740a.js" "b/assets/guide_React_react\345\274\202\345\270\270\346\234\272\345\210\266.md.6a032df0.js" similarity index 84% rename from "assets/guide_React_react\345\274\202\345\270\270\346\234\272\345\210\266.md.b97e740a.js" rename to "assets/guide_React_react\345\274\202\345\270\270\346\234\272\345\210\266.md.6a032df0.js" index fcdd03ba..9a6f29a6 100644 --- "a/assets/guide_React_react\345\274\202\345\270\270\346\234\272\345\210\266.md.b97e740a.js" +++ "b/assets/guide_React_react\345\274\202\345\270\270\346\234\272\345\210\266.md.6a032df0.js" @@ -1 +1 @@ -import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/react异常机制.md","filePath":"guide/React/react异常机制.md","lastUpdated":1707358495000}'),c={name:"guide/React/react异常机制.md"};function r(o,s,d,n,_,i){return t(),a("div")}const f=e(c,[["render",r]]);export{m as __pageData,f as default}; +import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/react异常机制.md","filePath":"guide/React/react异常机制.md","lastUpdated":1707358769000}'),c={name:"guide/React/react异常机制.md"};function r(o,s,d,n,_,i){return t(),a("div")}const f=e(c,[["render",r]]);export{m as __pageData,f as default}; diff --git "a/assets/guide_React_react\345\274\202\345\270\270\346\234\272\345\210\266.md.b97e740a.lean.js" "b/assets/guide_React_react\345\274\202\345\270\270\346\234\272\345\210\266.md.6a032df0.lean.js" similarity index 84% rename from "assets/guide_React_react\345\274\202\345\270\270\346\234\272\345\210\266.md.b97e740a.lean.js" rename to "assets/guide_React_react\345\274\202\345\270\270\346\234\272\345\210\266.md.6a032df0.lean.js" index fcdd03ba..9a6f29a6 100644 --- "a/assets/guide_React_react\345\274\202\345\270\270\346\234\272\345\210\266.md.b97e740a.lean.js" +++ "b/assets/guide_React_react\345\274\202\345\270\270\346\234\272\345\210\266.md.6a032df0.lean.js" @@ -1 +1 @@ -import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/react异常机制.md","filePath":"guide/React/react异常机制.md","lastUpdated":1707358495000}'),c={name:"guide/React/react异常机制.md"};function r(o,s,d,n,_,i){return t(),a("div")}const f=e(c,[["render",r]]);export{m as __pageData,f as default}; +import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/react异常机制.md","filePath":"guide/React/react异常机制.md","lastUpdated":1707358769000}'),c={name:"guide/React/react异常机制.md"};function r(o,s,d,n,_,i){return t(),a("div")}const f=e(c,[["render",r]]);export{m as __pageData,f as default}; diff --git "a/assets/guide_React_setState\346\230\257\345\220\214\346\255\245\350\277\230\346\230\257\345\274\202\346\255\245\347\232\204.md.181019e4.js" "b/assets/guide_React_setState\346\230\257\345\220\214\346\255\245\350\277\230\346\230\257\345\274\202\346\255\245\347\232\204.md.89186477.js" similarity index 99% rename from "assets/guide_React_setState\346\230\257\345\220\214\346\255\245\350\277\230\346\230\257\345\274\202\346\255\245\347\232\204.md.181019e4.js" rename to "assets/guide_React_setState\346\230\257\345\220\214\346\255\245\350\277\230\346\230\257\345\274\202\346\255\245\347\232\204.md.89186477.js" index 79f58ad6..fb19e9fc 100644 --- "a/assets/guide_React_setState\346\230\257\345\220\214\346\255\245\350\277\230\346\230\257\345\274\202\346\255\245\347\232\204.md.181019e4.js" +++ "b/assets/guide_React_setState\346\230\257\345\220\214\346\255\245\350\277\230\346\230\257\345\274\202\346\255\245\347\232\204.md.89186477.js" @@ -1,4 +1,4 @@ -import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/1.5e4dabab.png",h=JSON.parse('{"title":"setState 是同步还是异步的?","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/setState是同步还是异步的.md","filePath":"guide/React/setState是同步还是异步的.md","lastUpdated":1707358495000}'),o={name:"guide/React/setState是同步还是异步的.md"},e=l('

setState 是同步还是异步的?

概要

setState 用于状态变更,触发组件的重新渲染,更新视图。

在 React 18 以前,setState 同步还是异步取决于是否处于 isBatchUpdates 字段,true 的话就是异步,否则就是同步

在 React 18 版本所有的 setState 都是异步批量操作

setState

js
// React 15
+import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/1.5e4dabab.png",h=JSON.parse('{"title":"setState 是同步还是异步的?","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/setState是同步还是异步的.md","filePath":"guide/React/setState是同步还是异步的.md","lastUpdated":1707358769000}'),o={name:"guide/React/setState是同步还是异步的.md"},e=l('

setState 是同步还是异步的?

概要

setState 用于状态变更,触发组件的重新渲染,更新视图。

在 React 18 以前,setState 同步还是异步取决于是否处于 isBatchUpdates 字段,true 的话就是异步,否则就是同步

在 React 18 版本所有的 setState 都是异步批量操作

setState

js
// React 15
 function enqueueUpdate (component) {
   // isBatchingUpdates 判断当前是否处理批量更新操作
   if (!batchingStrategy.isBatchingUpdates) { // 锁管理器
diff --git "a/assets/guide_React_setState\346\230\257\345\220\214\346\255\245\350\277\230\346\230\257\345\274\202\346\255\245\347\232\204.md.181019e4.lean.js" "b/assets/guide_React_setState\346\230\257\345\220\214\346\255\245\350\277\230\346\230\257\345\274\202\346\255\245\347\232\204.md.89186477.lean.js"
similarity index 88%
rename from "assets/guide_React_setState\346\230\257\345\220\214\346\255\245\350\277\230\346\230\257\345\274\202\346\255\245\347\232\204.md.181019e4.lean.js"
rename to "assets/guide_React_setState\346\230\257\345\220\214\346\255\245\350\277\230\346\230\257\345\274\202\346\255\245\347\232\204.md.89186477.lean.js"
index 0bcfd34b..732b8f64 100644
--- "a/assets/guide_React_setState\346\230\257\345\220\214\346\255\245\350\277\230\346\230\257\345\274\202\346\255\245\347\232\204.md.181019e4.lean.js"
+++ "b/assets/guide_React_setState\346\230\257\345\220\214\346\255\245\350\277\230\346\230\257\345\274\202\346\255\245\347\232\204.md.89186477.lean.js"
@@ -1 +1 @@
-import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/1.5e4dabab.png",h=JSON.parse('{"title":"setState 是同步还是异步的?","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/setState是同步还是异步的.md","filePath":"guide/React/setState是同步还是异步的.md","lastUpdated":1707358495000}'),o={name:"guide/React/setState是同步还是异步的.md"},e=l("",35),t=[e];function c(r,E,y,i,F,d){return n(),a("div",null,t)}const C=s(o,[["render",c]]);export{h as __pageData,C as default};
+import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/1.5e4dabab.png",h=JSON.parse('{"title":"setState 是同步还是异步的?","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/setState是同步还是异步的.md","filePath":"guide/React/setState是同步还是异步的.md","lastUpdated":1707358769000}'),o={name:"guide/React/setState是同步还是异步的.md"},e=l("",35),t=[e];function c(r,E,y,i,F,d){return n(),a("div",null,t)}const C=s(o,[["render",c]]);export{h as __pageData,C as default};
diff --git "a/assets/guide_React_\344\273\200\344\271\210\346\230\257Fiber.md.3ee10b32.js" "b/assets/guide_React_\344\273\200\344\271\210\346\230\257Fiber.md.ec244869.js"
similarity index 96%
rename from "assets/guide_React_\344\273\200\344\271\210\346\230\257Fiber.md.3ee10b32.js"
rename to "assets/guide_React_\344\273\200\344\271\210\346\230\257Fiber.md.ec244869.js"
index 40441435..ef783bd0 100644
--- "a/assets/guide_React_\344\273\200\344\271\210\346\230\257Fiber.md.3ee10b32.js"
+++ "b/assets/guide_React_\344\273\200\344\271\210\346\230\257Fiber.md.ec244869.js"
@@ -1 +1 @@
-import{_ as e,o as i,c as r,Q as a}from"./chunks/framework.b6910bb2.js";const t="/vitePress-blob/assets/10.44b174be.png",F=JSON.parse('{"title":"什么是 Fiber","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/什么是Fiber.md","filePath":"guide/React/什么是Fiber.md","lastUpdated":1707358495000}'),l={name:"guide/React/什么是Fiber.md"},o=a('

什么是 Fiber

Fiber 是什么

  • 从计算机领域来看: Fiber 是比线程还要纤细的一个过程, 也就是所谓的 “纤程”

  • 从架构角度上看: Fiber是对 React 核心算法的重写,将 React16以前的 Stack Reconciler 替换成了异步可中断的 Fiber Reconciler

  • 从编码的角度上看: Fiber 是 React 内部定义的数据结构,每一个节点都是一个 FiberNode 对象,用来存储组件的各种状态

  • 从工作流的角度上看: Fiber 节点保存了组件需要更新的状态和副作用, 便于更新与复用

Fiber 架构应用的目的是为了实现任务可中断、可恢复、并赋予任务优先级,从而实现时间切片,让出主线程,让主线程有时间去处理其他任务,从而提升用户体验。

Fiber 之间的关系图

  • 通过 child 可以获取子节点
  • 通过 sibling 可以获取兄弟节点
  • 通过 return 可以获取父节点

Fiber 之间的关系图

',7),c=[o];function s(b,n,_,d,p,h){return i(),r("div",null,c)}const f=e(l,[["render",s]]);export{F as __pageData,f as default}; +import{_ as e,o as i,c as r,Q as a}from"./chunks/framework.b6910bb2.js";const t="/vitePress-blob/assets/10.44b174be.png",F=JSON.parse('{"title":"什么是 Fiber","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/什么是Fiber.md","filePath":"guide/React/什么是Fiber.md","lastUpdated":1707358769000}'),l={name:"guide/React/什么是Fiber.md"},o=a('

什么是 Fiber

Fiber 是什么

  • 从计算机领域来看: Fiber 是比线程还要纤细的一个过程, 也就是所谓的 “纤程”

  • 从架构角度上看: Fiber是对 React 核心算法的重写,将 React16以前的 Stack Reconciler 替换成了异步可中断的 Fiber Reconciler

  • 从编码的角度上看: Fiber 是 React 内部定义的数据结构,每一个节点都是一个 FiberNode 对象,用来存储组件的各种状态

  • 从工作流的角度上看: Fiber 节点保存了组件需要更新的状态和副作用, 便于更新与复用

Fiber 架构应用的目的是为了实现任务可中断、可恢复、并赋予任务优先级,从而实现时间切片,让出主线程,让主线程有时间去处理其他任务,从而提升用户体验。

Fiber 之间的关系图

  • 通过 child 可以获取子节点
  • 通过 sibling 可以获取兄弟节点
  • 通过 return 可以获取父节点

Fiber 之间的关系图

',7),c=[o];function s(b,n,_,d,p,h){return i(),r("div",null,c)}const f=e(l,[["render",s]]);export{F as __pageData,f as default}; diff --git "a/assets/guide_React_\344\273\200\344\271\210\346\230\257Fiber.md.3ee10b32.lean.js" "b/assets/guide_React_\344\273\200\344\271\210\346\230\257Fiber.md.ec244869.lean.js" similarity index 87% rename from "assets/guide_React_\344\273\200\344\271\210\346\230\257Fiber.md.3ee10b32.lean.js" rename to "assets/guide_React_\344\273\200\344\271\210\346\230\257Fiber.md.ec244869.lean.js" index fb4540b2..a6562430 100644 --- "a/assets/guide_React_\344\273\200\344\271\210\346\230\257Fiber.md.3ee10b32.lean.js" +++ "b/assets/guide_React_\344\273\200\344\271\210\346\230\257Fiber.md.ec244869.lean.js" @@ -1 +1 @@ -import{_ as e,o as i,c as r,Q as a}from"./chunks/framework.b6910bb2.js";const t="/vitePress-blob/assets/10.44b174be.png",F=JSON.parse('{"title":"什么是 Fiber","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/什么是Fiber.md","filePath":"guide/React/什么是Fiber.md","lastUpdated":1707358495000}'),l={name:"guide/React/什么是Fiber.md"},o=a("",7),c=[o];function s(b,n,_,d,p,h){return i(),r("div",null,c)}const f=e(l,[["render",s]]);export{F as __pageData,f as default}; +import{_ as e,o as i,c as r,Q as a}from"./chunks/framework.b6910bb2.js";const t="/vitePress-blob/assets/10.44b174be.png",F=JSON.parse('{"title":"什么是 Fiber","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/什么是Fiber.md","filePath":"guide/React/什么是Fiber.md","lastUpdated":1707358769000}'),l={name:"guide/React/什么是Fiber.md"},o=a("",7),c=[o];function s(b,n,_,d,p,h){return i(),r("div",null,c)}const f=e(l,[["render",s]]);export{F as __pageData,f as default}; diff --git "a/assets/guide_React_\345\246\202\344\275\225\350\256\276\350\256\241React\347\273\204\344\273\266.md.d49001fb.js" "b/assets/guide_React_\345\246\202\344\275\225\350\256\276\350\256\241React\347\273\204\344\273\266.md.195ded5e.js" similarity index 95% rename from "assets/guide_React_\345\246\202\344\275\225\350\256\276\350\256\241React\347\273\204\344\273\266.md.d49001fb.js" rename to "assets/guide_React_\345\246\202\344\275\225\350\256\276\350\256\241React\347\273\204\344\273\266.md.195ded5e.js" index 2cd70c17..566ac4a1 100644 --- "a/assets/guide_React_\345\246\202\344\275\225\350\256\276\350\256\241React\347\273\204\344\273\266.md.d49001fb.js" +++ "b/assets/guide_React_\345\246\202\344\275\225\350\256\276\350\256\241React\347\273\204\344\273\266.md.195ded5e.js" @@ -1 +1 @@ -import{_ as a,o as e,c as t,Q as r}from"./chunks/framework.b6910bb2.js";const o="/vitePress-blob/assets/1.df8894ba.png",f=JSON.parse('{"title":"如何设计 React 组件","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/如何设计React组件.md","filePath":"guide/React/如何设计React组件.md","lastUpdated":1707358495000}'),c={name:"guide/React/如何设计React组件.md"},s=r('

如何设计 React 组件

设计分类

  • 展示组件: 只负责 UI 展示,不涉及业务逻辑

  • 业务组件: 复用负责业务逻辑

展示组件

展示组件一般受制于 props, 具有通用性、复用性

业务组件

业务组件一般受制于 state, 具有复用性

组件分类

',8),i=[s];function _(l,n,d,h,p,u){return e(),t("div",null,i)}const b=a(c,[["render",_]]);export{f as __pageData,b as default}; +import{_ as a,o as e,c as t,Q as r}from"./chunks/framework.b6910bb2.js";const o="/vitePress-blob/assets/1.df8894ba.png",f=JSON.parse('{"title":"如何设计 React 组件","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/如何设计React组件.md","filePath":"guide/React/如何设计React组件.md","lastUpdated":1707358769000}'),c={name:"guide/React/如何设计React组件.md"},s=r('

如何设计 React 组件

设计分类

  • 展示组件: 只负责 UI 展示,不涉及业务逻辑

  • 业务组件: 复用负责业务逻辑

展示组件

展示组件一般受制于 props, 具有通用性、复用性

业务组件

业务组件一般受制于 state, 具有复用性

组件分类

',8),i=[s];function _(l,n,d,h,p,u){return e(),t("div",null,i)}const b=a(c,[["render",_]]);export{f as __pageData,b as default}; diff --git "a/assets/guide_React_\345\246\202\344\275\225\350\256\276\350\256\241React\347\273\204\344\273\266.md.d49001fb.lean.js" "b/assets/guide_React_\345\246\202\344\275\225\350\256\276\350\256\241React\347\273\204\344\273\266.md.195ded5e.lean.js" similarity index 88% rename from "assets/guide_React_\345\246\202\344\275\225\350\256\276\350\256\241React\347\273\204\344\273\266.md.d49001fb.lean.js" rename to "assets/guide_React_\345\246\202\344\275\225\350\256\276\350\256\241React\347\273\204\344\273\266.md.195ded5e.lean.js" index ba5845d0..116f22f6 100644 --- "a/assets/guide_React_\345\246\202\344\275\225\350\256\276\350\256\241React\347\273\204\344\273\266.md.d49001fb.lean.js" +++ "b/assets/guide_React_\345\246\202\344\275\225\350\256\276\350\256\241React\347\273\204\344\273\266.md.195ded5e.lean.js" @@ -1 +1 @@ -import{_ as a,o as e,c as t,Q as r}from"./chunks/framework.b6910bb2.js";const o="/vitePress-blob/assets/1.df8894ba.png",f=JSON.parse('{"title":"如何设计 React 组件","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/如何设计React组件.md","filePath":"guide/React/如何设计React组件.md","lastUpdated":1707358495000}'),c={name:"guide/React/如何设计React组件.md"},s=r("",8),i=[s];function _(l,n,d,h,p,u){return e(),t("div",null,i)}const b=a(c,[["render",_]]);export{f as __pageData,b as default}; +import{_ as a,o as e,c as t,Q as r}from"./chunks/framework.b6910bb2.js";const o="/vitePress-blob/assets/1.df8894ba.png",f=JSON.parse('{"title":"如何设计 React 组件","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/如何设计React组件.md","filePath":"guide/React/如何设计React组件.md","lastUpdated":1707358769000}'),c={name:"guide/React/如何设计React组件.md"},s=r("",8),i=[s];function _(l,n,d,h,p,u){return e(),t("div",null,i)}const b=a(c,[["render",_]]);export{f as __pageData,b as default}; diff --git "a/assets/guide_React_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.fc7d945a.js" "b/assets/guide_React_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.4f1f1ac9.js" similarity index 91% rename from "assets/guide_React_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.fc7d945a.js" rename to "assets/guide_React_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.4f1f1ac9.js" index b2e10728..71fce115 100644 --- "a/assets/guide_React_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.fc7d945a.js" +++ "b/assets/guide_React_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.4f1f1ac9.js" @@ -1 +1 @@ -import{_ as a,o as t,c as r,k as e,a as s}from"./chunks/framework.b6910bb2.js";const x=JSON.parse('{"title":"常见的问题","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/常见的问题.md","filePath":"guide/React/常见的问题.md","lastUpdated":1707358495000}'),o={name:"guide/React/常见的问题.md"},c=e("h1",{id:"常见的问题",tabindex:"-1"},[s("常见的问题 "),e("a",{class:"header-anchor",href:"#常见的问题","aria-label":'Permalink to "常见的问题"'},"​")],-1),d=e("h2",{id:"",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#","aria-label":'Permalink to ""'},"​")],-1),n=[c,d];function i(_,l,h,p,m,f){return t(),r("div",null,n)}const k=a(o,[["render",i]]);export{x as __pageData,k as default}; +import{_ as a,o as t,c as r,k as e,a as s}from"./chunks/framework.b6910bb2.js";const x=JSON.parse('{"title":"常见的问题","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/常见的问题.md","filePath":"guide/React/常见的问题.md","lastUpdated":1707358769000}'),o={name:"guide/React/常见的问题.md"},c=e("h1",{id:"常见的问题",tabindex:"-1"},[s("常见的问题 "),e("a",{class:"header-anchor",href:"#常见的问题","aria-label":'Permalink to "常见的问题"'},"​")],-1),d=e("h2",{id:"",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#","aria-label":'Permalink to ""'},"​")],-1),n=[c,d];function i(_,l,h,p,m,f){return t(),r("div",null,n)}const k=a(o,[["render",i]]);export{x as __pageData,k as default}; diff --git "a/assets/guide_React_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.fc7d945a.lean.js" "b/assets/guide_React_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.4f1f1ac9.lean.js" similarity index 91% rename from "assets/guide_React_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.fc7d945a.lean.js" rename to "assets/guide_React_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.4f1f1ac9.lean.js" index b2e10728..71fce115 100644 --- "a/assets/guide_React_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.fc7d945a.lean.js" +++ "b/assets/guide_React_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.4f1f1ac9.lean.js" @@ -1 +1 @@ -import{_ as a,o as t,c as r,k as e,a as s}from"./chunks/framework.b6910bb2.js";const x=JSON.parse('{"title":"常见的问题","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/常见的问题.md","filePath":"guide/React/常见的问题.md","lastUpdated":1707358495000}'),o={name:"guide/React/常见的问题.md"},c=e("h1",{id:"常见的问题",tabindex:"-1"},[s("常见的问题 "),e("a",{class:"header-anchor",href:"#常见的问题","aria-label":'Permalink to "常见的问题"'},"​")],-1),d=e("h2",{id:"",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#","aria-label":'Permalink to ""'},"​")],-1),n=[c,d];function i(_,l,h,p,m,f){return t(),r("div",null,n)}const k=a(o,[["render",i]]);export{x as __pageData,k as default}; +import{_ as a,o as t,c as r,k as e,a as s}from"./chunks/framework.b6910bb2.js";const x=JSON.parse('{"title":"常见的问题","description":"","frontmatter":{},"headers":[],"relativePath":"guide/React/常见的问题.md","filePath":"guide/React/常见的问题.md","lastUpdated":1707358769000}'),o={name:"guide/React/常见的问题.md"},c=e("h1",{id:"常见的问题",tabindex:"-1"},[s("常见的问题 "),e("a",{class:"header-anchor",href:"#常见的问题","aria-label":'Permalink to "常见的问题"'},"​")],-1),d=e("h2",{id:"",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#","aria-label":'Permalink to ""'},"​")],-1),n=[c,d];function i(_,l,h,p,m,f){return t(),r("div",null,n)}const k=a(o,[["render",i]]);export{x as __pageData,k as default}; diff --git "a/assets/guide_Redux_\346\272\220\347\240\201\350\247\243\350\257\273.md.b8a89f65.js" "b/assets/guide_Redux_\346\272\220\347\240\201\350\247\243\350\257\273.md.dc2eca87.js" similarity index 89% rename from "assets/guide_Redux_\346\272\220\347\240\201\350\247\243\350\257\273.md.b8a89f65.js" rename to "assets/guide_Redux_\346\272\220\347\240\201\350\247\243\350\257\273.md.dc2eca87.js" index 5a951e0a..e2c19bc3 100644 --- "a/assets/guide_Redux_\346\272\220\347\240\201\350\247\243\350\257\273.md.b8a89f65.js" +++ "b/assets/guide_Redux_\346\272\220\347\240\201\350\247\243\350\257\273.md.dc2eca87.js" @@ -1 +1 @@ -import{_ as a,o as t,c as s,k as e,a as d}from"./chunks/framework.b6910bb2.js";const f=JSON.parse('{"title":"源码解读","description":"","frontmatter":{},"headers":[],"relativePath":"guide/Redux/源码解读.md","filePath":"guide/Redux/源码解读.md","lastUpdated":1707358495000}'),o={name:"guide/Redux/源码解读.md"},r=e("h1",{id:"源码解读",tabindex:"-1"},[d("源码解读 "),e("a",{class:"header-anchor",href:"#源码解读","aria-label":'Permalink to "源码解读"'},"​")],-1),c=[r];function n(i,_,l,p,u,h){return t(),s("div",null,c)}const x=a(o,[["render",n]]);export{f as __pageData,x as default}; +import{_ as a,o as t,c as s,k as e,a as d}from"./chunks/framework.b6910bb2.js";const f=JSON.parse('{"title":"源码解读","description":"","frontmatter":{},"headers":[],"relativePath":"guide/Redux/源码解读.md","filePath":"guide/Redux/源码解读.md","lastUpdated":1707358769000}'),o={name:"guide/Redux/源码解读.md"},r=e("h1",{id:"源码解读",tabindex:"-1"},[d("源码解读 "),e("a",{class:"header-anchor",href:"#源码解读","aria-label":'Permalink to "源码解读"'},"​")],-1),c=[r];function n(i,_,l,p,u,h){return t(),s("div",null,c)}const x=a(o,[["render",n]]);export{f as __pageData,x as default}; diff --git "a/assets/guide_Redux_\346\272\220\347\240\201\350\247\243\350\257\273.md.b8a89f65.lean.js" "b/assets/guide_Redux_\346\272\220\347\240\201\350\247\243\350\257\273.md.dc2eca87.lean.js" similarity index 89% rename from "assets/guide_Redux_\346\272\220\347\240\201\350\247\243\350\257\273.md.b8a89f65.lean.js" rename to "assets/guide_Redux_\346\272\220\347\240\201\350\247\243\350\257\273.md.dc2eca87.lean.js" index 5a951e0a..e2c19bc3 100644 --- "a/assets/guide_Redux_\346\272\220\347\240\201\350\247\243\350\257\273.md.b8a89f65.lean.js" +++ "b/assets/guide_Redux_\346\272\220\347\240\201\350\247\243\350\257\273.md.dc2eca87.lean.js" @@ -1 +1 @@ -import{_ as a,o as t,c as s,k as e,a as d}from"./chunks/framework.b6910bb2.js";const f=JSON.parse('{"title":"源码解读","description":"","frontmatter":{},"headers":[],"relativePath":"guide/Redux/源码解读.md","filePath":"guide/Redux/源码解读.md","lastUpdated":1707358495000}'),o={name:"guide/Redux/源码解读.md"},r=e("h1",{id:"源码解读",tabindex:"-1"},[d("源码解读 "),e("a",{class:"header-anchor",href:"#源码解读","aria-label":'Permalink to "源码解读"'},"​")],-1),c=[r];function n(i,_,l,p,u,h){return t(),s("div",null,c)}const x=a(o,[["render",n]]);export{f as __pageData,x as default}; +import{_ as a,o as t,c as s,k as e,a as d}from"./chunks/framework.b6910bb2.js";const f=JSON.parse('{"title":"源码解读","description":"","frontmatter":{},"headers":[],"relativePath":"guide/Redux/源码解读.md","filePath":"guide/Redux/源码解读.md","lastUpdated":1707358769000}'),o={name:"guide/Redux/源码解读.md"},r=e("h1",{id:"源码解读",tabindex:"-1"},[d("源码解读 "),e("a",{class:"header-anchor",href:"#源码解读","aria-label":'Permalink to "源码解读"'},"​")],-1),c=[r];function n(i,_,l,p,u,h){return t(),s("div",null,c)}const x=a(o,[["render",n]]);export{f as __pageData,x as default}; diff --git "a/assets/guide_Redux_\350\256\276\350\256\241\347\220\206\345\277\265.md.ec673eba.js" "b/assets/guide_Redux_\350\256\276\350\256\241\347\220\206\345\277\265.md.b1a2b96a.js" similarity index 89% rename from "assets/guide_Redux_\350\256\276\350\256\241\347\220\206\345\277\265.md.ec673eba.js" rename to "assets/guide_Redux_\350\256\276\350\256\241\347\220\206\345\277\265.md.b1a2b96a.js" index d096f4c2..df3405c5 100644 --- "a/assets/guide_Redux_\350\256\276\350\256\241\347\220\206\345\277\265.md.ec673eba.js" +++ "b/assets/guide_Redux_\350\256\276\350\256\241\347\220\206\345\277\265.md.b1a2b96a.js" @@ -1 +1 @@ -import{_ as a,o as t,c as s,k as e,a as d}from"./chunks/framework.b6910bb2.js";const f=JSON.parse('{"title":"设计理念","description":"","frontmatter":{},"headers":[],"relativePath":"guide/Redux/设计理念.md","filePath":"guide/Redux/设计理念.md","lastUpdated":1707358495000}'),o={name:"guide/Redux/设计理念.md"},r=e("h1",{id:"设计理念",tabindex:"-1"},[d("设计理念 "),e("a",{class:"header-anchor",href:"#设计理念","aria-label":'Permalink to "设计理念"'},"​")],-1),c=[r];function n(i,_,l,p,u,h){return t(),s("div",null,c)}const x=a(o,[["render",n]]);export{f as __pageData,x as default}; +import{_ as a,o as t,c as s,k as e,a as d}from"./chunks/framework.b6910bb2.js";const f=JSON.parse('{"title":"设计理念","description":"","frontmatter":{},"headers":[],"relativePath":"guide/Redux/设计理念.md","filePath":"guide/Redux/设计理念.md","lastUpdated":1707358769000}'),o={name:"guide/Redux/设计理念.md"},r=e("h1",{id:"设计理念",tabindex:"-1"},[d("设计理念 "),e("a",{class:"header-anchor",href:"#设计理念","aria-label":'Permalink to "设计理念"'},"​")],-1),c=[r];function n(i,_,l,p,u,h){return t(),s("div",null,c)}const x=a(o,[["render",n]]);export{f as __pageData,x as default}; diff --git "a/assets/guide_Redux_\350\256\276\350\256\241\347\220\206\345\277\265.md.ec673eba.lean.js" "b/assets/guide_Redux_\350\256\276\350\256\241\347\220\206\345\277\265.md.b1a2b96a.lean.js" similarity index 89% rename from "assets/guide_Redux_\350\256\276\350\256\241\347\220\206\345\277\265.md.ec673eba.lean.js" rename to "assets/guide_Redux_\350\256\276\350\256\241\347\220\206\345\277\265.md.b1a2b96a.lean.js" index d096f4c2..df3405c5 100644 --- "a/assets/guide_Redux_\350\256\276\350\256\241\347\220\206\345\277\265.md.ec673eba.lean.js" +++ "b/assets/guide_Redux_\350\256\276\350\256\241\347\220\206\345\277\265.md.b1a2b96a.lean.js" @@ -1 +1 @@ -import{_ as a,o as t,c as s,k as e,a as d}from"./chunks/framework.b6910bb2.js";const f=JSON.parse('{"title":"设计理念","description":"","frontmatter":{},"headers":[],"relativePath":"guide/Redux/设计理念.md","filePath":"guide/Redux/设计理念.md","lastUpdated":1707358495000}'),o={name:"guide/Redux/设计理念.md"},r=e("h1",{id:"设计理念",tabindex:"-1"},[d("设计理念 "),e("a",{class:"header-anchor",href:"#设计理念","aria-label":'Permalink to "设计理念"'},"​")],-1),c=[r];function n(i,_,l,p,u,h){return t(),s("div",null,c)}const x=a(o,[["render",n]]);export{f as __pageData,x as default}; +import{_ as a,o as t,c as s,k as e,a as d}from"./chunks/framework.b6910bb2.js";const f=JSON.parse('{"title":"设计理念","description":"","frontmatter":{},"headers":[],"relativePath":"guide/Redux/设计理念.md","filePath":"guide/Redux/设计理念.md","lastUpdated":1707358769000}'),o={name:"guide/Redux/设计理念.md"},r=e("h1",{id:"设计理念",tabindex:"-1"},[d("设计理念 "),e("a",{class:"header-anchor",href:"#设计理念","aria-label":'Permalink to "设计理念"'},"​")],-1),c=[r];function n(i,_,l,p,u,h){return t(),s("div",null,c)}const x=a(o,[["render",n]]);export{f as __pageData,x as default}; diff --git "a/assets/guide_canvas_Canvas\345\260\272\345\257\270\345\217\212\345\210\206\350\276\250\347\216\207\347\237\253\346\255\243.md.5236c485.js" "b/assets/guide_canvas_Canvas\345\260\272\345\257\270\345\217\212\345\210\206\350\276\250\347\216\207\347\237\253\346\255\243.md.a8665ee4.js" similarity index 99% rename from "assets/guide_canvas_Canvas\345\260\272\345\257\270\345\217\212\345\210\206\350\276\250\347\216\207\347\237\253\346\255\243.md.5236c485.js" rename to "assets/guide_canvas_Canvas\345\260\272\345\257\270\345\217\212\345\210\206\350\276\250\347\216\207\347\237\253\346\255\243.md.a8665ee4.js" index a28f251d..5e2f7695 100644 --- "a/assets/guide_canvas_Canvas\345\260\272\345\257\270\345\217\212\345\210\206\350\276\250\347\216\207\347\237\253\346\255\243.md.5236c485.js" +++ "b/assets/guide_canvas_Canvas\345\260\272\345\257\270\345\217\212\345\210\206\350\276\250\347\216\207\347\237\253\346\255\243.md.a8665ee4.js" @@ -1,4 +1,4 @@ -import{_ as s,o as a,c as n,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/1.15edf814.png",o="/vitePress-blob/assets/2.19007fd9.png",t="/vitePress-blob/assets/3.59bb2b90.png",v=JSON.parse('{"title":"Canvas 尺寸与分辨率矫正","description":"","frontmatter":{},"headers":[],"relativePath":"guide/canvas/Canvas尺寸及分辨率矫正.md","filePath":"guide/canvas/Canvas尺寸及分辨率矫正.md","lastUpdated":1707358495000}'),e={name:"guide/canvas/Canvas尺寸及分辨率矫正.md"},c=l(`

Canvas 尺寸与分辨率矫正

前言

Canvas 的默认大小为 300 像素 ×150 像素(宽 × 高,像素的单位是 px)

html
<canvas id="tutorial" width="150" height="150"></canvas>
<canvas id="tutorial" width="150" height="150"></canvas>

canvas 看起来和 img 元素很相像,唯一的不同就是它并没有 src 和 alt 属性。实际上,canvas 标签只有两个属性: width 和 height。

正文

设置画布的 css 大小

canvas 可以使用CSS来定义大小,但在绘制时图像会伸缩以适应它的框架尺寸:如果 CSS 的尺寸与初始画布的比例不一致,它会出现扭曲。

假设一个场景,当我们给 canvas 设置了 css 的宽高 500px * 500px, 但是我们在 canvas 中绘制的图形是 100px * 100px, 那么最终的图形会被拉伸,如下图所示:

html
<canvas id="test-canvas"></canvas>
+import{_ as s,o as a,c as n,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/1.15edf814.png",o="/vitePress-blob/assets/2.19007fd9.png",t="/vitePress-blob/assets/3.59bb2b90.png",v=JSON.parse('{"title":"Canvas 尺寸与分辨率矫正","description":"","frontmatter":{},"headers":[],"relativePath":"guide/canvas/Canvas尺寸及分辨率矫正.md","filePath":"guide/canvas/Canvas尺寸及分辨率矫正.md","lastUpdated":1707358769000}'),e={name:"guide/canvas/Canvas尺寸及分辨率矫正.md"},c=l(`

Canvas 尺寸与分辨率矫正

前言

Canvas 的默认大小为 300 像素 ×150 像素(宽 × 高,像素的单位是 px)

html
<canvas id="tutorial" width="150" height="150"></canvas>
<canvas id="tutorial" width="150" height="150"></canvas>

canvas 看起来和 img 元素很相像,唯一的不同就是它并没有 src 和 alt 属性。实际上,canvas 标签只有两个属性: width 和 height。

正文

设置画布的 css 大小

canvas 可以使用CSS来定义大小,但在绘制时图像会伸缩以适应它的框架尺寸:如果 CSS 的尺寸与初始画布的比例不一致,它会出现扭曲。

假设一个场景,当我们给 canvas 设置了 css 的宽高 500px * 500px, 但是我们在 canvas 中绘制的图形是 100px * 100px, 那么最终的图形会被拉伸,如下图所示:

html
<canvas id="test-canvas"></canvas>
 <script>
     const canvas = document.getElementById('test-canvas');
     const ctx = canvas.getContext('2d');
diff --git "a/assets/guide_canvas_Canvas\345\260\272\345\257\270\345\217\212\345\210\206\350\276\250\347\216\207\347\237\253\346\255\243.md.5236c485.lean.js" "b/assets/guide_canvas_Canvas\345\260\272\345\257\270\345\217\212\345\210\206\350\276\250\347\216\207\347\237\253\346\255\243.md.a8665ee4.lean.js"
similarity index 90%
rename from "assets/guide_canvas_Canvas\345\260\272\345\257\270\345\217\212\345\210\206\350\276\250\347\216\207\347\237\253\346\255\243.md.5236c485.lean.js"
rename to "assets/guide_canvas_Canvas\345\260\272\345\257\270\345\217\212\345\210\206\350\276\250\347\216\207\347\237\253\346\255\243.md.a8665ee4.lean.js"
index dab789d2..a6641aeb 100644
--- "a/assets/guide_canvas_Canvas\345\260\272\345\257\270\345\217\212\345\210\206\350\276\250\347\216\207\347\237\253\346\255\243.md.5236c485.lean.js"
+++ "b/assets/guide_canvas_Canvas\345\260\272\345\257\270\345\217\212\345\210\206\350\276\250\347\216\207\347\237\253\346\255\243.md.a8665ee4.lean.js"
@@ -1 +1 @@
-import{_ as s,o as a,c as n,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/1.15edf814.png",o="/vitePress-blob/assets/2.19007fd9.png",t="/vitePress-blob/assets/3.59bb2b90.png",v=JSON.parse('{"title":"Canvas 尺寸与分辨率矫正","description":"","frontmatter":{},"headers":[],"relativePath":"guide/canvas/Canvas尺寸及分辨率矫正.md","filePath":"guide/canvas/Canvas尺寸及分辨率矫正.md","lastUpdated":1707358495000}'),e={name:"guide/canvas/Canvas尺寸及分辨率矫正.md"},c=l("",29),r=[c];function E(y,i,F,d,h,C){return a(),n("div",null,r)}const u=s(e,[["render",E]]);export{v as __pageData,u as default};
+import{_ as s,o as a,c as n,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/1.15edf814.png",o="/vitePress-blob/assets/2.19007fd9.png",t="/vitePress-blob/assets/3.59bb2b90.png",v=JSON.parse('{"title":"Canvas 尺寸与分辨率矫正","description":"","frontmatter":{},"headers":[],"relativePath":"guide/canvas/Canvas尺寸及分辨率矫正.md","filePath":"guide/canvas/Canvas尺寸及分辨率矫正.md","lastUpdated":1707358769000}'),e={name:"guide/canvas/Canvas尺寸及分辨率矫正.md"},c=l("",29),r=[c];function E(y,i,F,d,h,C){return a(),n("div",null,r)}const u=s(e,[["render",E]]);export{v as __pageData,u as default};
diff --git "a/assets/guide_canvas_\345\217\257\350\247\206\345\214\272\345\237\237\345\206\205\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.3686d5ec.js" "b/assets/guide_canvas_\345\217\257\350\247\206\345\214\272\345\237\237\345\206\205\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.419e5315.js"
similarity index 99%
rename from "assets/guide_canvas_\345\217\257\350\247\206\345\214\272\345\237\237\345\206\205\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.3686d5ec.js"
rename to "assets/guide_canvas_\345\217\257\350\247\206\345\214\272\345\237\237\345\206\205\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.419e5315.js"
index 7942b7d8..7a145492 100644
--- "a/assets/guide_canvas_\345\217\257\350\247\206\345\214\272\345\237\237\345\206\205\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.3686d5ec.js"
+++ "b/assets/guide_canvas_\345\217\257\350\247\206\345\214\272\345\237\237\345\206\205\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.419e5315.js"
@@ -1,4 +1,4 @@
-import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/13.ebfa1a54.png",o="/vitePress-blob/assets/14.92ddec45.png",e="/vitePress-blob/assets/15.3e4e2641.gif",t="/vitePress-blob/assets/17.75314470.png",c="/vitePress-blob/assets/18.34b0479f.gif",D=JSON.parse('{"title":"可视区域内渲染提高 Canvas 的书写性能","description":"","frontmatter":{},"headers":[],"relativePath":"guide/canvas/可视区域内渲染提高Canvas书写性能.md","filePath":"guide/canvas/可视区域内渲染提高Canvas书写性能.md","lastUpdated":1707358495000}'),r={name:"guide/canvas/可视区域内渲染提高Canvas书写性能.md"},E=l('

可视区域内渲染提高 Canvas 的书写性能

前言

上一节我们通过离屏渲染提高了 Canvas 的渲染性能,但是离屏渲染也有一些缺点,比如会增加内存的使用,而且在某些场景下,离屏渲染的性能并不会比直接在 Canvas 上绘制要高。本节我们将介绍如何通过可视区域内渲染提高 Canvas 的书写性能。

前提

一般我们说的可视区域内渲染,是指在 Canvas 上只绘制可视区域内的内容,而不是绘制整个 Canvas 的内容。这样做的好处是可以减少 Canvas 的绘制区域,从而提高 Canvas 的渲染性能。

对于 Canvas 而言,无法无限制地扩大 Canvas 的面积,因此浏览器对 Canvas 的大小也有一定的限制。从 MDN 文档 可知, 在 Chrome 浏览器中,Canvas 的大小限制为 32767px * 32767px。由于 Canvas 的大小限制,因此我们在实现 无限画布 的功能时,不能无限拓展 Canvas 的大小,可以通过坐标的切换,来实现无限画布的功能。

实现无限画布

实现思路

记初始坐标A (x, y), 横向滚动距离为 scrollX, 纵向滚动距离为 scrollY

在初始状态下, scrollX、scrollY 均为 0

初始状态图

假设现在,我们在水平方向向右滚动了scrollX,垂直方向向下滚动scrollY。那么滚动后的坐标就是

x1 = x - scrollX

y1 = y - scrollY

这里大家可能会有疑惑,为什么是减法呢?因为向下滚动后,绘制的图形应该是往上移动的,因此我们需要减去滚动的距离。

滚动后的状态图

在代码中,我们可以通过监听 Canvas 的 WheelEvent 事件,来获取滚动的距离,然后根据上面的公式计算出滚动后的坐标,最后重新绘制 Canvas。

具体实现如下

jsx
ctx.clearRect(0, 0, window.innerWidth, window.innerHeight);
+import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/13.ebfa1a54.png",o="/vitePress-blob/assets/14.92ddec45.png",e="/vitePress-blob/assets/15.3e4e2641.gif",t="/vitePress-blob/assets/17.75314470.png",c="/vitePress-blob/assets/18.34b0479f.gif",D=JSON.parse('{"title":"可视区域内渲染提高 Canvas 的书写性能","description":"","frontmatter":{},"headers":[],"relativePath":"guide/canvas/可视区域内渲染提高Canvas书写性能.md","filePath":"guide/canvas/可视区域内渲染提高Canvas书写性能.md","lastUpdated":1707358769000}'),r={name:"guide/canvas/可视区域内渲染提高Canvas书写性能.md"},E=l('

可视区域内渲染提高 Canvas 的书写性能

前言

上一节我们通过离屏渲染提高了 Canvas 的渲染性能,但是离屏渲染也有一些缺点,比如会增加内存的使用,而且在某些场景下,离屏渲染的性能并不会比直接在 Canvas 上绘制要高。本节我们将介绍如何通过可视区域内渲染提高 Canvas 的书写性能。

前提

一般我们说的可视区域内渲染,是指在 Canvas 上只绘制可视区域内的内容,而不是绘制整个 Canvas 的内容。这样做的好处是可以减少 Canvas 的绘制区域,从而提高 Canvas 的渲染性能。

对于 Canvas 而言,无法无限制地扩大 Canvas 的面积,因此浏览器对 Canvas 的大小也有一定的限制。从 MDN 文档 可知, 在 Chrome 浏览器中,Canvas 的大小限制为 32767px * 32767px。由于 Canvas 的大小限制,因此我们在实现 无限画布 的功能时,不能无限拓展 Canvas 的大小,可以通过坐标的切换,来实现无限画布的功能。

实现无限画布

实现思路

记初始坐标A (x, y), 横向滚动距离为 scrollX, 纵向滚动距离为 scrollY

在初始状态下, scrollX、scrollY 均为 0

初始状态图

假设现在,我们在水平方向向右滚动了scrollX,垂直方向向下滚动scrollY。那么滚动后的坐标就是

x1 = x - scrollX

y1 = y - scrollY

这里大家可能会有疑惑,为什么是减法呢?因为向下滚动后,绘制的图形应该是往上移动的,因此我们需要减去滚动的距离。

滚动后的状态图

在代码中,我们可以通过监听 Canvas 的 WheelEvent 事件,来获取滚动的距离,然后根据上面的公式计算出滚动后的坐标,最后重新绘制 Canvas。

具体实现如下

jsx
ctx.clearRect(0, 0, window.innerWidth, window.innerHeight);
 ctx.save();
 ctx.translate(scrollX, scrollY);
 // 绘制相关的逻辑
diff --git "a/assets/guide_canvas_\345\217\257\350\247\206\345\214\272\345\237\237\345\206\205\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.3686d5ec.lean.js" "b/assets/guide_canvas_\345\217\257\350\247\206\345\214\272\345\237\237\345\206\205\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.419e5315.lean.js"
similarity index 92%
rename from "assets/guide_canvas_\345\217\257\350\247\206\345\214\272\345\237\237\345\206\205\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.3686d5ec.lean.js"
rename to "assets/guide_canvas_\345\217\257\350\247\206\345\214\272\345\237\237\345\206\205\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.419e5315.lean.js"
index b2b7fbc6..7d74290b 100644
--- "a/assets/guide_canvas_\345\217\257\350\247\206\345\214\272\345\237\237\345\206\205\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.3686d5ec.lean.js"
+++ "b/assets/guide_canvas_\345\217\257\350\247\206\345\214\272\345\237\237\345\206\205\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.419e5315.lean.js"
@@ -1 +1 @@
-import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/13.ebfa1a54.png",o="/vitePress-blob/assets/14.92ddec45.png",e="/vitePress-blob/assets/15.3e4e2641.gif",t="/vitePress-blob/assets/17.75314470.png",c="/vitePress-blob/assets/18.34b0479f.gif",D=JSON.parse('{"title":"可视区域内渲染提高 Canvas 的书写性能","description":"","frontmatter":{},"headers":[],"relativePath":"guide/canvas/可视区域内渲染提高Canvas书写性能.md","filePath":"guide/canvas/可视区域内渲染提高Canvas书写性能.md","lastUpdated":1707358495000}'),r={name:"guide/canvas/可视区域内渲染提高Canvas书写性能.md"},E=l("",46),y=[E];function i(F,d,m,h,C,A){return n(),a("div",null,y)}const x=s(r,[["render",i]]);export{D as __pageData,x as default};
+import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/13.ebfa1a54.png",o="/vitePress-blob/assets/14.92ddec45.png",e="/vitePress-blob/assets/15.3e4e2641.gif",t="/vitePress-blob/assets/17.75314470.png",c="/vitePress-blob/assets/18.34b0479f.gif",D=JSON.parse('{"title":"可视区域内渲染提高 Canvas 的书写性能","description":"","frontmatter":{},"headers":[],"relativePath":"guide/canvas/可视区域内渲染提高Canvas书写性能.md","filePath":"guide/canvas/可视区域内渲染提高Canvas书写性能.md","lastUpdated":1707358769000}'),r={name:"guide/canvas/可视区域内渲染提高Canvas书写性能.md"},E=l("",46),y=[E];function i(F,d,m,h,C,A){return n(),a("div",null,y)}const x=s(r,[["render",i]]);export{D as __pageData,x as default};
diff --git "a/assets/guide_canvas_\345\246\202\344\275\225\345\234\250Canvas\347\224\273\346\235\277\344\270\212\350\207\252\347\224\261\344\271\246\345\206\231.md.984beaeb.js" "b/assets/guide_canvas_\345\246\202\344\275\225\345\234\250Canvas\347\224\273\346\235\277\344\270\212\350\207\252\347\224\261\344\271\246\345\206\231.md.b9949f49.js"
similarity index 99%
rename from "assets/guide_canvas_\345\246\202\344\275\225\345\234\250Canvas\347\224\273\346\235\277\344\270\212\350\207\252\347\224\261\344\271\246\345\206\231.md.984beaeb.js"
rename to "assets/guide_canvas_\345\246\202\344\275\225\345\234\250Canvas\347\224\273\346\235\277\344\270\212\350\207\252\347\224\261\344\271\246\345\206\231.md.b9949f49.js"
index fc4913f6..6b8f3fc7 100644
--- "a/assets/guide_canvas_\345\246\202\344\275\225\345\234\250Canvas\347\224\273\346\235\277\344\270\212\350\207\252\347\224\261\344\271\246\345\206\231.md.984beaeb.js"
+++ "b/assets/guide_canvas_\345\246\202\344\275\225\345\234\250Canvas\347\224\273\346\235\277\344\270\212\350\207\252\347\224\261\344\271\246\345\206\231.md.b9949f49.js"
@@ -1,4 +1,4 @@
-import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/4.6c4ce0eb.gif",o="/vitePress-blob/assets/6.bb9fb817.png",e="/vitePress-blob/assets/5.016fbc65.png",t="/vitePress-blob/assets/7.2b4ce5bb.gif",h=JSON.parse('{"title":"如何实现一个自由绘制的 Canvas 画板","description":"","frontmatter":{},"headers":[],"relativePath":"guide/canvas/如何在Canvas画板上自由书写.md","filePath":"guide/canvas/如何在Canvas画板上自由书写.md","lastUpdated":1707358495000}'),c={name:"guide/canvas/如何在Canvas画板上自由书写.md"},r=l(`

如何实现一个自由绘制的 Canvas 画板

前言

承接上文,当我们了解了如何去设置一个 Canvas 尺寸,并通过分辨率对 Canvas 进行矫正后,我们就可以开始实现一个自由绘制的 Canvas 画板了。

正文

实现思路

自由画笔的实现可以通过:

    1. 监听鼠标事件
    1. 将鼠标移动的点记录下来
    1. 将这些点连成线,就可以实现自由画笔了。

实现代码

html
<!DOCTYPE html>
+import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/4.6c4ce0eb.gif",o="/vitePress-blob/assets/6.bb9fb817.png",e="/vitePress-blob/assets/5.016fbc65.png",t="/vitePress-blob/assets/7.2b4ce5bb.gif",h=JSON.parse('{"title":"如何实现一个自由绘制的 Canvas 画板","description":"","frontmatter":{},"headers":[],"relativePath":"guide/canvas/如何在Canvas画板上自由书写.md","filePath":"guide/canvas/如何在Canvas画板上自由书写.md","lastUpdated":1707358769000}'),c={name:"guide/canvas/如何在Canvas画板上自由书写.md"},r=l(`

如何实现一个自由绘制的 Canvas 画板

前言

承接上文,当我们了解了如何去设置一个 Canvas 尺寸,并通过分辨率对 Canvas 进行矫正后,我们就可以开始实现一个自由绘制的 Canvas 画板了。

正文

实现思路

自由画笔的实现可以通过:

    1. 监听鼠标事件
    1. 将鼠标移动的点记录下来
    1. 将这些点连成线,就可以实现自由画笔了。

实现代码

html
<!DOCTYPE html>
 <html lang="en">
 
 <head>
diff --git "a/assets/guide_canvas_\345\246\202\344\275\225\345\234\250Canvas\347\224\273\346\235\277\344\270\212\350\207\252\347\224\261\344\271\246\345\206\231.md.984beaeb.lean.js" "b/assets/guide_canvas_\345\246\202\344\275\225\345\234\250Canvas\347\224\273\346\235\277\344\270\212\350\207\252\347\224\261\344\271\246\345\206\231.md.b9949f49.lean.js"
similarity index 91%
rename from "assets/guide_canvas_\345\246\202\344\275\225\345\234\250Canvas\347\224\273\346\235\277\344\270\212\350\207\252\347\224\261\344\271\246\345\206\231.md.984beaeb.lean.js"
rename to "assets/guide_canvas_\345\246\202\344\275\225\345\234\250Canvas\347\224\273\346\235\277\344\270\212\350\207\252\347\224\261\344\271\246\345\206\231.md.b9949f49.lean.js"
index 7d4fada2..78bc6704 100644
--- "a/assets/guide_canvas_\345\246\202\344\275\225\345\234\250Canvas\347\224\273\346\235\277\344\270\212\350\207\252\347\224\261\344\271\246\345\206\231.md.984beaeb.lean.js"
+++ "b/assets/guide_canvas_\345\246\202\344\275\225\345\234\250Canvas\347\224\273\346\235\277\344\270\212\350\207\252\347\224\261\344\271\246\345\206\231.md.b9949f49.lean.js"
@@ -1 +1 @@
-import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/4.6c4ce0eb.gif",o="/vitePress-blob/assets/6.bb9fb817.png",e="/vitePress-blob/assets/5.016fbc65.png",t="/vitePress-blob/assets/7.2b4ce5bb.gif",h=JSON.parse('{"title":"如何实现一个自由绘制的 Canvas 画板","description":"","frontmatter":{},"headers":[],"relativePath":"guide/canvas/如何在Canvas画板上自由书写.md","filePath":"guide/canvas/如何在Canvas画板上自由书写.md","lastUpdated":1707358495000}'),c={name:"guide/canvas/如何在Canvas画板上自由书写.md"},r=l("",23),E=[r];function y(i,F,C,A,D,d){return n(),a("div",null,E)}const B=s(c,[["render",y]]);export{h as __pageData,B as default};
+import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/4.6c4ce0eb.gif",o="/vitePress-blob/assets/6.bb9fb817.png",e="/vitePress-blob/assets/5.016fbc65.png",t="/vitePress-blob/assets/7.2b4ce5bb.gif",h=JSON.parse('{"title":"如何实现一个自由绘制的 Canvas 画板","description":"","frontmatter":{},"headers":[],"relativePath":"guide/canvas/如何在Canvas画板上自由书写.md","filePath":"guide/canvas/如何在Canvas画板上自由书写.md","lastUpdated":1707358769000}'),c={name:"guide/canvas/如何在Canvas画板上自由书写.md"},r=l("",23),E=[r];function y(i,F,C,A,D,d){return n(),a("div",null,E)}const B=s(c,[["render",y]]);export{h as __pageData,B as default};
diff --git "a/assets/guide_canvas_\351\200\232\350\277\207 OffscreenCanvas _ Worker \346\217\220\351\253\230\344\271\246\345\206\231\346\200\247\350\203\275.md.18a4aa5f.js" "b/assets/guide_canvas_\351\200\232\350\277\207 OffscreenCanvas _ Worker \346\217\220\351\253\230\344\271\246\345\206\231\346\200\247\350\203\275.md.10b7092a.js"
similarity index 99%
rename from "assets/guide_canvas_\351\200\232\350\277\207 OffscreenCanvas _ Worker \346\217\220\351\253\230\344\271\246\345\206\231\346\200\247\350\203\275.md.18a4aa5f.js"
rename to "assets/guide_canvas_\351\200\232\350\277\207 OffscreenCanvas _ Worker \346\217\220\351\253\230\344\271\246\345\206\231\346\200\247\350\203\275.md.10b7092a.js"
index 4cab11ef..89b5bbf0 100644
--- "a/assets/guide_canvas_\351\200\232\350\277\207 OffscreenCanvas _ Worker \346\217\220\351\253\230\344\271\246\345\206\231\346\200\247\350\203\275.md.18a4aa5f.js"	
+++ "b/assets/guide_canvas_\351\200\232\350\277\207 OffscreenCanvas _ Worker \346\217\220\351\253\230\344\271\246\345\206\231\346\200\247\350\203\275.md.10b7092a.js"	
@@ -1,4 +1,4 @@
-import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/19.ad6d5c6e.gif",h=JSON.parse('{"title":"通过 OffscreenCanvas + Worker 提高书写性能","description":"","frontmatter":{},"headers":[],"relativePath":"guide/canvas/通过 OffscreenCanvas + Worker 提高书写性能.md","filePath":"guide/canvas/通过 OffscreenCanvas + Worker 提高书写性能.md","lastUpdated":1707358495000}'),o={name:"guide/canvas/通过 OffscreenCanvas + Worker 提高书写性能.md"},e=l(`

通过 OffscreenCanvas + Worker 提高书写性能

前言

上一节我们通过离屏渲染提高了 Canvas 的渲染性能,但是在绘制的过程中,我们会发现,当绘制的图形越来越多时,Canvas 的渲染性能会越来越差,这是因为我们在绘制图形会阻塞主线程,如果主线程中还有其他的任务也会表现出卡顿的效果,Canvas 的渲染性能越来越差。

这节我们将通过 OffscreenCanvas + Worker 将绘制图形的任务放到 Worker 中进行,避免阻塞主线程,从而提高 Canvas 的渲染性能。

实现思路

在 worker 线程中是无法操作 DOM 的,但 OffscreenCanvas 可以在 worker 线程中进行操作,因此我们可以通过 OffscreenCanvas 将绘制图形的任务放到 worker 线程中进行。这样可以减少主线程的任务,从而提高书写性能。

具体实现

创建 OffscreenCanvas

js
const canvas = document.getElementById('draw');
+import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/19.ad6d5c6e.gif",h=JSON.parse('{"title":"通过 OffscreenCanvas + Worker 提高书写性能","description":"","frontmatter":{},"headers":[],"relativePath":"guide/canvas/通过 OffscreenCanvas + Worker 提高书写性能.md","filePath":"guide/canvas/通过 OffscreenCanvas + Worker 提高书写性能.md","lastUpdated":1707358769000}'),o={name:"guide/canvas/通过 OffscreenCanvas + Worker 提高书写性能.md"},e=l(`

通过 OffscreenCanvas + Worker 提高书写性能

前言

上一节我们通过离屏渲染提高了 Canvas 的渲染性能,但是在绘制的过程中,我们会发现,当绘制的图形越来越多时,Canvas 的渲染性能会越来越差,这是因为我们在绘制图形会阻塞主线程,如果主线程中还有其他的任务也会表现出卡顿的效果,Canvas 的渲染性能越来越差。

这节我们将通过 OffscreenCanvas + Worker 将绘制图形的任务放到 Worker 中进行,避免阻塞主线程,从而提高 Canvas 的渲染性能。

实现思路

在 worker 线程中是无法操作 DOM 的,但 OffscreenCanvas 可以在 worker 线程中进行操作,因此我们可以通过 OffscreenCanvas 将绘制图形的任务放到 worker 线程中进行。这样可以减少主线程的任务,从而提高书写性能。

具体实现

创建 OffscreenCanvas

js
const canvas = document.getElementById('draw');
 const offScreenCanvas = canvas.transferControlToOffscreen(); // 将 canvas 转换为 offScreenCanvas
const canvas = document.getElementById('draw');
 const offScreenCanvas = canvas.transferControlToOffscreen(); // 将 canvas 转换为 offScreenCanvas

将 offScreenCanvas 传递给 worker 线程

js
const worker = new Worker('./worker.js'); // 创建一个 webWorker
 const offScreenCanvas = canvas.transferControlToOffscreen(); // 将 canvas 转换为 offScreenCanvas
diff --git "a/assets/guide_canvas_\351\200\232\350\277\207 OffscreenCanvas _ Worker \346\217\220\351\253\230\344\271\246\345\206\231\346\200\247\350\203\275.md.18a4aa5f.lean.js" "b/assets/guide_canvas_\351\200\232\350\277\207 OffscreenCanvas _ Worker \346\217\220\351\253\230\344\271\246\345\206\231\346\200\247\350\203\275.md.10b7092a.lean.js"
similarity index 90%
rename from "assets/guide_canvas_\351\200\232\350\277\207 OffscreenCanvas _ Worker \346\217\220\351\253\230\344\271\246\345\206\231\346\200\247\350\203\275.md.18a4aa5f.lean.js"
rename to "assets/guide_canvas_\351\200\232\350\277\207 OffscreenCanvas _ Worker \346\217\220\351\253\230\344\271\246\345\206\231\346\200\247\350\203\275.md.10b7092a.lean.js"
index 71b9538c..7c414edb 100644
--- "a/assets/guide_canvas_\351\200\232\350\277\207 OffscreenCanvas _ Worker \346\217\220\351\253\230\344\271\246\345\206\231\346\200\247\350\203\275.md.18a4aa5f.lean.js"	
+++ "b/assets/guide_canvas_\351\200\232\350\277\207 OffscreenCanvas _ Worker \346\217\220\351\253\230\344\271\246\345\206\231\346\200\247\350\203\275.md.10b7092a.lean.js"	
@@ -1 +1 @@
-import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/19.ad6d5c6e.gif",h=JSON.parse('{"title":"通过 OffscreenCanvas + Worker 提高书写性能","description":"","frontmatter":{},"headers":[],"relativePath":"guide/canvas/通过 OffscreenCanvas + Worker 提高书写性能.md","filePath":"guide/canvas/通过 OffscreenCanvas + Worker 提高书写性能.md","lastUpdated":1707358495000}'),o={name:"guide/canvas/通过 OffscreenCanvas + Worker 提高书写性能.md"},e=l("",18),r=[e];function c(t,E,y,i,d,f){return n(),a("div",null,r)}const v=s(o,[["render",c]]);export{h as __pageData,v as default};
+import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/19.ad6d5c6e.gif",h=JSON.parse('{"title":"通过 OffscreenCanvas + Worker 提高书写性能","description":"","frontmatter":{},"headers":[],"relativePath":"guide/canvas/通过 OffscreenCanvas + Worker 提高书写性能.md","filePath":"guide/canvas/通过 OffscreenCanvas + Worker 提高书写性能.md","lastUpdated":1707358769000}'),o={name:"guide/canvas/通过 OffscreenCanvas + Worker 提高书写性能.md"},e=l("",18),r=[e];function c(t,E,y,i,d,f){return n(),a("div",null,r)}const v=s(o,[["render",c]]);export{h as __pageData,v as default};
diff --git "a/assets/guide_canvas_\351\200\232\350\277\207\344\270\212\344\270\213\345\210\206\345\261\202\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.ef016078.js" "b/assets/guide_canvas_\351\200\232\350\277\207\344\270\212\344\270\213\345\210\206\345\261\202\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.2eca7891.js"
similarity index 99%
rename from "assets/guide_canvas_\351\200\232\350\277\207\344\270\212\344\270\213\345\210\206\345\261\202\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.ef016078.js"
rename to "assets/guide_canvas_\351\200\232\350\277\207\344\270\212\344\270\213\345\210\206\345\261\202\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.2eca7891.js"
index ff5a7ed9..81031139 100644
--- "a/assets/guide_canvas_\351\200\232\350\277\207\344\270\212\344\270\213\345\210\206\345\261\202\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.ef016078.js"
+++ "b/assets/guide_canvas_\351\200\232\350\277\207\344\270\212\344\270\213\345\210\206\345\261\202\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.2eca7891.js"
@@ -1,4 +1,4 @@
-import{_ as s,o as a,c as n,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/10.57bb4969.gif",o="/vitePress-blob/assets/11.298d6f19.gif",h=JSON.parse('{"title":"通过上下分层优化 Canvas 书写性能","description":"","frontmatter":{},"headers":[],"relativePath":"guide/canvas/通过上下分层优化Canvas书写性能.md","filePath":"guide/canvas/通过上下分层优化Canvas书写性能.md","lastUpdated":1707358495000}'),e={name:"guide/canvas/通过上下分层优化Canvas书写性能.md"},t=l(`

通过上下分层优化 Canvas 书写性能

前言

上一节,我们通过点稀疏的方式,优化了 Canvas 的绘制性能。但在书写的过程中,因为点的数量减少导致书写的效果不够理想,因此通过贝塞尔曲线的方式,将点连接起来,形成平滑的曲线,从而达到书写的效果。 这节,我们将通过上下分层的方式,优化 Canvas 的书写性能。

基本思路

这里我将 Canvas 分为上下两层,上层称之为动态层,下层称之为静态层,动态层用于书写,静态层用于显示书写的效果。当书写的时候,将书写的点绘制到上层,当书写完成后,将上层的内容绘制到下层,然后清空上层的内容,这样就可以达到书写的效果。

因为 Canvas 每次渲染都会将整个 Canvas 清空,所以我们需要将静态层的内容保存下来,然后在每次书写的时候,只需要渲染当前动态层的内容即可。

实现

创建 2 个 Canvas

首先创建 2 个 Canvas, 上层 Canvas 用于书写, 书写完成后将上层 Canvas 的内容绘制到下层 Canvas 中, 然后清空上层 Canvas 的内容, 这样就可以达到书写的效果。

这样的好处在于, 每次书写的时候, 只需要渲染上层 Canvas 的书写内容即可, 不需要每次都渲染整个 Canvas, 从而达到优化性能的目的。

html
<style>
+import{_ as s,o as a,c as n,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/10.57bb4969.gif",o="/vitePress-blob/assets/11.298d6f19.gif",h=JSON.parse('{"title":"通过上下分层优化 Canvas 书写性能","description":"","frontmatter":{},"headers":[],"relativePath":"guide/canvas/通过上下分层优化Canvas书写性能.md","filePath":"guide/canvas/通过上下分层优化Canvas书写性能.md","lastUpdated":1707358769000}'),e={name:"guide/canvas/通过上下分层优化Canvas书写性能.md"},t=l(`

通过上下分层优化 Canvas 书写性能

前言

上一节,我们通过点稀疏的方式,优化了 Canvas 的绘制性能。但在书写的过程中,因为点的数量减少导致书写的效果不够理想,因此通过贝塞尔曲线的方式,将点连接起来,形成平滑的曲线,从而达到书写的效果。 这节,我们将通过上下分层的方式,优化 Canvas 的书写性能。

基本思路

这里我将 Canvas 分为上下两层,上层称之为动态层,下层称之为静态层,动态层用于书写,静态层用于显示书写的效果。当书写的时候,将书写的点绘制到上层,当书写完成后,将上层的内容绘制到下层,然后清空上层的内容,这样就可以达到书写的效果。

因为 Canvas 每次渲染都会将整个 Canvas 清空,所以我们需要将静态层的内容保存下来,然后在每次书写的时候,只需要渲染当前动态层的内容即可。

实现

创建 2 个 Canvas

首先创建 2 个 Canvas, 上层 Canvas 用于书写, 书写完成后将上层 Canvas 的内容绘制到下层 Canvas 中, 然后清空上层 Canvas 的内容, 这样就可以达到书写的效果。

这样的好处在于, 每次书写的时候, 只需要渲染上层 Canvas 的书写内容即可, 不需要每次都渲染整个 Canvas, 从而达到优化性能的目的。

html
<style>
     #draw {
         border: 1px solid black;
         position: absolute;
diff --git "a/assets/guide_canvas_\351\200\232\350\277\207\344\270\212\344\270\213\345\210\206\345\261\202\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.ef016078.lean.js" "b/assets/guide_canvas_\351\200\232\350\277\207\344\270\212\344\270\213\345\210\206\345\261\202\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.2eca7891.lean.js"
similarity index 90%
rename from "assets/guide_canvas_\351\200\232\350\277\207\344\270\212\344\270\213\345\210\206\345\261\202\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.ef016078.lean.js"
rename to "assets/guide_canvas_\351\200\232\350\277\207\344\270\212\344\270\213\345\210\206\345\261\202\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.2eca7891.lean.js"
index bce6b62b..4e9f5f85 100644
--- "a/assets/guide_canvas_\351\200\232\350\277\207\344\270\212\344\270\213\345\210\206\345\261\202\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.ef016078.lean.js"
+++ "b/assets/guide_canvas_\351\200\232\350\277\207\344\270\212\344\270\213\345\210\206\345\261\202\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.2eca7891.lean.js"
@@ -1 +1 @@
-import{_ as s,o as a,c as n,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/10.57bb4969.gif",o="/vitePress-blob/assets/11.298d6f19.gif",h=JSON.parse('{"title":"通过上下分层优化 Canvas 书写性能","description":"","frontmatter":{},"headers":[],"relativePath":"guide/canvas/通过上下分层优化Canvas书写性能.md","filePath":"guide/canvas/通过上下分层优化Canvas书写性能.md","lastUpdated":1707358495000}'),e={name:"guide/canvas/通过上下分层优化Canvas书写性能.md"},t=l("",22),c=[t];function r(E,y,i,d,C,v){return a(),n("div",null,c)}const u=s(e,[["render",r]]);export{h as __pageData,u as default};
+import{_ as s,o as a,c as n,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/10.57bb4969.gif",o="/vitePress-blob/assets/11.298d6f19.gif",h=JSON.parse('{"title":"通过上下分层优化 Canvas 书写性能","description":"","frontmatter":{},"headers":[],"relativePath":"guide/canvas/通过上下分层优化Canvas书写性能.md","filePath":"guide/canvas/通过上下分层优化Canvas书写性能.md","lastUpdated":1707358769000}'),e={name:"guide/canvas/通过上下分层优化Canvas书写性能.md"},t=l("",22),c=[t];function r(E,y,i,d,C,v){return a(),n("div",null,c)}const u=s(e,[["render",r]]);export{h as __pageData,u as default};
diff --git "a/assets/guide_canvas_\351\200\232\350\277\207\347\246\273\345\261\217\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.c3dc05ff.js" "b/assets/guide_canvas_\351\200\232\350\277\207\347\246\273\345\261\217\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.af60bf99.js"
similarity index 99%
rename from "assets/guide_canvas_\351\200\232\350\277\207\347\246\273\345\261\217\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.c3dc05ff.js"
rename to "assets/guide_canvas_\351\200\232\350\277\207\347\246\273\345\261\217\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.af60bf99.js"
index 0d1da947..65dea750 100644
--- "a/assets/guide_canvas_\351\200\232\350\277\207\347\246\273\345\261\217\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.c3dc05ff.js"
+++ "b/assets/guide_canvas_\351\200\232\350\277\207\347\246\273\345\261\217\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.af60bf99.js"
@@ -1,4 +1,4 @@
-import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/12.31e4f330.gif",D=JSON.parse('{"title":"通过离屏渲染提高 Canvas 书写性能","description":"","frontmatter":{},"headers":[],"relativePath":"guide/canvas/通过离屏渲染提高Canvas书写性能.md","filePath":"guide/canvas/通过离屏渲染提高Canvas书写性能.md","lastUpdated":1707358495000}'),o={name:"guide/canvas/通过离屏渲染提高Canvas书写性能.md"},e=l(`

通过离屏渲染提高 Canvas 书写性能

前言

前面我们通过上下分层的方式,优化了 Canvas 的书写性能,接下来我们通过离屏渲染的方式,进一步优化 Canvas 的书写性能。

基本思路

在书写的过程中,每绘制一笔都需要不断地调用 Canvas 的 API,重新渲染整个 Canvas,这样就会导致性能的浪费。 而离屏渲染则是将 绘制内容存储到离屏的 Canvas 中,相当于一个缓冲区,然后将需要绘制的画面在离屏的 Canvas 缓冲好,最后将离屏的 Canvas 转化成图片,渲染到屏幕上,这样就可以达到优化性能的目的。

实现

创建离屏 Canvas

思路如下: 基于上一节的基础,我们改写 render 函数,如果是离屏渲染的话,将绘制的内容存储到离屏的 Canvas 中,然后将离屏的 Canvas 缓存起来,下次绘制的时候,如果命中缓存的话,就直接使用缓存的 Canvas,从而达到优化性能的目的。

操作如下:

  • 1 在执行 render 函数之前,先判断是否存在缓存的 Canvas,如果存在的话,就直接使用缓存的 Canvas
  • 2 如果命中缓存,使用离屏 Canvas 转化成图片进行绘制
  • 3 如果不存在缓存的 Canvas,就创建一个离屏的 Canvas,然后将绘制的内容存储到离屏的 Canvas 中,最后将离屏的 Canvas 缓存起来
html
<script>
+import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/12.31e4f330.gif",D=JSON.parse('{"title":"通过离屏渲染提高 Canvas 书写性能","description":"","frontmatter":{},"headers":[],"relativePath":"guide/canvas/通过离屏渲染提高Canvas书写性能.md","filePath":"guide/canvas/通过离屏渲染提高Canvas书写性能.md","lastUpdated":1707358769000}'),o={name:"guide/canvas/通过离屏渲染提高Canvas书写性能.md"},e=l(`

通过离屏渲染提高 Canvas 书写性能

前言

前面我们通过上下分层的方式,优化了 Canvas 的书写性能,接下来我们通过离屏渲染的方式,进一步优化 Canvas 的书写性能。

基本思路

在书写的过程中,每绘制一笔都需要不断地调用 Canvas 的 API,重新渲染整个 Canvas,这样就会导致性能的浪费。 而离屏渲染则是将 绘制内容存储到离屏的 Canvas 中,相当于一个缓冲区,然后将需要绘制的画面在离屏的 Canvas 缓冲好,最后将离屏的 Canvas 转化成图片,渲染到屏幕上,这样就可以达到优化性能的目的。

实现

创建离屏 Canvas

思路如下: 基于上一节的基础,我们改写 render 函数,如果是离屏渲染的话,将绘制的内容存储到离屏的 Canvas 中,然后将离屏的 Canvas 缓存起来,下次绘制的时候,如果命中缓存的话,就直接使用缓存的 Canvas,从而达到优化性能的目的。

操作如下:

  • 1 在执行 render 函数之前,先判断是否存在缓存的 Canvas,如果存在的话,就直接使用缓存的 Canvas
  • 2 如果命中缓存,使用离屏 Canvas 转化成图片进行绘制
  • 3 如果不存在缓存的 Canvas,就创建一个离屏的 Canvas,然后将绘制的内容存储到离屏的 Canvas 中,最后将离屏的 Canvas 缓存起来
html
<script>
         const elementWithCanvasCache = new WeakMap(); // 用于存储离屏 Canvas 的缓存
         const generateOffScreenCanvas = (points) => {
             const padding = 20; // 避免笔记被 Canvas 
diff --git "a/assets/guide_canvas_\351\200\232\350\277\207\347\246\273\345\261\217\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.c3dc05ff.lean.js" "b/assets/guide_canvas_\351\200\232\350\277\207\347\246\273\345\261\217\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.af60bf99.lean.js"
similarity index 89%
rename from "assets/guide_canvas_\351\200\232\350\277\207\347\246\273\345\261\217\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.c3dc05ff.lean.js"
rename to "assets/guide_canvas_\351\200\232\350\277\207\347\246\273\345\261\217\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.af60bf99.lean.js"
index c87910b6..f6355644 100644
--- "a/assets/guide_canvas_\351\200\232\350\277\207\347\246\273\345\261\217\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.c3dc05ff.lean.js"
+++ "b/assets/guide_canvas_\351\200\232\350\277\207\347\246\273\345\261\217\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.af60bf99.lean.js"
@@ -1 +1 @@
-import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/12.31e4f330.gif",D=JSON.parse('{"title":"通过离屏渲染提高 Canvas 书写性能","description":"","frontmatter":{},"headers":[],"relativePath":"guide/canvas/通过离屏渲染提高Canvas书写性能.md","filePath":"guide/canvas/通过离屏渲染提高Canvas书写性能.md","lastUpdated":1707358495000}'),o={name:"guide/canvas/通过离屏渲染提高Canvas书写性能.md"},e=l("",19),t=[e];function c(r,E,y,i,F,C){return n(),a("div",null,t)}const h=s(o,[["render",c]]);export{D as __pageData,h as default};
+import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/12.31e4f330.gif",D=JSON.parse('{"title":"通过离屏渲染提高 Canvas 书写性能","description":"","frontmatter":{},"headers":[],"relativePath":"guide/canvas/通过离屏渲染提高Canvas书写性能.md","filePath":"guide/canvas/通过离屏渲染提高Canvas书写性能.md","lastUpdated":1707358769000}'),o={name:"guide/canvas/通过离屏渲染提高Canvas书写性能.md"},e=l("",19),t=[e];function c(r,E,y,i,F,C){return n(),a("div",null,t)}const h=s(o,[["render",c]]);export{D as __pageData,h as default};
diff --git "a/assets/guide_canvas_\351\200\232\350\277\207\350\264\235\345\241\236\345\260\224\346\233\262\347\272\277\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.acad2b6c.js" "b/assets/guide_canvas_\351\200\232\350\277\207\350\264\235\345\241\236\345\260\224\346\233\262\347\272\277\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.c136fb49.js"
similarity index 99%
rename from "assets/guide_canvas_\351\200\232\350\277\207\350\264\235\345\241\236\345\260\224\346\233\262\347\272\277\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.acad2b6c.js"
rename to "assets/guide_canvas_\351\200\232\350\277\207\350\264\235\345\241\236\345\260\224\346\233\262\347\272\277\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.c136fb49.js"
index b57c8536..66da3f18 100644
--- "a/assets/guide_canvas_\351\200\232\350\277\207\350\264\235\345\241\236\345\260\224\346\233\262\347\272\277\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.acad2b6c.js"
+++ "b/assets/guide_canvas_\351\200\232\350\277\207\350\264\235\345\241\236\345\260\224\346\233\262\347\272\277\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.c136fb49.js"
@@ -1,4 +1,4 @@
-import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/8.4bb53b64.gif",o="/vitePress-blob/assets/9.4148f2f2.gif",d=JSON.parse('{"title":"通过贝塞尔曲线解决 Canvas 书写的圆滑问题","description":"","frontmatter":{},"headers":[],"relativePath":"guide/canvas/通过贝塞尔曲线优化Canvas书写性能.md","filePath":"guide/canvas/通过贝塞尔曲线优化Canvas书写性能.md","lastUpdated":1707358495000}'),e={name:"guide/canvas/通过贝塞尔曲线优化Canvas书写性能.md"},t=l('

通过贝塞尔曲线解决 Canvas 书写的圆滑问题

前言

书接上回,当我们实现了一个自由书写的 Canvas 画板后,我们发现采集的点越少,画出来的圈圈越不圆润,这时候我们可以使用贝塞尔曲线来优化书写。

canvas

正文

贝塞尔曲线

贝塞尔曲线是一种数学曲线,常见的有: 线性贝塞尔曲线、二次·贝塞尔曲线、三次贝塞尔曲线等, 它可以用来实现平滑曲线,我们可以通过贝塞尔曲线以相对圆滑的方式来优化我们的 Canvas 书写。

优化思路

我们可以通过贝塞尔曲线来优化我们的 Canvas 书写性能,将笔直的线变的更加圆滑弯曲。

在 Canvas2D API 中有一个方法叫做 quadraticCurveTo 用于创建二次贝塞尔曲线。它需要两个点:一个控制点和一个终点。曲线从当前的绘图位置开始绘制,并以控制点为参考,向终点绘制曲线。

这个方法的语法是:context.quadraticCurveTo(cp1x, cp1y, x, y);

其中:

cp1x 和 cp1y 是控制点坐标。
+import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/8.4bb53b64.gif",o="/vitePress-blob/assets/9.4148f2f2.gif",d=JSON.parse('{"title":"通过贝塞尔曲线解决 Canvas 书写的圆滑问题","description":"","frontmatter":{},"headers":[],"relativePath":"guide/canvas/通过贝塞尔曲线优化Canvas书写性能.md","filePath":"guide/canvas/通过贝塞尔曲线优化Canvas书写性能.md","lastUpdated":1707358769000}'),e={name:"guide/canvas/通过贝塞尔曲线优化Canvas书写性能.md"},t=l('

通过贝塞尔曲线解决 Canvas 书写的圆滑问题

前言

书接上回,当我们实现了一个自由书写的 Canvas 画板后,我们发现采集的点越少,画出来的圈圈越不圆润,这时候我们可以使用贝塞尔曲线来优化书写。

canvas

正文

贝塞尔曲线

贝塞尔曲线是一种数学曲线,常见的有: 线性贝塞尔曲线、二次·贝塞尔曲线、三次贝塞尔曲线等, 它可以用来实现平滑曲线,我们可以通过贝塞尔曲线以相对圆滑的方式来优化我们的 Canvas 书写。

优化思路

我们可以通过贝塞尔曲线来优化我们的 Canvas 书写性能,将笔直的线变的更加圆滑弯曲。

在 Canvas2D API 中有一个方法叫做 quadraticCurveTo 用于创建二次贝塞尔曲线。它需要两个点:一个控制点和一个终点。曲线从当前的绘图位置开始绘制,并以控制点为参考,向终点绘制曲线。

这个方法的语法是:context.quadraticCurveTo(cp1x, cp1y, x, y);

其中:

cp1x 和 cp1y 是控制点坐标。
 x 和 y 是终点坐标。
 

这个方法不会直接绘制曲线,而是将曲线添加到当前的路径中。要在画布上实际绘制曲线,你需要使用 stroke 或 fill 方法

优化实现

1 采集到所有的点集 2 前一个点作为控制点,当前点作为终点,绘制二次贝塞尔曲线

html
<!DOCTYPE html>
 <html lang="en">
diff --git "a/assets/guide_canvas_\351\200\232\350\277\207\350\264\235\345\241\236\345\260\224\346\233\262\347\272\277\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.acad2b6c.lean.js" "b/assets/guide_canvas_\351\200\232\350\277\207\350\264\235\345\241\236\345\260\224\346\233\262\347\272\277\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.c136fb49.lean.js"
similarity index 90%
rename from "assets/guide_canvas_\351\200\232\350\277\207\350\264\235\345\241\236\345\260\224\346\233\262\347\272\277\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.acad2b6c.lean.js"
rename to "assets/guide_canvas_\351\200\232\350\277\207\350\264\235\345\241\236\345\260\224\346\233\262\347\272\277\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.c136fb49.lean.js"
index 36953b75..48322539 100644
--- "a/assets/guide_canvas_\351\200\232\350\277\207\350\264\235\345\241\236\345\260\224\346\233\262\347\272\277\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.acad2b6c.lean.js"
+++ "b/assets/guide_canvas_\351\200\232\350\277\207\350\264\235\345\241\236\345\260\224\346\233\262\347\272\277\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.md.c136fb49.lean.js"
@@ -1 +1 @@
-import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/8.4bb53b64.gif",o="/vitePress-blob/assets/9.4148f2f2.gif",d=JSON.parse('{"title":"通过贝塞尔曲线解决 Canvas 书写的圆滑问题","description":"","frontmatter":{},"headers":[],"relativePath":"guide/canvas/通过贝塞尔曲线优化Canvas书写性能.md","filePath":"guide/canvas/通过贝塞尔曲线优化Canvas书写性能.md","lastUpdated":1707358495000}'),e={name:"guide/canvas/通过贝塞尔曲线优化Canvas书写性能.md"},t=l("",21),c=[t];function r(E,y,i,F,A,C){return n(),a("div",null,c)}const u=s(e,[["render",r]]);export{d as __pageData,u as default};
+import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/8.4bb53b64.gif",o="/vitePress-blob/assets/9.4148f2f2.gif",d=JSON.parse('{"title":"通过贝塞尔曲线解决 Canvas 书写的圆滑问题","description":"","frontmatter":{},"headers":[],"relativePath":"guide/canvas/通过贝塞尔曲线优化Canvas书写性能.md","filePath":"guide/canvas/通过贝塞尔曲线优化Canvas书写性能.md","lastUpdated":1707358769000}'),e={name:"guide/canvas/通过贝塞尔曲线优化Canvas书写性能.md"},t=l("",21),c=[t];function r(E,y,i,F,A,C){return n(),a("div",null,c)}const u=s(e,[["render",r]]);export{d as __pageData,u as default};
diff --git "a/assets/guide_css\347\233\270\345\205\263_BFC.md.0b433659.js" "b/assets/guide_css\347\233\270\345\205\263_BFC.md.0cc3082f.js"
similarity index 96%
rename from "assets/guide_css\347\233\270\345\205\263_BFC.md.0b433659.js"
rename to "assets/guide_css\347\233\270\345\205\263_BFC.md.0cc3082f.js"
index 21a80bf4..d2aa4e47 100644
--- "a/assets/guide_css\347\233\270\345\205\263_BFC.md.0b433659.js"
+++ "b/assets/guide_css\347\233\270\345\205\263_BFC.md.0cc3082f.js"
@@ -1 +1 @@
-import{_ as i,o as a,c as l,Q as e}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"BFC","description":"","frontmatter":{},"headers":[],"relativePath":"guide/css相关/BFC.md","filePath":"guide/css相关/BFC.md","lastUpdated":1707358495000}'),o={name:"guide/css相关/BFC.md"},t=e('

BFC

块级格式化上下文

条件

  1. 根元素 (html)
  2. 浮动元素
  3. position 为绝对定位元素 (absolute/fixed)
  4. display: inline-block、inline-flex等
  5. overflow: auto/scroll/hidden (overflow 值不为 visible 或 clip 的块级元素)

特点

  1. BFC 内部元素不影响外部元素
  2. 计算高度需要计算浮动元素
  3. BFC 区域不会与浮动容器发生重叠
  4. 在 BFC 中上下相邻的俩个容器的 margin 会重叠
  5. 每个元素的左 margin 值和容器的左 border 相接触

作用

  1. 清除浮动带来的高度塌陷问题
  2. 解决俩个元素的 margin 重叠问题
  3. 创建自适应的俩栏布局
',8),r=[t];function s(n,c,d,h,_,f){return a(),l("div",null,r)}const p=i(o,[["render",s]]);export{m as __pageData,p as default}; +import{_ as i,o as a,c as l,Q as e}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"BFC","description":"","frontmatter":{},"headers":[],"relativePath":"guide/css相关/BFC.md","filePath":"guide/css相关/BFC.md","lastUpdated":1707358769000}'),o={name:"guide/css相关/BFC.md"},t=e('

BFC

块级格式化上下文

条件

  1. 根元素 (html)
  2. 浮动元素
  3. position 为绝对定位元素 (absolute/fixed)
  4. display: inline-block、inline-flex等
  5. overflow: auto/scroll/hidden (overflow 值不为 visible 或 clip 的块级元素)

特点

  1. BFC 内部元素不影响外部元素
  2. 计算高度需要计算浮动元素
  3. BFC 区域不会与浮动容器发生重叠
  4. 在 BFC 中上下相邻的俩个容器的 margin 会重叠
  5. 每个元素的左 margin 值和容器的左 border 相接触

作用

  1. 清除浮动带来的高度塌陷问题
  2. 解决俩个元素的 margin 重叠问题
  3. 创建自适应的俩栏布局
',8),r=[t];function s(n,c,d,h,_,f){return a(),l("div",null,r)}const p=i(o,[["render",s]]);export{m as __pageData,p as default}; diff --git "a/assets/guide_css\347\233\270\345\205\263_BFC.md.0b433659.lean.js" "b/assets/guide_css\347\233\270\345\205\263_BFC.md.0cc3082f.lean.js" similarity index 85% rename from "assets/guide_css\347\233\270\345\205\263_BFC.md.0b433659.lean.js" rename to "assets/guide_css\347\233\270\345\205\263_BFC.md.0cc3082f.lean.js" index dbc51387..f7c09ce1 100644 --- "a/assets/guide_css\347\233\270\345\205\263_BFC.md.0b433659.lean.js" +++ "b/assets/guide_css\347\233\270\345\205\263_BFC.md.0cc3082f.lean.js" @@ -1 +1 @@ -import{_ as i,o as a,c as l,Q as e}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"BFC","description":"","frontmatter":{},"headers":[],"relativePath":"guide/css相关/BFC.md","filePath":"guide/css相关/BFC.md","lastUpdated":1707358495000}'),o={name:"guide/css相关/BFC.md"},t=e("",8),r=[t];function s(n,c,d,h,_,f){return a(),l("div",null,r)}const p=i(o,[["render",s]]);export{m as __pageData,p as default}; +import{_ as i,o as a,c as l,Q as e}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"BFC","description":"","frontmatter":{},"headers":[],"relativePath":"guide/css相关/BFC.md","filePath":"guide/css相关/BFC.md","lastUpdated":1707358769000}'),o={name:"guide/css相关/BFC.md"},t=e("",8),r=[t];function s(n,c,d,h,_,f){return a(),l("div",null,r)}const p=i(o,[["render",s]]);export{m as __pageData,p as default}; diff --git "a/assets/guide_css\347\233\270\345\205\263_display.md.1eb7437c.js" "b/assets/guide_css\347\233\270\345\205\263_display.md.24ba2b32.js" similarity index 99% rename from "assets/guide_css\347\233\270\345\205\263_display.md.1eb7437c.js" rename to "assets/guide_css\347\233\270\345\205\263_display.md.24ba2b32.js" index 7d091116..d1eba3fa 100644 --- "a/assets/guide_css\347\233\270\345\205\263_display.md.1eb7437c.js" +++ "b/assets/guide_css\347\233\270\345\205\263_display.md.24ba2b32.js" @@ -1,4 +1,4 @@ -import{_ as s,o as n,c as l,Q as a}from"./chunks/framework.b6910bb2.js";const d=JSON.parse('{"title":"display","description":"","frontmatter":{},"headers":[],"relativePath":"guide/css相关/display.md","filePath":"guide/css相关/display.md","lastUpdated":1707358495000}'),p={name:"guide/css相关/display.md"},o=a(`

display

none

不显示元素,脱离文档流

inline 行内元素

不能设置宽高、不换行

水平 padding、margin 有效

垂直方向 padding、margin 无效

line-block

可以设置宽高、不换行

block

块级元素,可以设置宽高,独占一行

flex

弹性布局

table

元素作为块级表格元素使用

inherit

继承父元素 display 值

常见的问题

line-block、inline 都会有空格问题

因为浏览器会将换行符当空格字符处理

解决方案:

  1. 使用 font-size 时,可通过设置 font-size: 0、letter-spacing、word-spacing 解决
  2. 使用弹性布局
  3. 使用 margin 负值

浏览器对于空格的默认表现

  1. 元素的头尾的空白符会直接忽略
  2. 内容中间有多个空格,会被合并成一个空格
js
<!DOCTYPE html>
+import{_ as s,o as n,c as l,Q as a}from"./chunks/framework.b6910bb2.js";const d=JSON.parse('{"title":"display","description":"","frontmatter":{},"headers":[],"relativePath":"guide/css相关/display.md","filePath":"guide/css相关/display.md","lastUpdated":1707358769000}'),p={name:"guide/css相关/display.md"},o=a(`

display

none

不显示元素,脱离文档流

inline 行内元素

不能设置宽高、不换行

水平 padding、margin 有效

垂直方向 padding、margin 无效

line-block

可以设置宽高、不换行

block

块级元素,可以设置宽高,独占一行

flex

弹性布局

table

元素作为块级表格元素使用

inherit

继承父元素 display 值

常见的问题

line-block、inline 都会有空格问题

因为浏览器会将换行符当空格字符处理

解决方案:

  1. 使用 font-size 时,可通过设置 font-size: 0、letter-spacing、word-spacing 解决
  2. 使用弹性布局
  3. 使用 margin 负值

浏览器对于空格的默认表现

  1. 元素的头尾的空白符会直接忽略
  2. 内容中间有多个空格,会被合并成一个空格
js
<!DOCTYPE html>
 <html lang="en">
 
 <head>
diff --git "a/assets/guide_css\347\233\270\345\205\263_display.md.1eb7437c.lean.js" "b/assets/guide_css\347\233\270\345\205\263_display.md.24ba2b32.lean.js"
similarity index 85%
rename from "assets/guide_css\347\233\270\345\205\263_display.md.1eb7437c.lean.js"
rename to "assets/guide_css\347\233\270\345\205\263_display.md.24ba2b32.lean.js"
index f585899d..78e7cbb4 100644
--- "a/assets/guide_css\347\233\270\345\205\263_display.md.1eb7437c.lean.js"
+++ "b/assets/guide_css\347\233\270\345\205\263_display.md.24ba2b32.lean.js"
@@ -1 +1 @@
-import{_ as s,o as n,c as l,Q as a}from"./chunks/framework.b6910bb2.js";const d=JSON.parse('{"title":"display","description":"","frontmatter":{},"headers":[],"relativePath":"guide/css相关/display.md","filePath":"guide/css相关/display.md","lastUpdated":1707358495000}'),p={name:"guide/css相关/display.md"},o=a("",25),t=[o];function e(c,E,r,y,i,g){return n(),l("div",null,t)}const u=s(p,[["render",e]]);export{d as __pageData,u as default};
+import{_ as s,o as n,c as l,Q as a}from"./chunks/framework.b6910bb2.js";const d=JSON.parse('{"title":"display","description":"","frontmatter":{},"headers":[],"relativePath":"guide/css相关/display.md","filePath":"guide/css相关/display.md","lastUpdated":1707358769000}'),p={name:"guide/css相关/display.md"},o=a("",25),t=[o];function e(c,E,r,y,i,g){return n(),l("div",null,t)}const u=s(p,[["render",e]]);export{d as __pageData,u as default};
diff --git "a/assets/guide_css\347\233\270\345\205\263_display\343\200\201float\343\200\201position\347\232\204\345\205\263\347\263\273.md.1fe9ac57.js" "b/assets/guide_css\347\233\270\345\205\263_display\343\200\201float\343\200\201position\347\232\204\345\205\263\347\263\273.md.1a5ef489.js"
similarity index 99%
rename from "assets/guide_css\347\233\270\345\205\263_display\343\200\201float\343\200\201position\347\232\204\345\205\263\347\263\273.md.1fe9ac57.js"
rename to "assets/guide_css\347\233\270\345\205\263_display\343\200\201float\343\200\201position\347\232\204\345\205\263\347\263\273.md.1a5ef489.js"
index 7e37fe66..2e8a9e3a 100644
--- "a/assets/guide_css\347\233\270\345\205\263_display\343\200\201float\343\200\201position\347\232\204\345\205\263\347\263\273.md.1fe9ac57.js"
+++ "b/assets/guide_css\347\233\270\345\205\263_display\343\200\201float\343\200\201position\347\232\204\345\205\263\347\263\273.md.1a5ef489.js"
@@ -1,4 +1,4 @@
-import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const C=JSON.parse('{"title":"display、float、position的关系","description":"","frontmatter":{},"headers":[],"relativePath":"guide/css相关/display、float、position的关系.md","filePath":"guide/css相关/display、float、position的关系.md","lastUpdated":1707358495000}'),p={name:"guide/css相关/display、float、position的关系.md"},o=l(`

display、float、position的关系

  • 如果元素的 display 为 none 直接隐藏
  • 如果元素的 position 为 absolute 或者 fixed 时,float 失效,display 会提升块级元素
  • 如果元素的 position 为 relative, 会在浮动后的元素进行定位,display 会被提升成块级元素
  • 如果是根元素,display 会被提升为块级元素
  • 浮动元素会将 display 提升为块级元素
html
<!DOCTYPE html>
+import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const C=JSON.parse('{"title":"display、float、position的关系","description":"","frontmatter":{},"headers":[],"relativePath":"guide/css相关/display、float、position的关系.md","filePath":"guide/css相关/display、float、position的关系.md","lastUpdated":1707358769000}'),p={name:"guide/css相关/display、float、position的关系.md"},o=l(`

display、float、position的关系

  • 如果元素的 display 为 none 直接隐藏
  • 如果元素的 position 为 absolute 或者 fixed 时,float 失效,display 会提升块级元素
  • 如果元素的 position 为 relative, 会在浮动后的元素进行定位,display 会被提升成块级元素
  • 如果是根元素,display 会被提升为块级元素
  • 浮动元素会将 display 提升为块级元素
html
<!DOCTYPE html>
 <html lang="en">
 
 <head>
diff --git "a/assets/guide_css\347\233\270\345\205\263_display\343\200\201float\343\200\201position\347\232\204\345\205\263\347\263\273.md.1fe9ac57.lean.js" "b/assets/guide_css\347\233\270\345\205\263_display\343\200\201float\343\200\201position\347\232\204\345\205\263\347\263\273.md.1a5ef489.lean.js"
similarity index 88%
rename from "assets/guide_css\347\233\270\345\205\263_display\343\200\201float\343\200\201position\347\232\204\345\205\263\347\263\273.md.1fe9ac57.lean.js"
rename to "assets/guide_css\347\233\270\345\205\263_display\343\200\201float\343\200\201position\347\232\204\345\205\263\347\263\273.md.1a5ef489.lean.js"
index 5ce66853..e2215646 100644
--- "a/assets/guide_css\347\233\270\345\205\263_display\343\200\201float\343\200\201position\347\232\204\345\205\263\347\263\273.md.1fe9ac57.lean.js"
+++ "b/assets/guide_css\347\233\270\345\205\263_display\343\200\201float\343\200\201position\347\232\204\345\205\263\347\263\273.md.1a5ef489.lean.js"
@@ -1 +1 @@
-import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const C=JSON.parse('{"title":"display、float、position的关系","description":"","frontmatter":{},"headers":[],"relativePath":"guide/css相关/display、float、position的关系.md","filePath":"guide/css相关/display、float、position的关系.md","lastUpdated":1707358495000}'),p={name:"guide/css相关/display、float、position的关系.md"},o=l("",3),t=[o];function e(c,E,r,y,i,d){return n(),a("div",null,t)}const u=s(p,[["render",e]]);export{C as __pageData,u as default};
+import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const C=JSON.parse('{"title":"display、float、position的关系","description":"","frontmatter":{},"headers":[],"relativePath":"guide/css相关/display、float、position的关系.md","filePath":"guide/css相关/display、float、position的关系.md","lastUpdated":1707358769000}'),p={name:"guide/css相关/display、float、position的关系.md"},o=l("",3),t=[o];function e(c,E,r,y,i,d){return n(),a("div",null,t)}const u=s(p,[["render",e]]);export{C as __pageData,u as default};
diff --git "a/assets/guide_css\347\233\270\345\205\263_display\343\200\201visibility\343\200\201opacity\345\214\272\345\210\253.md.79a76e72.js" "b/assets/guide_css\347\233\270\345\205\263_display\343\200\201visibility\343\200\201opacity\345\214\272\345\210\253.md.5aec2cb5.js"
similarity index 96%
rename from "assets/guide_css\347\233\270\345\205\263_display\343\200\201visibility\343\200\201opacity\345\214\272\345\210\253.md.79a76e72.js"
rename to "assets/guide_css\347\233\270\345\205\263_display\343\200\201visibility\343\200\201opacity\345\214\272\345\210\253.md.5aec2cb5.js"
index 72066cd4..a6f07d4d 100644
--- "a/assets/guide_css\347\233\270\345\205\263_display\343\200\201visibility\343\200\201opacity\345\214\272\345\210\253.md.79a76e72.js"
+++ "b/assets/guide_css\347\233\270\345\205\263_display\343\200\201visibility\343\200\201opacity\345\214\272\345\210\253.md.5aec2cb5.js"
@@ -1 +1 @@
-import{_ as i,o as l,c as a,Q as t}from"./chunks/framework.b6910bb2.js";const b=JSON.parse('{"title":"display、visibility、opacity区别","description":"","frontmatter":{},"headers":[],"relativePath":"guide/css相关/display、visibility、opacity区别.md","filePath":"guide/css相关/display、visibility、opacity区别.md","lastUpdated":1707358495000}'),s={name:"guide/css相关/display、visibility、opacity区别.md"},e=t('

display、visibility、opacity区别

  • 占据空间

    • opacity、visibility 占据空间,不会引起回流,但是会重绘
    • display 不占据空间,但会引起页面的回流和重绘
  • 绑定事件

    • display、visibility 不会触发绑定事件
    • opacity 会触发绑定事件

display: none 和 visibility: hidden 的区别

  • 从渲染树上看
    • display: none 不存在渲染树中
    • visibility: hidden 的元素存在渲染树中,还会占据空间
  • 从继承上看
    • display 不会被继承
    • visibility 会被继承
  • 从渲染上看
    • display 会影响回流重绘
    • visibility 只会引起重绘
',4),d=[e];function y(o,p,n,c,_,r){return l(),a("div",null,d)}const h=i(s,[["render",y]]);export{b as __pageData,h as default}; +import{_ as i,o as l,c as a,Q as t}from"./chunks/framework.b6910bb2.js";const b=JSON.parse('{"title":"display、visibility、opacity区别","description":"","frontmatter":{},"headers":[],"relativePath":"guide/css相关/display、visibility、opacity区别.md","filePath":"guide/css相关/display、visibility、opacity区别.md","lastUpdated":1707358769000}'),s={name:"guide/css相关/display、visibility、opacity区别.md"},e=t('

display、visibility、opacity区别

  • 占据空间

    • opacity、visibility 占据空间,不会引起回流,但是会重绘
    • display 不占据空间,但会引起页面的回流和重绘
  • 绑定事件

    • display、visibility 不会触发绑定事件
    • opacity 会触发绑定事件

display: none 和 visibility: hidden 的区别

  • 从渲染树上看
    • display: none 不存在渲染树中
    • visibility: hidden 的元素存在渲染树中,还会占据空间
  • 从继承上看
    • display 不会被继承
    • visibility 会被继承
  • 从渲染上看
    • display 会影响回流重绘
    • visibility 只会引起重绘
',4),d=[e];function y(o,p,n,c,_,r){return l(),a("div",null,d)}const h=i(s,[["render",y]]);export{b as __pageData,h as default}; diff --git "a/assets/guide_css\347\233\270\345\205\263_display\343\200\201visibility\343\200\201opacity\345\214\272\345\210\253.md.79a76e72.lean.js" "b/assets/guide_css\347\233\270\345\205\263_display\343\200\201visibility\343\200\201opacity\345\214\272\345\210\253.md.5aec2cb5.lean.js" similarity index 88% rename from "assets/guide_css\347\233\270\345\205\263_display\343\200\201visibility\343\200\201opacity\345\214\272\345\210\253.md.79a76e72.lean.js" rename to "assets/guide_css\347\233\270\345\205\263_display\343\200\201visibility\343\200\201opacity\345\214\272\345\210\253.md.5aec2cb5.lean.js" index fe956dc4..4c1c02b5 100644 --- "a/assets/guide_css\347\233\270\345\205\263_display\343\200\201visibility\343\200\201opacity\345\214\272\345\210\253.md.79a76e72.lean.js" +++ "b/assets/guide_css\347\233\270\345\205\263_display\343\200\201visibility\343\200\201opacity\345\214\272\345\210\253.md.5aec2cb5.lean.js" @@ -1 +1 @@ -import{_ as i,o as l,c as a,Q as t}from"./chunks/framework.b6910bb2.js";const b=JSON.parse('{"title":"display、visibility、opacity区别","description":"","frontmatter":{},"headers":[],"relativePath":"guide/css相关/display、visibility、opacity区别.md","filePath":"guide/css相关/display、visibility、opacity区别.md","lastUpdated":1707358495000}'),s={name:"guide/css相关/display、visibility、opacity区别.md"},e=t("",4),d=[e];function y(o,p,n,c,_,r){return l(),a("div",null,d)}const h=i(s,[["render",y]]);export{b as __pageData,h as default}; +import{_ as i,o as l,c as a,Q as t}from"./chunks/framework.b6910bb2.js";const b=JSON.parse('{"title":"display、visibility、opacity区别","description":"","frontmatter":{},"headers":[],"relativePath":"guide/css相关/display、visibility、opacity区别.md","filePath":"guide/css相关/display、visibility、opacity区别.md","lastUpdated":1707358769000}'),s={name:"guide/css相关/display、visibility、opacity区别.md"},e=t("",4),d=[e];function y(o,p,n,c,_,r){return l(),a("div",null,d)}const h=i(s,[["render",y]]);export{b as __pageData,h as default}; diff --git "a/assets/guide_css\347\233\270\345\205\263_position.md.cc780e52.js" "b/assets/guide_css\347\233\270\345\205\263_position.md.f6e57cb3.js" similarity index 99% rename from "assets/guide_css\347\233\270\345\205\263_position.md.cc780e52.js" rename to "assets/guide_css\347\233\270\345\205\263_position.md.f6e57cb3.js" index 314f81e3..6a678606 100644 --- "a/assets/guide_css\347\233\270\345\205\263_position.md.cc780e52.js" +++ "b/assets/guide_css\347\233\270\345\205\263_position.md.f6e57cb3.js" @@ -1,4 +1,4 @@ -import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="data:image/jpeg;base64,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",o="/vitePress-blob/assets/2.bf4501cf.jpg",t="data:image/jpeg;base64,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",u=JSON.parse('{"title":"Position","description":"","frontmatter":{},"headers":[],"relativePath":"guide/css相关/position.md","filePath":"guide/css相关/position.md","lastUpdated":1707358495000}'),e={name:"guide/css相关/position.md"},c=l('

Position

static [ˈstætɪk]

默认值,没有定位,元素出现在正常的文档流中,会忽略 top,bottom,left,right 或者 z-index 声明

relative

生成相对定位元素,相对于其原来位置进行定位,元素的位置通过 left、top、right、bottom 属性规定

relative

元素定位永远相对于元素自身位置,和其他元素没有关系,也不会影响其他元素。

absolute

生成绝对定位的元素,相对于 static 定位以外的一个父元素进行定位

元素位置通过 left、top、right、bottom 属性规定

relative

浏览器会递归查找该元素的所有父元素,如果找到一个设置了非 static 的定位元素,就以该元素为基准定位,如果没有找到,就以浏览器边界定位

但是它具有破坏性,会导致其他元素位置的变化

fixed

生成绝对定位的元素,指定元素相对于屏幕视口的位置来制定元素位置。

relative

但是它具有破坏性,会导致其他元素位置的变化

sticky [ˈstɪki]

相对它的最近滚动祖先(nearest scrolling ancestor)和 containing block (最近块级祖先 nearest block-level ancestor),包括table-related元素,基于top, right, bottom, 和 left的值进行偏移。偏移值不会影响任何其他元素的位置。

inherit

规定从父元素继承 position 属性的值

js
<!DOCTYPE html>
+import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="data:image/jpeg;base64,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",o="/vitePress-blob/assets/2.bf4501cf.jpg",t="data:image/jpeg;base64,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",u=JSON.parse('{"title":"Position","description":"","frontmatter":{},"headers":[],"relativePath":"guide/css相关/position.md","filePath":"guide/css相关/position.md","lastUpdated":1707358769000}'),e={name:"guide/css相关/position.md"},c=l('

Position

static [ˈstætɪk]

默认值,没有定位,元素出现在正常的文档流中,会忽略 top,bottom,left,right 或者 z-index 声明

relative

生成相对定位元素,相对于其原来位置进行定位,元素的位置通过 left、top、right、bottom 属性规定

relative

元素定位永远相对于元素自身位置,和其他元素没有关系,也不会影响其他元素。

absolute

生成绝对定位的元素,相对于 static 定位以外的一个父元素进行定位

元素位置通过 left、top、right、bottom 属性规定

relative

浏览器会递归查找该元素的所有父元素,如果找到一个设置了非 static 的定位元素,就以该元素为基准定位,如果没有找到,就以浏览器边界定位

但是它具有破坏性,会导致其他元素位置的变化

fixed

生成绝对定位的元素,指定元素相对于屏幕视口的位置来制定元素位置。

relative

但是它具有破坏性,会导致其他元素位置的变化

sticky [ˈstɪki]

相对它的最近滚动祖先(nearest scrolling ancestor)和 containing block (最近块级祖先 nearest block-level ancestor),包括table-related元素,基于top, right, bottom, 和 left的值进行偏移。偏移值不会影响任何其他元素的位置。

inherit

规定从父元素继承 position 属性的值

js
<!DOCTYPE html>
 <html lang="en">
 
 <head>
diff --git "a/assets/guide_css\347\233\270\345\205\263_position.md.cc780e52.lean.js" "b/assets/guide_css\347\233\270\345\205\263_position.md.f6e57cb3.lean.js"
similarity index 99%
rename from "assets/guide_css\347\233\270\345\205\263_position.md.cc780e52.lean.js"
rename to "assets/guide_css\347\233\270\345\205\263_position.md.f6e57cb3.lean.js"
index 933bf3ae..5af2871f 100644
--- "a/assets/guide_css\347\233\270\345\205\263_position.md.cc780e52.lean.js"
+++ "b/assets/guide_css\347\233\270\345\205\263_position.md.f6e57cb3.lean.js"
@@ -1 +1 @@
-import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="data:image/jpeg;base64,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",o="/vitePress-blob/assets/2.bf4501cf.jpg",t="data:image/jpeg;base64,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",u=JSON.parse('{"title":"Position","description":"","frontmatter":{},"headers":[],"relativePath":"guide/css相关/position.md","filePath":"guide/css相关/position.md","lastUpdated":1707358495000}'),e={name:"guide/css相关/position.md"},c=l("",22),r=[c];function E(i,A,y,g,d,h){return n(),a("div",null,r)}const Q=s(e,[["render",E]]);export{u as __pageData,Q as default};
+import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="data:image/jpeg;base64,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",o="/vitePress-blob/assets/2.bf4501cf.jpg",t="data:image/jpeg;base64,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",u=JSON.parse('{"title":"Position","description":"","frontmatter":{},"headers":[],"relativePath":"guide/css相关/position.md","filePath":"guide/css相关/position.md","lastUpdated":1707358769000}'),e={name:"guide/css相关/position.md"},c=l("",22),r=[c];function E(i,A,y,g,d,h){return n(),a("div",null,r)}const Q=s(e,[["render",E]]);export{u as __pageData,Q as default};
diff --git "a/assets/guide_css\347\233\270\345\205\263_\345\257\271 line-height \347\232\204\347\220\206\350\247\243\345\217\212\345\205\266\350\265\213\345\200\274\346\226\271\345\274\217.md.91a29d6d.js" "b/assets/guide_css\347\233\270\345\205\263_\345\257\271 line-height \347\232\204\347\220\206\350\247\243\345\217\212\345\205\266\350\265\213\345\200\274\346\226\271\345\274\217.md.7b9b530a.js"
similarity index 97%
rename from "assets/guide_css\347\233\270\345\205\263_\345\257\271 line-height \347\232\204\347\220\206\350\247\243\345\217\212\345\205\266\350\265\213\345\200\274\346\226\271\345\274\217.md.91a29d6d.js"
rename to "assets/guide_css\347\233\270\345\205\263_\345\257\271 line-height \347\232\204\347\220\206\350\247\243\345\217\212\345\205\266\350\265\213\345\200\274\346\226\271\345\274\217.md.7b9b530a.js"
index 5a55796a..a0b00e37 100644
--- "a/assets/guide_css\347\233\270\345\205\263_\345\257\271 line-height \347\232\204\347\220\206\350\247\243\345\217\212\345\205\266\350\265\213\345\200\274\346\226\271\345\274\217.md.91a29d6d.js"	
+++ "b/assets/guide_css\347\233\270\345\205\263_\345\257\271 line-height \347\232\204\347\220\206\350\247\243\345\217\212\345\205\266\350\265\213\345\200\274\346\226\271\345\274\217.md.7b9b530a.js"	
@@ -1 +1 @@
-import{_ as e,o as a,c as t,Q as i}from"./chunks/framework.b6910bb2.js";const u=JSON.parse('{"title":"对 line-height 的理解及其赋值方式","description":"","frontmatter":{},"headers":[],"relativePath":"guide/css相关/对 line-height 的理解及其赋值方式.md","filePath":"guide/css相关/对 line-height 的理解及其赋值方式.md","lastUpdated":1707358495000}'),h={name:"guide/css相关/对 line-height 的理解及其赋值方式.md"},n=i('

对 line-height 的理解及其赋值方式

概念

line-height 指一行文本的高度,包含了字间距,实际上是下一行基线到上一行基线的距离

line-height 和 height 都能撑开元素高度 (如果 line-height 和 height 一致时可以实现单行文字的垂直居中)

计算方式

带单位的px

line-height 为 固定值

纯数字

直接 line-height 会把比例传递给后代

例如,父级行高为 1.5,子元素字体为 18px,则子元素行高为 1.5 * 18 = 27px

百分比

父元素将计算后的值传递给后代

例如,父元素行高为 200%,父元素字体为 18px,那么子元素行高为 18 * 200% = 36px

',13),r=[n];function l(o,s,_,d,c,p){return a(),t("div",null,r)}const x=e(h,[["render",l]]);export{u as __pageData,x as default}; +import{_ as e,o as a,c as t,Q as i}from"./chunks/framework.b6910bb2.js";const u=JSON.parse('{"title":"对 line-height 的理解及其赋值方式","description":"","frontmatter":{},"headers":[],"relativePath":"guide/css相关/对 line-height 的理解及其赋值方式.md","filePath":"guide/css相关/对 line-height 的理解及其赋值方式.md","lastUpdated":1707358769000}'),h={name:"guide/css相关/对 line-height 的理解及其赋值方式.md"},n=i('

对 line-height 的理解及其赋值方式

概念

line-height 指一行文本的高度,包含了字间距,实际上是下一行基线到上一行基线的距离

line-height 和 height 都能撑开元素高度 (如果 line-height 和 height 一致时可以实现单行文字的垂直居中)

计算方式

带单位的px

line-height 为 固定值

纯数字

直接 line-height 会把比例传递给后代

例如,父级行高为 1.5,子元素字体为 18px,则子元素行高为 1.5 * 18 = 27px

百分比

父元素将计算后的值传递给后代

例如,父元素行高为 200%,父元素字体为 18px,那么子元素行高为 18 * 200% = 36px

',13),r=[n];function l(o,s,_,d,c,p){return a(),t("div",null,r)}const x=e(h,[["render",l]]);export{u as __pageData,x as default}; diff --git "a/assets/guide_css\347\233\270\345\205\263_\345\257\271 line-height \347\232\204\347\220\206\350\247\243\345\217\212\345\205\266\350\265\213\345\200\274\346\226\271\345\274\217.md.91a29d6d.lean.js" "b/assets/guide_css\347\233\270\345\205\263_\345\257\271 line-height \347\232\204\347\220\206\350\247\243\345\217\212\345\205\266\350\265\213\345\200\274\346\226\271\345\274\217.md.7b9b530a.lean.js" similarity index 89% rename from "assets/guide_css\347\233\270\345\205\263_\345\257\271 line-height \347\232\204\347\220\206\350\247\243\345\217\212\345\205\266\350\265\213\345\200\274\346\226\271\345\274\217.md.91a29d6d.lean.js" rename to "assets/guide_css\347\233\270\345\205\263_\345\257\271 line-height \347\232\204\347\220\206\350\247\243\345\217\212\345\205\266\350\265\213\345\200\274\346\226\271\345\274\217.md.7b9b530a.lean.js" index a5d2b7ed..5d0281e3 100644 --- "a/assets/guide_css\347\233\270\345\205\263_\345\257\271 line-height \347\232\204\347\220\206\350\247\243\345\217\212\345\205\266\350\265\213\345\200\274\346\226\271\345\274\217.md.91a29d6d.lean.js" +++ "b/assets/guide_css\347\233\270\345\205\263_\345\257\271 line-height \347\232\204\347\220\206\350\247\243\345\217\212\345\205\266\350\265\213\345\200\274\346\226\271\345\274\217.md.7b9b530a.lean.js" @@ -1 +1 @@ -import{_ as e,o as a,c as t,Q as i}from"./chunks/framework.b6910bb2.js";const u=JSON.parse('{"title":"对 line-height 的理解及其赋值方式","description":"","frontmatter":{},"headers":[],"relativePath":"guide/css相关/对 line-height 的理解及其赋值方式.md","filePath":"guide/css相关/对 line-height 的理解及其赋值方式.md","lastUpdated":1707358495000}'),h={name:"guide/css相关/对 line-height 的理解及其赋值方式.md"},n=i("",13),r=[n];function l(o,s,_,d,c,p){return a(),t("div",null,r)}const x=e(h,[["render",l]]);export{u as __pageData,x as default}; +import{_ as e,o as a,c as t,Q as i}from"./chunks/framework.b6910bb2.js";const u=JSON.parse('{"title":"对 line-height 的理解及其赋值方式","description":"","frontmatter":{},"headers":[],"relativePath":"guide/css相关/对 line-height 的理解及其赋值方式.md","filePath":"guide/css相关/对 line-height 的理解及其赋值方式.md","lastUpdated":1707358769000}'),h={name:"guide/css相关/对 line-height 的理解及其赋值方式.md"},n=i("",13),r=[n];function l(o,s,_,d,c,p){return a(),t("div",null,r)}const x=e(h,[["render",l]]);export{u as __pageData,x as default}; diff --git "a/assets/guide_css\347\233\270\345\205\263_\346\246\202\350\246\201.md.28c775f1.js" "b/assets/guide_css\347\233\270\345\205\263_\346\246\202\350\246\201.md.20b96226.js" similarity index 87% rename from "assets/guide_css\347\233\270\345\205\263_\346\246\202\350\246\201.md.28c775f1.js" rename to "assets/guide_css\347\233\270\345\205\263_\346\246\202\350\246\201.md.20b96226.js" index 70a0a117..c2a13377 100644 --- "a/assets/guide_css\347\233\270\345\205\263_\346\246\202\350\246\201.md.28c775f1.js" +++ "b/assets/guide_css\347\233\270\345\205\263_\346\246\202\350\246\201.md.20b96226.js" @@ -1 +1 @@ -import{_ as e}from"./chunks/container.fad5294e.js";import{o as t,c as a,H as s}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{"aside":false,"outline":false},"headers":[],"relativePath":"guide/css相关/概要.md","filePath":"guide/css相关/概要.md","lastUpdated":1707358495000}'),c={name:"guide/css相关/概要.md"},n=Object.assign(c,{setup(o){return(r,d)=>(t(),a("div",null,[s(e,{url:"https://www.mubu.com/doc/1bKlzv2cCSK#m"})]))}});export{m as __pageData,n as default}; +import{_ as e}from"./chunks/container.fad5294e.js";import{o as t,c as a,H as s}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{"aside":false,"outline":false},"headers":[],"relativePath":"guide/css相关/概要.md","filePath":"guide/css相关/概要.md","lastUpdated":1707358769000}'),c={name:"guide/css相关/概要.md"},n=Object.assign(c,{setup(o){return(r,d)=>(t(),a("div",null,[s(e,{url:"https://www.mubu.com/doc/1bKlzv2cCSK#m"})]))}});export{m as __pageData,n as default}; diff --git "a/assets/guide_css\347\233\270\345\205\263_\346\246\202\350\246\201.md.28c775f1.lean.js" "b/assets/guide_css\347\233\270\345\205\263_\346\246\202\350\246\201.md.20b96226.lean.js" similarity index 87% rename from "assets/guide_css\347\233\270\345\205\263_\346\246\202\350\246\201.md.28c775f1.lean.js" rename to "assets/guide_css\347\233\270\345\205\263_\346\246\202\350\246\201.md.20b96226.lean.js" index 70a0a117..c2a13377 100644 --- "a/assets/guide_css\347\233\270\345\205\263_\346\246\202\350\246\201.md.28c775f1.lean.js" +++ "b/assets/guide_css\347\233\270\345\205\263_\346\246\202\350\246\201.md.20b96226.lean.js" @@ -1 +1 @@ -import{_ as e}from"./chunks/container.fad5294e.js";import{o as t,c as a,H as s}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{"aside":false,"outline":false},"headers":[],"relativePath":"guide/css相关/概要.md","filePath":"guide/css相关/概要.md","lastUpdated":1707358495000}'),c={name:"guide/css相关/概要.md"},n=Object.assign(c,{setup(o){return(r,d)=>(t(),a("div",null,[s(e,{url:"https://www.mubu.com/doc/1bKlzv2cCSK#m"})]))}});export{m as __pageData,n as default}; +import{_ as e}from"./chunks/container.fad5294e.js";import{o as t,c as a,H as s}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{"aside":false,"outline":false},"headers":[],"relativePath":"guide/css相关/概要.md","filePath":"guide/css相关/概要.md","lastUpdated":1707358769000}'),c={name:"guide/css相关/概要.md"},n=Object.assign(c,{setup(o){return(r,d)=>(t(),a("div",null,[s(e,{url:"https://www.mubu.com/doc/1bKlzv2cCSK#m"})]))}});export{m as __pageData,n as default}; diff --git "a/assets/guide_css\347\233\270\345\205\263_\351\232\220\350\227\217\345\205\203\347\264\240\347\232\204\346\226\271\346\263\225.md.b8d72453.js" "b/assets/guide_css\347\233\270\345\205\263_\351\232\220\350\227\217\345\205\203\347\264\240\347\232\204\346\226\271\346\263\225.md.49a19e25.js" similarity index 94% rename from "assets/guide_css\347\233\270\345\205\263_\351\232\220\350\227\217\345\205\203\347\264\240\347\232\204\346\226\271\346\263\225.md.b8d72453.js" rename to "assets/guide_css\347\233\270\345\205\263_\351\232\220\350\227\217\345\205\203\347\264\240\347\232\204\346\226\271\346\263\225.md.49a19e25.js" index f4badcf3..737772b7 100644 --- "a/assets/guide_css\347\233\270\345\205\263_\351\232\220\350\227\217\345\205\203\347\264\240\347\232\204\346\226\271\346\263\225.md.b8d72453.js" +++ "b/assets/guide_css\347\233\270\345\205\263_\351\232\220\350\227\217\345\205\203\347\264\240\347\232\204\346\226\271\346\263\225.md.49a19e25.js" @@ -1 +1 @@ -import{_ as l,o as i,c as t,Q as e}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"隐藏元素的方法","description":"","frontmatter":{},"headers":[],"relativePath":"guide/css相关/隐藏元素的方法.md","filePath":"guide/css相关/隐藏元素的方法.md","lastUpdated":1707358495000}'),a={name:"guide/css相关/隐藏元素的方法.md"},o=e('

隐藏元素的方法

    1. display: none - 不会显示在渲染树上,不占据空间,无法监听事件
    1. visibility: hidden - 占据空间,无法监听事件
    1. opacity: 0 - 占据空间,可以监听事件
    1. transform: scale(0, 0)
    1. 绝对定位
    1. z-index 为负数
',2),s=[o];function _(r,c,n,d,p,h){return i(),t("div",null,s)}const f=l(a,[["render",_]]);export{m as __pageData,f as default}; +import{_ as l,o as i,c as t,Q as e}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"隐藏元素的方法","description":"","frontmatter":{},"headers":[],"relativePath":"guide/css相关/隐藏元素的方法.md","filePath":"guide/css相关/隐藏元素的方法.md","lastUpdated":1707358769000}'),a={name:"guide/css相关/隐藏元素的方法.md"},o=e('

隐藏元素的方法

    1. display: none - 不会显示在渲染树上,不占据空间,无法监听事件
    1. visibility: hidden - 占据空间,无法监听事件
    1. opacity: 0 - 占据空间,可以监听事件
    1. transform: scale(0, 0)
    1. 绝对定位
    1. z-index 为负数
',2),s=[o];function _(r,c,n,d,p,h){return i(),t("div",null,s)}const f=l(a,[["render",_]]);export{m as __pageData,f as default}; diff --git "a/assets/guide_css\347\233\270\345\205\263_\351\232\220\350\227\217\345\205\203\347\264\240\347\232\204\346\226\271\346\263\225.md.b8d72453.lean.js" "b/assets/guide_css\347\233\270\345\205\263_\351\232\220\350\227\217\345\205\203\347\264\240\347\232\204\346\226\271\346\263\225.md.49a19e25.lean.js" similarity index 87% rename from "assets/guide_css\347\233\270\345\205\263_\351\232\220\350\227\217\345\205\203\347\264\240\347\232\204\346\226\271\346\263\225.md.b8d72453.lean.js" rename to "assets/guide_css\347\233\270\345\205\263_\351\232\220\350\227\217\345\205\203\347\264\240\347\232\204\346\226\271\346\263\225.md.49a19e25.lean.js" index cafdc563..6830701b 100644 --- "a/assets/guide_css\347\233\270\345\205\263_\351\232\220\350\227\217\345\205\203\347\264\240\347\232\204\346\226\271\346\263\225.md.b8d72453.lean.js" +++ "b/assets/guide_css\347\233\270\345\205\263_\351\232\220\350\227\217\345\205\203\347\264\240\347\232\204\346\226\271\346\263\225.md.49a19e25.lean.js" @@ -1 +1 @@ -import{_ as l,o as i,c as t,Q as e}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"隐藏元素的方法","description":"","frontmatter":{},"headers":[],"relativePath":"guide/css相关/隐藏元素的方法.md","filePath":"guide/css相关/隐藏元素的方法.md","lastUpdated":1707358495000}'),a={name:"guide/css相关/隐藏元素的方法.md"},o=e("",2),s=[o];function _(r,c,n,d,p,h){return i(),t("div",null,s)}const f=l(a,[["render",_]]);export{m as __pageData,f as default}; +import{_ as l,o as i,c as t,Q as e}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"隐藏元素的方法","description":"","frontmatter":{},"headers":[],"relativePath":"guide/css相关/隐藏元素的方法.md","filePath":"guide/css相关/隐藏元素的方法.md","lastUpdated":1707358769000}'),a={name:"guide/css相关/隐藏元素的方法.md"},o=e("",2),s=[o];function _(r,c,n,d,p,h){return i(),t("div",null,s)}const f=l(a,[["render",_]]);export{m as __pageData,f as default}; diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_DOM\347\233\270\345\205\263.md.016710fe.js" "b/assets/guide_javaScript\347\233\270\345\205\263_DOM\347\233\270\345\205\263.md.bd7d10f3.js" similarity index 99% rename from "assets/guide_javaScript\347\233\270\345\205\263_DOM\347\233\270\345\205\263.md.016710fe.js" rename to "assets/guide_javaScript\347\233\270\345\205\263_DOM\347\233\270\345\205\263.md.bd7d10f3.js" index 2e72df05..6736217d 100644 --- "a/assets/guide_javaScript\347\233\270\345\205\263_DOM\347\233\270\345\205\263.md.016710fe.js" +++ "b/assets/guide_javaScript\347\233\270\345\205\263_DOM\347\233\270\345\205\263.md.bd7d10f3.js" @@ -1,4 +1,4 @@ -import{_ as s,o as a,c as l,Q as n}from"./chunks/framework.b6910bb2.js";const h=JSON.parse('{"title":"DOM 相关","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/DOM相关.md","filePath":"guide/javaScript相关/DOM相关.md","lastUpdated":1707358495000}'),o={name:"guide/javaScript相关/DOM相关.md"},e=n(`

DOM 相关

如何阻止事件的冒泡和默认事件

js
event.stopPropagation(); // 阻止事件冒泡
+import{_ as s,o as a,c as l,Q as n}from"./chunks/framework.b6910bb2.js";const h=JSON.parse('{"title":"DOM 相关","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/DOM相关.md","filePath":"guide/javaScript相关/DOM相关.md","lastUpdated":1707358769000}'),o={name:"guide/javaScript相关/DOM相关.md"},e=n(`

DOM 相关

如何阻止事件的冒泡和默认事件

js
event.stopPropagation(); // 阻止事件冒泡
 event.preventDefalut(); // 阻止默认事件
 event.stopImmediatePropagation(); // 阻止监听同一事件的其他事件监听器被调用
event.stopPropagation(); // 阻止事件冒泡
 event.preventDefalut(); // 阻止默认事件
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_DOM\347\233\270\345\205\263.md.016710fe.lean.js" "b/assets/guide_javaScript\347\233\270\345\205\263_DOM\347\233\270\345\205\263.md.bd7d10f3.lean.js"
similarity index 86%
rename from "assets/guide_javaScript\347\233\270\345\205\263_DOM\347\233\270\345\205\263.md.016710fe.lean.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_DOM\347\233\270\345\205\263.md.bd7d10f3.lean.js"
index 85a091c1..4d42f07b 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_DOM\347\233\270\345\205\263.md.016710fe.lean.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_DOM\347\233\270\345\205\263.md.bd7d10f3.lean.js"
@@ -1 +1 @@
-import{_ as s,o as a,c as l,Q as n}from"./chunks/framework.b6910bb2.js";const h=JSON.parse('{"title":"DOM 相关","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/DOM相关.md","filePath":"guide/javaScript相关/DOM相关.md","lastUpdated":1707358495000}'),o={name:"guide/javaScript相关/DOM相关.md"},e=n("",16),p=[e];function t(c,r,i,y,E,d){return a(),l("div",null,p)}const u=s(o,[["render",t]]);export{h as __pageData,u as default};
+import{_ as s,o as a,c as l,Q as n}from"./chunks/framework.b6910bb2.js";const h=JSON.parse('{"title":"DOM 相关","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/DOM相关.md","filePath":"guide/javaScript相关/DOM相关.md","lastUpdated":1707358769000}'),o={name:"guide/javaScript相关/DOM相关.md"},e=n("",16),p=[e];function t(c,r,i,y,E,d){return a(),l("div",null,p)}const u=s(o,[["render",t]]);export{h as __pageData,u as default};
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_ES6\347\233\270\345\205\263.md.bd6110d8.js" "b/assets/guide_javaScript\347\233\270\345\205\263_ES6\347\233\270\345\205\263.md.98a38a5e.js"
similarity index 99%
rename from "assets/guide_javaScript\347\233\270\345\205\263_ES6\347\233\270\345\205\263.md.bd6110d8.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_ES6\347\233\270\345\205\263.md.98a38a5e.js"
index c879b21e..eacec705 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_ES6\347\233\270\345\205\263.md.bd6110d8.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_ES6\347\233\270\345\205\263.md.98a38a5e.js"
@@ -1,4 +1,4 @@
-import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/6.9b165bbb.png",b=JSON.parse('{"title":"ES6相关","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/ES6相关.md","filePath":"guide/javaScript相关/ES6相关.md","lastUpdated":1707358495000}'),o={name:"guide/javaScript相关/ES6相关.md"},e=l('

ES6相关

var、let、const 的区别

1 作用域 let、const 存在块级作用域 var 不存在块级作用域

2 const 常量 定义时赋值

3 变量提升 let/const 声明的变量需要声明后使用 var 声明的变量可以声明前使用

4 重复声明 let/const 不能重复声明 var 可以重复声明

5 暂时性死区 let/const 声明的变量不能在声明前使用

暂时性死区

箭头函数和普通函数的区别

1 箭头函数没有 arguments

2 箭头函数没有自己的 this this 由定义的所在父级上下文决定

3 箭头函数继承来的 this 不会改变 call、apply、bind 方法不能改变箭头函数的 this 指向

js
var id = 'global';
+import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/6.9b165bbb.png",b=JSON.parse('{"title":"ES6相关","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/ES6相关.md","filePath":"guide/javaScript相关/ES6相关.md","lastUpdated":1707358769000}'),o={name:"guide/javaScript相关/ES6相关.md"},e=l('

ES6相关

var、let、const 的区别

1 作用域 let、const 存在块级作用域 var 不存在块级作用域

2 const 常量 定义时赋值

3 变量提升 let/const 声明的变量需要声明后使用 var 声明的变量可以声明前使用

4 重复声明 let/const 不能重复声明 var 可以重复声明

5 暂时性死区 let/const 声明的变量不能在声明前使用

暂时性死区

箭头函数和普通函数的区别

1 箭头函数没有 arguments

2 箭头函数没有自己的 this this 由定义的所在父级上下文决定

3 箭头函数继承来的 this 不会改变 call、apply、bind 方法不能改变箭头函数的 this 指向

js
var id = 'global';
 var obj = {
     id: 'obj',
     a: function () {
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_ES6\347\233\270\345\205\263.md.bd6110d8.lean.js" "b/assets/guide_javaScript\347\233\270\345\205\263_ES6\347\233\270\345\205\263.md.98a38a5e.lean.js"
similarity index 87%
rename from "assets/guide_javaScript\347\233\270\345\205\263_ES6\347\233\270\345\205\263.md.bd6110d8.lean.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_ES6\347\233\270\345\205\263.md.98a38a5e.lean.js"
index f50ac4ac..db02d90d 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_ES6\347\233\270\345\205\263.md.bd6110d8.lean.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_ES6\347\233\270\345\205\263.md.98a38a5e.lean.js"
@@ -1 +1 @@
-import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/6.9b165bbb.png",b=JSON.parse('{"title":"ES6相关","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/ES6相关.md","filePath":"guide/javaScript相关/ES6相关.md","lastUpdated":1707358495000}'),o={name:"guide/javaScript相关/ES6相关.md"},e=l("",19),t=[e];function c(r,E,y,i,F,d){return n(),a("div",null,t)}const A=s(o,[["render",c]]);export{b as __pageData,A as default};
+import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/6.9b165bbb.png",b=JSON.parse('{"title":"ES6相关","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/ES6相关.md","filePath":"guide/javaScript相关/ES6相关.md","lastUpdated":1707358769000}'),o={name:"guide/javaScript相关/ES6相关.md"},e=l("",19),t=[e];function c(r,E,y,i,F,d){return n(),a("div",null,t)}const A=s(o,[["render",c]]);export{b as __pageData,A as default};
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_JS\345\274\202\345\270\270\346\215\225\350\216\267\346\234\272\345\210\266.md.93a23d57.js" "b/assets/guide_javaScript\347\233\270\345\205\263_JS\345\274\202\345\270\270\346\215\225\350\216\267\346\234\272\345\210\266.md.1e9b4755.js"
similarity index 86%
rename from "assets/guide_javaScript\347\233\270\345\205\263_JS\345\274\202\345\270\270\346\215\225\350\216\267\346\234\272\345\210\266.md.93a23d57.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_JS\345\274\202\345\270\270\346\215\225\350\216\267\346\234\272\345\210\266.md.1e9b4755.js"
index 73dc4d6f..db2afd09 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_JS\345\274\202\345\270\270\346\215\225\350\216\267\346\234\272\345\210\266.md.93a23d57.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_JS\345\274\202\345\270\270\346\215\225\350\216\267\346\234\272\345\210\266.md.1e9b4755.js"
@@ -1 +1 @@
-import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/JS异常捕获机制.md","filePath":"guide/javaScript相关/JS异常捕获机制.md","lastUpdated":1707358495000}'),r={name:"guide/javaScript相关/JS异常捕获机制.md"};function c(o,s,_,i,d,n){return t(),a("div")}const f=e(r,[["render",c]]);export{m as __pageData,f as default};
+import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/JS异常捕获机制.md","filePath":"guide/javaScript相关/JS异常捕获机制.md","lastUpdated":1707358769000}'),r={name:"guide/javaScript相关/JS异常捕获机制.md"};function c(o,s,_,i,d,n){return t(),a("div")}const f=e(r,[["render",c]]);export{m as __pageData,f as default};
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_JS\345\274\202\345\270\270\346\215\225\350\216\267\346\234\272\345\210\266.md.93a23d57.lean.js" "b/assets/guide_javaScript\347\233\270\345\205\263_JS\345\274\202\345\270\270\346\215\225\350\216\267\346\234\272\345\210\266.md.1e9b4755.lean.js"
similarity index 86%
rename from "assets/guide_javaScript\347\233\270\345\205\263_JS\345\274\202\345\270\270\346\215\225\350\216\267\346\234\272\345\210\266.md.93a23d57.lean.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_JS\345\274\202\345\270\270\346\215\225\350\216\267\346\234\272\345\210\266.md.1e9b4755.lean.js"
index 73dc4d6f..db2afd09 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_JS\345\274\202\345\270\270\346\215\225\350\216\267\346\234\272\345\210\266.md.93a23d57.lean.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_JS\345\274\202\345\270\270\346\215\225\350\216\267\346\234\272\345\210\266.md.1e9b4755.lean.js"
@@ -1 +1 @@
-import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/JS异常捕获机制.md","filePath":"guide/javaScript相关/JS异常捕获机制.md","lastUpdated":1707358495000}'),r={name:"guide/javaScript相关/JS异常捕获机制.md"};function c(o,s,_,i,d,n){return t(),a("div")}const f=e(r,[["render",c]]);export{m as __pageData,f as default};
+import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/JS异常捕获机制.md","filePath":"guide/javaScript相关/JS异常捕获机制.md","lastUpdated":1707358769000}'),r={name:"guide/javaScript相关/JS异常捕获机制.md"};function c(o,s,_,i,d,n){return t(),a("div")}const f=e(r,[["render",c]]);export{m as __pageData,f as default};
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_JavaScript\346\211\247\350\241\214\346\234\272\345\210\266.md.912ab316.js" "b/assets/guide_javaScript\347\233\270\345\205\263_JavaScript\346\211\247\350\241\214\346\234\272\345\210\266.md.8aebbf95.js"
similarity index 92%
rename from "assets/guide_javaScript\347\233\270\345\205\263_JavaScript\346\211\247\350\241\214\346\234\272\345\210\266.md.912ab316.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_JavaScript\346\211\247\350\241\214\346\234\272\345\210\266.md.8aebbf95.js"
index e2073088..74730ec9 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_JavaScript\346\211\247\350\241\214\346\234\272\345\210\266.md.912ab316.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_JavaScript\346\211\247\350\241\214\346\234\272\345\210\266.md.8aebbf95.js"
@@ -1 +1 @@
-import{_ as t,o as e,c as r,k as a,a as c}from"./chunks/framework.b6910bb2.js";const f=JSON.parse('{"title":"JavaScript 执行机制","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/JavaScript执行机制.md","filePath":"guide/javaScript相关/JavaScript执行机制.md","lastUpdated":1707358495000}'),i={name:"guide/javaScript相关/JavaScript执行机制.md"},s=a("h1",{id:"javascript-执行机制",tabindex:"-1"},[c("JavaScript 执行机制 "),a("a",{class:"header-anchor",href:"#javascript-执行机制","aria-label":'Permalink to "JavaScript 执行机制"'},"​")],-1),o=a("p",null,"先编译后执行",-1),p=a("p",null,"编译 -> 创建上下文、创建变量环境、创建词法环境 -> 将上下文压入执行调用栈执行代码",-1),n=[s,o,p];function d(_,l,v,h,S,m){return e(),r("div",null,n)}const J=t(i,[["render",d]]);export{f as __pageData,J as default};
+import{_ as t,o as e,c as r,k as a,a as c}from"./chunks/framework.b6910bb2.js";const f=JSON.parse('{"title":"JavaScript 执行机制","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/JavaScript执行机制.md","filePath":"guide/javaScript相关/JavaScript执行机制.md","lastUpdated":1707358769000}'),i={name:"guide/javaScript相关/JavaScript执行机制.md"},s=a("h1",{id:"javascript-执行机制",tabindex:"-1"},[c("JavaScript 执行机制 "),a("a",{class:"header-anchor",href:"#javascript-执行机制","aria-label":'Permalink to "JavaScript 执行机制"'},"​")],-1),o=a("p",null,"先编译后执行",-1),p=a("p",null,"编译 -> 创建上下文、创建变量环境、创建词法环境 -> 将上下文压入执行调用栈执行代码",-1),n=[s,o,p];function d(_,l,v,h,S,m){return e(),r("div",null,n)}const J=t(i,[["render",d]]);export{f as __pageData,J as default};
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_JavaScript\346\211\247\350\241\214\346\234\272\345\210\266.md.912ab316.lean.js" "b/assets/guide_javaScript\347\233\270\345\205\263_JavaScript\346\211\247\350\241\214\346\234\272\345\210\266.md.8aebbf95.lean.js"
similarity index 92%
rename from "assets/guide_javaScript\347\233\270\345\205\263_JavaScript\346\211\247\350\241\214\346\234\272\345\210\266.md.912ab316.lean.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_JavaScript\346\211\247\350\241\214\346\234\272\345\210\266.md.8aebbf95.lean.js"
index e2073088..74730ec9 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_JavaScript\346\211\247\350\241\214\346\234\272\345\210\266.md.912ab316.lean.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_JavaScript\346\211\247\350\241\214\346\234\272\345\210\266.md.8aebbf95.lean.js"
@@ -1 +1 @@
-import{_ as t,o as e,c as r,k as a,a as c}from"./chunks/framework.b6910bb2.js";const f=JSON.parse('{"title":"JavaScript 执行机制","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/JavaScript执行机制.md","filePath":"guide/javaScript相关/JavaScript执行机制.md","lastUpdated":1707358495000}'),i={name:"guide/javaScript相关/JavaScript执行机制.md"},s=a("h1",{id:"javascript-执行机制",tabindex:"-1"},[c("JavaScript 执行机制 "),a("a",{class:"header-anchor",href:"#javascript-执行机制","aria-label":'Permalink to "JavaScript 执行机制"'},"​")],-1),o=a("p",null,"先编译后执行",-1),p=a("p",null,"编译 -> 创建上下文、创建变量环境、创建词法环境 -> 将上下文压入执行调用栈执行代码",-1),n=[s,o,p];function d(_,l,v,h,S,m){return e(),r("div",null,n)}const J=t(i,[["render",d]]);export{f as __pageData,J as default};
+import{_ as t,o as e,c as r,k as a,a as c}from"./chunks/framework.b6910bb2.js";const f=JSON.parse('{"title":"JavaScript 执行机制","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/JavaScript执行机制.md","filePath":"guide/javaScript相关/JavaScript执行机制.md","lastUpdated":1707358769000}'),i={name:"guide/javaScript相关/JavaScript执行机制.md"},s=a("h1",{id:"javascript-执行机制",tabindex:"-1"},[c("JavaScript 执行机制 "),a("a",{class:"header-anchor",href:"#javascript-执行机制","aria-label":'Permalink to "JavaScript 执行机制"'},"​")],-1),o=a("p",null,"先编译后执行",-1),p=a("p",null,"编译 -> 创建上下文、创建变量环境、创建词法环境 -> 将上下文压入执行调用栈执行代码",-1),n=[s,o,p];function d(_,l,v,h,S,m){return e(),r("div",null,n)}const J=t(i,[["render",d]]);export{f as __pageData,J as default};
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_JavaScript\347\274\226\350\257\221\346\234\272\345\210\266.md.1bf41186.lean.js" "b/assets/guide_javaScript\347\233\270\345\205\263_JavaScript\347\274\226\350\257\221\346\234\272\345\210\266.md.6b3e2f0d.js"
similarity index 92%
rename from "assets/guide_javaScript\347\233\270\345\205\263_JavaScript\347\274\226\350\257\221\346\234\272\345\210\266.md.1bf41186.lean.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_JavaScript\347\274\226\350\257\221\346\234\272\345\210\266.md.6b3e2f0d.js"
index 1ba15166..c89ebbb0 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_JavaScript\347\274\226\350\257\221\346\234\272\345\210\266.md.1bf41186.lean.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_JavaScript\347\274\226\350\257\221\346\234\272\345\210\266.md.6b3e2f0d.js"
@@ -1 +1 @@
-import{_ as t,o as e,c as r,k as a,a as c}from"./chunks/framework.b6910bb2.js";const f=JSON.parse('{"title":"JavaScript 编译机制","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/JavaScript编译机制.md","filePath":"guide/javaScript相关/JavaScript编译机制.md","lastUpdated":1707358495000}'),i={name:"guide/javaScript相关/JavaScript编译机制.md"},s=a("h1",{id:"javascript-编译机制",tabindex:"-1"},[c("JavaScript 编译机制 "),a("a",{class:"header-anchor",href:"#javascript-编译机制","aria-label":'Permalink to "JavaScript 编译机制"'},"​")],-1),o=a("p",null,"code -> 词法分析、语法分析 -> AST -> 生成字节码 -> 解释执行",-1),p=[s,o];function d(n,_,l,v,S,h){return e(),r("div",null,p)}const u=t(i,[["render",d]]);export{f as __pageData,u as default};
+import{_ as t,o as e,c as r,k as a,a as c}from"./chunks/framework.b6910bb2.js";const f=JSON.parse('{"title":"JavaScript 编译机制","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/JavaScript编译机制.md","filePath":"guide/javaScript相关/JavaScript编译机制.md","lastUpdated":1707358769000}'),i={name:"guide/javaScript相关/JavaScript编译机制.md"},s=a("h1",{id:"javascript-编译机制",tabindex:"-1"},[c("JavaScript 编译机制 "),a("a",{class:"header-anchor",href:"#javascript-编译机制","aria-label":'Permalink to "JavaScript 编译机制"'},"​")],-1),o=a("p",null,"code -> 词法分析、语法分析 -> AST -> 生成字节码 -> 解释执行",-1),p=[s,o];function d(n,_,l,v,S,h){return e(),r("div",null,p)}const u=t(i,[["render",d]]);export{f as __pageData,u as default};
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_JavaScript\347\274\226\350\257\221\346\234\272\345\210\266.md.1bf41186.js" "b/assets/guide_javaScript\347\233\270\345\205\263_JavaScript\347\274\226\350\257\221\346\234\272\345\210\266.md.6b3e2f0d.lean.js"
similarity index 92%
rename from "assets/guide_javaScript\347\233\270\345\205\263_JavaScript\347\274\226\350\257\221\346\234\272\345\210\266.md.1bf41186.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_JavaScript\347\274\226\350\257\221\346\234\272\345\210\266.md.6b3e2f0d.lean.js"
index 1ba15166..c89ebbb0 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_JavaScript\347\274\226\350\257\221\346\234\272\345\210\266.md.1bf41186.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_JavaScript\347\274\226\350\257\221\346\234\272\345\210\266.md.6b3e2f0d.lean.js"
@@ -1 +1 @@
-import{_ as t,o as e,c as r,k as a,a as c}from"./chunks/framework.b6910bb2.js";const f=JSON.parse('{"title":"JavaScript 编译机制","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/JavaScript编译机制.md","filePath":"guide/javaScript相关/JavaScript编译机制.md","lastUpdated":1707358495000}'),i={name:"guide/javaScript相关/JavaScript编译机制.md"},s=a("h1",{id:"javascript-编译机制",tabindex:"-1"},[c("JavaScript 编译机制 "),a("a",{class:"header-anchor",href:"#javascript-编译机制","aria-label":'Permalink to "JavaScript 编译机制"'},"​")],-1),o=a("p",null,"code -> 词法分析、语法分析 -> AST -> 生成字节码 -> 解释执行",-1),p=[s,o];function d(n,_,l,v,S,h){return e(),r("div",null,p)}const u=t(i,[["render",d]]);export{f as __pageData,u as default};
+import{_ as t,o as e,c as r,k as a,a as c}from"./chunks/framework.b6910bb2.js";const f=JSON.parse('{"title":"JavaScript 编译机制","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/JavaScript编译机制.md","filePath":"guide/javaScript相关/JavaScript编译机制.md","lastUpdated":1707358769000}'),i={name:"guide/javaScript相关/JavaScript编译机制.md"},s=a("h1",{id:"javascript-编译机制",tabindex:"-1"},[c("JavaScript 编译机制 "),a("a",{class:"header-anchor",href:"#javascript-编译机制","aria-label":'Permalink to "JavaScript 编译机制"'},"​")],-1),o=a("p",null,"code -> 词法分析、语法分析 -> AST -> 生成字节码 -> 解释执行",-1),p=[s,o];function d(n,_,l,v,S,h){return e(),r("div",null,p)}const u=t(i,[["render",d]]);export{f as __pageData,u as default};
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_Promise.md.fa3d3914.js" "b/assets/guide_javaScript\347\233\270\345\205\263_Promise.md.adc6aed9.js"
similarity index 99%
rename from "assets/guide_javaScript\347\233\270\345\205\263_Promise.md.fa3d3914.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_Promise.md.adc6aed9.js"
index 076ce950..e3334c92 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_Promise.md.fa3d3914.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_Promise.md.adc6aed9.js"
@@ -1,4 +1,4 @@
-import{_ as s,o as a,c as n,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/10.5cd5f050.png",o="/vitePress-blob/assets/7.6a576ff8.png",e="/vitePress-blob/assets/8.56c35364.png",r="/vitePress-blob/assets/9.bf057657.png",v=JSON.parse('{"title":"Promise 相关","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/Promise.md","filePath":"guide/javaScript相关/Promise.md","lastUpdated":1707358495000}'),t={name:"guide/javaScript相关/Promise.md"},c=l(`

Promise 相关

定义

Promise 有 3 种状态:

  • 等待状态 pending
  • 成功状态 resolved
  • 失败状态 rejected

当 Promise 状态是 Pending 时,可以转换为 Resolved 或者 Rejected 状态,一旦状态转换,就不会再改变。

resolved、rejected 是异步函数

then 默认返回一个 Promise 对象,第一个参数是 resolved 的回调函数,第二个参数是 rejected 的回调函数 catch 会返回一个 Promise 对象,catch 正常返回 resolved 状态,里面报错返回 rejected 状态

Promise.resolve

Promise.resolve(value) 返回一个成功状态的 promise 对象

js
/*
+import{_ as s,o as a,c as n,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/10.5cd5f050.png",o="/vitePress-blob/assets/7.6a576ff8.png",e="/vitePress-blob/assets/8.56c35364.png",r="/vitePress-blob/assets/9.bf057657.png",v=JSON.parse('{"title":"Promise 相关","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/Promise.md","filePath":"guide/javaScript相关/Promise.md","lastUpdated":1707358769000}'),t={name:"guide/javaScript相关/Promise.md"},c=l(`

Promise 相关

定义

Promise 有 3 种状态:

  • 等待状态 pending
  • 成功状态 resolved
  • 失败状态 rejected

当 Promise 状态是 Pending 时,可以转换为 Resolved 或者 Rejected 状态,一旦状态转换,就不会再改变。

resolved、rejected 是异步函数

then 默认返回一个 Promise 对象,第一个参数是 resolved 的回调函数,第二个参数是 rejected 的回调函数 catch 会返回一个 Promise 对象,catch 正常返回 resolved 状态,里面报错返回 rejected 状态

Promise.resolve

Promise.resolve(value) 返回一个成功状态的 promise 对象

js
/*
   如果 .then 函数参数不是一个函数,那么会将其封装成 v => v 函数, 这里的 v 是上一个 resolve 的返回值
 */
 
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_Promise.md.fa3d3914.lean.js" "b/assets/guide_javaScript\347\233\270\345\205\263_Promise.md.adc6aed9.lean.js"
similarity index 90%
rename from "assets/guide_javaScript\347\233\270\345\205\263_Promise.md.fa3d3914.lean.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_Promise.md.adc6aed9.lean.js"
index d5d64d7c..21854f62 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_Promise.md.fa3d3914.lean.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_Promise.md.adc6aed9.lean.js"
@@ -1 +1 @@
-import{_ as s,o as a,c as n,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/10.5cd5f050.png",o="/vitePress-blob/assets/7.6a576ff8.png",e="/vitePress-blob/assets/8.56c35364.png",r="/vitePress-blob/assets/9.bf057657.png",v=JSON.parse('{"title":"Promise 相关","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/Promise.md","filePath":"guide/javaScript相关/Promise.md","lastUpdated":1707358495000}'),t={name:"guide/javaScript相关/Promise.md"},c=l("",34),E=[c];function y(i,d,F,h,m,P){return a(),n("div",null,E)}const A=s(t,[["render",y]]);export{v as __pageData,A as default};
+import{_ as s,o as a,c as n,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/10.5cd5f050.png",o="/vitePress-blob/assets/7.6a576ff8.png",e="/vitePress-blob/assets/8.56c35364.png",r="/vitePress-blob/assets/9.bf057657.png",v=JSON.parse('{"title":"Promise 相关","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/Promise.md","filePath":"guide/javaScript相关/Promise.md","lastUpdated":1707358769000}'),t={name:"guide/javaScript相关/Promise.md"},c=l("",34),E=[c];function y(i,d,F,h,m,P){return a(),n("div",null,E)}const A=s(t,[["render",y]]);export{v as __pageData,A as default};
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_index.md.b2d97d4d.js" "b/assets/guide_javaScript\347\233\270\345\205\263_index.md.ff95dc7a.js"
similarity index 88%
rename from "assets/guide_javaScript\347\233\270\345\205\263_index.md.b2d97d4d.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_index.md.ff95dc7a.js"
index 79bb97be..2eda4c89 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_index.md.b2d97d4d.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_index.md.ff95dc7a.js"
@@ -1 +1 @@
-import{_ as e}from"./chunks/container.fad5294e.js";import{o as a,c as t,H as i}from"./chunks/framework.b6910bb2.js";const l=JSON.parse('{"title":"","description":"","frontmatter":{"aside":false,"outline":false},"headers":[],"relativePath":"guide/javaScript相关/index.md","filePath":"guide/javaScript相关/index.md","lastUpdated":1707358495000}'),r={name:"guide/javaScript相关/index.md"},m=Object.assign(r,{setup(s){return(c,d)=>(a(),t("div",null,[i(e,{url:"https://www.mubu.com/doc/2GzwQWqBS-K#m"})]))}});export{l as __pageData,m as default};
+import{_ as e}from"./chunks/container.fad5294e.js";import{o as a,c as t,H as i}from"./chunks/framework.b6910bb2.js";const l=JSON.parse('{"title":"","description":"","frontmatter":{"aside":false,"outline":false},"headers":[],"relativePath":"guide/javaScript相关/index.md","filePath":"guide/javaScript相关/index.md","lastUpdated":1707358769000}'),r={name:"guide/javaScript相关/index.md"},m=Object.assign(r,{setup(s){return(c,d)=>(a(),t("div",null,[i(e,{url:"https://www.mubu.com/doc/2GzwQWqBS-K#m"})]))}});export{l as __pageData,m as default};
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_index.md.b2d97d4d.lean.js" "b/assets/guide_javaScript\347\233\270\345\205\263_index.md.ff95dc7a.lean.js"
similarity index 88%
rename from "assets/guide_javaScript\347\233\270\345\205\263_index.md.b2d97d4d.lean.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_index.md.ff95dc7a.lean.js"
index 79bb97be..2eda4c89 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_index.md.b2d97d4d.lean.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_index.md.ff95dc7a.lean.js"
@@ -1 +1 @@
-import{_ as e}from"./chunks/container.fad5294e.js";import{o as a,c as t,H as i}from"./chunks/framework.b6910bb2.js";const l=JSON.parse('{"title":"","description":"","frontmatter":{"aside":false,"outline":false},"headers":[],"relativePath":"guide/javaScript相关/index.md","filePath":"guide/javaScript相关/index.md","lastUpdated":1707358495000}'),r={name:"guide/javaScript相关/index.md"},m=Object.assign(r,{setup(s){return(c,d)=>(a(),t("div",null,[i(e,{url:"https://www.mubu.com/doc/2GzwQWqBS-K#m"})]))}});export{l as __pageData,m as default};
+import{_ as e}from"./chunks/container.fad5294e.js";import{o as a,c as t,H as i}from"./chunks/framework.b6910bb2.js";const l=JSON.parse('{"title":"","description":"","frontmatter":{"aside":false,"outline":false},"headers":[],"relativePath":"guide/javaScript相关/index.md","filePath":"guide/javaScript相关/index.md","lastUpdated":1707358769000}'),r={name:"guide/javaScript相关/index.md"},m=Object.assign(r,{setup(s){return(c,d)=>(a(),t("div",null,[i(e,{url:"https://www.mubu.com/doc/2GzwQWqBS-K#m"})]))}});export{l as __pageData,m as default};
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_\344\272\213\344\273\266\345\276\252\347\216\257\346\234\272\345\210\266.md.050f60d8.js" "b/assets/guide_javaScript\347\233\270\345\205\263_\344\272\213\344\273\266\345\276\252\347\216\257\346\234\272\345\210\266.md.4ff87ac5.js"
similarity index 93%
rename from "assets/guide_javaScript\347\233\270\345\205\263_\344\272\213\344\273\266\345\276\252\347\216\257\346\234\272\345\210\266.md.050f60d8.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_\344\272\213\344\273\266\345\276\252\347\216\257\346\234\272\345\210\266.md.4ff87ac5.js"
index f9bcbae5..b62162ee 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_\344\272\213\344\273\266\345\276\252\347\216\257\346\234\272\345\210\266.md.050f60d8.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_\344\272\213\344\273\266\345\276\252\347\216\257\346\234\272\345\210\266.md.4ff87ac5.js"
@@ -1 +1 @@
-import{_ as a,o as t,c as s,k as e,a as r}from"./chunks/framework.b6910bb2.js";const v=JSON.parse('{"title":"事件循环机制","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/事件循环机制.md","filePath":"guide/javaScript相关/事件循环机制.md","lastUpdated":1707358495000}'),o={name:"guide/javaScript相关/事件循环机制.md"},c=e("h1",{id:"事件循环机制",tabindex:"-1"},[r("事件循环机制 "),e("a",{class:"header-anchor",href:"#事件循环机制","aria-label":'Permalink to "事件循环机制"'},"​")],-1),d=e("p",null,"执行 js 代码时,会将代码分成同步代码和异步代码, 同步任务会进入主线程执行,异步任务又分成宏任务和微任务 宏任务会进入宏任务队列,微任务会进入微任务队列 当主线程的代码执行完后,会查看是否有微任务队列,有则执行,无则进入下一个宏任务",-1),i=[c,d];function n(_,l,p,h,m,f){return t(),s("div",null,i)}const x=a(o,[["render",n]]);export{v as __pageData,x as default};
+import{_ as a,o as t,c as s,k as e,a as r}from"./chunks/framework.b6910bb2.js";const v=JSON.parse('{"title":"事件循环机制","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/事件循环机制.md","filePath":"guide/javaScript相关/事件循环机制.md","lastUpdated":1707358769000}'),o={name:"guide/javaScript相关/事件循环机制.md"},c=e("h1",{id:"事件循环机制",tabindex:"-1"},[r("事件循环机制 "),e("a",{class:"header-anchor",href:"#事件循环机制","aria-label":'Permalink to "事件循环机制"'},"​")],-1),d=e("p",null,"执行 js 代码时,会将代码分成同步代码和异步代码, 同步任务会进入主线程执行,异步任务又分成宏任务和微任务 宏任务会进入宏任务队列,微任务会进入微任务队列 当主线程的代码执行完后,会查看是否有微任务队列,有则执行,无则进入下一个宏任务",-1),i=[c,d];function n(_,l,p,h,m,f){return t(),s("div",null,i)}const x=a(o,[["render",n]]);export{v as __pageData,x as default};
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_\344\272\213\344\273\266\345\276\252\347\216\257\346\234\272\345\210\266.md.050f60d8.lean.js" "b/assets/guide_javaScript\347\233\270\345\205\263_\344\272\213\344\273\266\345\276\252\347\216\257\346\234\272\345\210\266.md.4ff87ac5.lean.js"
similarity index 93%
rename from "assets/guide_javaScript\347\233\270\345\205\263_\344\272\213\344\273\266\345\276\252\347\216\257\346\234\272\345\210\266.md.050f60d8.lean.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_\344\272\213\344\273\266\345\276\252\347\216\257\346\234\272\345\210\266.md.4ff87ac5.lean.js"
index f9bcbae5..b62162ee 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_\344\272\213\344\273\266\345\276\252\347\216\257\346\234\272\345\210\266.md.050f60d8.lean.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_\344\272\213\344\273\266\345\276\252\347\216\257\346\234\272\345\210\266.md.4ff87ac5.lean.js"
@@ -1 +1 @@
-import{_ as a,o as t,c as s,k as e,a as r}from"./chunks/framework.b6910bb2.js";const v=JSON.parse('{"title":"事件循环机制","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/事件循环机制.md","filePath":"guide/javaScript相关/事件循环机制.md","lastUpdated":1707358495000}'),o={name:"guide/javaScript相关/事件循环机制.md"},c=e("h1",{id:"事件循环机制",tabindex:"-1"},[r("事件循环机制 "),e("a",{class:"header-anchor",href:"#事件循环机制","aria-label":'Permalink to "事件循环机制"'},"​")],-1),d=e("p",null,"执行 js 代码时,会将代码分成同步代码和异步代码, 同步任务会进入主线程执行,异步任务又分成宏任务和微任务 宏任务会进入宏任务队列,微任务会进入微任务队列 当主线程的代码执行完后,会查看是否有微任务队列,有则执行,无则进入下一个宏任务",-1),i=[c,d];function n(_,l,p,h,m,f){return t(),s("div",null,i)}const x=a(o,[["render",n]]);export{v as __pageData,x as default};
+import{_ as a,o as t,c as s,k as e,a as r}from"./chunks/framework.b6910bb2.js";const v=JSON.parse('{"title":"事件循环机制","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/事件循环机制.md","filePath":"guide/javaScript相关/事件循环机制.md","lastUpdated":1707358769000}'),o={name:"guide/javaScript相关/事件循环机制.md"},c=e("h1",{id:"事件循环机制",tabindex:"-1"},[r("事件循环机制 "),e("a",{class:"header-anchor",href:"#事件循环机制","aria-label":'Permalink to "事件循环机制"'},"​")],-1),d=e("p",null,"执行 js 代码时,会将代码分成同步代码和异步代码, 同步任务会进入主线程执行,异步任务又分成宏任务和微任务 宏任务会进入宏任务队列,微任务会进入微任务队列 当主线程的代码执行完后,会查看是否有微任务队列,有则执行,无则进入下一个宏任务",-1),i=[c,d];function n(_,l,p,h,m,f){return t(),s("div",null,i)}const x=a(o,[["render",n]]);export{v as __pageData,x as default};
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_\345\236\203\345\234\276\345\233\236\346\224\266\346\234\272\345\210\266.md.e3ad0c7a.js" "b/assets/guide_javaScript\347\233\270\345\205\263_\345\236\203\345\234\276\345\233\236\346\224\266\346\234\272\345\210\266.md.6755966f.js"
similarity index 95%
rename from "assets/guide_javaScript\347\233\270\345\205\263_\345\236\203\345\234\276\345\233\236\346\224\266\346\234\272\345\210\266.md.e3ad0c7a.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_\345\236\203\345\234\276\345\233\236\346\224\266\346\234\272\345\210\266.md.6755966f.js"
index fa3ea988..68a1c910 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_\345\236\203\345\234\276\345\233\236\346\224\266\346\234\272\345\210\266.md.e3ad0c7a.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_\345\236\203\345\234\276\345\233\236\346\224\266\346\234\272\345\210\266.md.6755966f.js"
@@ -1 +1 @@
-import{_ as t,o as a,c as s,k as e,a as o}from"./chunks/framework.b6910bb2.js";const S=JSON.parse('{"title":"垃圾回收机制","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/垃圾回收机制.md","filePath":"guide/javaScript相关/垃圾回收机制.md","lastUpdated":1707358495000}'),r={name:"guide/javaScript相关/垃圾回收机制.md"},c=e("h1",{id:"垃圾回收机制",tabindex:"-1"},[o("垃圾回收机制 "),e("a",{class:"header-anchor",href:"#垃圾回收机制","aria-label":'Permalink to "垃圾回收机制"'},"​")],-1),n=e("p",null,"在 JS 的垃圾回收机制中,分成新生代和老生代 新生代采用的是 GC 算法,将新生代划分成活动对象区域和空闲区域,例如声明的对象会被放入活动对象区域,当活动对象区域填满时, 会进行一次垃圾回收,将存活的对象移入空闲区域并进行碎片空间整理,完成后再将空闲区域和活动对象区域进行翻转,依次循环回收。",-1),_=e("p",null,"当进行 2次 垃圾回收后,存活的对象会被放入老生代中,",-1),d=e("p",null,"老生代采用的是标记清除和标记整理算法,递归遍历堆内存的变量,将不需要使用的变量标记为垃圾数据,将需要使用的变量标记成活动变量,清除掉垃圾,然后进行标记整理碎片空间。",-1),i=[c,n,_,d];function l(p,h,u,m,f,v){return a(),s("div",null,i)}const g=t(r,[["render",l]]);export{S as __pageData,g as default};
+import{_ as t,o as a,c as s,k as e,a as o}from"./chunks/framework.b6910bb2.js";const S=JSON.parse('{"title":"垃圾回收机制","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/垃圾回收机制.md","filePath":"guide/javaScript相关/垃圾回收机制.md","lastUpdated":1707358769000}'),r={name:"guide/javaScript相关/垃圾回收机制.md"},c=e("h1",{id:"垃圾回收机制",tabindex:"-1"},[o("垃圾回收机制 "),e("a",{class:"header-anchor",href:"#垃圾回收机制","aria-label":'Permalink to "垃圾回收机制"'},"​")],-1),n=e("p",null,"在 JS 的垃圾回收机制中,分成新生代和老生代 新生代采用的是 GC 算法,将新生代划分成活动对象区域和空闲区域,例如声明的对象会被放入活动对象区域,当活动对象区域填满时, 会进行一次垃圾回收,将存活的对象移入空闲区域并进行碎片空间整理,完成后再将空闲区域和活动对象区域进行翻转,依次循环回收。",-1),_=e("p",null,"当进行 2次 垃圾回收后,存活的对象会被放入老生代中,",-1),d=e("p",null,"老生代采用的是标记清除和标记整理算法,递归遍历堆内存的变量,将不需要使用的变量标记为垃圾数据,将需要使用的变量标记成活动变量,清除掉垃圾,然后进行标记整理碎片空间。",-1),i=[c,n,_,d];function l(p,h,u,m,f,v){return a(),s("div",null,i)}const g=t(r,[["render",l]]);export{S as __pageData,g as default};
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_\345\236\203\345\234\276\345\233\236\346\224\266\346\234\272\345\210\266.md.e3ad0c7a.lean.js" "b/assets/guide_javaScript\347\233\270\345\205\263_\345\236\203\345\234\276\345\233\236\346\224\266\346\234\272\345\210\266.md.6755966f.lean.js"
similarity index 95%
rename from "assets/guide_javaScript\347\233\270\345\205\263_\345\236\203\345\234\276\345\233\236\346\224\266\346\234\272\345\210\266.md.e3ad0c7a.lean.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_\345\236\203\345\234\276\345\233\236\346\224\266\346\234\272\345\210\266.md.6755966f.lean.js"
index fa3ea988..68a1c910 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_\345\236\203\345\234\276\345\233\236\346\224\266\346\234\272\345\210\266.md.e3ad0c7a.lean.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_\345\236\203\345\234\276\345\233\236\346\224\266\346\234\272\345\210\266.md.6755966f.lean.js"
@@ -1 +1 @@
-import{_ as t,o as a,c as s,k as e,a as o}from"./chunks/framework.b6910bb2.js";const S=JSON.parse('{"title":"垃圾回收机制","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/垃圾回收机制.md","filePath":"guide/javaScript相关/垃圾回收机制.md","lastUpdated":1707358495000}'),r={name:"guide/javaScript相关/垃圾回收机制.md"},c=e("h1",{id:"垃圾回收机制",tabindex:"-1"},[o("垃圾回收机制 "),e("a",{class:"header-anchor",href:"#垃圾回收机制","aria-label":'Permalink to "垃圾回收机制"'},"​")],-1),n=e("p",null,"在 JS 的垃圾回收机制中,分成新生代和老生代 新生代采用的是 GC 算法,将新生代划分成活动对象区域和空闲区域,例如声明的对象会被放入活动对象区域,当活动对象区域填满时, 会进行一次垃圾回收,将存活的对象移入空闲区域并进行碎片空间整理,完成后再将空闲区域和活动对象区域进行翻转,依次循环回收。",-1),_=e("p",null,"当进行 2次 垃圾回收后,存活的对象会被放入老生代中,",-1),d=e("p",null,"老生代采用的是标记清除和标记整理算法,递归遍历堆内存的变量,将不需要使用的变量标记为垃圾数据,将需要使用的变量标记成活动变量,清除掉垃圾,然后进行标记整理碎片空间。",-1),i=[c,n,_,d];function l(p,h,u,m,f,v){return a(),s("div",null,i)}const g=t(r,[["render",l]]);export{S as __pageData,g as default};
+import{_ as t,o as a,c as s,k as e,a as o}from"./chunks/framework.b6910bb2.js";const S=JSON.parse('{"title":"垃圾回收机制","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/垃圾回收机制.md","filePath":"guide/javaScript相关/垃圾回收机制.md","lastUpdated":1707358769000}'),r={name:"guide/javaScript相关/垃圾回收机制.md"},c=e("h1",{id:"垃圾回收机制",tabindex:"-1"},[o("垃圾回收机制 "),e("a",{class:"header-anchor",href:"#垃圾回收机制","aria-label":'Permalink to "垃圾回收机制"'},"​")],-1),n=e("p",null,"在 JS 的垃圾回收机制中,分成新生代和老生代 新生代采用的是 GC 算法,将新生代划分成活动对象区域和空闲区域,例如声明的对象会被放入活动对象区域,当活动对象区域填满时, 会进行一次垃圾回收,将存活的对象移入空闲区域并进行碎片空间整理,完成后再将空闲区域和活动对象区域进行翻转,依次循环回收。",-1),_=e("p",null,"当进行 2次 垃圾回收后,存活的对象会被放入老生代中,",-1),d=e("p",null,"老生代采用的是标记清除和标记整理算法,递归遍历堆内存的变量,将不需要使用的变量标记为垃圾数据,将需要使用的变量标记成活动变量,清除掉垃圾,然后进行标记整理碎片空间。",-1),i=[c,n,_,d];function l(p,h,u,m,f,v){return a(),s("div",null,i)}const g=t(r,[["render",l]]);export{S as __pageData,g as default};
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_\345\237\272\347\241\200\346\246\202\345\277\265.md.6cb63943.js" "b/assets/guide_javaScript\347\233\270\345\205\263_\345\237\272\347\241\200\346\246\202\345\277\265.md.dcfd312c.js"
similarity index 99%
rename from "assets/guide_javaScript\347\233\270\345\205\263_\345\237\272\347\241\200\346\246\202\345\277\265.md.6cb63943.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_\345\237\272\347\241\200\346\246\202\345\277\265.md.dcfd312c.js"
index acda0fc1..c9f9e5e1 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_\345\237\272\347\241\200\346\246\202\345\277\265.md.6cb63943.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_\345\237\272\347\241\200\346\246\202\345\277\265.md.dcfd312c.js"
@@ -1,4 +1,4 @@
-import{_ as a,o as s,c as l,Q as n}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/4.8663f597.png",o="/vitePress-blob/assets/5.83f69d4f.png",_=JSON.parse('{"title":"3 基础概念","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/基础概念.md","filePath":"guide/javaScript相关/基础概念.md","lastUpdated":1707358495000}'),e={name:"guide/javaScript相关/基础概念.md"},t=n('

3 基础概念

3.1 闭包

执行外部函数返回内部函数后,虽然外部函数已经弹出调用栈了,但是内部函数对外部函数变量的引用依然保存在内存中,那么内部函数和这些变量的集合就叫做闭包。

闭包的好处: 1. 私有变量在内存中持久化

闭包的坏处: 1. 使用不当会造成内存泄漏

3.2 原型

在 js 中对象是由构造函数创建的,构造函数中会有一个 prototype 属性,指向一个对象,这个对象包含了由该构造函数创建的实例所共享的属性和方法, 由该构造函数创建的实例可以通过 proto 属性指向这个对象,这个对象就是我们所说的原型。

当想要访问对象的某个属性时,如果在当前对象查找不到,就会往该对象的原型查找,对象的原型也会有属于他的原型对象,如此循环,直到 null 停止,这就是我们所说的原型链

隐式原型: proto 显示原型: prototype

相关方法: 1. hasOwnProperty() 判断属性是否是实例自身的属性 2. Object.getPrototypeOf() 获取实例的原型

3.3 作用域

作用域分成全局作用域函数作用域块级作用域,它标识着一个变量是否合法 (编译过程中就已经确认了)

当查询一个变量时,如果当前作用域查询不到,会往上一级作用域查找,如此循环,直到全局作用域,这就是我们所说的作用域链

3.4 执行上下文

从类型上看

  1. 全局执行上下文
  2. 函数执行上下文
  3. eval 执行上下文

从生命周期上看

  1. 创建阶段
    • this 绑定
    • 创建词法环境 (let、const会被提升到词法环境)
    • 创建变量环境 (var 声明的变量会被提升到变量环境)
  2. 执行阶段
    • 对变量进行赋值,执行代码
  3. 回收阶段
    • 当执行上下文弹出调用站后,会对上下文进行回收

执行上下文栈: 当 JS 执行代码时,首先遇到全局代码,会创建一个全局执行上下文并压入执行栈中,当遇到函数调用时,就会为该函数创建一个新的函数执行上下文压入栈中, 引擎会执行位于执行上下文栈顶的函数,当函数执行完后,执行上下文会从栈中弹出,继续执行下一个上下文,当所有代码都执行完毕后,从栈中弹出全局执行上下文

执行上下文

3.5 类数组对象

一个拥有 length 属性和若干索引属性的对象就是类数组对象。

将类数组对象转化成数组的方法:

1 Array.from(arrayLike)
+import{_ as a,o as s,c as l,Q as n}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/4.8663f597.png",o="/vitePress-blob/assets/5.83f69d4f.png",_=JSON.parse('{"title":"3 基础概念","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/基础概念.md","filePath":"guide/javaScript相关/基础概念.md","lastUpdated":1707358769000}'),e={name:"guide/javaScript相关/基础概念.md"},t=n('

3 基础概念

3.1 闭包

执行外部函数返回内部函数后,虽然外部函数已经弹出调用栈了,但是内部函数对外部函数变量的引用依然保存在内存中,那么内部函数和这些变量的集合就叫做闭包。

闭包的好处: 1. 私有变量在内存中持久化

闭包的坏处: 1. 使用不当会造成内存泄漏

3.2 原型

在 js 中对象是由构造函数创建的,构造函数中会有一个 prototype 属性,指向一个对象,这个对象包含了由该构造函数创建的实例所共享的属性和方法, 由该构造函数创建的实例可以通过 proto 属性指向这个对象,这个对象就是我们所说的原型。

当想要访问对象的某个属性时,如果在当前对象查找不到,就会往该对象的原型查找,对象的原型也会有属于他的原型对象,如此循环,直到 null 停止,这就是我们所说的原型链

隐式原型: proto 显示原型: prototype

相关方法: 1. hasOwnProperty() 判断属性是否是实例自身的属性 2. Object.getPrototypeOf() 获取实例的原型

3.3 作用域

作用域分成全局作用域函数作用域块级作用域,它标识着一个变量是否合法 (编译过程中就已经确认了)

当查询一个变量时,如果当前作用域查询不到,会往上一级作用域查找,如此循环,直到全局作用域,这就是我们所说的作用域链

3.4 执行上下文

从类型上看

  1. 全局执行上下文
  2. 函数执行上下文
  3. eval 执行上下文

从生命周期上看

  1. 创建阶段
    • this 绑定
    • 创建词法环境 (let、const会被提升到词法环境)
    • 创建变量环境 (var 声明的变量会被提升到变量环境)
  2. 执行阶段
    • 对变量进行赋值,执行代码
  3. 回收阶段
    • 当执行上下文弹出调用站后,会对上下文进行回收

执行上下文栈: 当 JS 执行代码时,首先遇到全局代码,会创建一个全局执行上下文并压入执行栈中,当遇到函数调用时,就会为该函数创建一个新的函数执行上下文压入栈中, 引擎会执行位于执行上下文栈顶的函数,当函数执行完后,执行上下文会从栈中弹出,继续执行下一个上下文,当所有代码都执行完毕后,从栈中弹出全局执行上下文

执行上下文

3.5 类数组对象

一个拥有 length 属性和若干索引属性的对象就是类数组对象。

将类数组对象转化成数组的方法:

1 Array.from(arrayLike)
 
 2 Array.prototype.slice.call(arrayLike)
 
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_\345\237\272\347\241\200\346\246\202\345\277\265.md.6cb63943.lean.js" "b/assets/guide_javaScript\347\233\270\345\205\263_\345\237\272\347\241\200\346\246\202\345\277\265.md.dcfd312c.lean.js"
similarity index 88%
rename from "assets/guide_javaScript\347\233\270\345\205\263_\345\237\272\347\241\200\346\246\202\345\277\265.md.6cb63943.lean.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_\345\237\272\347\241\200\346\246\202\345\277\265.md.dcfd312c.lean.js"
index bc0076d5..6f7f7c9c 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_\345\237\272\347\241\200\346\246\202\345\277\265.md.6cb63943.lean.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_\345\237\272\347\241\200\346\246\202\345\277\265.md.dcfd312c.lean.js"
@@ -1 +1 @@
-import{_ as a,o as s,c as l,Q as n}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/4.8663f597.png",o="/vitePress-blob/assets/5.83f69d4f.png",_=JSON.parse('{"title":"3 基础概念","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/基础概念.md","filePath":"guide/javaScript相关/基础概念.md","lastUpdated":1707358495000}'),e={name:"guide/javaScript相关/基础概念.md"},t=n("",63),r=[t];function c(i,y,E,h,d,u){return s(),l("div",null,r)}const b=a(e,[["render",c]]);export{_ as __pageData,b as default};
+import{_ as a,o as s,c as l,Q as n}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/4.8663f597.png",o="/vitePress-blob/assets/5.83f69d4f.png",_=JSON.parse('{"title":"3 基础概念","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/基础概念.md","filePath":"guide/javaScript相关/基础概念.md","lastUpdated":1707358769000}'),e={name:"guide/javaScript相关/基础概念.md"},t=n("",63),r=[t];function c(i,y,E,h,d,u){return s(),l("div",null,r)}const b=a(e,[["render",c]]);export{_ as __pageData,b as default};
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_\345\255\227\347\254\246\344\270\262\345\270\270\350\247\201\347\232\204API.md.f8114998.js" "b/assets/guide_javaScript\347\233\270\345\205\263_\345\255\227\347\254\246\344\270\262\345\270\270\350\247\201\347\232\204API.md.19aad48b.js"
similarity index 86%
rename from "assets/guide_javaScript\347\233\270\345\205\263_\345\255\227\347\254\246\344\270\262\345\270\270\350\247\201\347\232\204API.md.f8114998.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_\345\255\227\347\254\246\344\270\262\345\270\270\350\247\201\347\232\204API.md.19aad48b.js"
index 66057686..f42a6e4a 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_\345\255\227\347\254\246\344\270\262\345\270\270\350\247\201\347\232\204API.md.f8114998.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_\345\255\227\347\254\246\344\270\262\345\270\270\350\247\201\347\232\204API.md.19aad48b.js"
@@ -1 +1 @@
-import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/字符串常见的API.md","filePath":"guide/javaScript相关/字符串常见的API.md","lastUpdated":1707358495000}'),r={name:"guide/javaScript相关/字符串常见的API.md"};function c(o,s,_,i,d,n){return t(),a("div")}const f=e(r,[["render",c]]);export{m as __pageData,f as default};
+import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/字符串常见的API.md","filePath":"guide/javaScript相关/字符串常见的API.md","lastUpdated":1707358769000}'),r={name:"guide/javaScript相关/字符串常见的API.md"};function c(o,s,_,i,d,n){return t(),a("div")}const f=e(r,[["render",c]]);export{m as __pageData,f as default};
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_\345\255\227\347\254\246\344\270\262\345\270\270\350\247\201\347\232\204API.md.f8114998.lean.js" "b/assets/guide_javaScript\347\233\270\345\205\263_\345\255\227\347\254\246\344\270\262\345\270\270\350\247\201\347\232\204API.md.19aad48b.lean.js"
similarity index 86%
rename from "assets/guide_javaScript\347\233\270\345\205\263_\345\255\227\347\254\246\344\270\262\345\270\270\350\247\201\347\232\204API.md.f8114998.lean.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_\345\255\227\347\254\246\344\270\262\345\270\270\350\247\201\347\232\204API.md.19aad48b.lean.js"
index 66057686..f42a6e4a 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_\345\255\227\347\254\246\344\270\262\345\270\270\350\247\201\347\232\204API.md.f8114998.lean.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_\345\255\227\347\254\246\344\270\262\345\270\270\350\247\201\347\232\204API.md.19aad48b.lean.js"
@@ -1 +1 @@
-import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/字符串常见的API.md","filePath":"guide/javaScript相关/字符串常见的API.md","lastUpdated":1707358495000}'),r={name:"guide/javaScript相关/字符串常见的API.md"};function c(o,s,_,i,d,n){return t(),a("div")}const f=e(r,[["render",c]]);export{m as __pageData,f as default};
+import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/字符串常见的API.md","filePath":"guide/javaScript相关/字符串常见的API.md","lastUpdated":1707358769000}'),r={name:"guide/javaScript相关/字符串常见的API.md"};function c(o,s,_,i,d,n){return t(),a("div")}const f=e(r,[["render",c]]);export{m as __pageData,f as default};
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_\345\256\232\344\271\211.md.ede1ac70.js" "b/assets/guide_javaScript\347\233\270\345\205\263_\345\256\232\344\271\211.md.c58c5632.js"
similarity index 94%
rename from "assets/guide_javaScript\347\233\270\345\205\263_\345\256\232\344\271\211.md.ede1ac70.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_\345\256\232\344\271\211.md.c58c5632.js"
index 9e39c4e0..faf43c8b 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_\345\256\232\344\271\211.md.ede1ac70.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_\345\256\232\344\271\211.md.c58c5632.js"
@@ -1 +1 @@
-import{_ as a,o as s,c as o,k as t,a as e}from"./chunks/framework.b6910bb2.js";const c="/vitePress-blob/assets/2.192658da.png",k=JSON.parse('{"title":"1 定义","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/定义.md","filePath":"guide/javaScript相关/定义.md","lastUpdated":1707358495000}'),r={name:"guide/javaScript相关/定义.md"},i=t("h1",{id:"_1-定义",tabindex:"-1"},[e("1 定义 "),t("a",{class:"header-anchor",href:"#_1-定义","aria-label":'Permalink to "1 定义"'},"​")],-1),n=t("p",null,"JavaScript 是一门动态语言,可以不需要定义变量类型",-1),_=t("p",null,"JavaScript 是一门弱类型语言,存在隐式类型转化",-1),d=t("p",null,"JavaScript 是一门解释型语言,在运行程序时动态编译",-1),l=t("p",null,"解释型语言特点: 1 每次运行都需要将源代码转化成机器码并执行,效率低 2 只要平台提供相应的解析器,就可以运行源代码,跨平台",-1),p=t("p",null,[e("V8 执行一段代码的流程图 "),t("img",{src:c,alt:"流程"})],-1),h=[i,n,_,d,l,p];function u(m,f,v,S,g,x){return s(),o("div",null,h)}const J=a(r,[["render",u]]);export{k as __pageData,J as default};
+import{_ as a,o as s,c as o,k as t,a as e}from"./chunks/framework.b6910bb2.js";const c="/vitePress-blob/assets/2.192658da.png",k=JSON.parse('{"title":"1 定义","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/定义.md","filePath":"guide/javaScript相关/定义.md","lastUpdated":1707358769000}'),r={name:"guide/javaScript相关/定义.md"},i=t("h1",{id:"_1-定义",tabindex:"-1"},[e("1 定义 "),t("a",{class:"header-anchor",href:"#_1-定义","aria-label":'Permalink to "1 定义"'},"​")],-1),n=t("p",null,"JavaScript 是一门动态语言,可以不需要定义变量类型",-1),_=t("p",null,"JavaScript 是一门弱类型语言,存在隐式类型转化",-1),d=t("p",null,"JavaScript 是一门解释型语言,在运行程序时动态编译",-1),l=t("p",null,"解释型语言特点: 1 每次运行都需要将源代码转化成机器码并执行,效率低 2 只要平台提供相应的解析器,就可以运行源代码,跨平台",-1),p=t("p",null,[e("V8 执行一段代码的流程图 "),t("img",{src:c,alt:"流程"})],-1),h=[i,n,_,d,l,p];function u(m,f,v,S,g,x){return s(),o("div",null,h)}const J=a(r,[["render",u]]);export{k as __pageData,J as default};
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_\345\256\232\344\271\211.md.ede1ac70.lean.js" "b/assets/guide_javaScript\347\233\270\345\205\263_\345\256\232\344\271\211.md.c58c5632.lean.js"
similarity index 94%
rename from "assets/guide_javaScript\347\233\270\345\205\263_\345\256\232\344\271\211.md.ede1ac70.lean.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_\345\256\232\344\271\211.md.c58c5632.lean.js"
index 9e39c4e0..faf43c8b 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_\345\256\232\344\271\211.md.ede1ac70.lean.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_\345\256\232\344\271\211.md.c58c5632.lean.js"
@@ -1 +1 @@
-import{_ as a,o as s,c as o,k as t,a as e}from"./chunks/framework.b6910bb2.js";const c="/vitePress-blob/assets/2.192658da.png",k=JSON.parse('{"title":"1 定义","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/定义.md","filePath":"guide/javaScript相关/定义.md","lastUpdated":1707358495000}'),r={name:"guide/javaScript相关/定义.md"},i=t("h1",{id:"_1-定义",tabindex:"-1"},[e("1 定义 "),t("a",{class:"header-anchor",href:"#_1-定义","aria-label":'Permalink to "1 定义"'},"​")],-1),n=t("p",null,"JavaScript 是一门动态语言,可以不需要定义变量类型",-1),_=t("p",null,"JavaScript 是一门弱类型语言,存在隐式类型转化",-1),d=t("p",null,"JavaScript 是一门解释型语言,在运行程序时动态编译",-1),l=t("p",null,"解释型语言特点: 1 每次运行都需要将源代码转化成机器码并执行,效率低 2 只要平台提供相应的解析器,就可以运行源代码,跨平台",-1),p=t("p",null,[e("V8 执行一段代码的流程图 "),t("img",{src:c,alt:"流程"})],-1),h=[i,n,_,d,l,p];function u(m,f,v,S,g,x){return s(),o("div",null,h)}const J=a(r,[["render",u]]);export{k as __pageData,J as default};
+import{_ as a,o as s,c as o,k as t,a as e}from"./chunks/framework.b6910bb2.js";const c="/vitePress-blob/assets/2.192658da.png",k=JSON.parse('{"title":"1 定义","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/定义.md","filePath":"guide/javaScript相关/定义.md","lastUpdated":1707358769000}'),r={name:"guide/javaScript相关/定义.md"},i=t("h1",{id:"_1-定义",tabindex:"-1"},[e("1 定义 "),t("a",{class:"header-anchor",href:"#_1-定义","aria-label":'Permalink to "1 定义"'},"​")],-1),n=t("p",null,"JavaScript 是一门动态语言,可以不需要定义变量类型",-1),_=t("p",null,"JavaScript 是一门弱类型语言,存在隐式类型转化",-1),d=t("p",null,"JavaScript 是一门解释型语言,在运行程序时动态编译",-1),l=t("p",null,"解释型语言特点: 1 每次运行都需要将源代码转化成机器码并执行,效率低 2 只要平台提供相应的解析器,就可以运行源代码,跨平台",-1),p=t("p",null,[e("V8 执行一段代码的流程图 "),t("img",{src:c,alt:"流程"})],-1),h=[i,n,_,d,l,p];function u(m,f,v,S,g,x){return s(),o("div",null,h)}const J=a(r,[["render",u]]);export{k as __pageData,J as default};
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_\345\257\271\350\261\241\345\270\270\350\247\201\347\232\204API.md.fa4ed7c9.js" "b/assets/guide_javaScript\347\233\270\345\205\263_\345\257\271\350\261\241\345\270\270\350\247\201\347\232\204API.md.4eca8a1e.js"
similarity index 86%
rename from "assets/guide_javaScript\347\233\270\345\205\263_\345\257\271\350\261\241\345\270\270\350\247\201\347\232\204API.md.fa4ed7c9.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_\345\257\271\350\261\241\345\270\270\350\247\201\347\232\204API.md.4eca8a1e.js"
index d2b605e1..e05eb2ab 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_\345\257\271\350\261\241\345\270\270\350\247\201\347\232\204API.md.fa4ed7c9.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_\345\257\271\350\261\241\345\270\270\350\247\201\347\232\204API.md.4eca8a1e.js"
@@ -1 +1 @@
-import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/对象常见的API.md","filePath":"guide/javaScript相关/对象常见的API.md","lastUpdated":1707358495000}'),r={name:"guide/javaScript相关/对象常见的API.md"};function c(o,s,i,_,d,n){return t(),a("div")}const f=e(r,[["render",c]]);export{m as __pageData,f as default};
+import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/对象常见的API.md","filePath":"guide/javaScript相关/对象常见的API.md","lastUpdated":1707358769000}'),r={name:"guide/javaScript相关/对象常见的API.md"};function c(o,s,i,_,d,n){return t(),a("div")}const f=e(r,[["render",c]]);export{m as __pageData,f as default};
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_\345\257\271\350\261\241\345\270\270\350\247\201\347\232\204API.md.fa4ed7c9.lean.js" "b/assets/guide_javaScript\347\233\270\345\205\263_\345\257\271\350\261\241\345\270\270\350\247\201\347\232\204API.md.4eca8a1e.lean.js"
similarity index 86%
rename from "assets/guide_javaScript\347\233\270\345\205\263_\345\257\271\350\261\241\345\270\270\350\247\201\347\232\204API.md.fa4ed7c9.lean.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_\345\257\271\350\261\241\345\270\270\350\247\201\347\232\204API.md.4eca8a1e.lean.js"
index d2b605e1..e05eb2ab 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_\345\257\271\350\261\241\345\270\270\350\247\201\347\232\204API.md.fa4ed7c9.lean.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_\345\257\271\350\261\241\345\270\270\350\247\201\347\232\204API.md.4eca8a1e.lean.js"
@@ -1 +1 @@
-import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/对象常见的API.md","filePath":"guide/javaScript相关/对象常见的API.md","lastUpdated":1707358495000}'),r={name:"guide/javaScript相关/对象常见的API.md"};function c(o,s,i,_,d,n){return t(),a("div")}const f=e(r,[["render",c]]);export{m as __pageData,f as default};
+import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/对象常见的API.md","filePath":"guide/javaScript相关/对象常见的API.md","lastUpdated":1707358769000}'),r={name:"guide/javaScript相关/对象常见的API.md"};function c(o,s,i,_,d,n){return t(),a("div")}const f=e(r,[["render",c]]);export{m as __pageData,f as default};
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\346\215\256\347\261\273\345\236\213.md.78b17d35.js" "b/assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\346\215\256\347\261\273\345\236\213.md.d9e46f31.js"
similarity index 99%
rename from "assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\346\215\256\347\261\273\345\236\213.md.78b17d35.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\346\215\256\347\261\273\345\236\213.md.d9e46f31.js"
index c0e79ff8..53264bf5 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\346\215\256\347\261\273\345\236\213.md.78b17d35.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\346\215\256\347\261\273\345\236\213.md.d9e46f31.js"
@@ -1,4 +1,4 @@
-import{_ as s,o as a,c as n,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/3.d5809f49.png",b=JSON.parse('{"title":"2 数据类型","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/数据类型.md","filePath":"guide/javaScript相关/数据类型.md","lastUpdated":1707358495000}'),o={name:"guide/javaScript相关/数据类型.md"},e=l(`

2 数据类型

2.1 数据类型

一共有 7 种基本数据类型

  • 1 Number - 基于 IEEE 754 标准实现,采用双精度 64 位二进制格式, -(2 ^ 63 - 1) ~ 2 ^ 63 - 1
  • 2 Boolean - 只有 true 和 false
  • 3 Undefined - 没有定义的值
  • 4 Null - 空值
  • 5 String - 字符串
  • 6 Symbol - 唯一不可修改的值
  • 7 BigInt - 大整数类型

一种引用类型

  • Object - 引用类型,存储在堆中

2.2 类型检测

2.2.1 typeof

判断基础数据类型,除了 null 也可以判断 function

js
typeof (function() {}) // function
+import{_ as s,o as a,c as n,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/3.d5809f49.png",b=JSON.parse('{"title":"2 数据类型","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/数据类型.md","filePath":"guide/javaScript相关/数据类型.md","lastUpdated":1707358769000}'),o={name:"guide/javaScript相关/数据类型.md"},e=l(`

2 数据类型

2.1 数据类型

一共有 7 种基本数据类型

  • 1 Number - 基于 IEEE 754 标准实现,采用双精度 64 位二进制格式, -(2 ^ 63 - 1) ~ 2 ^ 63 - 1
  • 2 Boolean - 只有 true 和 false
  • 3 Undefined - 没有定义的值
  • 4 Null - 空值
  • 5 String - 字符串
  • 6 Symbol - 唯一不可修改的值
  • 7 BigInt - 大整数类型

一种引用类型

  • Object - 引用类型,存储在堆中

2.2 类型检测

2.2.1 typeof

判断基础数据类型,除了 null 也可以判断 function

js
typeof (function() {}) // function
 typeof (() => {}) // function
typeof (function() {}) // function
 typeof (() => {}) // function

但数组、对象、null 都会返回 object

js
typeof [] // object
 typeof {} // object
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\346\215\256\347\261\273\345\236\213.md.78b17d35.lean.js" "b/assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\346\215\256\347\261\273\345\236\213.md.d9e46f31.lean.js"
similarity index 87%
rename from "assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\346\215\256\347\261\273\345\236\213.md.78b17d35.lean.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\346\215\256\347\261\273\345\236\213.md.d9e46f31.lean.js"
index c53d1b0d..8d9b7fe0 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\346\215\256\347\261\273\345\236\213.md.78b17d35.lean.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\346\215\256\347\261\273\345\236\213.md.d9e46f31.lean.js"
@@ -1 +1 @@
-import{_ as s,o as a,c as n,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/3.d5809f49.png",b=JSON.parse('{"title":"2 数据类型","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/数据类型.md","filePath":"guide/javaScript相关/数据类型.md","lastUpdated":1707358495000}'),o={name:"guide/javaScript相关/数据类型.md"},e=l("",59),t=[e];function c(r,y,E,i,d,u){return a(),n("div",null,t)}const g=s(o,[["render",c]]);export{b as __pageData,g as default};
+import{_ as s,o as a,c as n,Q as l}from"./chunks/framework.b6910bb2.js";const p="/vitePress-blob/assets/3.d5809f49.png",b=JSON.parse('{"title":"2 数据类型","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/数据类型.md","filePath":"guide/javaScript相关/数据类型.md","lastUpdated":1707358769000}'),o={name:"guide/javaScript相关/数据类型.md"},e=l("",59),t=[e];function c(r,y,E,i,d,u){return a(),n("div",null,t)}const g=s(o,[["render",c]]);export{b as __pageData,g as default};
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\347\273\204\345\270\270\350\247\201\347\232\204API.md.4cdc62b7.js" "b/assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\347\273\204\345\270\270\350\247\201\347\232\204API.md.2dc845e4.js"
similarity index 86%
rename from "assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\347\273\204\345\270\270\350\247\201\347\232\204API.md.4cdc62b7.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\347\273\204\345\270\270\350\247\201\347\232\204API.md.2dc845e4.js"
index 38ad5768..016aede1 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\347\273\204\345\270\270\350\247\201\347\232\204API.md.4cdc62b7.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\347\273\204\345\270\270\350\247\201\347\232\204API.md.2dc845e4.js"
@@ -1 +1 @@
-import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/数组常见的API.md","filePath":"guide/javaScript相关/数组常见的API.md","lastUpdated":1707358495000}'),r={name:"guide/javaScript相关/数组常见的API.md"};function c(o,s,i,_,d,n){return t(),a("div")}const f=e(r,[["render",c]]);export{m as __pageData,f as default};
+import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/数组常见的API.md","filePath":"guide/javaScript相关/数组常见的API.md","lastUpdated":1707358769000}'),r={name:"guide/javaScript相关/数组常见的API.md"};function c(o,s,i,_,d,n){return t(),a("div")}const f=e(r,[["render",c]]);export{m as __pageData,f as default};
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\347\273\204\345\270\270\350\247\201\347\232\204API.md.4cdc62b7.lean.js" "b/assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\347\273\204\345\270\270\350\247\201\347\232\204API.md.2dc845e4.lean.js"
similarity index 86%
rename from "assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\347\273\204\345\270\270\350\247\201\347\232\204API.md.4cdc62b7.lean.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\347\273\204\345\270\270\350\247\201\347\232\204API.md.2dc845e4.lean.js"
index 38ad5768..016aede1 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\347\273\204\345\270\270\350\247\201\347\232\204API.md.4cdc62b7.lean.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_\346\225\260\347\273\204\345\270\270\350\247\201\347\232\204API.md.2dc845e4.lean.js"
@@ -1 +1 @@
-import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/数组常见的API.md","filePath":"guide/javaScript相关/数组常见的API.md","lastUpdated":1707358495000}'),r={name:"guide/javaScript相关/数组常见的API.md"};function c(o,s,i,_,d,n){return t(),a("div")}const f=e(r,[["render",c]]);export{m as __pageData,f as default};
+import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/数组常见的API.md","filePath":"guide/javaScript相关/数组常见的API.md","lastUpdated":1707358769000}'),r={name:"guide/javaScript相关/数组常见的API.md"};function c(o,s,i,_,d,n){return t(),a("div")}const f=e(r,[["render",c]]);export{m as __pageData,f as default};
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_\346\226\260\347\232\204\350\277\220\347\256\227\347\254\246.md.4ef7cdb7.js" "b/assets/guide_javaScript\347\233\270\345\205\263_\346\226\260\347\232\204\350\277\220\347\256\227\347\254\246.md.d9d1e0c1.js"
similarity index 85%
rename from "assets/guide_javaScript\347\233\270\345\205\263_\346\226\260\347\232\204\350\277\220\347\256\227\347\254\246.md.4ef7cdb7.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_\346\226\260\347\232\204\350\277\220\347\256\227\347\254\246.md.d9d1e0c1.js"
index e46b6dd2..db0d7619 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_\346\226\260\347\232\204\350\277\220\347\256\227\347\254\246.md.4ef7cdb7.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_\346\226\260\347\232\204\350\277\220\347\256\227\347\254\246.md.d9d1e0c1.js"
@@ -1 +1 @@
-import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/新的运算符.md","filePath":"guide/javaScript相关/新的运算符.md","lastUpdated":1707358495000}'),r={name:"guide/javaScript相关/新的运算符.md"};function c(o,s,i,_,d,n){return t(),a("div")}const f=e(r,[["render",c]]);export{m as __pageData,f as default};
+import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/新的运算符.md","filePath":"guide/javaScript相关/新的运算符.md","lastUpdated":1707358769000}'),r={name:"guide/javaScript相关/新的运算符.md"};function c(o,s,i,_,d,n){return t(),a("div")}const f=e(r,[["render",c]]);export{m as __pageData,f as default};
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_\346\226\260\347\232\204\350\277\220\347\256\227\347\254\246.md.4ef7cdb7.lean.js" "b/assets/guide_javaScript\347\233\270\345\205\263_\346\226\260\347\232\204\350\277\220\347\256\227\347\254\246.md.d9d1e0c1.lean.js"
similarity index 85%
rename from "assets/guide_javaScript\347\233\270\345\205\263_\346\226\260\347\232\204\350\277\220\347\256\227\347\254\246.md.4ef7cdb7.lean.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_\346\226\260\347\232\204\350\277\220\347\256\227\347\254\246.md.d9d1e0c1.lean.js"
index e46b6dd2..db0d7619 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_\346\226\260\347\232\204\350\277\220\347\256\227\347\254\246.md.4ef7cdb7.lean.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_\346\226\260\347\232\204\350\277\220\347\256\227\347\254\246.md.d9d1e0c1.lean.js"
@@ -1 +1 @@
-import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/新的运算符.md","filePath":"guide/javaScript相关/新的运算符.md","lastUpdated":1707358495000}'),r={name:"guide/javaScript相关/新的运算符.md"};function c(o,s,i,_,d,n){return t(),a("div")}const f=e(r,[["render",c]]);export{m as __pageData,f as default};
+import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/新的运算符.md","filePath":"guide/javaScript相关/新的运算符.md","lastUpdated":1707358769000}'),r={name:"guide/javaScript相关/新的运算符.md"};function c(o,s,i,_,d,n){return t(),a("div")}const f=e(r,[["render",c]]);export{m as __pageData,f as default};
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217.md.9ee8e248.js" "b/assets/guide_javaScript\347\233\270\345\205\263_\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217.md.37761b31.js"
similarity index 85%
rename from "assets/guide_javaScript\347\233\270\345\205\263_\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217.md.9ee8e248.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217.md.37761b31.js"
index 2a2123b9..42be48f0 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217.md.9ee8e248.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217.md.37761b31.js"
@@ -1 +1 @@
-import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/正则表达式.md","filePath":"guide/javaScript相关/正则表达式.md","lastUpdated":1707358495000}'),r={name:"guide/javaScript相关/正则表达式.md"};function c(o,s,i,_,d,n){return t(),a("div")}const f=e(r,[["render",c]]);export{m as __pageData,f as default};
+import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/正则表达式.md","filePath":"guide/javaScript相关/正则表达式.md","lastUpdated":1707358769000}'),r={name:"guide/javaScript相关/正则表达式.md"};function c(o,s,i,_,d,n){return t(),a("div")}const f=e(r,[["render",c]]);export{m as __pageData,f as default};
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217.md.9ee8e248.lean.js" "b/assets/guide_javaScript\347\233\270\345\205\263_\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217.md.37761b31.lean.js"
similarity index 85%
rename from "assets/guide_javaScript\347\233\270\345\205\263_\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217.md.9ee8e248.lean.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217.md.37761b31.lean.js"
index 2a2123b9..42be48f0 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217.md.9ee8e248.lean.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217.md.37761b31.lean.js"
@@ -1 +1 @@
-import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/正则表达式.md","filePath":"guide/javaScript相关/正则表达式.md","lastUpdated":1707358495000}'),r={name:"guide/javaScript相关/正则表达式.md"};function c(o,s,i,_,d,n){return t(),a("div")}const f=e(r,[["render",c]]);export{m as __pageData,f as default};
+import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/正则表达式.md","filePath":"guide/javaScript相关/正则表达式.md","lastUpdated":1707358769000}'),r={name:"guide/javaScript相关/正则表达式.md"};function c(o,s,i,_,d,n){return t(),a("div")}const f=e(r,[["render",c]]);export{m as __pageData,f as default};
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_\347\273\247\346\211\277\347\233\270\345\205\263.md.237c7c62.js" "b/assets/guide_javaScript\347\233\270\345\205\263_\347\273\247\346\211\277\347\233\270\345\205\263.md.0b549acd.js"
similarity index 99%
rename from "assets/guide_javaScript\347\233\270\345\205\263_\347\273\247\346\211\277\347\233\270\345\205\263.md.237c7c62.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_\347\273\247\346\211\277\347\233\270\345\205\263.md.0b549acd.js"
index 8933b4d1..c8a18f48 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_\347\273\247\346\211\277\347\233\270\345\205\263.md.237c7c62.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_\347\273\247\346\211\277\347\233\270\345\205\263.md.0b549acd.js"
@@ -1,4 +1,4 @@
-import{_ as s,o as n,c as a,Q as p}from"./chunks/framework.b6910bb2.js";const d=JSON.parse('{"title":"继承","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/继承相关.md","filePath":"guide/javaScript相关/继承相关.md","lastUpdated":1707358495000}'),l={name:"guide/javaScript相关/继承相关.md"},o=p(`

继承

原型链继承

子类的原型对象是父类的实例对象

优点:

  • 简单易懂 缺点:
  • 1 实例化子类时,没办法向父类的构造函数传值
  • 2 所有子类实例共享一个父类,当某个子类修改了父类的属性时,其他子类也会受到影响
js
function Parent() {
+import{_ as s,o as n,c as a,Q as p}from"./chunks/framework.b6910bb2.js";const d=JSON.parse('{"title":"继承","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/继承相关.md","filePath":"guide/javaScript相关/继承相关.md","lastUpdated":1707358769000}'),l={name:"guide/javaScript相关/继承相关.md"},o=p(`

继承

原型链继承

子类的原型对象是父类的实例对象

优点:

  • 简单易懂 缺点:
  • 1 实例化子类时,没办法向父类的构造函数传值
  • 2 所有子类实例共享一个父类,当某个子类修改了父类的属性时,其他子类也会受到影响
js
function Parent() {
     this.name = 'parent';
 }
 
diff --git "a/assets/guide_javaScript\347\233\270\345\205\263_\347\273\247\346\211\277\347\233\270\345\205\263.md.237c7c62.lean.js" "b/assets/guide_javaScript\347\233\270\345\205\263_\347\273\247\346\211\277\347\233\270\345\205\263.md.0b549acd.lean.js"
similarity index 86%
rename from "assets/guide_javaScript\347\233\270\345\205\263_\347\273\247\346\211\277\347\233\270\345\205\263.md.237c7c62.lean.js"
rename to "assets/guide_javaScript\347\233\270\345\205\263_\347\273\247\346\211\277\347\233\270\345\205\263.md.0b549acd.lean.js"
index 6e580163..239862b8 100644
--- "a/assets/guide_javaScript\347\233\270\345\205\263_\347\273\247\346\211\277\347\233\270\345\205\263.md.237c7c62.lean.js"
+++ "b/assets/guide_javaScript\347\233\270\345\205\263_\347\273\247\346\211\277\347\233\270\345\205\263.md.0b549acd.lean.js"
@@ -1 +1 @@
-import{_ as s,o as n,c as a,Q as p}from"./chunks/framework.b6910bb2.js";const d=JSON.parse('{"title":"继承","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/继承相关.md","filePath":"guide/javaScript相关/继承相关.md","lastUpdated":1707358495000}'),l={name:"guide/javaScript相关/继承相关.md"},o=p("",31),e=[o];function t(c,r,E,y,i,F){return n(),a("div",null,e)}const h=s(l,[["render",t]]);export{d as __pageData,h as default};
+import{_ as s,o as n,c as a,Q as p}from"./chunks/framework.b6910bb2.js";const d=JSON.parse('{"title":"继承","description":"","frontmatter":{},"headers":[],"relativePath":"guide/javaScript相关/继承相关.md","filePath":"guide/javaScript相关/继承相关.md","lastUpdated":1707358769000}'),l={name:"guide/javaScript相关/继承相关.md"},o=p("",31),e=[o];function t(c,r,E,y,i,F){return n(),a("div",null,e)}const h=s(l,[["render",t]]);export{d as __pageData,h as default};
diff --git a/assets/guide_webpack_index.md.e15e3d26.js b/assets/guide_webpack_index.md.f2414c6a.js
similarity index 94%
rename from assets/guide_webpack_index.md.e15e3d26.js
rename to assets/guide_webpack_index.md.f2414c6a.js
index 394cd09d..d21cc87a 100644
--- a/assets/guide_webpack_index.md.e15e3d26.js
+++ b/assets/guide_webpack_index.md.f2414c6a.js
@@ -1 +1 @@
-import{_ as t,o as a,c as r,k as e,a as o}from"./chunks/framework.b6910bb2.js";const f=JSON.parse('{"title":"参考文章","description":"","frontmatter":{},"headers":[],"relativePath":"guide/webpack/index.md","filePath":"guide/webpack/index.md","lastUpdated":1707358495000}'),i={name:"guide/webpack/index.md"},n=e("h1",{id:"参考文章",tabindex:"-1"},[o("参考文章 "),e("a",{class:"header-anchor",href:"#参考文章","aria-label":'Permalink to "参考文章"'},"​")],-1),s=e("ul",null,[e("li",null,[e("a",{href:"https://www.youtube.com/watch?v=Gc9-7PBqOC8&list=LLHK1mTHpwrUeYgF5gu-Kd4g",target:"_blank",rel:"noreferrer"},"https://www.youtube.com/watch?v=Gc9-7PBqOC8&list=LLHK1mTHpwrUeYgF5gu-Kd4g")]),e("li",null,[e("a",{href:"https://tsejx.github.io/webpack-guidebook/infra/implementation-principle/workflow",target:"_blank",rel:"noreferrer"},"https://tsejx.github.io/webpack-guidebook/infra/implementation-principle/workflow")])],-1),c=[n,s];function l(d,p,u,h,w,_){return a(),r("div",null,c)}const g=t(i,[["render",l]]);export{f as __pageData,g as default};
+import{_ as t,o as a,c as r,k as e,a as o}from"./chunks/framework.b6910bb2.js";const f=JSON.parse('{"title":"参考文章","description":"","frontmatter":{},"headers":[],"relativePath":"guide/webpack/index.md","filePath":"guide/webpack/index.md","lastUpdated":1707358769000}'),i={name:"guide/webpack/index.md"},n=e("h1",{id:"参考文章",tabindex:"-1"},[o("参考文章 "),e("a",{class:"header-anchor",href:"#参考文章","aria-label":'Permalink to "参考文章"'},"​")],-1),s=e("ul",null,[e("li",null,[e("a",{href:"https://www.youtube.com/watch?v=Gc9-7PBqOC8&list=LLHK1mTHpwrUeYgF5gu-Kd4g",target:"_blank",rel:"noreferrer"},"https://www.youtube.com/watch?v=Gc9-7PBqOC8&list=LLHK1mTHpwrUeYgF5gu-Kd4g")]),e("li",null,[e("a",{href:"https://tsejx.github.io/webpack-guidebook/infra/implementation-principle/workflow",target:"_blank",rel:"noreferrer"},"https://tsejx.github.io/webpack-guidebook/infra/implementation-principle/workflow")])],-1),c=[n,s];function l(d,p,u,h,w,_){return a(),r("div",null,c)}const g=t(i,[["render",l]]);export{f as __pageData,g as default};
diff --git a/assets/guide_webpack_index.md.e15e3d26.lean.js b/assets/guide_webpack_index.md.f2414c6a.lean.js
similarity index 94%
rename from assets/guide_webpack_index.md.e15e3d26.lean.js
rename to assets/guide_webpack_index.md.f2414c6a.lean.js
index 394cd09d..d21cc87a 100644
--- a/assets/guide_webpack_index.md.e15e3d26.lean.js
+++ b/assets/guide_webpack_index.md.f2414c6a.lean.js
@@ -1 +1 @@
-import{_ as t,o as a,c as r,k as e,a as o}from"./chunks/framework.b6910bb2.js";const f=JSON.parse('{"title":"参考文章","description":"","frontmatter":{},"headers":[],"relativePath":"guide/webpack/index.md","filePath":"guide/webpack/index.md","lastUpdated":1707358495000}'),i={name:"guide/webpack/index.md"},n=e("h1",{id:"参考文章",tabindex:"-1"},[o("参考文章 "),e("a",{class:"header-anchor",href:"#参考文章","aria-label":'Permalink to "参考文章"'},"​")],-1),s=e("ul",null,[e("li",null,[e("a",{href:"https://www.youtube.com/watch?v=Gc9-7PBqOC8&list=LLHK1mTHpwrUeYgF5gu-Kd4g",target:"_blank",rel:"noreferrer"},"https://www.youtube.com/watch?v=Gc9-7PBqOC8&list=LLHK1mTHpwrUeYgF5gu-Kd4g")]),e("li",null,[e("a",{href:"https://tsejx.github.io/webpack-guidebook/infra/implementation-principle/workflow",target:"_blank",rel:"noreferrer"},"https://tsejx.github.io/webpack-guidebook/infra/implementation-principle/workflow")])],-1),c=[n,s];function l(d,p,u,h,w,_){return a(),r("div",null,c)}const g=t(i,[["render",l]]);export{f as __pageData,g as default};
+import{_ as t,o as a,c as r,k as e,a as o}from"./chunks/framework.b6910bb2.js";const f=JSON.parse('{"title":"参考文章","description":"","frontmatter":{},"headers":[],"relativePath":"guide/webpack/index.md","filePath":"guide/webpack/index.md","lastUpdated":1707358769000}'),i={name:"guide/webpack/index.md"},n=e("h1",{id:"参考文章",tabindex:"-1"},[o("参考文章 "),e("a",{class:"header-anchor",href:"#参考文章","aria-label":'Permalink to "参考文章"'},"​")],-1),s=e("ul",null,[e("li",null,[e("a",{href:"https://www.youtube.com/watch?v=Gc9-7PBqOC8&list=LLHK1mTHpwrUeYgF5gu-Kd4g",target:"_blank",rel:"noreferrer"},"https://www.youtube.com/watch?v=Gc9-7PBqOC8&list=LLHK1mTHpwrUeYgF5gu-Kd4g")]),e("li",null,[e("a",{href:"https://tsejx.github.io/webpack-guidebook/infra/implementation-principle/workflow",target:"_blank",rel:"noreferrer"},"https://tsejx.github.io/webpack-guidebook/infra/implementation-principle/workflow")])],-1),c=[n,s];function l(d,p,u,h,w,_){return a(),r("div",null,c)}const g=t(i,[["render",l]]);export{f as __pageData,g as default};
diff --git "a/assets/guide_webpack_\346\236\204\345\273\272\346\265\201\347\250\213.md.379b02b0.js" "b/assets/guide_webpack_\346\236\204\345\273\272\346\265\201\347\250\213.md.07f4ea79.js"
similarity index 99%
rename from "assets/guide_webpack_\346\236\204\345\273\272\346\265\201\347\250\213.md.379b02b0.js"
rename to "assets/guide_webpack_\346\236\204\345\273\272\346\265\201\347\250\213.md.07f4ea79.js"
index 9fee76f3..81b77be5 100644
--- "a/assets/guide_webpack_\346\236\204\345\273\272\346\265\201\347\250\213.md.379b02b0.js"
+++ "b/assets/guide_webpack_\346\236\204\345\273\272\346\265\201\347\250\213.md.07f4ea79.js"
@@ -1,4 +1,4 @@
-import{_ as a,o as s,c as l,Q as n}from"./chunks/framework.b6910bb2.js";const y=JSON.parse('{"title":"构建流程","description":"","frontmatter":{},"headers":[],"relativePath":"guide/webpack/构建流程.md","filePath":"guide/webpack/构建流程.md","lastUpdated":1707358495000}'),e={name:"guide/webpack/构建流程.md"},p=n(`

构建流程

工作流程

webpack 的工作流程是一个串行的过程,从启动到结束会依次执行以下流程:

  1. 初始化参数:从配置文件和 Shell 语句中读取与合并参数,得出最终的参数;
  2. 开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译;
  3. 确定入口:根据配置中的 entry 确定入口文件;
  4. 编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行编译,再找出该模块依赖的模块,得到了每个模块被编译后的 最终内容 以及他们之间的 依赖关系图
  5. 输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会;
  6. 输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。

常见的问题

Module、Chunk、Bundle 的区别

module: 模块,一个模块就是一个文件

chunk: 代码块,一个 chunk 可以由多个模块组合而成

bundle: webpack 打包出来的文件

Loader 和 Plugin

loader 是一个加载器,让 webpack 拥有加载和解析非 JavaScript 文件的能力

Plugin 是一个插件,是对 webpack 功能的扩展,让 webpack 具有更高的灵活性

Compiler 和 Compilation 的区别

Compiler 对象在 webpack 启动时候被实例化,可以访问当前运行的 webpack 配置,包括 entry、output、loader 等配置,它是全局唯一的。

Plugin 的 apply 方法会传入一个 Compiler 对象,通过这个 Compiler 对象可以注册各种钩子函数,执行插件任务,也可以通过该对象获取配置信息。

js
Compiler.plugin('emit', function(compilation, callback) {
+import{_ as a,o as s,c as l,Q as n}from"./chunks/framework.b6910bb2.js";const y=JSON.parse('{"title":"构建流程","description":"","frontmatter":{},"headers":[],"relativePath":"guide/webpack/构建流程.md","filePath":"guide/webpack/构建流程.md","lastUpdated":1707358769000}'),e={name:"guide/webpack/构建流程.md"},p=n(`

构建流程

工作流程

webpack 的工作流程是一个串行的过程,从启动到结束会依次执行以下流程:

  1. 初始化参数:从配置文件和 Shell 语句中读取与合并参数,得出最终的参数;
  2. 开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译;
  3. 确定入口:根据配置中的 entry 确定入口文件;
  4. 编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行编译,再找出该模块依赖的模块,得到了每个模块被编译后的 最终内容 以及他们之间的 依赖关系图
  5. 输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会;
  6. 输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。

常见的问题

Module、Chunk、Bundle 的区别

module: 模块,一个模块就是一个文件

chunk: 代码块,一个 chunk 可以由多个模块组合而成

bundle: webpack 打包出来的文件

Loader 和 Plugin

loader 是一个加载器,让 webpack 拥有加载和解析非 JavaScript 文件的能力

Plugin 是一个插件,是对 webpack 功能的扩展,让 webpack 具有更高的灵活性

Compiler 和 Compilation 的区别

Compiler 对象在 webpack 启动时候被实例化,可以访问当前运行的 webpack 配置,包括 entry、output、loader 等配置,它是全局唯一的。

Plugin 的 apply 方法会传入一个 Compiler 对象,通过这个 Compiler 对象可以注册各种钩子函数,执行插件任务,也可以通过该对象获取配置信息。

js
Compiler.plugin('emit', function(compilation, callback) {
     // emit 是异步 hook, 在生成之前输出到目录之前调用
  });
Compiler.plugin('emit', function(compilation, callback) {
     // emit 是异步 hook, 在生成之前输出到目录之前调用
diff --git "a/assets/guide_webpack_\346\236\204\345\273\272\346\265\201\347\250\213.md.379b02b0.lean.js" "b/assets/guide_webpack_\346\236\204\345\273\272\346\265\201\347\250\213.md.07f4ea79.lean.js"
similarity index 86%
rename from "assets/guide_webpack_\346\236\204\345\273\272\346\265\201\347\250\213.md.379b02b0.lean.js"
rename to "assets/guide_webpack_\346\236\204\345\273\272\346\265\201\347\250\213.md.07f4ea79.lean.js"
index f00ad670..2da1a659 100644
--- "a/assets/guide_webpack_\346\236\204\345\273\272\346\265\201\347\250\213.md.379b02b0.lean.js"
+++ "b/assets/guide_webpack_\346\236\204\345\273\272\346\265\201\347\250\213.md.07f4ea79.lean.js"
@@ -1 +1 @@
-import{_ as a,o as s,c as l,Q as n}from"./chunks/framework.b6910bb2.js";const y=JSON.parse('{"title":"构建流程","description":"","frontmatter":{},"headers":[],"relativePath":"guide/webpack/构建流程.md","filePath":"guide/webpack/构建流程.md","lastUpdated":1707358495000}'),e={name:"guide/webpack/构建流程.md"},p=n("",34),o=[p];function c(t,i,r,d,E,u){return s(),l("div",null,o)}const k=a(e,[["render",c]]);export{y as __pageData,k as default};
+import{_ as a,o as s,c as l,Q as n}from"./chunks/framework.b6910bb2.js";const y=JSON.parse('{"title":"构建流程","description":"","frontmatter":{},"headers":[],"relativePath":"guide/webpack/构建流程.md","filePath":"guide/webpack/构建流程.md","lastUpdated":1707358769000}'),e={name:"guide/webpack/构建流程.md"},p=n("",34),o=[p];function c(t,i,r,d,E,u){return s(),l("div",null,o)}const k=a(e,[["render",c]]);export{y as __pageData,k as default};
diff --git "a/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\246\202\350\246\201.md.1965a3c6.js" "b/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\246\202\350\246\201.md.f313a7ec.js"
similarity index 88%
rename from "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\246\202\350\246\201.md.1965a3c6.js"
rename to "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\246\202\350\246\201.md.f313a7ec.js"
index 2f202aba..3f4b03fc 100644
--- "a/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\246\202\350\246\201.md.1965a3c6.js"
+++ "b/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\246\202\350\246\201.md.f313a7ec.js"
@@ -1 +1 @@
-import{_ as e}from"./chunks/container.fad5294e.js";import{o as t,c as a,H as s}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{"aside":false,"outline":false},"headers":[],"relativePath":"guide/浏览器相关/概要.md","filePath":"guide/浏览器相关/概要.md","lastUpdated":1707358495000}'),o={name:"guide/浏览器相关/概要.md"},n=Object.assign(o,{setup(r){return(c,d)=>(t(),a("div",null,[s(e,{url:"https://www.mubu.com/doc/-ip51T7dbe#m"})]))}});export{m as __pageData,n as default};
+import{_ as e}from"./chunks/container.fad5294e.js";import{o as t,c as a,H as s}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{"aside":false,"outline":false},"headers":[],"relativePath":"guide/浏览器相关/概要.md","filePath":"guide/浏览器相关/概要.md","lastUpdated":1707358769000}'),o={name:"guide/浏览器相关/概要.md"},n=Object.assign(o,{setup(r){return(c,d)=>(t(),a("div",null,[s(e,{url:"https://www.mubu.com/doc/-ip51T7dbe#m"})]))}});export{m as __pageData,n as default};
diff --git "a/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\246\202\350\246\201.md.1965a3c6.lean.js" "b/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\246\202\350\246\201.md.f313a7ec.lean.js"
similarity index 88%
rename from "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\246\202\350\246\201.md.1965a3c6.lean.js"
rename to "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\246\202\350\246\201.md.f313a7ec.lean.js"
index 2f202aba..3f4b03fc 100644
--- "a/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\246\202\350\246\201.md.1965a3c6.lean.js"
+++ "b/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\246\202\350\246\201.md.f313a7ec.lean.js"
@@ -1 +1 @@
-import{_ as e}from"./chunks/container.fad5294e.js";import{o as t,c as a,H as s}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{"aside":false,"outline":false},"headers":[],"relativePath":"guide/浏览器相关/概要.md","filePath":"guide/浏览器相关/概要.md","lastUpdated":1707358495000}'),o={name:"guide/浏览器相关/概要.md"},n=Object.assign(o,{setup(r){return(c,d)=>(t(),a("div",null,[s(e,{url:"https://www.mubu.com/doc/-ip51T7dbe#m"})]))}});export{m as __pageData,n as default};
+import{_ as e}from"./chunks/container.fad5294e.js";import{o as t,c as a,H as s}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{"aside":false,"outline":false},"headers":[],"relativePath":"guide/浏览器相关/概要.md","filePath":"guide/浏览器相关/概要.md","lastUpdated":1707358769000}'),o={name:"guide/浏览器相关/概要.md"},n=Object.assign(o,{setup(r){return(c,d)=>(t(),a("div",null,[s(e,{url:"https://www.mubu.com/doc/-ip51T7dbe#m"})]))}});export{m as __pageData,n as default};
diff --git "a/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\206\205\346\240\270.md.ac5651f8.js" "b/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\206\205\346\240\270.md.9cd84d74.js"
similarity index 92%
rename from "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\206\205\346\240\270.md.ac5651f8.js"
rename to "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\206\205\346\240\270.md.9cd84d74.js"
index 324f62a8..b044f5d4 100644
--- "a/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\206\205\346\240\270.md.ac5651f8.js"
+++ "b/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\206\205\346\240\270.md.9cd84d74.js"
@@ -1 +1 @@
-import{_ as t,o as a,c as i,k as e,a as l}from"./chunks/framework.b6910bb2.js";const k=JSON.parse('{"title":"浏览器内核","description":"","frontmatter":{},"headers":[],"relativePath":"guide/浏览器相关/浏览器内核.md","filePath":"guide/浏览器相关/浏览器内核.md","lastUpdated":1707358495000}'),n={name:"guide/浏览器相关/浏览器内核.md"},o=e("h1",{id:"浏览器内核",tabindex:"-1"},[l("浏览器内核 "),e("a",{class:"header-anchor",href:"#浏览器内核","aria-label":'Permalink to "浏览器内核"'},"​")],-1),r=e("ul",null,[e("li",null,"Trident (IE)"),e("li",null,"Gecko (Firefox)"),e("li",null,"Webkit (Safari)"),e("li",null,"Blink (Chrome、Opera) Blink 是 Webkit 的一个分支")],-1),s=[o,r];function d(c,_,u,p,h,f){return a(),i("div",null,s)}const x=t(n,[["render",d]]);export{k as __pageData,x as default};
+import{_ as t,o as a,c as i,k as e,a as l}from"./chunks/framework.b6910bb2.js";const k=JSON.parse('{"title":"浏览器内核","description":"","frontmatter":{},"headers":[],"relativePath":"guide/浏览器相关/浏览器内核.md","filePath":"guide/浏览器相关/浏览器内核.md","lastUpdated":1707358769000}'),n={name:"guide/浏览器相关/浏览器内核.md"},o=e("h1",{id:"浏览器内核",tabindex:"-1"},[l("浏览器内核 "),e("a",{class:"header-anchor",href:"#浏览器内核","aria-label":'Permalink to "浏览器内核"'},"​")],-1),r=e("ul",null,[e("li",null,"Trident (IE)"),e("li",null,"Gecko (Firefox)"),e("li",null,"Webkit (Safari)"),e("li",null,"Blink (Chrome、Opera) Blink 是 Webkit 的一个分支")],-1),s=[o,r];function d(c,_,u,p,h,f){return a(),i("div",null,s)}const x=t(n,[["render",d]]);export{k as __pageData,x as default};
diff --git "a/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\206\205\346\240\270.md.ac5651f8.lean.js" "b/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\206\205\346\240\270.md.9cd84d74.lean.js"
similarity index 92%
rename from "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\206\205\346\240\270.md.ac5651f8.lean.js"
rename to "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\206\205\346\240\270.md.9cd84d74.lean.js"
index 324f62a8..b044f5d4 100644
--- "a/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\206\205\346\240\270.md.ac5651f8.lean.js"
+++ "b/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\206\205\346\240\270.md.9cd84d74.lean.js"
@@ -1 +1 @@
-import{_ as t,o as a,c as i,k as e,a as l}from"./chunks/framework.b6910bb2.js";const k=JSON.parse('{"title":"浏览器内核","description":"","frontmatter":{},"headers":[],"relativePath":"guide/浏览器相关/浏览器内核.md","filePath":"guide/浏览器相关/浏览器内核.md","lastUpdated":1707358495000}'),n={name:"guide/浏览器相关/浏览器内核.md"},o=e("h1",{id:"浏览器内核",tabindex:"-1"},[l("浏览器内核 "),e("a",{class:"header-anchor",href:"#浏览器内核","aria-label":'Permalink to "浏览器内核"'},"​")],-1),r=e("ul",null,[e("li",null,"Trident (IE)"),e("li",null,"Gecko (Firefox)"),e("li",null,"Webkit (Safari)"),e("li",null,"Blink (Chrome、Opera) Blink 是 Webkit 的一个分支")],-1),s=[o,r];function d(c,_,u,p,h,f){return a(),i("div",null,s)}const x=t(n,[["render",d]]);export{k as __pageData,x as default};
+import{_ as t,o as a,c as i,k as e,a as l}from"./chunks/framework.b6910bb2.js";const k=JSON.parse('{"title":"浏览器内核","description":"","frontmatter":{},"headers":[],"relativePath":"guide/浏览器相关/浏览器内核.md","filePath":"guide/浏览器相关/浏览器内核.md","lastUpdated":1707358769000}'),n={name:"guide/浏览器相关/浏览器内核.md"},o=e("h1",{id:"浏览器内核",tabindex:"-1"},[l("浏览器内核 "),e("a",{class:"header-anchor",href:"#浏览器内核","aria-label":'Permalink to "浏览器内核"'},"​")],-1),r=e("ul",null,[e("li",null,"Trident (IE)"),e("li",null,"Gecko (Firefox)"),e("li",null,"Webkit (Safari)"),e("li",null,"Blink (Chrome、Opera) Blink 是 Webkit 的一个分支")],-1),s=[o,r];function d(c,_,u,p,h,f){return a(),i("div",null,s)}const x=t(n,[["render",d]]);export{k as __pageData,x as default};
diff --git "a/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\256\211\345\205\250.md.0e2ad803.js" "b/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\256\211\345\205\250.md.cda4119d.js"
similarity index 99%
rename from "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\256\211\345\205\250.md.0e2ad803.js"
rename to "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\256\211\345\205\250.md.cda4119d.js"
index 3f7e225e..e626a65b 100644
--- "a/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\256\211\345\205\250.md.0e2ad803.js"
+++ "b/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\256\211\345\205\250.md.cda4119d.js"
@@ -1 +1 @@
-import{_ as l,o as i,c as e,Q as a}from"./chunks/framework.b6910bb2.js";const o="/vitePress-blob/assets/6.36673f2f.jpg",t="/vitePress-blob/assets/7.d0aefc74.jpg",r="/vitePress-blob/assets/8.28d1dcd9.jpg",s="/vitePress-blob/assets/9.b32cc031.jpg",q=JSON.parse('{"title":"浏览器安全","description":"","frontmatter":{},"headers":[],"relativePath":"guide/浏览器相关/浏览器安全.md","filePath":"guide/浏览器相关/浏览器安全.md","lastUpdated":1707358495000}'),n={name:"guide/浏览器相关/浏览器安全.md"},c=a('

浏览器安全

页面安全

同源策略

协议、域名、端口号都相同,才是同源。

限制

  1. 无法进行 DOM 操作
  2. 无法获取 Cookie、LocalStorage 等数据
  3. 无法向不同源发请求

开放

  1. 默认页面中可以引用任意第三方资源

    引入 CSP (内容安全策略)

    渲染流程图

  2. 只能请求同源的接口

    引入 CORS (跨域资源共享)

    • 简单请求 (HEAD/POST/GET请求)

      1. 浏览器在请求头上添加 Oirgin 字段,该字段用来说明请求来自那个源,服务器可以根据这个值决定是否同意这次请求
      2. 当服务器收到请求后,根据 Origin 判断是否在许可范围内
      3. 如果不在范围内,服务器会返回一个正常的 HTTP 响应,浏览器发现该响应头没有包含 Access-Control-Allow-Origin 字段,就会抛出一个错误,被 XMLHttpRequest 的 onerror 回调函数捕获 (由于正常响应,其状态码是 200,所以该错误不能通过状态码识别)
      4. 如果 Origin 在指定范围内,服务器返回的响应会多几个头信息字段
        • Access-Control-Allow-Origin(必须) 判断源是否可以跨域,该值要么是请求的 Origin,要么是 *

        • Access-Control-Allow-Credentials 是否允许发送 Cookie,默认为 false 如果 Access-Control-Allow-Origin 的值为 *,则无法发送 Cookie

        • Access-Control-Expose-Headers 制定其他的头信息字段可以暴露给客户端 因为默认情况下,只有 6 个字段可以被暴露,其他的都会被过滤掉

          简单请求

    • 非简单请求 (PUT/DELETE 或者 Content-type字段类型是 application/json)

      1. 浏览器发起 Option 预检请求
      2. 服务器收到预检请求后,检查
        • Origin 发起请求的源信息
        • Access-Control-Request-Method 浏览器会发起请求的方法
        • Access-Control-Request-Headers 请求额外发送的头信息字段
      3. 如果服务器否定预检请求,会返回一个正常的 HTTP 响应,但是没有任何的 CORS 相关的头信息字段,这是浏览器会认定服务器不同意预检,触发错误
      4. 如果服务器同意预检请求,会返回一个正常的 HTTP 响应,但是会多几个 CORS 相关的头信息字段
        • Access-Control-Allow-Origin (必须)
        • Access-Control-Allow-Credentials
        • Access-Control-Expose-Headers
        • Access-Control-Max-Age - 预检请求的有效期, 单位秒
        • Access-Control-Allow-Methods (必须)
        • Access-Control-Allow-Headers

      非简单请求

  3. 只能操作同源的DOM 引入了跨文档消息机制 postMessage

XSS 攻击

跨域脚本攻击。

类型

  1. 存储型

    脚本存储在服务器,用户访问时,脚本从服务器返回,浏览器执行脚本

  2. 反射型

    在文章链接参数上存放了一段恶意脚本,用户访问时,脚本从参数中取出,浏览器执行脚本

  3. DOM 型

    比如在搜索的时候,添加了一段脚本, 如果网站的搜索功能没有对用户输入进行适当的过滤和转义,搜索结果页面可能会将恶意的脚本代码直接插入到 HTML 中,并在用户浏览器中执行

    web 资源在传输或者用户在使用的过程中修改了 Web 页面的数据

预防

  1. 对输入的内容进行截取或者转义(encode)
  2. 限制输入的长度和类型
  3. 引入内容安全策略 (CSP)
  4. 对 Cookie 设置 HttpOnly 属性

CSRF 攻击

跨站请求伪造。

比如诱导用户点击链接,访问网址后,网址通过用户的登录信息伪造请求

必要条件

  1. 站点有 CSRF 漏洞
  2. 用户登录了
  3. 用户点击了诱导链接

预防

  1. 给 Cookie 新增 SameSite 属性
    • Strict: 第三方站点无法发送 Cookie
    • Lax (默认): 第三方站点如果是 GET 请求可以发送 Cookie
    • None 不做限制 Cookie的书写
  2. 通过请求的 Origin or Referer 字段判断请求合法性
  3. 在请求地址中添加 token 并验证

浏览器安全

将渲染进程放在沙箱中

  • 无法持久存储
  • 无法访问网络
  • 无法监听用户交互
  • 需要通过 IPC 与浏览器主进程通信,由浏览器进程处理后,再将结果传递给渲染进程

网络安全

HTTPS、重放攻击、验签

',26),p=[c];function h(d,u,_,b,C,m){return i(),e("div",null,p)}const f=l(n,[["render",h]]);export{q as __pageData,f as default}; +import{_ as l,o as i,c as e,Q as a}from"./chunks/framework.b6910bb2.js";const o="/vitePress-blob/assets/6.36673f2f.jpg",t="/vitePress-blob/assets/7.d0aefc74.jpg",r="/vitePress-blob/assets/8.28d1dcd9.jpg",s="/vitePress-blob/assets/9.b32cc031.jpg",q=JSON.parse('{"title":"浏览器安全","description":"","frontmatter":{},"headers":[],"relativePath":"guide/浏览器相关/浏览器安全.md","filePath":"guide/浏览器相关/浏览器安全.md","lastUpdated":1707358769000}'),n={name:"guide/浏览器相关/浏览器安全.md"},c=a('

浏览器安全

页面安全

同源策略

协议、域名、端口号都相同,才是同源。

限制

  1. 无法进行 DOM 操作
  2. 无法获取 Cookie、LocalStorage 等数据
  3. 无法向不同源发请求

开放

  1. 默认页面中可以引用任意第三方资源

    引入 CSP (内容安全策略)

    渲染流程图

  2. 只能请求同源的接口

    引入 CORS (跨域资源共享)

    • 简单请求 (HEAD/POST/GET请求)

      1. 浏览器在请求头上添加 Oirgin 字段,该字段用来说明请求来自那个源,服务器可以根据这个值决定是否同意这次请求
      2. 当服务器收到请求后,根据 Origin 判断是否在许可范围内
      3. 如果不在范围内,服务器会返回一个正常的 HTTP 响应,浏览器发现该响应头没有包含 Access-Control-Allow-Origin 字段,就会抛出一个错误,被 XMLHttpRequest 的 onerror 回调函数捕获 (由于正常响应,其状态码是 200,所以该错误不能通过状态码识别)
      4. 如果 Origin 在指定范围内,服务器返回的响应会多几个头信息字段
        • Access-Control-Allow-Origin(必须) 判断源是否可以跨域,该值要么是请求的 Origin,要么是 *

        • Access-Control-Allow-Credentials 是否允许发送 Cookie,默认为 false 如果 Access-Control-Allow-Origin 的值为 *,则无法发送 Cookie

        • Access-Control-Expose-Headers 制定其他的头信息字段可以暴露给客户端 因为默认情况下,只有 6 个字段可以被暴露,其他的都会被过滤掉

          简单请求

    • 非简单请求 (PUT/DELETE 或者 Content-type字段类型是 application/json)

      1. 浏览器发起 Option 预检请求
      2. 服务器收到预检请求后,检查
        • Origin 发起请求的源信息
        • Access-Control-Request-Method 浏览器会发起请求的方法
        • Access-Control-Request-Headers 请求额外发送的头信息字段
      3. 如果服务器否定预检请求,会返回一个正常的 HTTP 响应,但是没有任何的 CORS 相关的头信息字段,这是浏览器会认定服务器不同意预检,触发错误
      4. 如果服务器同意预检请求,会返回一个正常的 HTTP 响应,但是会多几个 CORS 相关的头信息字段
        • Access-Control-Allow-Origin (必须)
        • Access-Control-Allow-Credentials
        • Access-Control-Expose-Headers
        • Access-Control-Max-Age - 预检请求的有效期, 单位秒
        • Access-Control-Allow-Methods (必须)
        • Access-Control-Allow-Headers

      非简单请求

  3. 只能操作同源的DOM 引入了跨文档消息机制 postMessage

XSS 攻击

跨域脚本攻击。

类型

  1. 存储型

    脚本存储在服务器,用户访问时,脚本从服务器返回,浏览器执行脚本

  2. 反射型

    在文章链接参数上存放了一段恶意脚本,用户访问时,脚本从参数中取出,浏览器执行脚本

  3. DOM 型

    比如在搜索的时候,添加了一段脚本, 如果网站的搜索功能没有对用户输入进行适当的过滤和转义,搜索结果页面可能会将恶意的脚本代码直接插入到 HTML 中,并在用户浏览器中执行

    web 资源在传输或者用户在使用的过程中修改了 Web 页面的数据

预防

  1. 对输入的内容进行截取或者转义(encode)
  2. 限制输入的长度和类型
  3. 引入内容安全策略 (CSP)
  4. 对 Cookie 设置 HttpOnly 属性

CSRF 攻击

跨站请求伪造。

比如诱导用户点击链接,访问网址后,网址通过用户的登录信息伪造请求

必要条件

  1. 站点有 CSRF 漏洞
  2. 用户登录了
  3. 用户点击了诱导链接

预防

  1. 给 Cookie 新增 SameSite 属性
    • Strict: 第三方站点无法发送 Cookie
    • Lax (默认): 第三方站点如果是 GET 请求可以发送 Cookie
    • None 不做限制 Cookie的书写
  2. 通过请求的 Origin or Referer 字段判断请求合法性
  3. 在请求地址中添加 token 并验证

浏览器安全

将渲染进程放在沙箱中

  • 无法持久存储
  • 无法访问网络
  • 无法监听用户交互
  • 需要通过 IPC 与浏览器主进程通信,由浏览器进程处理后,再将结果传递给渲染进程

网络安全

HTTPS、重放攻击、验签

',26),p=[c];function h(d,u,_,b,C,m){return i(),e("div",null,p)}const f=l(n,[["render",h]]);export{q as __pageData,f as default}; diff --git "a/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\256\211\345\205\250.md.0e2ad803.lean.js" "b/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\256\211\345\205\250.md.cda4119d.lean.js" similarity index 90% rename from "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\256\211\345\205\250.md.0e2ad803.lean.js" rename to "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\256\211\345\205\250.md.cda4119d.lean.js" index a102634d..005ca094 100644 --- "a/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\256\211\345\205\250.md.0e2ad803.lean.js" +++ "b/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\345\256\211\345\205\250.md.cda4119d.lean.js" @@ -1 +1 @@ -import{_ as l,o as i,c as e,Q as a}from"./chunks/framework.b6910bb2.js";const o="/vitePress-blob/assets/6.36673f2f.jpg",t="/vitePress-blob/assets/7.d0aefc74.jpg",r="/vitePress-blob/assets/8.28d1dcd9.jpg",s="/vitePress-blob/assets/9.b32cc031.jpg",q=JSON.parse('{"title":"浏览器安全","description":"","frontmatter":{},"headers":[],"relativePath":"guide/浏览器相关/浏览器安全.md","filePath":"guide/浏览器相关/浏览器安全.md","lastUpdated":1707358495000}'),n={name:"guide/浏览器相关/浏览器安全.md"},c=a("",26),p=[c];function h(d,u,_,b,C,m){return i(),e("div",null,p)}const f=l(n,[["render",h]]);export{q as __pageData,f as default}; +import{_ as l,o as i,c as e,Q as a}from"./chunks/framework.b6910bb2.js";const o="/vitePress-blob/assets/6.36673f2f.jpg",t="/vitePress-blob/assets/7.d0aefc74.jpg",r="/vitePress-blob/assets/8.28d1dcd9.jpg",s="/vitePress-blob/assets/9.b32cc031.jpg",q=JSON.parse('{"title":"浏览器安全","description":"","frontmatter":{},"headers":[],"relativePath":"guide/浏览器相关/浏览器安全.md","filePath":"guide/浏览器相关/浏览器安全.md","lastUpdated":1707358769000}'),n={name:"guide/浏览器相关/浏览器安全.md"},c=a("",26),p=[c];function h(d,u,_,b,C,m){return i(),e("div",null,p)}const f=l(n,[["render",h]]);export{q as __pageData,f as default}; diff --git "a/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\346\265\201\347\250\213.md.a1f24938.js" "b/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\346\265\201\347\250\213.md.1331606e.js" similarity index 99% rename from "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\346\265\201\347\250\213.md.a1f24938.js" rename to "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\346\265\201\347\250\213.md.1331606e.js" index f2df4348..0c7baa23 100644 --- "a/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\346\265\201\347\250\213.md.a1f24938.js" +++ "b/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\346\265\201\347\250\213.md.1331606e.js" @@ -1 +1 @@ -import{_ as l,o as i,c as e,Q as a}from"./chunks/framework.b6910bb2.js";const t="/vitePress-blob/assets/3.8bc85ddd.png",o="/vitePress-blob/assets/4.9caf6b36.png",s="/vitePress-blob/assets/5.bbea4579.jpg",m=JSON.parse('{"title":"浏览器渲染流程","description":"","frontmatter":{},"headers":[],"relativePath":"guide/浏览器相关/浏览器渲染流程.md","filePath":"guide/浏览器相关/浏览器渲染流程.md","lastUpdated":1707358495000}'),r={name:"guide/浏览器相关/浏览器渲染流程.md"},n=a('

浏览器渲染流程

浏览器渲染流程

  1. 发出请求到页面首次绘制
    • 第一阶段: 页面提交请求到服务器响应,这时候页面还是之前的页面
    • 第二阶段: 获取到响应数据提交到渲染进程,进行 HTML 解析、CSS 加载、JS 加载、JS 执行、CSSOM 解析、布局树生成、页面绘制
    • 第三阶段: 等首次加载完成后,页面一点点被渲染
  2. HTML 解析
  3. 生成 CSSOM 树 CSS 不会阻塞 HTML 解析,但是会阻塞页面渲染,因为要生成渲染树
  4. 生成布局树 去除不显示的节点,计算样式
  5. 分层和合成机制
    • 分层: 分层树在布局树之后,分层树的每一个节点都是图层,如没有,则和父节点同一个图层
    • 绘制阶段: 根据图层在绘制阶段生成绘制指令
    • 光栅化: 根据绘制指令,将每个图层都绘制成一张图片
    • 合成: 合成线程将多张图片合成一张图片,然后显示在屏幕上 (由合成线程完成,不影响主线程) - 优化操作1: 合成线程内会维护一个光栅化线程池,将绘制指令列表提交到 GPU 进行光栅化,生成位图,放在内存中 - 优化操作2: 分块,合成线程将图层分块,优先渲染离屏幕最近的图块 - 合成线程
  6. 页面显示

常见的问题

1 从输入 URL 到页面渲染完成,发生了什么?

  1. 浏览器会根据用户输入的内容判断是关键字还是URL
  2. 如果是关键字,会将其组成成带有搜索关键字的URL,通过IPC进程通信发送给网络进程
  3. 网络进程发起请求前,会判断是否命中强缓存,如命中直接返回存储资源
  4. 否则发起请求,根据 DNS 解析获取域名对应的 IP 地址,进行 TCP、HTTP 连接
  5. 服务端收到请求后,会判断是否命中协商缓存,如命中则返回304状态码
  6. 如返回的是301、302状态码,浏览器会根据响应头返回的location字段,进行重定向
  7. 如是正常返回资源类型,浏览器会根据 content-type 对资源做相对应的操作,如果是下载类型则进行下载,如果是html类型则会提交到渲染进程进行解析
  8. 解析HTML,转换成浏览器能识别的DOM树
  9. 解析CSS,转化成浏览器能识别的CSS样式树
  10. 根据DOM和CSS样式树,通过布局计算生成布局树
  11. 根据布局树上的分层属性(z-index),生成分层树
  12. 根据分层树,生成绘制指令列表
  13. 渲染主线程会将绘制指令列表提交给合成线程
  14. 合成线程会发送指令给光栅化线程池,将绘制指令列表提交到 GPU 进行光栅化,生成位图,放在内存中
  15. 合成线程通信浏览器进程,浏览器进程将内存中的数据输出到显卡的后缓存区,在下一帧绘制之前,显卡的后缓冲区与前缓冲区对换,显示屏读取前缓冲区数据,显示到屏幕上

整体流程

2 回流和重绘有什么区别

回流:元素尺寸、定位改变,可能会影响到其他元素的位置

重绘:元素外观改变,如背景色、颜色,元素尺寸位置不改变且不影响其他元素

减少回流的方法:

  1. 集中修改
    • 修改样式,使用 class
    • 修改前将 DOM 改成 display: none,修改后再显示
    • 使用 DocumentFragment
    • resize、scroll 事件,使用防抖
  2. 使用 BFC
    • 隔离内部元素对外部元素的影响
  3. 脱离文档流
    • position: absolute、fixed
    • float
  4. 提升合成图层
    • CSS3 属性: will-change、transform: translate3d(0);
  5. 不是用 offsetHeight、getBoundingClientRect
    • 使用 intersectionObserver API - 判断元素是否在可视区域内

BFC: 块级格式化上下文 特点: BFC 内部元素不会影响到外部元素 形成条件:

  1. HTML 元素
  2. overflow: hidden、auto、scroll
  3. position: absolute、fixed
  4. float 元素
  5. display: inline-block、flex、inline-flex等

3 渲染流程图

渲染流程图

JS 会阻塞 HTML 的解析和渲染

CSS 不会阻塞 HTML 解析,但会阻塞 DOM 渲染,还会阻塞 JS 的执行

为什么 CSS 会阻塞 JS 的执行?

因为 JS 可能会操作 DOM 节点和 CSS 样式,因此浏览器为了获取到最新的 CSS 样式,样式表会在后面的 JS 执行前先加载执行完毕,所以 CSS 会阻塞 JS 的执行

',20),c=[n];function d(_,p,u,h,S,b){return i(),e("div",null,c)}const C=l(r,[["render",d]]);export{m as __pageData,C as default}; +import{_ as l,o as i,c as e,Q as a}from"./chunks/framework.b6910bb2.js";const t="/vitePress-blob/assets/3.8bc85ddd.png",o="/vitePress-blob/assets/4.9caf6b36.png",s="/vitePress-blob/assets/5.bbea4579.jpg",m=JSON.parse('{"title":"浏览器渲染流程","description":"","frontmatter":{},"headers":[],"relativePath":"guide/浏览器相关/浏览器渲染流程.md","filePath":"guide/浏览器相关/浏览器渲染流程.md","lastUpdated":1707358769000}'),r={name:"guide/浏览器相关/浏览器渲染流程.md"},n=a('

浏览器渲染流程

浏览器渲染流程

  1. 发出请求到页面首次绘制
    • 第一阶段: 页面提交请求到服务器响应,这时候页面还是之前的页面
    • 第二阶段: 获取到响应数据提交到渲染进程,进行 HTML 解析、CSS 加载、JS 加载、JS 执行、CSSOM 解析、布局树生成、页面绘制
    • 第三阶段: 等首次加载完成后,页面一点点被渲染
  2. HTML 解析
  3. 生成 CSSOM 树 CSS 不会阻塞 HTML 解析,但是会阻塞页面渲染,因为要生成渲染树
  4. 生成布局树 去除不显示的节点,计算样式
  5. 分层和合成机制
    • 分层: 分层树在布局树之后,分层树的每一个节点都是图层,如没有,则和父节点同一个图层
    • 绘制阶段: 根据图层在绘制阶段生成绘制指令
    • 光栅化: 根据绘制指令,将每个图层都绘制成一张图片
    • 合成: 合成线程将多张图片合成一张图片,然后显示在屏幕上 (由合成线程完成,不影响主线程) - 优化操作1: 合成线程内会维护一个光栅化线程池,将绘制指令列表提交到 GPU 进行光栅化,生成位图,放在内存中 - 优化操作2: 分块,合成线程将图层分块,优先渲染离屏幕最近的图块 - 合成线程
  6. 页面显示

常见的问题

1 从输入 URL 到页面渲染完成,发生了什么?

  1. 浏览器会根据用户输入的内容判断是关键字还是URL
  2. 如果是关键字,会将其组成成带有搜索关键字的URL,通过IPC进程通信发送给网络进程
  3. 网络进程发起请求前,会判断是否命中强缓存,如命中直接返回存储资源
  4. 否则发起请求,根据 DNS 解析获取域名对应的 IP 地址,进行 TCP、HTTP 连接
  5. 服务端收到请求后,会判断是否命中协商缓存,如命中则返回304状态码
  6. 如返回的是301、302状态码,浏览器会根据响应头返回的location字段,进行重定向
  7. 如是正常返回资源类型,浏览器会根据 content-type 对资源做相对应的操作,如果是下载类型则进行下载,如果是html类型则会提交到渲染进程进行解析
  8. 解析HTML,转换成浏览器能识别的DOM树
  9. 解析CSS,转化成浏览器能识别的CSS样式树
  10. 根据DOM和CSS样式树,通过布局计算生成布局树
  11. 根据布局树上的分层属性(z-index),生成分层树
  12. 根据分层树,生成绘制指令列表
  13. 渲染主线程会将绘制指令列表提交给合成线程
  14. 合成线程会发送指令给光栅化线程池,将绘制指令列表提交到 GPU 进行光栅化,生成位图,放在内存中
  15. 合成线程通信浏览器进程,浏览器进程将内存中的数据输出到显卡的后缓存区,在下一帧绘制之前,显卡的后缓冲区与前缓冲区对换,显示屏读取前缓冲区数据,显示到屏幕上

整体流程

2 回流和重绘有什么区别

回流:元素尺寸、定位改变,可能会影响到其他元素的位置

重绘:元素外观改变,如背景色、颜色,元素尺寸位置不改变且不影响其他元素

减少回流的方法:

  1. 集中修改
    • 修改样式,使用 class
    • 修改前将 DOM 改成 display: none,修改后再显示
    • 使用 DocumentFragment
    • resize、scroll 事件,使用防抖
  2. 使用 BFC
    • 隔离内部元素对外部元素的影响
  3. 脱离文档流
    • position: absolute、fixed
    • float
  4. 提升合成图层
    • CSS3 属性: will-change、transform: translate3d(0);
  5. 不是用 offsetHeight、getBoundingClientRect
    • 使用 intersectionObserver API - 判断元素是否在可视区域内

BFC: 块级格式化上下文 特点: BFC 内部元素不会影响到外部元素 形成条件:

  1. HTML 元素
  2. overflow: hidden、auto、scroll
  3. position: absolute、fixed
  4. float 元素
  5. display: inline-block、flex、inline-flex等

3 渲染流程图

渲染流程图

JS 会阻塞 HTML 的解析和渲染

CSS 不会阻塞 HTML 解析,但会阻塞 DOM 渲染,还会阻塞 JS 的执行

为什么 CSS 会阻塞 JS 的执行?

因为 JS 可能会操作 DOM 节点和 CSS 样式,因此浏览器为了获取到最新的 CSS 样式,样式表会在后面的 JS 执行前先加载执行完毕,所以 CSS 会阻塞 JS 的执行

',20),c=[n];function d(_,p,u,h,S,b){return i(),e("div",null,c)}const C=l(r,[["render",d]]);export{m as __pageData,C as default}; diff --git "a/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\346\265\201\347\250\213.md.a1f24938.lean.js" "b/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\346\265\201\347\250\213.md.1331606e.lean.js" similarity index 90% rename from "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\346\265\201\347\250\213.md.a1f24938.lean.js" rename to "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\346\265\201\347\250\213.md.1331606e.lean.js" index 5f5dd501..9d18e3af 100644 --- "a/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\346\265\201\347\250\213.md.a1f24938.lean.js" +++ "b/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\346\265\201\347\250\213.md.1331606e.lean.js" @@ -1 +1 @@ -import{_ as l,o as i,c as e,Q as a}from"./chunks/framework.b6910bb2.js";const t="/vitePress-blob/assets/3.8bc85ddd.png",o="/vitePress-blob/assets/4.9caf6b36.png",s="/vitePress-blob/assets/5.bbea4579.jpg",m=JSON.parse('{"title":"浏览器渲染流程","description":"","frontmatter":{},"headers":[],"relativePath":"guide/浏览器相关/浏览器渲染流程.md","filePath":"guide/浏览器相关/浏览器渲染流程.md","lastUpdated":1707358495000}'),r={name:"guide/浏览器相关/浏览器渲染流程.md"},n=a("",20),c=[n];function d(_,p,u,h,S,b){return i(),e("div",null,c)}const C=l(r,[["render",d]]);export{m as __pageData,C as default}; +import{_ as l,o as i,c as e,Q as a}from"./chunks/framework.b6910bb2.js";const t="/vitePress-blob/assets/3.8bc85ddd.png",o="/vitePress-blob/assets/4.9caf6b36.png",s="/vitePress-blob/assets/5.bbea4579.jpg",m=JSON.parse('{"title":"浏览器渲染流程","description":"","frontmatter":{},"headers":[],"relativePath":"guide/浏览器相关/浏览器渲染流程.md","filePath":"guide/浏览器相关/浏览器渲染流程.md","lastUpdated":1707358769000}'),r={name:"guide/浏览器相关/浏览器渲染流程.md"},n=a("",20),c=[n];function d(_,p,u,h,S,b){return i(),e("div",null,c)}const C=l(r,[["render",d]]);export{m as __pageData,C as default}; diff --git "a/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\347\274\223\345\255\230.md.8cddcc95.js" "b/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\347\274\223\345\255\230.md.88373219.js" similarity index 99% rename from "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\347\274\223\345\255\230.md.8cddcc95.js" rename to "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\347\274\223\345\255\230.md.88373219.js" index 15dd5726..408bd43c 100644 --- "a/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\347\274\223\345\255\230.md.8cddcc95.js" +++ "b/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\347\274\223\345\255\230.md.88373219.js" @@ -1,4 +1,4 @@ -import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const F=JSON.parse('{"title":"浏览器缓存","description":"","frontmatter":{},"headers":[],"relativePath":"guide/浏览器相关/浏览器缓存.md","filePath":"guide/浏览器相关/浏览器缓存.md","lastUpdated":1707358495000}'),p={name:"guide/浏览器相关/浏览器缓存.md"},o=l(`

浏览器缓存

缓存

从 HTTP 缓存策略来说

  • 强缓存
  • 协商缓存

从浏览器的缓存位置来说

  • Service Worker Cache (必须是 Https)
  • Memory Cache (内存缓存)
  • Disk Cache (硬盘缓存)
  • Push Cache (Http2.0)

本地存储

请求时携带,用于信息持久化

Local Storage 本地存储

用于长期不变化的数据,只能存储字符串

Session Storage 会话存储

用于存储当前会话的数据,只能存储字符串

indexedDB

非关系型数据库

Service Worker

运行在浏览器背后的独立线程(必须 HTTPS 才能使用)

js
// main.js
+import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const F=JSON.parse('{"title":"浏览器缓存","description":"","frontmatter":{},"headers":[],"relativePath":"guide/浏览器相关/浏览器缓存.md","filePath":"guide/浏览器相关/浏览器缓存.md","lastUpdated":1707358769000}'),p={name:"guide/浏览器相关/浏览器缓存.md"},o=l(`

浏览器缓存

缓存

从 HTTP 缓存策略来说

  • 强缓存
  • 协商缓存

从浏览器的缓存位置来说

  • Service Worker Cache (必须是 Https)
  • Memory Cache (内存缓存)
  • Disk Cache (硬盘缓存)
  • Push Cache (Http2.0)

本地存储

请求时携带,用于信息持久化

Local Storage 本地存储

用于长期不变化的数据,只能存储字符串

Session Storage 会话存储

用于存储当前会话的数据,只能存储字符串

indexedDB

非关系型数据库

Service Worker

运行在浏览器背后的独立线程(必须 HTTPS 才能使用)

js
// main.js
 /* 判断当前浏览器是否支持serviceWorker */
 if ('serviceWorker' in navigator) {
   /* 当页面加载完成就创建一个 serviceWorker */
diff --git "a/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\347\274\223\345\255\230.md.8cddcc95.lean.js" "b/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\347\274\223\345\255\230.md.88373219.lean.js"
similarity index 87%
rename from "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\347\274\223\345\255\230.md.8cddcc95.lean.js"
rename to "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\347\274\223\345\255\230.md.88373219.lean.js"
index 65c81414..f4e6a1b0 100644
--- "a/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\347\274\223\345\255\230.md.8cddcc95.lean.js"
+++ "b/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\347\274\223\345\255\230.md.88373219.lean.js"
@@ -1 +1 @@
-import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const F=JSON.parse('{"title":"浏览器缓存","description":"","frontmatter":{},"headers":[],"relativePath":"guide/浏览器相关/浏览器缓存.md","filePath":"guide/浏览器相关/浏览器缓存.md","lastUpdated":1707358495000}'),p={name:"guide/浏览器相关/浏览器缓存.md"},o=l("",19),e=[o];function c(t,r,E,y,i,h){return n(),a("div",null,e)}const u=s(p,[["render",c]]);export{F as __pageData,u as default};
+import{_ as s,o as n,c as a,Q as l}from"./chunks/framework.b6910bb2.js";const F=JSON.parse('{"title":"浏览器缓存","description":"","frontmatter":{},"headers":[],"relativePath":"guide/浏览器相关/浏览器缓存.md","filePath":"guide/浏览器相关/浏览器缓存.md","lastUpdated":1707358769000}'),p={name:"guide/浏览器相关/浏览器缓存.md"},o=l("",19),e=[o];function c(t,r,E,y,i,h){return n(),a("div",null,e)}const u=s(p,[["render",c]]);export{F as __pageData,u as default};
diff --git "a/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\350\277\233\347\250\213\346\236\266\346\236\204.md.13fb4bd1.js" "b/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\350\277\233\347\250\213\346\236\266\346\236\204.md.1b1db83e.js"
similarity index 97%
rename from "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\350\277\233\347\250\213\346\236\266\346\236\204.md.13fb4bd1.js"
rename to "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\350\277\233\347\250\213\346\236\266\346\236\204.md.1b1db83e.js"
index 507207b4..bb995a71 100644
--- "a/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\350\277\233\347\250\213\346\236\266\346\236\204.md.13fb4bd1.js"
+++ "b/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\350\277\233\347\250\213\346\236\266\346\236\204.md.1b1db83e.js"
@@ -1 +1 @@
-import{_ as a,o as e,c as t,Q as r}from"./chunks/framework.b6910bb2.js";const b=JSON.parse('{"title":"浏览器进程架构","description":"","frontmatter":{},"headers":[],"relativePath":"guide/浏览器相关/浏览器进程架构.md","filePath":"guide/浏览器相关/浏览器进程架构.md","lastUpdated":1707358495000}'),o={name:"guide/浏览器相关/浏览器进程架构.md"},h=r('

浏览器进程架构

进程与线程

进程

进程是一个程序的实例 进程是系统进行资源调度和分配的最小单位 进程之间相互独立,通过 IPC 进行通信

线程

线程是 CPU 调度的最小单位 线程之间共享进程的数据 线程里面会有协程,但只能运行一个

浏览器架构

1 浏览器主进程

用户交互、文件存储、页面显示、子进程管理

2 渲染进程

解析资源、执行 js 渲染进程被浏览器放在安全沙箱里面,因此渲染进程的资源是通过网络获取 - 渲染线程: 渲染页面 - JS 线程:解析执行 js - 事件触发线程: 事件循环 - 定时器线程:定时器相关 - 异步 http 请求线程: 请求相关

3 GPU 进程

UI界面的绘制

4 网络进程

网络资源加载

5 插件进程

管理插件

',17),i=[h];function l(d,n,s,_,c,u){return e(),t("div",null,i)}const q=a(o,[["render",l]]);export{b as __pageData,q as default}; +import{_ as a,o as e,c as t,Q as r}from"./chunks/framework.b6910bb2.js";const b=JSON.parse('{"title":"浏览器进程架构","description":"","frontmatter":{},"headers":[],"relativePath":"guide/浏览器相关/浏览器进程架构.md","filePath":"guide/浏览器相关/浏览器进程架构.md","lastUpdated":1707358769000}'),o={name:"guide/浏览器相关/浏览器进程架构.md"},h=r('

浏览器进程架构

进程与线程

进程

进程是一个程序的实例 进程是系统进行资源调度和分配的最小单位 进程之间相互独立,通过 IPC 进行通信

线程

线程是 CPU 调度的最小单位 线程之间共享进程的数据 线程里面会有协程,但只能运行一个

浏览器架构

1 浏览器主进程

用户交互、文件存储、页面显示、子进程管理

2 渲染进程

解析资源、执行 js 渲染进程被浏览器放在安全沙箱里面,因此渲染进程的资源是通过网络获取 - 渲染线程: 渲染页面 - JS 线程:解析执行 js - 事件触发线程: 事件循环 - 定时器线程:定时器相关 - 异步 http 请求线程: 请求相关

3 GPU 进程

UI界面的绘制

4 网络进程

网络资源加载

5 插件进程

管理插件

',17),i=[h];function l(d,n,s,_,c,u){return e(),t("div",null,i)}const q=a(o,[["render",l]]);export{b as __pageData,q as default}; diff --git "a/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\350\277\233\347\250\213\346\236\266\346\236\204.md.13fb4bd1.lean.js" "b/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\350\277\233\347\250\213\346\236\266\346\236\204.md.1b1db83e.lean.js" similarity index 87% rename from "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\350\277\233\347\250\213\346\236\266\346\236\204.md.13fb4bd1.lean.js" rename to "assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\350\277\233\347\250\213\346\236\266\346\236\204.md.1b1db83e.lean.js" index 9acd1973..6883facf 100644 --- "a/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\350\277\233\347\250\213\346\236\266\346\236\204.md.13fb4bd1.lean.js" +++ "b/assets/guide_\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263_\346\265\217\350\247\210\345\231\250\350\277\233\347\250\213\346\236\266\346\236\204.md.1b1db83e.lean.js" @@ -1 +1 @@ -import{_ as a,o as e,c as t,Q as r}from"./chunks/framework.b6910bb2.js";const b=JSON.parse('{"title":"浏览器进程架构","description":"","frontmatter":{},"headers":[],"relativePath":"guide/浏览器相关/浏览器进程架构.md","filePath":"guide/浏览器相关/浏览器进程架构.md","lastUpdated":1707358495000}'),o={name:"guide/浏览器相关/浏览器进程架构.md"},h=r("",17),i=[h];function l(d,n,s,_,c,u){return e(),t("div",null,i)}const q=a(o,[["render",l]]);export{b as __pageData,q as default}; +import{_ as a,o as e,c as t,Q as r}from"./chunks/framework.b6910bb2.js";const b=JSON.parse('{"title":"浏览器进程架构","description":"","frontmatter":{},"headers":[],"relativePath":"guide/浏览器相关/浏览器进程架构.md","filePath":"guide/浏览器相关/浏览器进程架构.md","lastUpdated":1707358769000}'),o={name:"guide/浏览器相关/浏览器进程架构.md"},h=r("",17),i=[h];function l(d,n,s,_,c,u){return e(),t("div",null,i)}const q=a(o,[["render",l]]);export{b as __pageData,q as default}; diff --git "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_CDN.md.c26e601b.js" "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_CDN.md.e85fe02e.js" similarity index 98% rename from "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_CDN.md.c26e601b.js" rename to "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_CDN.md.e85fe02e.js" index a8b6022c..c86c1b03 100644 --- "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_CDN.md.c26e601b.js" +++ "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_CDN.md.e85fe02e.js" @@ -1 +1 @@ -import{_ as l,o as a,c as i,Q as e}from"./chunks/framework.b6910bb2.js";const t="/vitePress-blob/assets/13.1322b23d.jpg",C=JSON.parse('{"title":"CDN","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/CDN.md","filePath":"guide/网络相关/CDN.md","lastUpdated":1707358495000}'),o={name:"guide/网络相关/CDN.md"},r=e('

CDN

定义

内容分发网络,利用最靠近用户的服务器,将资源更快更可靠的给到用户

组成

  1. 分发服务系统

    最小单位是 Cache 设备

    • 响应用户请求
    • 与源站点进行资源同步
  2. 负载均衡系统

    负责对用户的请求进行调度

  3. 运营管理系统

    负责业务层面与外界系统的交互所需要的收集、整理、交付等工作 (为了做闭环)

    运营管理子系统 网络管理子系统

作用

托管 web 资源,加速 web 资源的获取速度

性能方面

  1. 用户从最近的 CDN 站点获取资源,访问速度更快
  2. 突破 TCP 只有同域名下只有 6 个的限制
  3. 减少源服务器的负担

安全方面

  1. 针对 DDos: 通过监控分析异常流量,限制请求频率
  2. 针对 MITM: 从源服务器到 CDN 节点到 ISP (Internet Service Provider, 网络运营提供商),全链路 HTTPS 通信

工作原理

没有使用 CDN 过程

  1. 浏览器通过 DNS 对域名进行解析,得到此域名对应的 IP 地址
  2. 浏览器根据得到的 IP 地址,向域名的服务主机发送数据请求
  3. 服务器向浏览器返回响应数据

使用了 CDN 过程

  1. 获取负载均衡服务器 IP 地址 (自底向上)

      1. 数据的 URL 先进行 DNS 系统解析,发现该 URL 对应的是一个 CDN 专用的 DNS 服务器,DNS 系统就会将域名解析权交给 CNAME 指向的 CDN 专用的 DNS 服务器
      1. CDN 专用的 DNS 服务器将 CDN 全局负载均衡设备 IP 地址返回给用户
      1. 用户向 CDN 的全局负载均衡设备发起数据请求
  2. 获取目标缓存服务器 IP 地址 (自顶向下)

      1. CDN 全局负载均衡设备根据用户 IP 地址以及用户请求的 URL,选择一台用户所属区域的负载均衡设备
      1. 区域负责均衡设备选择一台适合的缓存服务器来提供服务,将该缓存服务器的 IP 地址返回给全局负载均衡设备
      1. 全局负载均衡设备把服务器 IP 地址返回给用户
  3. 用户发起请求获取

    • 用户向该缓存服务器发起请求,缓存服务器响应用户的请求,将用户所需内容发送支用户终端 (如果缓存服务器没有用户想要的内容,那么缓存服务器会穿透 CDN 集群往源服务器获取设备)

流程

使用场景

  1. 使用第三方 CDN 服务 (例如开源框架可以使用第三方 CDN 服务,如 React、Vue、JQuery)
  2. 使用 CDN 进行静态资源的缓存 (将网站的资源放在 CDN 上)
  3. 直播传送 (直播本质也是使用流媒体进行传送,CDN 也支持流媒体传送,所以直播完全可以使用 CDN 来提高访问速度)
',19),h=[r];function n(d,s,c,p,u,D){return a(),i("div",null,h)}const _=l(o,[["render",n]]);export{C as __pageData,_ as default}; +import{_ as l,o as a,c as i,Q as e}from"./chunks/framework.b6910bb2.js";const t="/vitePress-blob/assets/13.1322b23d.jpg",C=JSON.parse('{"title":"CDN","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/CDN.md","filePath":"guide/网络相关/CDN.md","lastUpdated":1707358769000}'),o={name:"guide/网络相关/CDN.md"},r=e('

CDN

定义

内容分发网络,利用最靠近用户的服务器,将资源更快更可靠的给到用户

组成

  1. 分发服务系统

    最小单位是 Cache 设备

    • 响应用户请求
    • 与源站点进行资源同步
  2. 负载均衡系统

    负责对用户的请求进行调度

  3. 运营管理系统

    负责业务层面与外界系统的交互所需要的收集、整理、交付等工作 (为了做闭环)

    运营管理子系统 网络管理子系统

作用

托管 web 资源,加速 web 资源的获取速度

性能方面

  1. 用户从最近的 CDN 站点获取资源,访问速度更快
  2. 突破 TCP 只有同域名下只有 6 个的限制
  3. 减少源服务器的负担

安全方面

  1. 针对 DDos: 通过监控分析异常流量,限制请求频率
  2. 针对 MITM: 从源服务器到 CDN 节点到 ISP (Internet Service Provider, 网络运营提供商),全链路 HTTPS 通信

工作原理

没有使用 CDN 过程

  1. 浏览器通过 DNS 对域名进行解析,得到此域名对应的 IP 地址
  2. 浏览器根据得到的 IP 地址,向域名的服务主机发送数据请求
  3. 服务器向浏览器返回响应数据

使用了 CDN 过程

  1. 获取负载均衡服务器 IP 地址 (自底向上)

      1. 数据的 URL 先进行 DNS 系统解析,发现该 URL 对应的是一个 CDN 专用的 DNS 服务器,DNS 系统就会将域名解析权交给 CNAME 指向的 CDN 专用的 DNS 服务器
      1. CDN 专用的 DNS 服务器将 CDN 全局负载均衡设备 IP 地址返回给用户
      1. 用户向 CDN 的全局负载均衡设备发起数据请求
  2. 获取目标缓存服务器 IP 地址 (自顶向下)

      1. CDN 全局负载均衡设备根据用户 IP 地址以及用户请求的 URL,选择一台用户所属区域的负载均衡设备
      1. 区域负责均衡设备选择一台适合的缓存服务器来提供服务,将该缓存服务器的 IP 地址返回给全局负载均衡设备
      1. 全局负载均衡设备把服务器 IP 地址返回给用户
  3. 用户发起请求获取

    • 用户向该缓存服务器发起请求,缓存服务器响应用户的请求,将用户所需内容发送支用户终端 (如果缓存服务器没有用户想要的内容,那么缓存服务器会穿透 CDN 集群往源服务器获取设备)

流程

使用场景

  1. 使用第三方 CDN 服务 (例如开源框架可以使用第三方 CDN 服务,如 React、Vue、JQuery)
  2. 使用 CDN 进行静态资源的缓存 (将网站的资源放在 CDN 上)
  3. 直播传送 (直播本质也是使用流媒体进行传送,CDN 也支持流媒体传送,所以直播完全可以使用 CDN 来提高访问速度)
',19),h=[r];function n(d,s,c,p,u,D){return a(),i("div",null,h)}const _=l(o,[["render",n]]);export{C as __pageData,_ as default}; diff --git "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_CDN.md.c26e601b.lean.js" "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_CDN.md.e85fe02e.lean.js" similarity index 86% rename from "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_CDN.md.c26e601b.lean.js" rename to "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_CDN.md.e85fe02e.lean.js" index f5653584..095bf766 100644 --- "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_CDN.md.c26e601b.lean.js" +++ "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_CDN.md.e85fe02e.lean.js" @@ -1 +1 @@ -import{_ as l,o as a,c as i,Q as e}from"./chunks/framework.b6910bb2.js";const t="/vitePress-blob/assets/13.1322b23d.jpg",C=JSON.parse('{"title":"CDN","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/CDN.md","filePath":"guide/网络相关/CDN.md","lastUpdated":1707358495000}'),o={name:"guide/网络相关/CDN.md"},r=e("",19),h=[r];function n(d,s,c,p,u,D){return a(),i("div",null,h)}const _=l(o,[["render",n]]);export{C as __pageData,_ as default}; +import{_ as l,o as a,c as i,Q as e}from"./chunks/framework.b6910bb2.js";const t="/vitePress-blob/assets/13.1322b23d.jpg",C=JSON.parse('{"title":"CDN","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/CDN.md","filePath":"guide/网络相关/CDN.md","lastUpdated":1707358769000}'),o={name:"guide/网络相关/CDN.md"},r=e("",19),h=[r];function n(d,s,c,p,u,D){return a(),i("div",null,h)}const _=l(o,[["render",n]]);export{C as __pageData,_ as default}; diff --git "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_DNS.md.e56a26c8.js" "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_DNS.md.3f43cbe6.js" similarity index 96% rename from "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_DNS.md.e56a26c8.js" rename to "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_DNS.md.3f43cbe6.js" index 09014a18..1dc7738c 100644 --- "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_DNS.md.e56a26c8.js" +++ "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_DNS.md.3f43cbe6.js" @@ -1 +1 @@ -import{_ as l,o as i,c as a,Q as e}from"./chunks/framework.b6910bb2.js";const S=JSON.parse('{"title":"DNS","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/DNS.md","filePath":"guide/网络相关/DNS.md","lastUpdated":1707358495000}'),o={name:"guide/网络相关/DNS.md"},t=e('

DNS

定义

域名解析系统

工作原理 (自下而上)

例如查找 www.baidu.com 的 ip 地址

  1. 查找缓存
      1. 检查浏览器缓存
      1. 检查操作系统缓存 (常见的有 host 文件)
      1. 检查路由器缓存
  2. 如何缓存查找到,会向 ISP (网络服务提供商) 的本地 DNS 服务器查询
  3. 如果本地 DNS 服务器没有找到,会向根域名服务器请求解析,分为以下几步:(自顶向下)
      1. 根服务器返回顶级域名服务器(如.com、.cn、.org等)地址,例如该例子中的 .com 的地址
      1. 接着向顶级瑜域名服务器发送请求,然后会返回次级域名服务器的地址,例如该例子会返回 .baidu 的地址
      1. 接着向次级域名服务器发送请求,会返回通过三级域名地址的 IP,例如本例子返回的 www.baidu.com 的地址
    • 4.Local DNS Server会缓存结果,并返回给用户,缓存在系统中
',6),r=[t];function s(d,c,n,_,h,u){return i(),a("div",null,r)}const m=l(o,[["render",s]]);export{S as __pageData,m as default}; +import{_ as l,o as i,c as a,Q as e}from"./chunks/framework.b6910bb2.js";const S=JSON.parse('{"title":"DNS","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/DNS.md","filePath":"guide/网络相关/DNS.md","lastUpdated":1707358769000}'),o={name:"guide/网络相关/DNS.md"},t=e('

DNS

定义

域名解析系统

工作原理 (自下而上)

例如查找 www.baidu.com 的 ip 地址

  1. 查找缓存
      1. 检查浏览器缓存
      1. 检查操作系统缓存 (常见的有 host 文件)
      1. 检查路由器缓存
  2. 如何缓存查找到,会向 ISP (网络服务提供商) 的本地 DNS 服务器查询
  3. 如果本地 DNS 服务器没有找到,会向根域名服务器请求解析,分为以下几步:(自顶向下)
      1. 根服务器返回顶级域名服务器(如.com、.cn、.org等)地址,例如该例子中的 .com 的地址
      1. 接着向顶级瑜域名服务器发送请求,然后会返回次级域名服务器的地址,例如该例子会返回 .baidu 的地址
      1. 接着向次级域名服务器发送请求,会返回通过三级域名地址的 IP,例如本例子返回的 www.baidu.com 的地址
    • 4.Local DNS Server会缓存结果,并返回给用户,缓存在系统中
',6),r=[t];function s(d,c,n,_,h,u){return i(),a("div",null,r)}const m=l(o,[["render",s]]);export{S as __pageData,m as default}; diff --git "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_DNS.md.e56a26c8.lean.js" "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_DNS.md.3f43cbe6.lean.js" similarity index 85% rename from "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_DNS.md.e56a26c8.lean.js" rename to "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_DNS.md.3f43cbe6.lean.js" index a7413409..38e1180b 100644 --- "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_DNS.md.e56a26c8.lean.js" +++ "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_DNS.md.3f43cbe6.lean.js" @@ -1 +1 @@ -import{_ as l,o as i,c as a,Q as e}from"./chunks/framework.b6910bb2.js";const S=JSON.parse('{"title":"DNS","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/DNS.md","filePath":"guide/网络相关/DNS.md","lastUpdated":1707358495000}'),o={name:"guide/网络相关/DNS.md"},t=e("",6),r=[t];function s(d,c,n,_,h,u){return i(),a("div",null,r)}const m=l(o,[["render",s]]);export{S as __pageData,m as default}; +import{_ as l,o as i,c as a,Q as e}from"./chunks/framework.b6910bb2.js";const S=JSON.parse('{"title":"DNS","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/DNS.md","filePath":"guide/网络相关/DNS.md","lastUpdated":1707358769000}'),o={name:"guide/网络相关/DNS.md"},t=e("",6),r=[t];function s(d,c,n,_,h,u){return i(),a("div",null,r)}const m=l(o,[["render",s]]);export{S as __pageData,m as default}; diff --git "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_GET\350\257\267\346\261\202\345\222\214POST\350\257\267\346\261\202\347\232\204\345\214\272\345\210\253.md.5e98e509.js" "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_GET\350\257\267\346\261\202\345\222\214POST\350\257\267\346\261\202\347\232\204\345\214\272\345\210\253.md.5b02925b.js" similarity index 95% rename from "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_GET\350\257\267\346\261\202\345\222\214POST\350\257\267\346\261\202\347\232\204\345\214\272\345\210\253.md.5e98e509.js" rename to "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_GET\350\257\267\346\261\202\345\222\214POST\350\257\267\346\261\202\347\232\204\345\214\272\345\210\253.md.5b02925b.js" index 965646c1..71d43962 100644 --- "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_GET\350\257\267\346\261\202\345\222\214POST\350\257\267\346\261\202\347\232\204\345\214\272\345\210\253.md.5e98e509.js" +++ "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_GET\350\257\267\346\261\202\345\222\214POST\350\257\267\346\261\202\347\232\204\345\214\272\345\210\253.md.5b02925b.js" @@ -1 +1 @@ -import{_ as t,o as a,c as l,k as e,a as o}from"./chunks/framework.b6910bb2.js";const O=JSON.parse('{"title":"GET 请求和 POST 请求的区别","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/GET请求和POST请求的区别.md","filePath":"guide/网络相关/GET请求和POST请求的区别.md","lastUpdated":1707358495000}'),s={name:"guide/网络相关/GET请求和POST请求的区别.md"},n=e("h1",{id:"get-请求和-post-请求的区别",tabindex:"-1"},[o("GET 请求和 POST 请求的区别 "),e("a",{class:"header-anchor",href:"#get-请求和-post-请求的区别","aria-label":'Permalink to "GET 请求和 POST 请求的区别"'},"​")],-1),i=e("ol",null,[e("li",null,"功能上: GET 请求常用于获取数据,POST 请求常用于提交数据"),e("li",null,"参数上: GET 请求参数放在 URL 上,POST 请求参数放在请求体上"),e("li",null,"参数类型上: POST 请求支持更多的参数类型"),e("li",null,"安全性上: POST 请求更加安全"),e("li",null,"是否有缓存上: GET 请求会被缓存"),e("li",null,"请求长度上: 由于浏览器存在 URL 长度限制,因此会影响 GET 请求的长度")],-1),r=[n,i];function _(d,T,c,u,p,P){return a(),l("div",null,r)}const S=t(s,[["render",_]]);export{O as __pageData,S as default}; +import{_ as t,o as a,c as l,k as e,a as o}from"./chunks/framework.b6910bb2.js";const O=JSON.parse('{"title":"GET 请求和 POST 请求的区别","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/GET请求和POST请求的区别.md","filePath":"guide/网络相关/GET请求和POST请求的区别.md","lastUpdated":1707358769000}'),s={name:"guide/网络相关/GET请求和POST请求的区别.md"},n=e("h1",{id:"get-请求和-post-请求的区别",tabindex:"-1"},[o("GET 请求和 POST 请求的区别 "),e("a",{class:"header-anchor",href:"#get-请求和-post-请求的区别","aria-label":'Permalink to "GET 请求和 POST 请求的区别"'},"​")],-1),i=e("ol",null,[e("li",null,"功能上: GET 请求常用于获取数据,POST 请求常用于提交数据"),e("li",null,"参数上: GET 请求参数放在 URL 上,POST 请求参数放在请求体上"),e("li",null,"参数类型上: POST 请求支持更多的参数类型"),e("li",null,"安全性上: POST 请求更加安全"),e("li",null,"是否有缓存上: GET 请求会被缓存"),e("li",null,"请求长度上: 由于浏览器存在 URL 长度限制,因此会影响 GET 请求的长度")],-1),r=[n,i];function _(d,T,c,u,p,P){return a(),l("div",null,r)}const S=t(s,[["render",_]]);export{O as __pageData,S as default}; diff --git "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_GET\350\257\267\346\261\202\345\222\214POST\350\257\267\346\261\202\347\232\204\345\214\272\345\210\253.md.5e98e509.lean.js" "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_GET\350\257\267\346\261\202\345\222\214POST\350\257\267\346\261\202\347\232\204\345\214\272\345\210\253.md.5b02925b.lean.js" similarity index 95% rename from "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_GET\350\257\267\346\261\202\345\222\214POST\350\257\267\346\261\202\347\232\204\345\214\272\345\210\253.md.5e98e509.lean.js" rename to "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_GET\350\257\267\346\261\202\345\222\214POST\350\257\267\346\261\202\347\232\204\345\214\272\345\210\253.md.5b02925b.lean.js" index 965646c1..71d43962 100644 --- "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_GET\350\257\267\346\261\202\345\222\214POST\350\257\267\346\261\202\347\232\204\345\214\272\345\210\253.md.5e98e509.lean.js" +++ "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_GET\350\257\267\346\261\202\345\222\214POST\350\257\267\346\261\202\347\232\204\345\214\272\345\210\253.md.5b02925b.lean.js" @@ -1 +1 @@ -import{_ as t,o as a,c as l,k as e,a as o}from"./chunks/framework.b6910bb2.js";const O=JSON.parse('{"title":"GET 请求和 POST 请求的区别","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/GET请求和POST请求的区别.md","filePath":"guide/网络相关/GET请求和POST请求的区别.md","lastUpdated":1707358495000}'),s={name:"guide/网络相关/GET请求和POST请求的区别.md"},n=e("h1",{id:"get-请求和-post-请求的区别",tabindex:"-1"},[o("GET 请求和 POST 请求的区别 "),e("a",{class:"header-anchor",href:"#get-请求和-post-请求的区别","aria-label":'Permalink to "GET 请求和 POST 请求的区别"'},"​")],-1),i=e("ol",null,[e("li",null,"功能上: GET 请求常用于获取数据,POST 请求常用于提交数据"),e("li",null,"参数上: GET 请求参数放在 URL 上,POST 请求参数放在请求体上"),e("li",null,"参数类型上: POST 请求支持更多的参数类型"),e("li",null,"安全性上: POST 请求更加安全"),e("li",null,"是否有缓存上: GET 请求会被缓存"),e("li",null,"请求长度上: 由于浏览器存在 URL 长度限制,因此会影响 GET 请求的长度")],-1),r=[n,i];function _(d,T,c,u,p,P){return a(),l("div",null,r)}const S=t(s,[["render",_]]);export{O as __pageData,S as default}; +import{_ as t,o as a,c as l,k as e,a as o}from"./chunks/framework.b6910bb2.js";const O=JSON.parse('{"title":"GET 请求和 POST 请求的区别","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/GET请求和POST请求的区别.md","filePath":"guide/网络相关/GET请求和POST请求的区别.md","lastUpdated":1707358769000}'),s={name:"guide/网络相关/GET请求和POST请求的区别.md"},n=e("h1",{id:"get-请求和-post-请求的区别",tabindex:"-1"},[o("GET 请求和 POST 请求的区别 "),e("a",{class:"header-anchor",href:"#get-请求和-post-请求的区别","aria-label":'Permalink to "GET 请求和 POST 请求的区别"'},"​")],-1),i=e("ol",null,[e("li",null,"功能上: GET 请求常用于获取数据,POST 请求常用于提交数据"),e("li",null,"参数上: GET 请求参数放在 URL 上,POST 请求参数放在请求体上"),e("li",null,"参数类型上: POST 请求支持更多的参数类型"),e("li",null,"安全性上: POST 请求更加安全"),e("li",null,"是否有缓存上: GET 请求会被缓存"),e("li",null,"请求长度上: 由于浏览器存在 URL 长度限制,因此会影响 GET 请求的长度")],-1),r=[n,i];function _(d,T,c,u,p,P){return a(),l("div",null,r)}const S=t(s,[["render",_]]);export{O as __pageData,S as default}; diff --git "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTP.md.22d66eca.js" "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTP.md.3d19dae2.js" similarity index 99% rename from "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTP.md.22d66eca.js" rename to "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTP.md.3d19dae2.js" index b163da20..9afe5891 100644 --- "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTP.md.22d66eca.js" +++ "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTP.md.3d19dae2.js" @@ -1 +1 @@ -import{_ as a,o as t,c as e,Q as l}from"./chunks/framework.b6910bb2.js";const i="/vitePress-blob/assets/5.c8205ece.jpg",o="/vitePress-blob/assets/6.76a1cb50.jpg",r="/vitePress-blob/assets/7.ee9188c9.jpg",H=JSON.parse('{"title":"HTTP","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/HTTP.md","filePath":"guide/网络相关/HTTP.md","lastUpdated":1707358495000}'),h={name:"guide/网络相关/HTTP.md"},T=l('

HTTP

HTTP 0.9

早期做学术研究使用,只是单纯的文本传输(只有请求行、没有请求头和请求体)

HTTP1.0

支持图片、视频传输,但传输效率太低

核心需求:支持多种类型的文件下载(引入了请求头和响应头)

HTTP1.1

持久连接 keep-alive

在此之前一个 HTTP 请求需要建立一个 TCP 连接

目前浏览器中对于 同一个域名,默认允许同时建立 6 个 TCP 连接

管道化连接

将串行请求改成并行请求

支持虚拟主机

HTTP 根据 Host 去区分同一 IP 物理机子上的不同虚拟主机

对动态生成的内容提供完美支持

Chunk transfer 机制

Cookie、完全机制

主要问题

    1. HTTP/1.1 对头阻塞问题 在 HTTP 中,因为前一条请求因某些原因没有及时返回,会导致后面的请求无法发起,容易导致对头阻塞(串行)。虽然 HTTP1.1 引入了管道化技术尝试解决队头阻塞问题,但服务端还是需要按顺序处理请求并返回,因此阻塞问题依然存在
    1. 带宽利用率不理想
    • 原因:
      • TCP 的慢启动: 传输数据的速度从慢到快
      • 同时开启多个 TCP 连接,那么这些连接会竞争固定的带宽(带宽不足时,TCP 传输速度会变慢)

HTTP/1.0 与 HTTP/1.1 的 区别?

1 连接方面

持久化连接: HTTP1.1 支持持久化连接,减少每次 HTTP 请求都需要建立 TCP 连接的耗时

管道化连接:提高请求效率

2 缓存方面

HTTP1.1 新增了协商缓存的字段 ETag 比 if-None-Match 更加紧准

3 新增 Host 字段

根据 Host 区分同一 IP 服务器上的不同网站

之前只能通过 IP 区分网站

4 请求资源方面

添加范围请求 (206 状态码)

5 新增了请求方法

PUT、HEAD、OPTIONS 等

HTTP/2.0

一个域名只有一个 TCP 长连接传输数据 (避规 HTTP 1.1 的 TCP 慢启动和多个 TCP 连接时竞争带宽资源)

多路复用机制

通过引入二进制分帧层,实现多路复用机制

整体流程整体流程

  1. 浏览器发起请求,经过二进制分帧层将请求拆分成一个个带请求id的帧,发送给服务端
  2. 服务端收到这些帧后,根据请求id组装成完整请求信息,服务端处理完请求后,将响应请求发送到二进制分帧层,经过二进制分帧层转化为一个个带有响应id的帧发送给浏览器
  3. 浏览器收到这些帧后,会组合成一个完整的响应请求

实现基础: HTTP2 是一个二进制协议,在 HTTP/1.1 版中,报文的头信息必须是文本(ASCII 编码),数据体可以是文本,也可以是二进制。HTTP/2 则是一个彻底的二进制协议,头信息和数据体都是二进制,并且统称为"帧",可以分为头信息帧和数据帧。 帧的概念是它实现多路复用的基础

头部压缩

HTTP/2 实现了头信息压缩,由于 HTTP 1.1 协议不带状态,每次请求都必须附上所有信息。所以,请求的很多字段都是重复的,比如 Cookie 和 User Agent ,一模一样的内容,每次请求都必须附带,这会浪费很多带宽,也影响速度。HTTP/2 对这一点做了优化,引入了头信息压缩机制。一方面,头信息使用 gzip 或 compress 压缩后再发送;另一方面,客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就能提高速度了。

设置请求优先级

服务器推送

存在的问题

TCP 协议本身存在的问题:

    1. TCP 的队头阻塞 TCP 传输过程中把一份数据分成多个数据包进行传输,当某个数据包没有按顺序返回,接收端会一直保持连接等待数据包返回,这就阻塞了后续数据包的传输 整体流程
    1. TCP 建立连接需要耗时

优点

多路复用技术能有效利用带宽(只有一个TCP连接),缓解 TCP 慢启动带来的问题,解决了 HTTP 队头阻塞问题,同时还支持设置优先级、服务器推送、头部压缩极大的提高了 HTTP 的传输效率

http2 与 http1 的区别?

  1. 为了解决 HTTP1.1 的队头阻塞问题引入了二进制分帧层
  2. 只建立一个 TCP 连接,解决 HTTP1.1中 TCP 慢启动以及多个 TCP 之间相互竞争带宽问题
  3. 头部压缩,HTTP2 请求头部采用头部压缩,减少数据内容的大小,提高效率
  4. 服务端推送: 服务端可以向客户端推送资源

HTTP3.0

采用UDP + QUIC协议

  1. UDP 可以减少连接耗费的 RTT,加快数据传输
  2. 使用 QUIC 协议,可以使用多路复用、TLS、可靠性传输等 TCP 协议的特点

存在的问题:

  1. 规范的制定和落地有着较大的差异(比如官方的QUIC和谷歌的QUIC协议有较大差异)
  2. 是对底层协议的改造,落地成本高。

HTTP1.0/1.1/2.0有什么区别?

这道题应该从HTTP的发展历史的角度出发

  1. http1.0 在 http0.9 时代新增了图片、视频的传输,同时新增了请求、响应头,支持文件下载,但请求的效率低,因为每个http请求需要一次TCP连接
  2. HTTP1.1 引入了缓存策略、支持长连接keep-alive等,支持PUT/DELETE/OPTION方法,提高了HTTP的传输效率,但并发请求时会有一个HTTP的头部阻塞问题
  3. HTTP2 通过引入二进制分帧层、采用多路复用避规了HTTP的头部阻塞问题,还支持头部压缩,提高HTTP的传输效率,服务端推送

RTT

浏览器发送数据包到服务器 + 浏览器接收到服务器确认接收的数据包的往返时间,成为RTT

',60),s=[T];function P(n,p,d,c,u,b){return t(),e("div",null,s)}const m=a(h,[["render",P]]);export{H as __pageData,m as default}; +import{_ as a,o as t,c as e,Q as l}from"./chunks/framework.b6910bb2.js";const i="/vitePress-blob/assets/5.c8205ece.jpg",o="/vitePress-blob/assets/6.76a1cb50.jpg",r="/vitePress-blob/assets/7.ee9188c9.jpg",H=JSON.parse('{"title":"HTTP","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/HTTP.md","filePath":"guide/网络相关/HTTP.md","lastUpdated":1707358769000}'),h={name:"guide/网络相关/HTTP.md"},T=l('

HTTP

HTTP 0.9

早期做学术研究使用,只是单纯的文本传输(只有请求行、没有请求头和请求体)

HTTP1.0

支持图片、视频传输,但传输效率太低

核心需求:支持多种类型的文件下载(引入了请求头和响应头)

HTTP1.1

持久连接 keep-alive

在此之前一个 HTTP 请求需要建立一个 TCP 连接

目前浏览器中对于 同一个域名,默认允许同时建立 6 个 TCP 连接

管道化连接

将串行请求改成并行请求

支持虚拟主机

HTTP 根据 Host 去区分同一 IP 物理机子上的不同虚拟主机

对动态生成的内容提供完美支持

Chunk transfer 机制

Cookie、完全机制

主要问题

    1. HTTP/1.1 对头阻塞问题 在 HTTP 中,因为前一条请求因某些原因没有及时返回,会导致后面的请求无法发起,容易导致对头阻塞(串行)。虽然 HTTP1.1 引入了管道化技术尝试解决队头阻塞问题,但服务端还是需要按顺序处理请求并返回,因此阻塞问题依然存在
    1. 带宽利用率不理想
    • 原因:
      • TCP 的慢启动: 传输数据的速度从慢到快
      • 同时开启多个 TCP 连接,那么这些连接会竞争固定的带宽(带宽不足时,TCP 传输速度会变慢)

HTTP/1.0 与 HTTP/1.1 的 区别?

1 连接方面

持久化连接: HTTP1.1 支持持久化连接,减少每次 HTTP 请求都需要建立 TCP 连接的耗时

管道化连接:提高请求效率

2 缓存方面

HTTP1.1 新增了协商缓存的字段 ETag 比 if-None-Match 更加紧准

3 新增 Host 字段

根据 Host 区分同一 IP 服务器上的不同网站

之前只能通过 IP 区分网站

4 请求资源方面

添加范围请求 (206 状态码)

5 新增了请求方法

PUT、HEAD、OPTIONS 等

HTTP/2.0

一个域名只有一个 TCP 长连接传输数据 (避规 HTTP 1.1 的 TCP 慢启动和多个 TCP 连接时竞争带宽资源)

多路复用机制

通过引入二进制分帧层,实现多路复用机制

整体流程整体流程

  1. 浏览器发起请求,经过二进制分帧层将请求拆分成一个个带请求id的帧,发送给服务端
  2. 服务端收到这些帧后,根据请求id组装成完整请求信息,服务端处理完请求后,将响应请求发送到二进制分帧层,经过二进制分帧层转化为一个个带有响应id的帧发送给浏览器
  3. 浏览器收到这些帧后,会组合成一个完整的响应请求

实现基础: HTTP2 是一个二进制协议,在 HTTP/1.1 版中,报文的头信息必须是文本(ASCII 编码),数据体可以是文本,也可以是二进制。HTTP/2 则是一个彻底的二进制协议,头信息和数据体都是二进制,并且统称为"帧",可以分为头信息帧和数据帧。 帧的概念是它实现多路复用的基础

头部压缩

HTTP/2 实现了头信息压缩,由于 HTTP 1.1 协议不带状态,每次请求都必须附上所有信息。所以,请求的很多字段都是重复的,比如 Cookie 和 User Agent ,一模一样的内容,每次请求都必须附带,这会浪费很多带宽,也影响速度。HTTP/2 对这一点做了优化,引入了头信息压缩机制。一方面,头信息使用 gzip 或 compress 压缩后再发送;另一方面,客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就能提高速度了。

设置请求优先级

服务器推送

存在的问题

TCP 协议本身存在的问题:

    1. TCP 的队头阻塞 TCP 传输过程中把一份数据分成多个数据包进行传输,当某个数据包没有按顺序返回,接收端会一直保持连接等待数据包返回,这就阻塞了后续数据包的传输 整体流程
    1. TCP 建立连接需要耗时

优点

多路复用技术能有效利用带宽(只有一个TCP连接),缓解 TCP 慢启动带来的问题,解决了 HTTP 队头阻塞问题,同时还支持设置优先级、服务器推送、头部压缩极大的提高了 HTTP 的传输效率

http2 与 http1 的区别?

  1. 为了解决 HTTP1.1 的队头阻塞问题引入了二进制分帧层
  2. 只建立一个 TCP 连接,解决 HTTP1.1中 TCP 慢启动以及多个 TCP 之间相互竞争带宽问题
  3. 头部压缩,HTTP2 请求头部采用头部压缩,减少数据内容的大小,提高效率
  4. 服务端推送: 服务端可以向客户端推送资源

HTTP3.0

采用UDP + QUIC协议

  1. UDP 可以减少连接耗费的 RTT,加快数据传输
  2. 使用 QUIC 协议,可以使用多路复用、TLS、可靠性传输等 TCP 协议的特点

存在的问题:

  1. 规范的制定和落地有着较大的差异(比如官方的QUIC和谷歌的QUIC协议有较大差异)
  2. 是对底层协议的改造,落地成本高。

HTTP1.0/1.1/2.0有什么区别?

这道题应该从HTTP的发展历史的角度出发

  1. http1.0 在 http0.9 时代新增了图片、视频的传输,同时新增了请求、响应头,支持文件下载,但请求的效率低,因为每个http请求需要一次TCP连接
  2. HTTP1.1 引入了缓存策略、支持长连接keep-alive等,支持PUT/DELETE/OPTION方法,提高了HTTP的传输效率,但并发请求时会有一个HTTP的头部阻塞问题
  3. HTTP2 通过引入二进制分帧层、采用多路复用避规了HTTP的头部阻塞问题,还支持头部压缩,提高HTTP的传输效率,服务端推送

RTT

浏览器发送数据包到服务器 + 浏览器接收到服务器确认接收的数据包的往返时间,成为RTT

',60),s=[T];function P(n,p,d,c,u,b){return t(),e("div",null,s)}const m=a(h,[["render",P]]);export{H as __pageData,m as default}; diff --git "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTP.md.22d66eca.lean.js" "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTP.md.3d19dae2.lean.js" similarity index 88% rename from "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTP.md.22d66eca.lean.js" rename to "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTP.md.3d19dae2.lean.js" index 1e2ae009..5d5b7b9c 100644 --- "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTP.md.22d66eca.lean.js" +++ "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTP.md.3d19dae2.lean.js" @@ -1 +1 @@ -import{_ as a,o as t,c as e,Q as l}from"./chunks/framework.b6910bb2.js";const i="/vitePress-blob/assets/5.c8205ece.jpg",o="/vitePress-blob/assets/6.76a1cb50.jpg",r="/vitePress-blob/assets/7.ee9188c9.jpg",H=JSON.parse('{"title":"HTTP","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/HTTP.md","filePath":"guide/网络相关/HTTP.md","lastUpdated":1707358495000}'),h={name:"guide/网络相关/HTTP.md"},T=l("",60),s=[T];function P(n,p,d,c,u,b){return t(),e("div",null,s)}const m=a(h,[["render",P]]);export{H as __pageData,m as default}; +import{_ as a,o as t,c as e,Q as l}from"./chunks/framework.b6910bb2.js";const i="/vitePress-blob/assets/5.c8205ece.jpg",o="/vitePress-blob/assets/6.76a1cb50.jpg",r="/vitePress-blob/assets/7.ee9188c9.jpg",H=JSON.parse('{"title":"HTTP","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/HTTP.md","filePath":"guide/网络相关/HTTP.md","lastUpdated":1707358769000}'),h={name:"guide/网络相关/HTTP.md"},T=l("",60),s=[T];function P(n,p,d,c,u,b){return t(),e("div",null,s)}const m=a(h,[["render",P]]);export{H as __pageData,m as default}; diff --git "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTPS.md.24fcb37f.js" "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTPS.md.4c7346fd.js" similarity index 98% rename from "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTPS.md.24fcb37f.js" rename to "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTPS.md.4c7346fd.js" index 6d3ae8c2..6bdbba38 100644 --- "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTPS.md.24fcb37f.js" +++ "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTPS.md.4c7346fd.js" @@ -1 +1 @@ -import{_ as a,o as t,c as e,Q as i}from"./chunks/framework.b6910bb2.js";const l="/vitePress-blob/assets/8.428d7ec3.jpg",s="/vitePress-blob/assets/9.7081f11f.jpg",o="/vitePress-blob/assets/10.80b27028.jpg",r="/vitePress-blob/assets/11.8b44a308.jpg",h="/vitePress-blob/assets/12.c1a5b37b.jpg",S=JSON.parse('{"title":"HTTPS","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/HTTPS.md","filePath":"guide/网络相关/HTTPS.md","lastUpdated":1707358495000}'),T={name:"guide/网络相关/HTTPS.md"},n=i('

HTTPS

HTTP 和 HTTPS 的区别

  1. HTTP 是超文本传输协议,明文传输、简单、无状态,而 HTTPS 是在 HTTP 基础上增加了 SSL 协议,更加安全
  2. HTTP 协议默认端口是 80,HTTPS 协议默认端口是 443
  3. HTTPS 需要 CA 证书、相对于 HTTP 费用更高

HTTPS 演进过程

第一版对称加密 - 不安全

流程

非对称加密 - 传输效率低

流程

对称加密与非对称加密结合 - 存在中间人攻击

流程

通过数字证书校验网站的真实性和获取网站的公钥

之前传输的是密钥,这种方式传输的是装有密钥的保险箱,就算获取到了保险箱,也没有保险箱的钥匙🔑

流程

  1. 浏览器将对称加密方法列表、非对称加密方法列表、随机数 A 传输给服务端
  2. 服务器接受后,将对称加密、非对称加密方法、服务器生成的随机数 B 、数字证书发送给浏览器
  3. 浏览器接受后,验证证书的可靠性,并获取证书内的非对称加密的公钥
  4. 浏览器通过 2 个随机数生成新的随机数 C,并通过非对成加密的公钥对随机数 C 进行加密发送给服务器
  5. 服务器确认后,服务器与浏览器通过 3 个随机数生成对称加密密钥,进行数据传输

如何验证证书的可靠性

  1. 浏览器获取到证书后,通过 CA 相同的 Hash 算法对证书信息进行加密得到摘要 A
  2. 通过 CA 的公钥对证书内的数字签名进行解密,获取到摘要 B
  3. 如果 AB 相同,则证书可靠

什么是 HTTPS 中间人攻击?如何预防?

  1. 先说下 HTTPS 传输过程
  2. 客户端和服务端通信之间,新增一个中间人,伪造 CA 证书和加密数据,获取服务器和客户端的通信信息

流程

如何预防?

使用正规厂商的第三方证书

',21),c=[n];function p(d,P,_,b,m,u){return t(),e("div",null,c)}const f=a(T,[["render",p]]);export{S as __pageData,f as default}; +import{_ as a,o as t,c as e,Q as i}from"./chunks/framework.b6910bb2.js";const l="/vitePress-blob/assets/8.428d7ec3.jpg",s="/vitePress-blob/assets/9.7081f11f.jpg",o="/vitePress-blob/assets/10.80b27028.jpg",r="/vitePress-blob/assets/11.8b44a308.jpg",h="/vitePress-blob/assets/12.c1a5b37b.jpg",S=JSON.parse('{"title":"HTTPS","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/HTTPS.md","filePath":"guide/网络相关/HTTPS.md","lastUpdated":1707358769000}'),T={name:"guide/网络相关/HTTPS.md"},n=i('

HTTPS

HTTP 和 HTTPS 的区别

  1. HTTP 是超文本传输协议,明文传输、简单、无状态,而 HTTPS 是在 HTTP 基础上增加了 SSL 协议,更加安全
  2. HTTP 协议默认端口是 80,HTTPS 协议默认端口是 443
  3. HTTPS 需要 CA 证书、相对于 HTTP 费用更高

HTTPS 演进过程

第一版对称加密 - 不安全

流程

非对称加密 - 传输效率低

流程

对称加密与非对称加密结合 - 存在中间人攻击

流程

通过数字证书校验网站的真实性和获取网站的公钥

之前传输的是密钥,这种方式传输的是装有密钥的保险箱,就算获取到了保险箱,也没有保险箱的钥匙🔑

流程

  1. 浏览器将对称加密方法列表、非对称加密方法列表、随机数 A 传输给服务端
  2. 服务器接受后,将对称加密、非对称加密方法、服务器生成的随机数 B 、数字证书发送给浏览器
  3. 浏览器接受后,验证证书的可靠性,并获取证书内的非对称加密的公钥
  4. 浏览器通过 2 个随机数生成新的随机数 C,并通过非对成加密的公钥对随机数 C 进行加密发送给服务器
  5. 服务器确认后,服务器与浏览器通过 3 个随机数生成对称加密密钥,进行数据传输

如何验证证书的可靠性

  1. 浏览器获取到证书后,通过 CA 相同的 Hash 算法对证书信息进行加密得到摘要 A
  2. 通过 CA 的公钥对证书内的数字签名进行解密,获取到摘要 B
  3. 如果 AB 相同,则证书可靠

什么是 HTTPS 中间人攻击?如何预防?

  1. 先说下 HTTPS 传输过程
  2. 客户端和服务端通信之间,新增一个中间人,伪造 CA 证书和加密数据,获取服务器和客户端的通信信息

流程

如何预防?

使用正规厂商的第三方证书

',21),c=[n];function p(d,P,_,b,m,u){return t(),e("div",null,c)}const f=a(T,[["render",p]]);export{S as __pageData,f as default}; diff --git "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTPS.md.24fcb37f.lean.js" "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTPS.md.4c7346fd.lean.js" similarity index 90% rename from "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTPS.md.24fcb37f.lean.js" rename to "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTPS.md.4c7346fd.lean.js" index c56831cc..3500f9bf 100644 --- "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTPS.md.24fcb37f.lean.js" +++ "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_HTTPS.md.4c7346fd.lean.js" @@ -1 +1 @@ -import{_ as a,o as t,c as e,Q as i}from"./chunks/framework.b6910bb2.js";const l="/vitePress-blob/assets/8.428d7ec3.jpg",s="/vitePress-blob/assets/9.7081f11f.jpg",o="/vitePress-blob/assets/10.80b27028.jpg",r="/vitePress-blob/assets/11.8b44a308.jpg",h="/vitePress-blob/assets/12.c1a5b37b.jpg",S=JSON.parse('{"title":"HTTPS","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/HTTPS.md","filePath":"guide/网络相关/HTTPS.md","lastUpdated":1707358495000}'),T={name:"guide/网络相关/HTTPS.md"},n=i("",21),c=[n];function p(d,P,_,b,m,u){return t(),e("div",null,c)}const f=a(T,[["render",p]]);export{S as __pageData,f as default}; +import{_ as a,o as t,c as e,Q as i}from"./chunks/framework.b6910bb2.js";const l="/vitePress-blob/assets/8.428d7ec3.jpg",s="/vitePress-blob/assets/9.7081f11f.jpg",o="/vitePress-blob/assets/10.80b27028.jpg",r="/vitePress-blob/assets/11.8b44a308.jpg",h="/vitePress-blob/assets/12.c1a5b37b.jpg",S=JSON.parse('{"title":"HTTPS","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/HTTPS.md","filePath":"guide/网络相关/HTTPS.md","lastUpdated":1707358769000}'),T={name:"guide/网络相关/HTTPS.md"},n=i("",21),c=[n];function p(d,P,_,b,m,u){return t(),e("div",null,c)}const f=a(T,[["render",p]]);export{S as __pageData,f as default}; diff --git "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\223\215\345\272\224\346\212\245\346\226\207.md.2f7e04b4.js" "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\223\215\345\272\224\346\212\245\346\226\207.md.e9c73579.js" similarity index 99% rename from "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\223\215\345\272\224\346\212\245\346\226\207.md.2f7e04b4.js" rename to "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\223\215\345\272\224\346\212\245\346\226\207.md.e9c73579.js" index 946590ce..e0f7d77c 100644 --- "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\223\215\345\272\224\346\212\245\346\226\207.md.2f7e04b4.js" +++ "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\223\215\345\272\224\346\212\245\346\226\207.md.e9c73579.js" @@ -1 +1 @@ -import{_ as i,o as l,c as a,Q as e}from"./chunks/framework.b6910bb2.js";const t="data:image/jpeg;base64,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",C=JSON.parse('{"title":"响应报文","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/响应报文.md","filePath":"guide/网络相关/响应报文.md","lastUpdated":1707358495000}'),o={name:"guide/网络相关/响应报文.md"},r=e('

响应报文

由响应行、响应头、响应体组成

响应行

由版本、状态码、原因语句组成

状态码

  • 1xx: 请求已被接受,需要继续处理

  • 2xx: 请求已成功处理

    • 200 请求正常处理、命中强缓存
    • 204 请求处理成功,但没有资源返回
    • 206 客户端进行了范围请求,服务端成功执行了这部分 GET 请求
  • 3xx:客户端需要采取进一步操作才能完成

    • 301 永久重定向
    • 302 临时重定向
    • 304 命中协商缓存
  • 4xx: 客户端错误

    • 400 请求存在语法错误
    • 401 用户登录权限不通过
    • 403 用户登录了,但操作权限不通过
    • 404 资源不存在
    • 405 请求行中制定的方法不能被用于请求相应的资源
  • 5xx: 服务端错误

    • 500 服务端报错
    • 504 服务/网关超时

流程

响应头

响应内容相关

  • content-type 内容类型 Content-Type: text/plain;charset=UTF-8
    • 常见的有:
      • application/x-www-form-urlencoded: 浏览器的原生 form 表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。该种方式提交的数据放在 body 里面,数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL转码
      • application/json: 服务器消息主体是序列化后的 JSON 字符串
      • multipart/form-data: 该种方式也是一个常见的 POST 提交方式,通常表单上传文件时使用该种方式。
  • content-length 内容长度

缓存相关

  • Cache-Control
  • Last-Modified
  • ETag

客户端相关

  • Set-Cookie: isGray=true;

跨域相关

  • 简单请求

    • Access-Control-Allow-Origin
  • 非简单请求

    • Access-Control-Allow-Methods
    • Access-Control-Allow-Headers
    • Access-Control-Max-Age
  • Cookie 相关

    • Access-Control-Allow-Credentials: true;

时间相关

Date: Mon, 21 Mar 2022 03:36:53 GMT

响应体

',19),d=[r];function n(h,s,p,u,c,A){return l(),a("div",null,d)}const f=i(o,[["render",n]]);export{C as __pageData,f as default}; +import{_ as i,o as l,c as a,Q as e}from"./chunks/framework.b6910bb2.js";const t="data:image/jpeg;base64,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",C=JSON.parse('{"title":"响应报文","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/响应报文.md","filePath":"guide/网络相关/响应报文.md","lastUpdated":1707358769000}'),o={name:"guide/网络相关/响应报文.md"},r=e('

响应报文

由响应行、响应头、响应体组成

响应行

由版本、状态码、原因语句组成

状态码

  • 1xx: 请求已被接受,需要继续处理

  • 2xx: 请求已成功处理

    • 200 请求正常处理、命中强缓存
    • 204 请求处理成功,但没有资源返回
    • 206 客户端进行了范围请求,服务端成功执行了这部分 GET 请求
  • 3xx:客户端需要采取进一步操作才能完成

    • 301 永久重定向
    • 302 临时重定向
    • 304 命中协商缓存
  • 4xx: 客户端错误

    • 400 请求存在语法错误
    • 401 用户登录权限不通过
    • 403 用户登录了,但操作权限不通过
    • 404 资源不存在
    • 405 请求行中制定的方法不能被用于请求相应的资源
  • 5xx: 服务端错误

    • 500 服务端报错
    • 504 服务/网关超时

流程

响应头

响应内容相关

  • content-type 内容类型 Content-Type: text/plain;charset=UTF-8
    • 常见的有:
      • application/x-www-form-urlencoded: 浏览器的原生 form 表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。该种方式提交的数据放在 body 里面,数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL转码
      • application/json: 服务器消息主体是序列化后的 JSON 字符串
      • multipart/form-data: 该种方式也是一个常见的 POST 提交方式,通常表单上传文件时使用该种方式。
  • content-length 内容长度

缓存相关

  • Cache-Control
  • Last-Modified
  • ETag

客户端相关

  • Set-Cookie: isGray=true;

跨域相关

  • 简单请求

    • Access-Control-Allow-Origin
  • 非简单请求

    • Access-Control-Allow-Methods
    • Access-Control-Allow-Headers
    • Access-Control-Max-Age
  • Cookie 相关

    • Access-Control-Allow-Credentials: true;

时间相关

Date: Mon, 21 Mar 2022 03:36:53 GMT

响应体

',19),d=[r];function n(h,s,p,u,c,A){return l(),a("div",null,d)}const f=i(o,[["render",n]]);export{C as __pageData,f as default}; diff --git "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\223\215\345\272\224\346\212\245\346\226\207.md.2f7e04b4.lean.js" "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\223\215\345\272\224\346\212\245\346\226\207.md.e9c73579.lean.js" similarity index 98% rename from "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\223\215\345\272\224\346\212\245\346\226\207.md.2f7e04b4.lean.js" rename to "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\223\215\345\272\224\346\212\245\346\226\207.md.e9c73579.lean.js" index a941fff6..16b803c7 100644 --- "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\223\215\345\272\224\346\212\245\346\226\207.md.2f7e04b4.lean.js" +++ "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\223\215\345\272\224\346\212\245\346\226\207.md.e9c73579.lean.js" @@ -1 +1 @@ -import{_ as i,o as l,c as a,Q as e}from"./chunks/framework.b6910bb2.js";const t="data:image/jpeg;base64,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",C=JSON.parse('{"title":"响应报文","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/响应报文.md","filePath":"guide/网络相关/响应报文.md","lastUpdated":1707358495000}'),o={name:"guide/网络相关/响应报文.md"},r=e("",19),d=[r];function n(h,s,p,u,c,A){return l(),a("div",null,d)}const f=i(o,[["render",n]]);export{C as __pageData,f as default}; +import{_ as i,o as l,c as a,Q as e}from"./chunks/framework.b6910bb2.js";const t="data:image/jpeg;base64,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",C=JSON.parse('{"title":"响应报文","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/响应报文.md","filePath":"guide/网络相关/响应报文.md","lastUpdated":1707358769000}'),o={name:"guide/网络相关/响应报文.md"},r=e("",19),d=[r];function n(h,s,p,u,c,A){return l(),a("div",null,d)}const f=i(o,[["render",n]]);export{C as __pageData,f as default}; diff --git "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.e25938b4.js" "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.3b584d49.js" similarity index 85% rename from "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.e25938b4.js" rename to "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.3b584d49.js" index 2bf838f1..255a3b46 100644 --- "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.e25938b4.js" +++ "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.3b584d49.js" @@ -1 +1 @@ -import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/常见的问题.md","filePath":"guide/网络相关/常见的问题.md","lastUpdated":1707358495000}'),r={name:"guide/网络相关/常见的问题.md"};function o(s,_,c,d,n,i){return t(),a("div")}const f=e(r,[["render",o]]);export{m as __pageData,f as default}; +import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/常见的问题.md","filePath":"guide/网络相关/常见的问题.md","lastUpdated":1707358769000}'),r={name:"guide/网络相关/常见的问题.md"};function o(s,_,c,d,n,i){return t(),a("div")}const f=e(r,[["render",o]]);export{m as __pageData,f as default}; diff --git "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.e25938b4.lean.js" "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.3b584d49.lean.js" similarity index 85% rename from "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.e25938b4.lean.js" rename to "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.3b584d49.lean.js" index 2bf838f1..255a3b46 100644 --- "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.e25938b4.lean.js" +++ "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.md.3b584d49.lean.js" @@ -1 +1 @@ -import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/常见的问题.md","filePath":"guide/网络相关/常见的问题.md","lastUpdated":1707358495000}'),r={name:"guide/网络相关/常见的问题.md"};function o(s,_,c,d,n,i){return t(),a("div")}const f=e(r,[["render",o]]);export{m as __pageData,f as default}; +import{_ as e,o as t,c as a}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/常见的问题.md","filePath":"guide/网络相关/常见的问题.md","lastUpdated":1707358769000}'),r={name:"guide/网络相关/常见的问题.md"};function o(s,_,c,d,n,i){return t(),a("div")}const f=e(r,[["render",o]]);export{m as __pageData,f as default}; diff --git "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\346\246\202\350\246\201.md.3cfbfdfd.js" "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\346\246\202\350\246\201.md.3b48bb07.js" similarity index 88% rename from "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\346\246\202\350\246\201.md.3cfbfdfd.js" rename to "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\346\246\202\350\246\201.md.3b48bb07.js" index a292e055..51b15adb 100644 --- "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\346\246\202\350\246\201.md.3cfbfdfd.js" +++ "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\346\246\202\350\246\201.md.3b48bb07.js" @@ -1 +1 @@ -import{_ as e}from"./chunks/container.fad5294e.js";import{o as t,c as a,H as s}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{"aside":false,"outline":false},"headers":[],"relativePath":"guide/网络相关/概要.md","filePath":"guide/网络相关/概要.md","lastUpdated":1707358495000}'),o={name:"guide/网络相关/概要.md"},n=Object.assign(o,{setup(r){return(c,d)=>(t(),a("div",null,[s(e,{url:"https://www.mubu.com/doc/7RYbHADBDCK#m"})]))}});export{m as __pageData,n as default}; +import{_ as e}from"./chunks/container.fad5294e.js";import{o as t,c as a,H as s}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{"aside":false,"outline":false},"headers":[],"relativePath":"guide/网络相关/概要.md","filePath":"guide/网络相关/概要.md","lastUpdated":1707358769000}'),o={name:"guide/网络相关/概要.md"},n=Object.assign(o,{setup(r){return(c,d)=>(t(),a("div",null,[s(e,{url:"https://www.mubu.com/doc/7RYbHADBDCK#m"})]))}});export{m as __pageData,n as default}; diff --git "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\346\246\202\350\246\201.md.3cfbfdfd.lean.js" "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\346\246\202\350\246\201.md.3b48bb07.lean.js" similarity index 88% rename from "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\346\246\202\350\246\201.md.3cfbfdfd.lean.js" rename to "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\346\246\202\350\246\201.md.3b48bb07.lean.js" index a292e055..51b15adb 100644 --- "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\346\246\202\350\246\201.md.3cfbfdfd.lean.js" +++ "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\346\246\202\350\246\201.md.3b48bb07.lean.js" @@ -1 +1 @@ -import{_ as e}from"./chunks/container.fad5294e.js";import{o as t,c as a,H as s}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{"aside":false,"outline":false},"headers":[],"relativePath":"guide/网络相关/概要.md","filePath":"guide/网络相关/概要.md","lastUpdated":1707358495000}'),o={name:"guide/网络相关/概要.md"},n=Object.assign(o,{setup(r){return(c,d)=>(t(),a("div",null,[s(e,{url:"https://www.mubu.com/doc/7RYbHADBDCK#m"})]))}});export{m as __pageData,n as default}; +import{_ as e}from"./chunks/container.fad5294e.js";import{o as t,c as a,H as s}from"./chunks/framework.b6910bb2.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{"aside":false,"outline":false},"headers":[],"relativePath":"guide/网络相关/概要.md","filePath":"guide/网络相关/概要.md","lastUpdated":1707358769000}'),o={name:"guide/网络相关/概要.md"},n=Object.assign(o,{setup(r){return(c,d)=>(t(),a("div",null,[s(e,{url:"https://www.mubu.com/doc/7RYbHADBDCK#m"})]))}});export{m as __pageData,n as default}; diff --git "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\257\267\346\261\202\346\212\245\346\226\207.md.ccdffe1b.js" "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\257\267\346\261\202\346\212\245\346\226\207.md.715db4fc.js" similarity index 98% rename from "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\257\267\346\261\202\346\212\245\346\226\207.md.ccdffe1b.js" rename to "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\257\267\346\261\202\346\212\245\346\226\207.md.715db4fc.js" index 49c7ca99..708af2d3 100644 --- "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\257\267\346\261\202\346\212\245\346\226\207.md.ccdffe1b.js" +++ "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\257\267\346\261\202\346\212\245\346\226\207.md.715db4fc.js" @@ -1 +1 @@ -import{_ as a,o as e,c as i,Q as l}from"./chunks/framework.b6910bb2.js";const t="/vitePress-blob/assets/2.8a82dbf4.png",o="/vitePress-blob/assets/3.8de7cbe1.jpg",m=JSON.parse('{"title":"请求报文","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/请求报文.md","filePath":"guide/网络相关/请求报文.md","lastUpdated":1707358495000}'),r={name:"guide/网络相关/请求报文.md"},n=l('

请求报文

由请求行、请求头、请求体组成

请求行

由请求方法、URI、协议版本组成

流程

请求方法

  1. GET 请求获取资源
  2. POST 提交数据
  3. PUT 更新资源
  4. DELETE 删除资源
  5. OPTIONS 查询针对请求 URL 指定的资源支持的方法(常用在非简单请求的预检上)
  6. HEAD 获取响应头
  7. CONNECT 要求用隧道协议链接代理
  8. TRACE 追踪请求经过的路径

URI 字段

协议版本

HTTP0.9、 HTTP1.0、HTTP1.1、HTTP2.0、HTTP3.0

请求头

接受内容相关

  1. Accept 浏览器接受的格式 Accept: application/json, text/plain, /
  2. Accept-Encoding 浏览器接受的压缩格式 Accept-Encoding: gzip, deflate, br
  3. Accept-Language 浏览器接受的语言 Accept-Language: zh-CN
  4. Accept-Charset 浏览器接受的字符集

强缓存相关

  1. Cache-Control

协商缓存相关

  1. If-Modified-Since 上一次访问时文件的更改时间 (存在校验问题,比如文件内容只是添加了空格,但是 Last-Modified 改变了)
  2. If-None-Match 上次访问的 ETag 信息 (如果 If-None-Match 和 ETag 一致,则命中 304 协商缓存)

请求域名相关

  1. HOST HTTP 请求的域名
  2. Origin 页面域名 (常用于防止 CSRF 攻击和跨域请求)
  3. Referer 发出请求的页面 URL

客户端相关

  • UA
  • COOKIE

连接相关

  • Connection Connection: keep-alive

流程

请求体

',25),h=[n];function c(s,d,u,p,_,b){return e(),i("div",null,h)}const P=a(r,[["render",c]]);export{m as __pageData,P as default}; +import{_ as a,o as e,c as i,Q as l}from"./chunks/framework.b6910bb2.js";const t="/vitePress-blob/assets/2.8a82dbf4.png",o="/vitePress-blob/assets/3.8de7cbe1.jpg",m=JSON.parse('{"title":"请求报文","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/请求报文.md","filePath":"guide/网络相关/请求报文.md","lastUpdated":1707358769000}'),r={name:"guide/网络相关/请求报文.md"},n=l('

请求报文

由请求行、请求头、请求体组成

请求行

由请求方法、URI、协议版本组成

流程

请求方法

  1. GET 请求获取资源
  2. POST 提交数据
  3. PUT 更新资源
  4. DELETE 删除资源
  5. OPTIONS 查询针对请求 URL 指定的资源支持的方法(常用在非简单请求的预检上)
  6. HEAD 获取响应头
  7. CONNECT 要求用隧道协议链接代理
  8. TRACE 追踪请求经过的路径

URI 字段

协议版本

HTTP0.9、 HTTP1.0、HTTP1.1、HTTP2.0、HTTP3.0

请求头

接受内容相关

  1. Accept 浏览器接受的格式 Accept: application/json, text/plain, /
  2. Accept-Encoding 浏览器接受的压缩格式 Accept-Encoding: gzip, deflate, br
  3. Accept-Language 浏览器接受的语言 Accept-Language: zh-CN
  4. Accept-Charset 浏览器接受的字符集

强缓存相关

  1. Cache-Control

协商缓存相关

  1. If-Modified-Since 上一次访问时文件的更改时间 (存在校验问题,比如文件内容只是添加了空格,但是 Last-Modified 改变了)
  2. If-None-Match 上次访问的 ETag 信息 (如果 If-None-Match 和 ETag 一致,则命中 304 协商缓存)

请求域名相关

  1. HOST HTTP 请求的域名
  2. Origin 页面域名 (常用于防止 CSRF 攻击和跨域请求)
  3. Referer 发出请求的页面 URL

客户端相关

  • UA
  • COOKIE

连接相关

  • Connection Connection: keep-alive

流程

请求体

',25),h=[n];function c(s,d,u,p,_,b){return e(),i("div",null,h)}const P=a(r,[["render",c]]);export{m as __pageData,P as default}; diff --git "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\257\267\346\261\202\346\212\245\346\226\207.md.ccdffe1b.lean.js" "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\257\267\346\261\202\346\212\245\346\226\207.md.715db4fc.lean.js" similarity index 88% rename from "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\257\267\346\261\202\346\212\245\346\226\207.md.ccdffe1b.lean.js" rename to "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\257\267\346\261\202\346\212\245\346\226\207.md.715db4fc.lean.js" index 40dfd1f2..726f6d24 100644 --- "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\257\267\346\261\202\346\212\245\346\226\207.md.ccdffe1b.lean.js" +++ "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\257\267\346\261\202\346\212\245\346\226\207.md.715db4fc.lean.js" @@ -1 +1 @@ -import{_ as a,o as e,c as i,Q as l}from"./chunks/framework.b6910bb2.js";const t="/vitePress-blob/assets/2.8a82dbf4.png",o="/vitePress-blob/assets/3.8de7cbe1.jpg",m=JSON.parse('{"title":"请求报文","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/请求报文.md","filePath":"guide/网络相关/请求报文.md","lastUpdated":1707358495000}'),r={name:"guide/网络相关/请求报文.md"},n=l("",25),h=[n];function c(s,d,u,p,_,b){return e(),i("div",null,h)}const P=a(r,[["render",c]]);export{m as __pageData,P as default}; +import{_ as a,o as e,c as i,Q as l}from"./chunks/framework.b6910bb2.js";const t="/vitePress-blob/assets/2.8a82dbf4.png",o="/vitePress-blob/assets/3.8de7cbe1.jpg",m=JSON.parse('{"title":"请求报文","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/请求报文.md","filePath":"guide/网络相关/请求报文.md","lastUpdated":1707358769000}'),r={name:"guide/网络相关/请求报文.md"},n=l("",25),h=[n];function c(s,d,u,p,_,b){return e(),i("div",null,h)}const P=a(r,[["render",c]]);export{m as __pageData,P as default}; diff --git "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\267\250\345\237\237\350\257\267\346\261\202.md.2626dc46.js" "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\267\250\345\237\237\350\257\267\346\261\202.md.f2530ac2.js" similarity index 99% rename from "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\267\250\345\237\237\350\257\267\346\261\202.md.2626dc46.js" rename to "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\267\250\345\237\237\350\257\267\346\261\202.md.f2530ac2.js" index 8c07f833..18c05390 100644 --- "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\267\250\345\237\237\350\257\267\346\261\202.md.2626dc46.js" +++ "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\267\250\345\237\237\350\257\267\346\261\202.md.f2530ac2.js" @@ -1 +1 @@ -import{_ as i,o,c as l,Q as e}from"./chunks/framework.b6910bb2.js";const a="/vitePress-blob/assets/7.d0aefc74.jpg",t="/vitePress-blob/assets/8.28d1dcd9.jpg",s="/vitePress-blob/assets/16.ecfc65d2.jpg",r="/vitePress-blob/assets/17.8329667f.jpg",n="/vitePress-blob/assets/18.5204f2f6.jpg",q=JSON.parse('{"title":"跨域请求","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/跨域请求.md","filePath":"guide/网络相关/跨域请求.md","lastUpdated":1707358495000}'),c={name:"guide/网络相关/跨域请求.md"},d=e('

跨域请求

简单请求

若请求满足所有下述条件,则该请求可视为简单请求:

  1. HEAD/GET/POST 请求
  2. Content-Type: text/plain、multipart/form-data、application/x-www-form-urlencoded
  3. 除了被用户代理自动设置的标头字段,剩下的请求头是: Accept、Accept-Language、Content-Language、Content-Type、Range

请求过程

  1. 发起请求,请求头会带上 Origin 字段,该字段用来说明请求来自哪个源(协议 + 域名 + 端口),服务器根据这个值决定是否同意这次请求
  2. 当服务器接收到请求后,根据 Origin 判断是否在允许的范围内
  3. 如果不在范围内,服务器会返回一个正常的 HTTP 响应,浏览器发现响应头信息没有 Access-Control-Allow-Origin 字段,就知道出错了,从而抛出错误,被 XML 的 onerror 回调函数捕获。(注意:由于正常响应,其状态码为200,因此该错误不能通过状态码识别)
  4. 如果 Origin 指定的域名在范围内,服务器返回的响应会多出几个头信息字段(Access-Control-Allow-Origin、Access-Control-Allow-Credentials、Access-Control-Expose-Header 等)

流程

非简单请求

请求方法是 PUT、DELETE 或者 Content-Type 是 application/json 类型

请求过程 (源、请求头、方法、缓存、Cookie)

  1. 浏览器发起 Option 预检请求
  2. 服务器收到预检请求以后,检查了 Origin、Access-Control-Request-Method 和 Access-Control-Request-Headers 字段后,确认允许跨域请求,就可以做出回应
    • Origin (必须): 发起请求的源信息
    • Access-Control-Request-Method(必须): 用来列出浏览器的 CORS 请求会用到哪些 HTTP 方法
    • Access-Control-Request-Headers 跨域请求而外的请求头字段
  3. 如果服务器预检请求,会返回一个正常的 HTTP 回应,但没有任何的 CORS 相关的头信息字段,这时浏览器就会认定服务器不同意预检请求,触发错误。
  4. 如果服务器通过了预检请求,以后每次浏览器正常的 CORS 请求就跟简单请求一样
    • Access-Control-Allow-Origin(必须): 运行哪些源跨域,如果是 * 无法携带 Cookie
    • Access-Control-Allow-Method(必须): 服务器支持哪些请求
    • Access-Control-Allow-Header: 服务器支持的头信息字段
    • Access-Control-Max-Age: 预检请求的有效期,单位秒

流程

  1. 响应头设置 Access-Control-Allow-Credentials 等于 true
  2. Access-Control-Allow-Origin 不能设置成 * (Cookie 的 SameSite 属性如果是 Lax 可能也会导致带不上去)
  3. 前端设置 withCredentials: true

常见的问题

cookie 一般用于登录验证,存储用户信息,大小为 4KB,会随着网络请求携带给服务端

session 一般存储在服务端,常用于与 Cookie 配合做登录检验

  • cookie 是 HTTP 的内容,token 是自定义的数据
  • cookie 可以默认存储在浏览器中,token 需要自行存储
  • token 没有跨域限制,cookie 存在跨域限制
  • token 常用于 CSRF 或者 JWT(JSON WEB TOKEN)
  • Cookie 常于 Session 配合,做用户登录鉴权
  • 基本属性:

    • name
    • value
  • 访问性:

    • expire
    • path
    • domain
  • 安全性:

    • secure
    • httpOnly
    • sameSite

Session 和 JWT 哪个更合适?

  • Session

    • 优点:
      1. 易于学习
      2. 用户信息存储在服务器,可以快速封禁某个用户
    • 缺点:
      1. 占用服务器资源,硬件成本高
      2. 多进程、多服务器时,不好同步 (需要第三方缓存, Redis)
      3. Session 需要配合 Cookie 使用,cookie 有域名限制
  • Json Web Token

    • 优点:
      1. 存储在客户端,不占用服务端资源
      2. 易于同步
      3. 没有跨域限制
    • 缺点:
      1. 无法快速封禁用户
      2. Token 不安全,一但秘钥被泄漏,容易窃取用户信息
      3. Token很大,影响请求体积
  • 使用场景:

    • 用户信息安全 -> 使用 Session
    • 没有特殊要求 -> 使用 JWT

如何实现 SSO 单点登录

Cookie 默认跨域不共享

可以通过设置 Cookie 的 domain 为相同的主域名,即可共享 Cookie

比如 www.baidu.com、image.baidu.com 主域名是相同的,设置 cookie domain 为主域名,即可共享 cookie

流程

如果主域名不一致

  1. 使用 SSO 第三方登录, 获取 ticket 返回给 A、B 系统

流程

  1. OAuth2.0

第三方登录(例如微信扫码登录)

流程

',36),h=[d];function p(u,k,m,b,C,_){return o(),l("div",null,h)}const A=i(c,[["render",p]]);export{q as __pageData,A as default}; +import{_ as i,o,c as l,Q as e}from"./chunks/framework.b6910bb2.js";const a="/vitePress-blob/assets/7.d0aefc74.jpg",t="/vitePress-blob/assets/8.28d1dcd9.jpg",s="/vitePress-blob/assets/16.ecfc65d2.jpg",r="/vitePress-blob/assets/17.8329667f.jpg",n="/vitePress-blob/assets/18.5204f2f6.jpg",q=JSON.parse('{"title":"跨域请求","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/跨域请求.md","filePath":"guide/网络相关/跨域请求.md","lastUpdated":1707358769000}'),c={name:"guide/网络相关/跨域请求.md"},d=e('

跨域请求

简单请求

若请求满足所有下述条件,则该请求可视为简单请求:

  1. HEAD/GET/POST 请求
  2. Content-Type: text/plain、multipart/form-data、application/x-www-form-urlencoded
  3. 除了被用户代理自动设置的标头字段,剩下的请求头是: Accept、Accept-Language、Content-Language、Content-Type、Range

请求过程

  1. 发起请求,请求头会带上 Origin 字段,该字段用来说明请求来自哪个源(协议 + 域名 + 端口),服务器根据这个值决定是否同意这次请求
  2. 当服务器接收到请求后,根据 Origin 判断是否在允许的范围内
  3. 如果不在范围内,服务器会返回一个正常的 HTTP 响应,浏览器发现响应头信息没有 Access-Control-Allow-Origin 字段,就知道出错了,从而抛出错误,被 XML 的 onerror 回调函数捕获。(注意:由于正常响应,其状态码为200,因此该错误不能通过状态码识别)
  4. 如果 Origin 指定的域名在范围内,服务器返回的响应会多出几个头信息字段(Access-Control-Allow-Origin、Access-Control-Allow-Credentials、Access-Control-Expose-Header 等)

流程

非简单请求

请求方法是 PUT、DELETE 或者 Content-Type 是 application/json 类型

请求过程 (源、请求头、方法、缓存、Cookie)

  1. 浏览器发起 Option 预检请求
  2. 服务器收到预检请求以后,检查了 Origin、Access-Control-Request-Method 和 Access-Control-Request-Headers 字段后,确认允许跨域请求,就可以做出回应
    • Origin (必须): 发起请求的源信息
    • Access-Control-Request-Method(必须): 用来列出浏览器的 CORS 请求会用到哪些 HTTP 方法
    • Access-Control-Request-Headers 跨域请求而外的请求头字段
  3. 如果服务器预检请求,会返回一个正常的 HTTP 回应,但没有任何的 CORS 相关的头信息字段,这时浏览器就会认定服务器不同意预检请求,触发错误。
  4. 如果服务器通过了预检请求,以后每次浏览器正常的 CORS 请求就跟简单请求一样
    • Access-Control-Allow-Origin(必须): 运行哪些源跨域,如果是 * 无法携带 Cookie
    • Access-Control-Allow-Method(必须): 服务器支持哪些请求
    • Access-Control-Allow-Header: 服务器支持的头信息字段
    • Access-Control-Max-Age: 预检请求的有效期,单位秒

流程

  1. 响应头设置 Access-Control-Allow-Credentials 等于 true
  2. Access-Control-Allow-Origin 不能设置成 * (Cookie 的 SameSite 属性如果是 Lax 可能也会导致带不上去)
  3. 前端设置 withCredentials: true

常见的问题

cookie 一般用于登录验证,存储用户信息,大小为 4KB,会随着网络请求携带给服务端

session 一般存储在服务端,常用于与 Cookie 配合做登录检验

  • cookie 是 HTTP 的内容,token 是自定义的数据
  • cookie 可以默认存储在浏览器中,token 需要自行存储
  • token 没有跨域限制,cookie 存在跨域限制
  • token 常用于 CSRF 或者 JWT(JSON WEB TOKEN)
  • Cookie 常于 Session 配合,做用户登录鉴权
  • 基本属性:

    • name
    • value
  • 访问性:

    • expire
    • path
    • domain
  • 安全性:

    • secure
    • httpOnly
    • sameSite

Session 和 JWT 哪个更合适?

  • Session

    • 优点:
      1. 易于学习
      2. 用户信息存储在服务器,可以快速封禁某个用户
    • 缺点:
      1. 占用服务器资源,硬件成本高
      2. 多进程、多服务器时,不好同步 (需要第三方缓存, Redis)
      3. Session 需要配合 Cookie 使用,cookie 有域名限制
  • Json Web Token

    • 优点:
      1. 存储在客户端,不占用服务端资源
      2. 易于同步
      3. 没有跨域限制
    • 缺点:
      1. 无法快速封禁用户
      2. Token 不安全,一但秘钥被泄漏,容易窃取用户信息
      3. Token很大,影响请求体积
  • 使用场景:

    • 用户信息安全 -> 使用 Session
    • 没有特殊要求 -> 使用 JWT

如何实现 SSO 单点登录

Cookie 默认跨域不共享

可以通过设置 Cookie 的 domain 为相同的主域名,即可共享 Cookie

比如 www.baidu.com、image.baidu.com 主域名是相同的,设置 cookie domain 为主域名,即可共享 cookie

流程

如果主域名不一致

  1. 使用 SSO 第三方登录, 获取 ticket 返回给 A、B 系统

流程

  1. OAuth2.0

第三方登录(例如微信扫码登录)

流程

',36),h=[d];function p(u,k,m,b,C,_){return o(),l("div",null,h)}const A=i(c,[["render",p]]);export{q as __pageData,A as default}; diff --git "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\267\250\345\237\237\350\257\267\346\261\202.md.2626dc46.lean.js" "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\267\250\345\237\237\350\257\267\346\261\202.md.f2530ac2.lean.js" similarity index 90% rename from "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\267\250\345\237\237\350\257\267\346\261\202.md.2626dc46.lean.js" rename to "assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\267\250\345\237\237\350\257\267\346\261\202.md.f2530ac2.lean.js" index 418c839c..67563a56 100644 --- "a/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\267\250\345\237\237\350\257\267\346\261\202.md.2626dc46.lean.js" +++ "b/assets/guide_\347\275\221\347\273\234\347\233\270\345\205\263_\350\267\250\345\237\237\350\257\267\346\261\202.md.f2530ac2.lean.js" @@ -1 +1 @@ -import{_ as i,o,c as l,Q as e}from"./chunks/framework.b6910bb2.js";const a="/vitePress-blob/assets/7.d0aefc74.jpg",t="/vitePress-blob/assets/8.28d1dcd9.jpg",s="/vitePress-blob/assets/16.ecfc65d2.jpg",r="/vitePress-blob/assets/17.8329667f.jpg",n="/vitePress-blob/assets/18.5204f2f6.jpg",q=JSON.parse('{"title":"跨域请求","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/跨域请求.md","filePath":"guide/网络相关/跨域请求.md","lastUpdated":1707358495000}'),c={name:"guide/网络相关/跨域请求.md"},d=e("",36),h=[d];function p(u,k,m,b,C,_){return o(),l("div",null,h)}const A=i(c,[["render",p]]);export{q as __pageData,A as default}; +import{_ as i,o,c as l,Q as e}from"./chunks/framework.b6910bb2.js";const a="/vitePress-blob/assets/7.d0aefc74.jpg",t="/vitePress-blob/assets/8.28d1dcd9.jpg",s="/vitePress-blob/assets/16.ecfc65d2.jpg",r="/vitePress-blob/assets/17.8329667f.jpg",n="/vitePress-blob/assets/18.5204f2f6.jpg",q=JSON.parse('{"title":"跨域请求","description":"","frontmatter":{},"headers":[],"relativePath":"guide/网络相关/跨域请求.md","filePath":"guide/网络相关/跨域请求.md","lastUpdated":1707358769000}'),c={name:"guide/网络相关/跨域请求.md"},d=e("",36),h=[d];function p(u,k,m,b,C,_){return o(),l("div",null,h)}const A=i(c,[["render",p]]);export{q as __pageData,A as default}; diff --git a/assets/index.md.57af2e65.js b/assets/index.md.a6c2532f.js similarity index 92% rename from assets/index.md.57af2e65.js rename to assets/index.md.a6c2532f.js index 04163802..8faf309a 100644 --- a/assets/index.md.57af2e65.js +++ b/assets/index.md.a6c2532f.js @@ -1 +1 @@ -import{_ as t,o as a,c as s,k as e,a as n}from"./chunks/framework.b6910bb2.js";const k=JSON.parse('{"title":"","description":"","frontmatter":{"layout":"doc"},"headers":[],"relativePath":"index.md","filePath":"index.md","lastUpdated":1707358495000}'),o={name:"index.md"},d=e("h3",{id:"个人知识库",tabindex:"-1"},[n("个人知识库 "),e("a",{class:"header-anchor",href:"#个人知识库","aria-label":'Permalink to "个人知识库"'},"​")],-1),r=e("p",null,"👋 欢迎来到我的博客,这里是我记录学习和生活的地方,希望能帮助到你",-1),_=e("p",null,"采用 VitePress 进行构建,为了有更好的阅读体验,请使用新版本浏览器",-1),c=[d,r,_];function i(l,p,h,m,x,f){return a(),s("div",null,c)}const P=t(o,[["render",i]]);export{k as __pageData,P as default}; +import{_ as t,o as a,c as s,k as e,a as n}from"./chunks/framework.b6910bb2.js";const k=JSON.parse('{"title":"","description":"","frontmatter":{"layout":"doc"},"headers":[],"relativePath":"index.md","filePath":"index.md","lastUpdated":1707358769000}'),o={name:"index.md"},d=e("h3",{id:"个人知识库",tabindex:"-1"},[n("个人知识库 "),e("a",{class:"header-anchor",href:"#个人知识库","aria-label":'Permalink to "个人知识库"'},"​")],-1),r=e("p",null,"👋 欢迎来到我的博客,这里是我记录学习和生活的地方,希望能帮助到你",-1),_=e("p",null,"采用 VitePress 进行构建,为了有更好的阅读体验,请使用新版本浏览器",-1),c=[d,r,_];function i(l,p,h,m,x,f){return a(),s("div",null,c)}const P=t(o,[["render",i]]);export{k as __pageData,P as default}; diff --git a/assets/index.md.57af2e65.lean.js b/assets/index.md.a6c2532f.lean.js similarity index 92% rename from assets/index.md.57af2e65.lean.js rename to assets/index.md.a6c2532f.lean.js index 04163802..8faf309a 100644 --- a/assets/index.md.57af2e65.lean.js +++ b/assets/index.md.a6c2532f.lean.js @@ -1 +1 @@ -import{_ as t,o as a,c as s,k as e,a as n}from"./chunks/framework.b6910bb2.js";const k=JSON.parse('{"title":"","description":"","frontmatter":{"layout":"doc"},"headers":[],"relativePath":"index.md","filePath":"index.md","lastUpdated":1707358495000}'),o={name:"index.md"},d=e("h3",{id:"个人知识库",tabindex:"-1"},[n("个人知识库 "),e("a",{class:"header-anchor",href:"#个人知识库","aria-label":'Permalink to "个人知识库"'},"​")],-1),r=e("p",null,"👋 欢迎来到我的博客,这里是我记录学习和生活的地方,希望能帮助到你",-1),_=e("p",null,"采用 VitePress 进行构建,为了有更好的阅读体验,请使用新版本浏览器",-1),c=[d,r,_];function i(l,p,h,m,x,f){return a(),s("div",null,c)}const P=t(o,[["render",i]]);export{k as __pageData,P as default}; +import{_ as t,o as a,c as s,k as e,a as n}from"./chunks/framework.b6910bb2.js";const k=JSON.parse('{"title":"","description":"","frontmatter":{"layout":"doc"},"headers":[],"relativePath":"index.md","filePath":"index.md","lastUpdated":1707358769000}'),o={name:"index.md"},d=e("h3",{id:"个人知识库",tabindex:"-1"},[n("个人知识库 "),e("a",{class:"header-anchor",href:"#个人知识库","aria-label":'Permalink to "个人知识库"'},"​")],-1),r=e("p",null,"👋 欢迎来到我的博客,这里是我记录学习和生活的地方,希望能帮助到你",-1),_=e("p",null,"采用 VitePress 进行构建,为了有更好的阅读体验,请使用新版本浏览器",-1),c=[d,r,_];function i(l,p,h,m,x,f){return a(),s("div",null,c)}const P=t(o,[["render",i]]);export{k as __pageData,P as default}; diff --git "a/assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_ISO\346\204\237\345\205\211\345\272\246.md.f82c77cc.js" "b/assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_ISO\346\204\237\345\205\211\345\272\246.md.1470d204.js" similarity index 91% rename from "assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_ISO\346\204\237\345\205\211\345\272\246.md.f82c77cc.js" rename to "assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_ISO\346\204\237\345\205\211\345\272\246.md.1470d204.js" index d7553390..1a1bfa9c 100644 --- "a/assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_ISO\346\204\237\345\205\211\345\272\246.md.f82c77cc.js" +++ "b/assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_ISO\346\204\237\345\205\211\345\272\246.md.1470d204.js" @@ -1 +1 @@ -import{_ as t,o as a,c as o,k as e,a as s}from"./chunks/framework.b6910bb2.js";const S=JSON.parse('{"title":"ISO 感光度","description":"","frontmatter":{},"headers":[],"relativePath":"shoot/基础概念/ISO感光度.md","filePath":"shoot/基础概念/ISO感光度.md","lastUpdated":1707358495000}'),n={name:"shoot/基础概念/ISO感光度.md"},r=e("h1",{id:"iso-感光度",tabindex:"-1"},[s("ISO 感光度 "),e("a",{class:"header-anchor",href:"#iso-感光度","aria-label":'Permalink to "ISO 感光度"'},"​")],-1),c=e("p",null,"传感器对光线的敏感程度",-1),l=e("ul",null,[e("li",null,"感光度越大、图片越亮,但也容易出现噪点")],-1),_=[r,c,l];function d(i,h,p,m,f,u){return a(),o("div",null,_)}const I=t(n,[["render",d]]);export{S as __pageData,I as default}; +import{_ as t,o as a,c as o,k as e,a as s}from"./chunks/framework.b6910bb2.js";const S=JSON.parse('{"title":"ISO 感光度","description":"","frontmatter":{},"headers":[],"relativePath":"shoot/基础概念/ISO感光度.md","filePath":"shoot/基础概念/ISO感光度.md","lastUpdated":1707358769000}'),n={name:"shoot/基础概念/ISO感光度.md"},r=e("h1",{id:"iso-感光度",tabindex:"-1"},[s("ISO 感光度 "),e("a",{class:"header-anchor",href:"#iso-感光度","aria-label":'Permalink to "ISO 感光度"'},"​")],-1),c=e("p",null,"传感器对光线的敏感程度",-1),l=e("ul",null,[e("li",null,"感光度越大、图片越亮,但也容易出现噪点")],-1),_=[r,c,l];function d(i,h,p,m,f,u){return a(),o("div",null,_)}const I=t(n,[["render",d]]);export{S as __pageData,I as default}; diff --git "a/assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_ISO\346\204\237\345\205\211\345\272\246.md.f82c77cc.lean.js" "b/assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_ISO\346\204\237\345\205\211\345\272\246.md.1470d204.lean.js" similarity index 91% rename from "assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_ISO\346\204\237\345\205\211\345\272\246.md.f82c77cc.lean.js" rename to "assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_ISO\346\204\237\345\205\211\345\272\246.md.1470d204.lean.js" index d7553390..1a1bfa9c 100644 --- "a/assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_ISO\346\204\237\345\205\211\345\272\246.md.f82c77cc.lean.js" +++ "b/assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_ISO\346\204\237\345\205\211\345\272\246.md.1470d204.lean.js" @@ -1 +1 @@ -import{_ as t,o as a,c as o,k as e,a as s}from"./chunks/framework.b6910bb2.js";const S=JSON.parse('{"title":"ISO 感光度","description":"","frontmatter":{},"headers":[],"relativePath":"shoot/基础概念/ISO感光度.md","filePath":"shoot/基础概念/ISO感光度.md","lastUpdated":1707358495000}'),n={name:"shoot/基础概念/ISO感光度.md"},r=e("h1",{id:"iso-感光度",tabindex:"-1"},[s("ISO 感光度 "),e("a",{class:"header-anchor",href:"#iso-感光度","aria-label":'Permalink to "ISO 感光度"'},"​")],-1),c=e("p",null,"传感器对光线的敏感程度",-1),l=e("ul",null,[e("li",null,"感光度越大、图片越亮,但也容易出现噪点")],-1),_=[r,c,l];function d(i,h,p,m,f,u){return a(),o("div",null,_)}const I=t(n,[["render",d]]);export{S as __pageData,I as default}; +import{_ as t,o as a,c as o,k as e,a as s}from"./chunks/framework.b6910bb2.js";const S=JSON.parse('{"title":"ISO 感光度","description":"","frontmatter":{},"headers":[],"relativePath":"shoot/基础概念/ISO感光度.md","filePath":"shoot/基础概念/ISO感光度.md","lastUpdated":1707358769000}'),n={name:"shoot/基础概念/ISO感光度.md"},r=e("h1",{id:"iso-感光度",tabindex:"-1"},[s("ISO 感光度 "),e("a",{class:"header-anchor",href:"#iso-感光度","aria-label":'Permalink to "ISO 感光度"'},"​")],-1),c=e("p",null,"传感器对光线的敏感程度",-1),l=e("ul",null,[e("li",null,"感光度越大、图片越亮,但也容易出现噪点")],-1),_=[r,c,l];function d(i,h,p,m,f,u){return a(),o("div",null,_)}const I=t(n,[["render",d]]);export{S as __pageData,I as default}; diff --git "a/assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\205\211\345\234\210.md.6fcc955a.js" "b/assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\205\211\345\234\210.md.ae3bc87c.js" similarity index 92% rename from "assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\205\211\345\234\210.md.6fcc955a.js" rename to "assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\205\211\345\234\210.md.ae3bc87c.js" index 31952018..825e97a1 100644 --- "a/assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\205\211\345\234\210.md.6fcc955a.js" +++ "b/assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\205\211\345\234\210.md.ae3bc87c.js" @@ -1 +1 @@ -import{_ as t,o as a,c as o,k as e,a as s}from"./chunks/framework.b6910bb2.js";const k=JSON.parse('{"title":"光圈","description":"","frontmatter":{},"headers":[],"relativePath":"shoot/基础概念/光圈.md","filePath":"shoot/基础概念/光圈.md","lastUpdated":1707358495000}'),n={name:"shoot/基础概念/光圈.md"},l=e("h1",{id:"光圈",tabindex:"-1"},[s("光圈 "),e("a",{class:"header-anchor",href:"#光圈","aria-label":'Permalink to "光圈"'},"​")],-1),r=e("p",null,"控制光圈大小",-1),c=e("ol",null,[e("li",null,"数字越大、光圈越小就越暗 - 图像越清晰"),e("li",null,"数字越小、光圈越大就越亮 - 光圈过大虚化效果明显")],-1),d=[l,r,c];function _(i,h,p,m,f,u){return a(),o("div",null,d)}const $=t(n,[["render",_]]);export{k as __pageData,$ as default}; +import{_ as t,o as a,c as o,k as e,a as s}from"./chunks/framework.b6910bb2.js";const k=JSON.parse('{"title":"光圈","description":"","frontmatter":{},"headers":[],"relativePath":"shoot/基础概念/光圈.md","filePath":"shoot/基础概念/光圈.md","lastUpdated":1707358769000}'),n={name:"shoot/基础概念/光圈.md"},l=e("h1",{id:"光圈",tabindex:"-1"},[s("光圈 "),e("a",{class:"header-anchor",href:"#光圈","aria-label":'Permalink to "光圈"'},"​")],-1),r=e("p",null,"控制光圈大小",-1),c=e("ol",null,[e("li",null,"数字越大、光圈越小就越暗 - 图像越清晰"),e("li",null,"数字越小、光圈越大就越亮 - 光圈过大虚化效果明显")],-1),d=[l,r,c];function _(i,h,p,m,f,u){return a(),o("div",null,d)}const $=t(n,[["render",_]]);export{k as __pageData,$ as default}; diff --git "a/assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\205\211\345\234\210.md.6fcc955a.lean.js" "b/assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\205\211\345\234\210.md.ae3bc87c.lean.js" similarity index 92% rename from "assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\205\211\345\234\210.md.6fcc955a.lean.js" rename to "assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\205\211\345\234\210.md.ae3bc87c.lean.js" index 31952018..825e97a1 100644 --- "a/assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\205\211\345\234\210.md.6fcc955a.lean.js" +++ "b/assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\205\211\345\234\210.md.ae3bc87c.lean.js" @@ -1 +1 @@ -import{_ as t,o as a,c as o,k as e,a as s}from"./chunks/framework.b6910bb2.js";const k=JSON.parse('{"title":"光圈","description":"","frontmatter":{},"headers":[],"relativePath":"shoot/基础概念/光圈.md","filePath":"shoot/基础概念/光圈.md","lastUpdated":1707358495000}'),n={name:"shoot/基础概念/光圈.md"},l=e("h1",{id:"光圈",tabindex:"-1"},[s("光圈 "),e("a",{class:"header-anchor",href:"#光圈","aria-label":'Permalink to "光圈"'},"​")],-1),r=e("p",null,"控制光圈大小",-1),c=e("ol",null,[e("li",null,"数字越大、光圈越小就越暗 - 图像越清晰"),e("li",null,"数字越小、光圈越大就越亮 - 光圈过大虚化效果明显")],-1),d=[l,r,c];function _(i,h,p,m,f,u){return a(),o("div",null,d)}const $=t(n,[["render",_]]);export{k as __pageData,$ as default}; +import{_ as t,o as a,c as o,k as e,a as s}from"./chunks/framework.b6910bb2.js";const k=JSON.parse('{"title":"光圈","description":"","frontmatter":{},"headers":[],"relativePath":"shoot/基础概念/光圈.md","filePath":"shoot/基础概念/光圈.md","lastUpdated":1707358769000}'),n={name:"shoot/基础概念/光圈.md"},l=e("h1",{id:"光圈",tabindex:"-1"},[s("光圈 "),e("a",{class:"header-anchor",href:"#光圈","aria-label":'Permalink to "光圈"'},"​")],-1),r=e("p",null,"控制光圈大小",-1),c=e("ol",null,[e("li",null,"数字越大、光圈越小就越暗 - 图像越清晰"),e("li",null,"数字越小、光圈越大就越亮 - 光圈过大虚化效果明显")],-1),d=[l,r,c];function _(i,h,p,m,f,u){return a(),o("div",null,d)}const $=t(n,[["render",_]]);export{k as __pageData,$ as default}; diff --git "a/assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\277\253\351\227\250\351\200\237\345\272\246.md.0fea1225.js" "b/assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\277\253\351\227\250\351\200\237\345\272\246.md.9e05d8bb.js" similarity index 93% rename from "assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\277\253\351\227\250\351\200\237\345\272\246.md.0fea1225.js" rename to "assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\277\253\351\227\250\351\200\237\345\272\246.md.9e05d8bb.js" index 5a686cf7..6d319979 100644 --- "a/assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\277\253\351\227\250\351\200\237\345\272\246.md.0fea1225.js" +++ "b/assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\277\253\351\227\250\351\200\237\345\272\246.md.9e05d8bb.js" @@ -1 +1 @@ -import{_ as a,o as s,c as o,k as e,a as t}from"./chunks/framework.b6910bb2.js";const l="/vitePress-blob/assets/1.2aa2aedd.png",k=JSON.parse('{"title":"快门速度","description":"","frontmatter":{},"headers":[],"relativePath":"shoot/基础概念/快门速度.md","filePath":"shoot/基础概念/快门速度.md","lastUpdated":1707358495000}'),n={name:"shoot/基础概念/快门速度.md"},r=e("h1",{id:"快门速度",tabindex:"-1"},[t("快门速度 "),e("a",{class:"header-anchor",href:"#快门速度","aria-label":'Permalink to "快门速度"'},"​")],-1),c=e("p",null,"控制开启传感器的时间",-1),i=e("ul",null,[e("li",null,"快门速度越短,越能凝固物体,常用在抓拍"),e("li",null,[t("快门速度越长,容易得到拖影的图 "),e("ul",null,[e("li",null,[e("img",{src:l,alt:"快门速度"})]),e("li",null,"拍静止的水面 (一般需要借助三脚架)")])])],-1),_=[r,c,i];function d(h,p,u,m,f,x){return s(),o("div",null,_)}const P=a(n,[["render",d]]);export{k as __pageData,P as default}; +import{_ as a,o as s,c as o,k as e,a as t}from"./chunks/framework.b6910bb2.js";const l="/vitePress-blob/assets/1.2aa2aedd.png",k=JSON.parse('{"title":"快门速度","description":"","frontmatter":{},"headers":[],"relativePath":"shoot/基础概念/快门速度.md","filePath":"shoot/基础概念/快门速度.md","lastUpdated":1707358769000}'),n={name:"shoot/基础概念/快门速度.md"},r=e("h1",{id:"快门速度",tabindex:"-1"},[t("快门速度 "),e("a",{class:"header-anchor",href:"#快门速度","aria-label":'Permalink to "快门速度"'},"​")],-1),c=e("p",null,"控制开启传感器的时间",-1),i=e("ul",null,[e("li",null,"快门速度越短,越能凝固物体,常用在抓拍"),e("li",null,[t("快门速度越长,容易得到拖影的图 "),e("ul",null,[e("li",null,[e("img",{src:l,alt:"快门速度"})]),e("li",null,"拍静止的水面 (一般需要借助三脚架)")])])],-1),_=[r,c,i];function d(h,p,u,m,f,x){return s(),o("div",null,_)}const P=a(n,[["render",d]]);export{k as __pageData,P as default}; diff --git "a/assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\277\253\351\227\250\351\200\237\345\272\246.md.0fea1225.lean.js" "b/assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\277\253\351\227\250\351\200\237\345\272\246.md.9e05d8bb.lean.js" similarity index 93% rename from "assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\277\253\351\227\250\351\200\237\345\272\246.md.0fea1225.lean.js" rename to "assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\277\253\351\227\250\351\200\237\345\272\246.md.9e05d8bb.lean.js" index 5a686cf7..6d319979 100644 --- "a/assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\277\253\351\227\250\351\200\237\345\272\246.md.0fea1225.lean.js" +++ "b/assets/shoot_\345\237\272\347\241\200\346\246\202\345\277\265_\345\277\253\351\227\250\351\200\237\345\272\246.md.9e05d8bb.lean.js" @@ -1 +1 @@ -import{_ as a,o as s,c as o,k as e,a as t}from"./chunks/framework.b6910bb2.js";const l="/vitePress-blob/assets/1.2aa2aedd.png",k=JSON.parse('{"title":"快门速度","description":"","frontmatter":{},"headers":[],"relativePath":"shoot/基础概念/快门速度.md","filePath":"shoot/基础概念/快门速度.md","lastUpdated":1707358495000}'),n={name:"shoot/基础概念/快门速度.md"},r=e("h1",{id:"快门速度",tabindex:"-1"},[t("快门速度 "),e("a",{class:"header-anchor",href:"#快门速度","aria-label":'Permalink to "快门速度"'},"​")],-1),c=e("p",null,"控制开启传感器的时间",-1),i=e("ul",null,[e("li",null,"快门速度越短,越能凝固物体,常用在抓拍"),e("li",null,[t("快门速度越长,容易得到拖影的图 "),e("ul",null,[e("li",null,[e("img",{src:l,alt:"快门速度"})]),e("li",null,"拍静止的水面 (一般需要借助三脚架)")])])],-1),_=[r,c,i];function d(h,p,u,m,f,x){return s(),o("div",null,_)}const P=a(n,[["render",d]]);export{k as __pageData,P as default}; +import{_ as a,o as s,c as o,k as e,a as t}from"./chunks/framework.b6910bb2.js";const l="/vitePress-blob/assets/1.2aa2aedd.png",k=JSON.parse('{"title":"快门速度","description":"","frontmatter":{},"headers":[],"relativePath":"shoot/基础概念/快门速度.md","filePath":"shoot/基础概念/快门速度.md","lastUpdated":1707358769000}'),n={name:"shoot/基础概念/快门速度.md"},r=e("h1",{id:"快门速度",tabindex:"-1"},[t("快门速度 "),e("a",{class:"header-anchor",href:"#快门速度","aria-label":'Permalink to "快门速度"'},"​")],-1),c=e("p",null,"控制开启传感器的时间",-1),i=e("ul",null,[e("li",null,"快门速度越短,越能凝固物体,常用在抓拍"),e("li",null,[t("快门速度越长,容易得到拖影的图 "),e("ul",null,[e("li",null,[e("img",{src:l,alt:"快门速度"})]),e("li",null,"拍静止的水面 (一般需要借助三脚架)")])])],-1),_=[r,c,i];function d(h,p,u,m,f,x){return s(),o("div",null,_)}const P=a(n,[["render",d]]);export{k as __pageData,P as default}; diff --git "a/assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\350\212\261\347\232\204\351\273\221\350\203\214\346\231\257.md.647a17e0.js" "b/assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\350\212\261\347\232\204\351\273\221\350\203\214\346\231\257.md.013683af.js" similarity index 92% rename from "assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\350\212\261\347\232\204\351\273\221\350\203\214\346\231\257.md.647a17e0.js" rename to "assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\350\212\261\347\232\204\351\273\221\350\203\214\346\231\257.md.013683af.js" index a37c493b..0733a005 100644 --- "a/assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\350\212\261\347\232\204\351\273\221\350\203\214\346\231\257.md.647a17e0.js" +++ "b/assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\350\212\261\347\232\204\351\273\221\350\203\214\346\231\257.md.013683af.js" @@ -1 +1 @@ -import{_ as a,o,c as s,k as e,a as t}from"./chunks/framework.b6910bb2.js";const x=JSON.parse('{"title":"如何拍花","description":"","frontmatter":{},"headers":[],"relativePath":"shoot/实战技巧/如何拍花的黑背景.md","filePath":"shoot/实战技巧/如何拍花的黑背景.md","lastUpdated":1707358495000}'),l={name:"shoot/实战技巧/如何拍花的黑背景.md"},n=e("h1",{id:"如何拍花",tabindex:"-1"},[t("如何拍花 "),e("a",{class:"header-anchor",href:"#如何拍花","aria-label":'Permalink to "如何拍花"'},"​")],-1),r=e("ol",null,[e("li",null,[t("采用 "),e("code",null,"点测光"),t(" 突出花的亮度")]),e("li",null,[t("背景采用 "),e("code",null,"深色系"),t(" 突出主体")])],-1),_=[n,r];function c(d,i,h,p,m,u){return o(),s("div",null,_)}const k=a(l,[["render",c]]);export{x as __pageData,k as default}; +import{_ as a,o,c as s,k as e,a as t}from"./chunks/framework.b6910bb2.js";const x=JSON.parse('{"title":"如何拍花","description":"","frontmatter":{},"headers":[],"relativePath":"shoot/实战技巧/如何拍花的黑背景.md","filePath":"shoot/实战技巧/如何拍花的黑背景.md","lastUpdated":1707358769000}'),l={name:"shoot/实战技巧/如何拍花的黑背景.md"},n=e("h1",{id:"如何拍花",tabindex:"-1"},[t("如何拍花 "),e("a",{class:"header-anchor",href:"#如何拍花","aria-label":'Permalink to "如何拍花"'},"​")],-1),r=e("ol",null,[e("li",null,[t("采用 "),e("code",null,"点测光"),t(" 突出花的亮度")]),e("li",null,[t("背景采用 "),e("code",null,"深色系"),t(" 突出主体")])],-1),_=[n,r];function c(d,i,h,p,m,u){return o(),s("div",null,_)}const k=a(l,[["render",c]]);export{x as __pageData,k as default}; diff --git "a/assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\350\212\261\347\232\204\351\273\221\350\203\214\346\231\257.md.647a17e0.lean.js" "b/assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\350\212\261\347\232\204\351\273\221\350\203\214\346\231\257.md.013683af.lean.js" similarity index 92% rename from "assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\350\212\261\347\232\204\351\273\221\350\203\214\346\231\257.md.647a17e0.lean.js" rename to "assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\350\212\261\347\232\204\351\273\221\350\203\214\346\231\257.md.013683af.lean.js" index a37c493b..0733a005 100644 --- "a/assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\350\212\261\347\232\204\351\273\221\350\203\214\346\231\257.md.647a17e0.lean.js" +++ "b/assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\350\212\261\347\232\204\351\273\221\350\203\214\346\231\257.md.013683af.lean.js" @@ -1 +1 @@ -import{_ as a,o,c as s,k as e,a as t}from"./chunks/framework.b6910bb2.js";const x=JSON.parse('{"title":"如何拍花","description":"","frontmatter":{},"headers":[],"relativePath":"shoot/实战技巧/如何拍花的黑背景.md","filePath":"shoot/实战技巧/如何拍花的黑背景.md","lastUpdated":1707358495000}'),l={name:"shoot/实战技巧/如何拍花的黑背景.md"},n=e("h1",{id:"如何拍花",tabindex:"-1"},[t("如何拍花 "),e("a",{class:"header-anchor",href:"#如何拍花","aria-label":'Permalink to "如何拍花"'},"​")],-1),r=e("ol",null,[e("li",null,[t("采用 "),e("code",null,"点测光"),t(" 突出花的亮度")]),e("li",null,[t("背景采用 "),e("code",null,"深色系"),t(" 突出主体")])],-1),_=[n,r];function c(d,i,h,p,m,u){return o(),s("div",null,_)}const k=a(l,[["render",c]]);export{x as __pageData,k as default}; +import{_ as a,o,c as s,k as e,a as t}from"./chunks/framework.b6910bb2.js";const x=JSON.parse('{"title":"如何拍花","description":"","frontmatter":{},"headers":[],"relativePath":"shoot/实战技巧/如何拍花的黑背景.md","filePath":"shoot/实战技巧/如何拍花的黑背景.md","lastUpdated":1707358769000}'),l={name:"shoot/实战技巧/如何拍花的黑背景.md"},n=e("h1",{id:"如何拍花",tabindex:"-1"},[t("如何拍花 "),e("a",{class:"header-anchor",href:"#如何拍花","aria-label":'Permalink to "如何拍花"'},"​")],-1),r=e("ol",null,[e("li",null,[t("采用 "),e("code",null,"点测光"),t(" 突出花的亮度")]),e("li",null,[t("背景采用 "),e("code",null,"深色系"),t(" 突出主体")])],-1),_=[n,r];function c(d,i,h,p,m,u){return o(),s("div",null,_)}const k=a(l,[["render",c]]);export{x as __pageData,k as default}; diff --git "a/assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\351\233\250\344\270\235.md.5a2c1fb7.js" "b/assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\351\233\250\344\270\235.md.5a2c1fb7.js" new file mode 100644 index 00000000..d0522180 --- /dev/null +++ "b/assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\351\233\250\344\270\235.md.5a2c1fb7.js" @@ -0,0 +1 @@ +import{_ as a,o as e,c as t,Q as o}from"./chunks/framework.b6910bb2.js";const r="/vitePress-blob/assets/1.b55cef29.png",f=JSON.parse('{"title":"如何拍雨丝","description":"","frontmatter":{},"headers":[],"relativePath":"shoot/实战技巧/如何拍雨丝.md","filePath":"shoot/实战技巧/如何拍雨丝.md","lastUpdated":1707358769000}'),s={name:"shoot/实战技巧/如何拍雨丝.md"},i=o('

如何拍雨丝

灯位要求

需要俩盏灯

  • 逆光灯: 在拍摄物体后方 (容易拍摄到雨丝,而且物体会有光边效果)
  • 正光灯:在拍摄物体前方(避免物体逆光,变黑)

逆光灯亮度 > 主光灯

灯位要求

白平衡

如果拍摄物体偏黄,可以调低白平衡,使物体变白

快门速度

  • 快门速度越慢,雨水成丝
  • 快门速度越快,雨水成点
',10),l=[i];function _(n,c,h,d,p,u){return e(),t("div",null,l)}const b=a(s,[["render",_]]);export{f as __pageData,b as default}; diff --git "a/assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\351\233\250\344\270\235.md.c8378969.lean.js" "b/assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\351\233\250\344\270\235.md.5a2c1fb7.lean.js" similarity index 51% rename from "assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\351\233\250\344\270\235.md.c8378969.lean.js" rename to "assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\351\233\250\344\270\235.md.5a2c1fb7.lean.js" index e9982796..75f50d61 100644 --- "a/assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\351\233\250\344\270\235.md.c8378969.lean.js" +++ "b/assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\351\233\250\344\270\235.md.5a2c1fb7.lean.js" @@ -1 +1 @@ -import{_ as a,o as e,c as t,Q as o}from"./chunks/framework.b6910bb2.js";const l="/vitePress-blob/assets/1.b55cef29.png",f=JSON.parse('{"title":"如何拍雨丝","description":"","frontmatter":{},"headers":[],"relativePath":"shoot/实战技巧/如何拍雨丝.md","filePath":"shoot/实战技巧/如何拍雨丝.md","lastUpdated":1707358495000}'),i={name:"shoot/实战技巧/如何拍雨丝.md"},r=o("",10),s=[r];function _(n,c,h,d,p,u){return e(),t("div",null,s)}const b=a(i,[["render",_]]);export{f as __pageData,b as default}; +import{_ as a,o as e,c as t,Q as o}from"./chunks/framework.b6910bb2.js";const r="/vitePress-blob/assets/1.b55cef29.png",f=JSON.parse('{"title":"如何拍雨丝","description":"","frontmatter":{},"headers":[],"relativePath":"shoot/实战技巧/如何拍雨丝.md","filePath":"shoot/实战技巧/如何拍雨丝.md","lastUpdated":1707358769000}'),s={name:"shoot/实战技巧/如何拍雨丝.md"},i=o("",10),l=[i];function _(n,c,h,d,p,u){return e(),t("div",null,l)}const b=a(s,[["render",_]]);export{f as __pageData,b as default}; diff --git "a/assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\351\233\250\344\270\235.md.c8378969.js" "b/assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\351\233\250\344\270\235.md.c8378969.js" deleted file mode 100644 index a87d5503..00000000 --- "a/assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\345\246\202\344\275\225\346\213\215\351\233\250\344\270\235.md.c8378969.js" +++ /dev/null @@ -1 +0,0 @@ -import{_ as a,o as e,c as t,Q as o}from"./chunks/framework.b6910bb2.js";const l="/vitePress-blob/assets/1.b55cef29.png",f=JSON.parse('{"title":"如何拍雨丝","description":"","frontmatter":{},"headers":[],"relativePath":"shoot/实战技巧/如何拍雨丝.md","filePath":"shoot/实战技巧/如何拍雨丝.md","lastUpdated":1707358495000}'),i={name:"shoot/实战技巧/如何拍雨丝.md"},r=o('

如何拍雨丝

灯位要求

需要俩盏灯

  • 逆光灯: 在拍摄物体后方 (容易拍摄到雨丝,而且物体会有光边效果)
  • 正光灯:在拍摄物体前方(避免物体逆光,变黑)

逆光灯亮度 > 主光灯

  • 灯位要求

白平衡

如果拍摄物体偏黄,可以调低白平衡,使物体变白

快门速度

  • 快门速度越慢,雨水成丝
  • 快门速度越快,雨水成点
',10),s=[r];function _(n,c,h,d,p,u){return e(),t("div",null,s)}const b=a(i,[["render",_]]);export{f as __pageData,b as default}; diff --git "a/assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\346\213\215\346\221\204\346\242\246\345\271\273\345\205\211\346\226\221.md.ab138890.js" "b/assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\346\213\215\346\221\204\346\242\246\345\271\273\345\205\211\346\226\221.md.345608b9.js" similarity index 93% rename from "assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\346\213\215\346\221\204\346\242\246\345\271\273\345\205\211\346\226\221.md.ab138890.js" rename to "assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\346\213\215\346\221\204\346\242\246\345\271\273\345\205\211\346\226\221.md.345608b9.js" index d287e049..fc863db3 100644 --- "a/assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\346\213\215\346\221\204\346\242\246\345\271\273\345\205\211\346\226\221.md.ab138890.js" +++ "b/assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\346\213\215\346\221\204\346\242\246\345\271\273\345\205\211\346\226\221.md.345608b9.js" @@ -1 +1 @@ -import{_ as t,o as a,c as o,k as e,a as s}from"./chunks/framework.b6910bb2.js";const $=JSON.parse('{"title":"拍摄梦幻光斑","description":"","frontmatter":{},"headers":[],"relativePath":"shoot/实战技巧/拍摄梦幻光斑.md","filePath":"shoot/实战技巧/拍摄梦幻光斑.md","lastUpdated":1707358495000}'),n={name:"shoot/实战技巧/拍摄梦幻光斑.md"},l=e("h1",{id:"拍摄梦幻光斑",tabindex:"-1"},[s("拍摄梦幻光斑 "),e("a",{class:"header-anchor",href:"#拍摄梦幻光斑","aria-label":'Permalink to "拍摄梦幻光斑"'},"​")],-1),_=e("p",null,"采用大光圈镜头,有很好的背景虚化效果",-1),r=e("p",null,"需要一个补光灯,减少避免物体逆光导致过黑",-1),c=e("ul",null,[e("li",null,"拍摄物体在光斑前面"),e("li",null,"对焦到物体上(也可以通过精细对焦,即放大后手动对焦)")],-1),d=[l,_,r,c];function i(h,p,u,m,f,x){return a(),o("div",null,d)}const B=t(n,[["render",i]]);export{$ as __pageData,B as default}; +import{_ as t,o as a,c as o,k as e,a as s}from"./chunks/framework.b6910bb2.js";const $=JSON.parse('{"title":"拍摄梦幻光斑","description":"","frontmatter":{},"headers":[],"relativePath":"shoot/实战技巧/拍摄梦幻光斑.md","filePath":"shoot/实战技巧/拍摄梦幻光斑.md","lastUpdated":1707358769000}'),n={name:"shoot/实战技巧/拍摄梦幻光斑.md"},l=e("h1",{id:"拍摄梦幻光斑",tabindex:"-1"},[s("拍摄梦幻光斑 "),e("a",{class:"header-anchor",href:"#拍摄梦幻光斑","aria-label":'Permalink to "拍摄梦幻光斑"'},"​")],-1),_=e("p",null,"采用大光圈镜头,有很好的背景虚化效果",-1),r=e("p",null,"需要一个补光灯,减少避免物体逆光导致过黑",-1),c=e("ul",null,[e("li",null,"拍摄物体在光斑前面"),e("li",null,"对焦到物体上(也可以通过精细对焦,即放大后手动对焦)")],-1),d=[l,_,r,c];function i(h,p,u,m,f,x){return a(),o("div",null,d)}const B=t(n,[["render",i]]);export{$ as __pageData,B as default}; diff --git "a/assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\346\213\215\346\221\204\346\242\246\345\271\273\345\205\211\346\226\221.md.ab138890.lean.js" "b/assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\346\213\215\346\221\204\346\242\246\345\271\273\345\205\211\346\226\221.md.345608b9.lean.js" similarity index 93% rename from "assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\346\213\215\346\221\204\346\242\246\345\271\273\345\205\211\346\226\221.md.ab138890.lean.js" rename to "assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\346\213\215\346\221\204\346\242\246\345\271\273\345\205\211\346\226\221.md.345608b9.lean.js" index d287e049..fc863db3 100644 --- "a/assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\346\213\215\346\221\204\346\242\246\345\271\273\345\205\211\346\226\221.md.ab138890.lean.js" +++ "b/assets/shoot_\345\256\236\346\210\230\346\212\200\345\267\247_\346\213\215\346\221\204\346\242\246\345\271\273\345\205\211\346\226\221.md.345608b9.lean.js" @@ -1 +1 @@ -import{_ as t,o as a,c as o,k as e,a as s}from"./chunks/framework.b6910bb2.js";const $=JSON.parse('{"title":"拍摄梦幻光斑","description":"","frontmatter":{},"headers":[],"relativePath":"shoot/实战技巧/拍摄梦幻光斑.md","filePath":"shoot/实战技巧/拍摄梦幻光斑.md","lastUpdated":1707358495000}'),n={name:"shoot/实战技巧/拍摄梦幻光斑.md"},l=e("h1",{id:"拍摄梦幻光斑",tabindex:"-1"},[s("拍摄梦幻光斑 "),e("a",{class:"header-anchor",href:"#拍摄梦幻光斑","aria-label":'Permalink to "拍摄梦幻光斑"'},"​")],-1),_=e("p",null,"采用大光圈镜头,有很好的背景虚化效果",-1),r=e("p",null,"需要一个补光灯,减少避免物体逆光导致过黑",-1),c=e("ul",null,[e("li",null,"拍摄物体在光斑前面"),e("li",null,"对焦到物体上(也可以通过精细对焦,即放大后手动对焦)")],-1),d=[l,_,r,c];function i(h,p,u,m,f,x){return a(),o("div",null,d)}const B=t(n,[["render",i]]);export{$ as __pageData,B as default}; +import{_ as t,o as a,c as o,k as e,a as s}from"./chunks/framework.b6910bb2.js";const $=JSON.parse('{"title":"拍摄梦幻光斑","description":"","frontmatter":{},"headers":[],"relativePath":"shoot/实战技巧/拍摄梦幻光斑.md","filePath":"shoot/实战技巧/拍摄梦幻光斑.md","lastUpdated":1707358769000}'),n={name:"shoot/实战技巧/拍摄梦幻光斑.md"},l=e("h1",{id:"拍摄梦幻光斑",tabindex:"-1"},[s("拍摄梦幻光斑 "),e("a",{class:"header-anchor",href:"#拍摄梦幻光斑","aria-label":'Permalink to "拍摄梦幻光斑"'},"​")],-1),_=e("p",null,"采用大光圈镜头,有很好的背景虚化效果",-1),r=e("p",null,"需要一个补光灯,减少避免物体逆光导致过黑",-1),c=e("ul",null,[e("li",null,"拍摄物体在光斑前面"),e("li",null,"对焦到物体上(也可以通过精细对焦,即放大后手动对焦)")],-1),d=[l,_,r,c];function i(h,p,u,m,f,x){return a(),o("div",null,d)}const B=t(n,[["render",i]]);export{$ as __pageData,B as default}; diff --git "a/guide/Node\347\233\270\345\205\263/\346\246\202\350\246\201.html" "b/guide/Node\347\233\270\345\205\263/\346\246\202\350\246\201.html" index abe01a73..5c231752 100644 --- "a/guide/Node\347\233\270\345\205\263/\346\246\202\350\246\201.html" +++ "b/guide/Node\347\233\270\345\205\263/\346\246\202\350\246\201.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content
- +
Skip to content
+ \ No newline at end of file diff --git "a/guide/React/React\344\270\216Vue\347\232\204\345\214\272\345\210\253.html" "b/guide/React/React\344\270\216Vue\347\232\204\345\214\272\345\210\253.html" index 721cc3f5..acce9129 100644 --- "a/guide/React/React\344\270\216Vue\347\232\204\345\214\272\345\210\253.html" +++ "b/guide/React/React\344\270\216Vue\347\232\204\345\214\272\345\210\253.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content
- +
Skip to content
+ \ No newline at end of file diff --git "a/guide/React/React\344\270\255\347\232\204\344\272\213\344\273\266\346\234\272\345\210\266.html" "b/guide/React/React\344\270\255\347\232\204\344\272\213\344\273\266\346\234\272\345\210\266.html" index 23b62bc9..c1a92450 100644 --- "a/guide/React/React\344\270\255\347\232\204\344\272\213\344\273\266\346\234\272\345\210\266.html" +++ "b/guide/React/React\344\270\255\347\232\204\344\272\213\344\273\266\346\234\272\345\210\266.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

React 事件机制

概要

为了抹平各个浏览器之间的差异以及统一维护和管理事件,React 自行实现了合成事件,用来模拟原生事件的行为 在 React 16 之前,React 的合成事件放在了 document 的冒泡阶段 在 React 16 之后,为了兼容各个版本,React 的合成事件放在了 根节点 的捕获和冒泡阶段

具体实现

- +
Skip to content

React 事件机制

概要

为了抹平各个浏览器之间的差异以及统一维护和管理事件,React 自行实现了合成事件,用来模拟原生事件的行为 在 React 16 之前,React 的合成事件放在了 document 的冒泡阶段 在 React 16 之后,为了兼容各个版本,React 的合成事件放在了 根节点 的捕获和冒泡阶段

具体实现

+ \ No newline at end of file diff --git "a/guide/React/React\344\270\255\347\232\204\345\274\202\345\270\270\346\234\272\345\210\266.html" "b/guide/React/React\344\270\255\347\232\204\345\274\202\345\270\270\346\234\272\345\210\266.html" index 5d45db6d..9d95ad3c 100644 --- "a/guide/React/React\344\270\255\347\232\204\345\274\202\345\270\270\346\234\272\345\210\266.html" +++ "b/guide/React/React\344\270\255\347\232\204\345\274\202\345\270\270\346\234\272\345\210\266.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content
- +
Skip to content
+ \ No newline at end of file diff --git "a/guide/React/React\344\270\255\347\232\204\346\200\247\350\203\275\344\274\230\345\214\226.html" "b/guide/React/React\344\270\255\347\232\204\346\200\247\350\203\275\344\274\230\345\214\226.html" index 6d9ae945..f875556e 100644 --- "a/guide/React/React\344\270\255\347\232\204\346\200\247\350\203\275\344\274\230\345\214\226.html" +++ "b/guide/React/React\344\270\255\347\232\204\346\200\247\350\203\275\344\274\230\345\214\226.html" @@ -11,7 +11,7 @@ - + @@ -459,8 +459,8 @@ return this.props.children; } -}

参考文章

  1. https://juejin.cn/post/6965747225154732069#heading-15
  2. https://cloud.tencent.com/developer/article/1810002
- +}

参考文章

  1. https://juejin.cn/post/6965747225154732069#heading-15
  2. https://cloud.tencent.com/developer/article/1810002
+ \ No newline at end of file diff --git "a/guide/React/React\344\270\272\344\273\200\344\271\210\350\246\201\344\275\277\347\224\250JSX.html" "b/guide/React/React\344\270\272\344\273\200\344\271\210\350\246\201\344\275\277\347\224\250JSX.html" index 8ef83efc..2e4fea9f 100644 --- "a/guide/React/React\344\270\272\344\273\200\344\271\210\350\246\201\344\275\277\347\224\250JSX.html" +++ "b/guide/React/React\344\270\272\344\273\200\344\271\210\350\246\201\344\275\277\347\224\250JSX.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

React 为什么要使用 JSX ?

JSX 是 JavaScript 语法拓展,结构类似于 XML,它可以在 JavaScript 中直接使用 HTML 标签,这样可以方便开发者编写组件,提高开发效率。

没有JSX时,也可以使用 React.createElement 实现一个组件,但是这样的代码可读性很差,而且不方便复用,所以 React 推荐使用 JSX。

- +
Skip to content

React 为什么要使用 JSX ?

JSX 是 JavaScript 语法拓展,结构类似于 XML,它可以在 JavaScript 中直接使用 HTML 标签,这样可以方便开发者编写组件,提高开发效率。

没有JSX时,也可以使用 React.createElement 实现一个组件,但是这样的代码可读性很差,而且不方便复用,所以 React 推荐使用 JSX。

+ \ No newline at end of file diff --git "a/guide/React/React\346\230\257\344\273\200\344\271\210.html" "b/guide/React/React\346\230\257\344\273\200\344\271\210.html" index b1e63377..105e01fe 100644 --- "a/guide/React/React\346\230\257\344\273\200\344\271\210.html" +++ "b/guide/React/React\346\230\257\344\273\200\344\271\210.html" @@ -11,7 +11,7 @@ - + @@ -27,8 +27,8 @@ return <div style={{color: 'red'}}>{props.children}</div> }
const Body = (props) => {
    return <div style={{color: 'red'}}>{props.children}</div>
-}

组件化

可以降低功能之间的耦合、提高功能的内聚性,便于复用

通用性

虚拟DOM的实现,保证了跨平台和可移植性

缺点

没有提供全链路的解决方法,比如 router、数据仓库,需要借助第三方库

- +}

组件化

可以降低功能之间的耦合、提高功能的内聚性,便于复用

通用性

虚拟DOM的实现,保证了跨平台和可移植性

缺点

没有提供全链路的解决方法,比如 router、数据仓库,需要借助第三方库

+ \ No newline at end of file diff --git "a/guide/React/React\346\230\257\345\246\202\344\275\225\346\270\262\346\237\223\347\232\204.html" "b/guide/React/React\346\230\257\345\246\202\344\275\225\346\270\262\346\237\223\347\232\204.html" index db3ac6a7..1593356b 100644 --- "a/guide/React/React\346\230\257\345\246\202\344\275\225\346\270\262\346\237\223\347\232\204.html" +++ "b/guide/React/React\346\230\257\345\246\202\344\275\225\346\270\262\346\237\223\347\232\204.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

React 是如何渲染的

概要

React 的渲染过程可以分成 2 大阶段, 分别是调和阶段和提交阶段。 调和阶段可以分成 beginWork 阶段、 completeWork 阶段。 在 beginWork 阶段中,React 会根据新生成的 ReactElement 对象和旧的 Fiber 节点进行对比,判断是否可以复用旧的 Fiber 节点并对 Fiber 进行标记。 在 completeWork 节点中,会自底向上构建副作用链表,用来记录需要更新的节点,生成的 DOM 节点会挂载在 Fiber 的 stateNode 属性上。

提交阶段主要分成:操作 DOM 前阶段、操作 DOM 阶段、操作 DOM 后阶段。

React 16 以前

在浏览器中 js 线程与渲染线程是互斥的,如果 js 线程长期占用着浏览器的主线程,那么界面将长时间不更新,在动画等一些场景下会造成卡顿效果。

因为 Stack Reconciler 是一个同步的递归过程,随着业务复杂度增加,Stack Reconciler 需要的调和时间会变长,

这意味着 js 将长时间占用浏览器,进而导致页面卡顿

Stack Reconciler

React 16 以后

将同步执行的 Stack Reconciler 替换成了异步可中断的 Fiber Reconciler

Fiber Reconciler

在更新时,每个任务会被赋予一个优先级,当任务抵达调度器时,高优先级的任务会更快抵达协调器,如有新的更高优先级的任务进入调度器时,当前协调器的任务就会被中断,更高优先级的任务将进入 reconciler

Fiber Reconciler

新的架构会导致部分生命周期重复执行:

  • componentWillMount
  • componentWillUpdate
  • showComponentUpdate
  • componentWillReceiveProps

Render Performance

从首次渲染的调用栈来看,React 的渲染过程主要分为以下几个步骤:

    1. Mount 阶段
    1. Render 阶段
    1. Commit 阶段

Mount 阶段

当执行 ReactDOM.render 时会直接调用 legacyRenderSubtreeIntoContainer 方法

legacyRenderSubtreeIntoContainer 方法

会创建 reactRootContainer 对象(也就是挂载的容器对象), reactRootContainer 对象的 _internalRoot 会指向 fiberRoot (FiberRootNode 类),也就是根节点对象。

legacyRenderSubtreeIntoContainer 最终返回挂载组件( App组件 )的实例对象。

Mount 渲染过程

FiberRootNode对象的描述

在 fiberRoot 对象( FiberRootNode类 )中的 current 属性将指向 rootFiber 对象 (根节点Fiber,即 FiberNode 实例)

fiberRoot对象指向 rootFiber 根节点Fiber

挂载创建关系图

updateContainer 函数

updateContainer 函数主要有以下 3 件事:

    1. 获取当前节点的优先级 lane
    1. 结合 lane 创建当前 Fiber 节点 update 对象,并将其入队
    1. 调度当前节点 (rootFiber 节点)

updateContainer

scheduleUpdateOnFiber 函数

scheduleUpdateOnFiber 函数中会获取 Fiber 节点的mode属性判断是否走同步渲染还是异步渲染的逻辑,在 React17 中首次渲染走的是同步渲染的逻辑

scheduleUpdateOnFiber

这里可能有小伙伴会问,Fiber架构不就是异步渲染的么? 我想说的是,Fiber架构的设计初衷确实是为了异步渲染而设计的,但是 Fiber 架构并不能和异步渲染画上等号,我们不难发现,Fiber 架构同时兼容了同步渲染和异步渲染,如下图,决定同步还是异步取决于 mode

mode 决定同步异步

Render 阶段

performSyncWorkOnRoot 函数

核心逻辑在 renderRootSync 函数中

renderRootSync 函数

核心方法有俩个 prepareFreshStackworkLoopSync 函数

renderRootSync 逻辑

prepareFreshStack 函数

主要是有个方法 createWorkInProgress , 用来构建 workInProgress 双缓冲树,通过 alternate 相互指向

createWorkInProgress 构建 work-in-progress 树

当建立好双缓冲树的关系后,我们不难得到以下的关系图

双缓冲树关系图

workLoopSync 函数

当我们构建完 workInProgress Tree 的根节点时,建立 current tree 和 workInProgess Tree 的关联关系后,将进入 workLoopSync 调和阶段。

反复判断 workInProgress 是否为空,如果不为空,就执行 performUnitOfWork 方法 workLoopSync 逻辑

performUnitOfWork 函数

performUnitOfWork 函数的作用是 beginWork 优先创建子节点。 completeUnitOfWork 创建完子节点后判断是否有兄弟节点,有则创建兄弟节点,无则继续向上遍历父节点,直到遍历到根节点为止

performUnitOfWork 逻辑

beginWork 函数

参考文档

1 https://zhuanlan.zhihu.com/p/385319664 2

- +
Skip to content

React 是如何渲染的

概要

React 的渲染过程可以分成 2 大阶段, 分别是调和阶段和提交阶段。 调和阶段可以分成 beginWork 阶段、 completeWork 阶段。 在 beginWork 阶段中,React 会根据新生成的 ReactElement 对象和旧的 Fiber 节点进行对比,判断是否可以复用旧的 Fiber 节点并对 Fiber 进行标记。 在 completeWork 节点中,会自底向上构建副作用链表,用来记录需要更新的节点,生成的 DOM 节点会挂载在 Fiber 的 stateNode 属性上。

提交阶段主要分成:操作 DOM 前阶段、操作 DOM 阶段、操作 DOM 后阶段。

React 16 以前

在浏览器中 js 线程与渲染线程是互斥的,如果 js 线程长期占用着浏览器的主线程,那么界面将长时间不更新,在动画等一些场景下会造成卡顿效果。

因为 Stack Reconciler 是一个同步的递归过程,随着业务复杂度增加,Stack Reconciler 需要的调和时间会变长,

这意味着 js 将长时间占用浏览器,进而导致页面卡顿

Stack Reconciler

React 16 以后

将同步执行的 Stack Reconciler 替换成了异步可中断的 Fiber Reconciler

Fiber Reconciler

在更新时,每个任务会被赋予一个优先级,当任务抵达调度器时,高优先级的任务会更快抵达协调器,如有新的更高优先级的任务进入调度器时,当前协调器的任务就会被中断,更高优先级的任务将进入 reconciler

Fiber Reconciler

新的架构会导致部分生命周期重复执行:

  • componentWillMount
  • componentWillUpdate
  • showComponentUpdate
  • componentWillReceiveProps

Render Performance

从首次渲染的调用栈来看,React 的渲染过程主要分为以下几个步骤:

    1. Mount 阶段
    1. Render 阶段
    1. Commit 阶段

Mount 阶段

当执行 ReactDOM.render 时会直接调用 legacyRenderSubtreeIntoContainer 方法

legacyRenderSubtreeIntoContainer 方法

会创建 reactRootContainer 对象(也就是挂载的容器对象), reactRootContainer 对象的 _internalRoot 会指向 fiberRoot (FiberRootNode 类),也就是根节点对象。

legacyRenderSubtreeIntoContainer 最终返回挂载组件( App组件 )的实例对象。

Mount 渲染过程

FiberRootNode对象的描述

在 fiberRoot 对象( FiberRootNode类 )中的 current 属性将指向 rootFiber 对象 (根节点Fiber,即 FiberNode 实例)

fiberRoot对象指向 rootFiber 根节点Fiber

挂载创建关系图

updateContainer 函数

updateContainer 函数主要有以下 3 件事:

    1. 获取当前节点的优先级 lane
    1. 结合 lane 创建当前 Fiber 节点 update 对象,并将其入队
    1. 调度当前节点 (rootFiber 节点)

updateContainer

scheduleUpdateOnFiber 函数

scheduleUpdateOnFiber 函数中会获取 Fiber 节点的mode属性判断是否走同步渲染还是异步渲染的逻辑,在 React17 中首次渲染走的是同步渲染的逻辑

scheduleUpdateOnFiber

这里可能有小伙伴会问,Fiber架构不就是异步渲染的么? 我想说的是,Fiber架构的设计初衷确实是为了异步渲染而设计的,但是 Fiber 架构并不能和异步渲染画上等号,我们不难发现,Fiber 架构同时兼容了同步渲染和异步渲染,如下图,决定同步还是异步取决于 mode

mode 决定同步异步

Render 阶段

performSyncWorkOnRoot 函数

核心逻辑在 renderRootSync 函数中

renderRootSync 函数

核心方法有俩个 prepareFreshStackworkLoopSync 函数

renderRootSync 逻辑

prepareFreshStack 函数

主要是有个方法 createWorkInProgress , 用来构建 workInProgress 双缓冲树,通过 alternate 相互指向

createWorkInProgress 构建 work-in-progress 树

当建立好双缓冲树的关系后,我们不难得到以下的关系图

双缓冲树关系图

workLoopSync 函数

当我们构建完 workInProgress Tree 的根节点时,建立 current tree 和 workInProgess Tree 的关联关系后,将进入 workLoopSync 调和阶段。

反复判断 workInProgress 是否为空,如果不为空,就执行 performUnitOfWork 方法 workLoopSync 逻辑

performUnitOfWork 函数

performUnitOfWork 函数的作用是 beginWork 优先创建子节点。 completeUnitOfWork 创建完子节点后判断是否有兄弟节点,有则创建兄弟节点,无则继续向上遍历父节点,直到遍历到根节点为止

performUnitOfWork 逻辑

beginWork 函数

参考文档

1 https://zhuanlan.zhihu.com/p/385319664 2

+ \ No newline at end of file diff --git "a/guide/React/React\347\273\204\344\273\266\346\230\257\345\246\202\344\275\225\351\200\232\344\277\241\347\232\204.html" "b/guide/React/React\347\273\204\344\273\266\346\230\257\345\246\202\344\275\225\351\200\232\344\277\241\347\232\204.html" index 46110352..72d20ee5 100644 --- "a/guide/React/React\347\273\204\344\273\266\346\230\257\345\246\202\344\275\225\351\200\232\344\277\241\347\232\204.html" +++ "b/guide/React/React\347\273\204\344\273\266\346\230\257\345\246\202\344\275\225\351\200\232\344\277\241\347\232\204.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

React 组件是如何通信的

- +
Skip to content

React 组件是如何通信的

+ \ No newline at end of file diff --git "a/guide/React/diff\347\256\227\346\263\225.html" "b/guide/React/diff\347\256\227\346\263\225.html" index 9f8be2b9..64bd3f95 100644 --- "a/guide/React/diff\347\256\227\346\263\225.html" +++ "b/guide/React/diff\347\256\227\346\263\225.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

React 中的 Diff 算法

概要

React Diff 算法主要分单节点和多节点 Diff 算法 在单节点 Diff 算法中,会对比 key 和 tag 是否可以复用 如果 key 和 tag 都相同时,复用当前的 Fiber 节点,标记其他 Fiber 节点为删除 如果 key 不相同,标记删除当前的 Fiber 节点,对比下一个节点 如果 key 相同、tag 不同,则标记删除所有 Fiber 节点,生成新的 Fiber 节点

在多节点 Diff 中,有俩个 for 循环,第一个 for 循环判断可以复用的节点,记录最后可复用节点的 lastIndex 位置

通过 Map 建立节点和下标的对应关系,如果新节点的key可以在 Map 中找到,则复用旧节点,并判断新节点下标和 lastIndex 下标的关系, 如果新节点下标 > lastIndex 下标,说明只需要更新节点,不需要移动位置,更新 lastIndex。 如果新节点下标 < lastIndex,说明需要更新移动位置,不需要更新 lastIndex。

单节点diff算法 (render方法创建的element元素子节点只有一个)

1. 旧节点不存在

  1. 如果旧节点不存在,则直接新增节点

2. 旧节点存在

1 判断 key 和 tag 是否相同,相同则复用节点,更新属性 2 如果 key 相同但 tag 不相同,则删除所有节点 3 如果 key、tag 不同,则不需要复用,旧节点标记为删除

多节点diff算法 (render方法创建的element元素子节点有多个)

多节点diff有俩次 for 循环, 第一次 for 循环判断元素是否需要更新,第二次 for 循环判断元素是否需要移动位置

1 第一次 for 循环比较key和tag, 如果相同则复用, 并用 lastIndex 标记当前可以复用的节点位置

2 遇到不相同时, 跳出第一层 for 循环, 创建一个 Map 对象, 存储旧节点的 key 和 index

  • key不同导致不可复用,立即跳出整个遍历,第一轮遍历结束
  • key 相同 type 不同导致不可复用,会将 oldFiber 标记为 DELETION,并继续遍历

3 在 Map 对象中查找新节点的 key, 如果存在, 则说明新节点可以复用旧节点, 并且判断是否需要移动位置

4 如果 index > lastIndex, 则不需要移动位置, 更新 lastIndex

5 如果 index < lastIndex, 则需要移动位置, 不需要更新 lastIndex

- +
Skip to content

React 中的 Diff 算法

概要

React Diff 算法主要分单节点和多节点 Diff 算法 在单节点 Diff 算法中,会对比 key 和 tag 是否可以复用 如果 key 和 tag 都相同时,复用当前的 Fiber 节点,标记其他 Fiber 节点为删除 如果 key 不相同,标记删除当前的 Fiber 节点,对比下一个节点 如果 key 相同、tag 不同,则标记删除所有 Fiber 节点,生成新的 Fiber 节点

在多节点 Diff 中,有俩个 for 循环,第一个 for 循环判断可以复用的节点,记录最后可复用节点的 lastIndex 位置

通过 Map 建立节点和下标的对应关系,如果新节点的key可以在 Map 中找到,则复用旧节点,并判断新节点下标和 lastIndex 下标的关系, 如果新节点下标 > lastIndex 下标,说明只需要更新节点,不需要移动位置,更新 lastIndex。 如果新节点下标 < lastIndex,说明需要更新移动位置,不需要更新 lastIndex。

单节点diff算法 (render方法创建的element元素子节点只有一个)

1. 旧节点不存在

  1. 如果旧节点不存在,则直接新增节点

2. 旧节点存在

1 判断 key 和 tag 是否相同,相同则复用节点,更新属性 2 如果 key 相同但 tag 不相同,则删除所有节点 3 如果 key、tag 不同,则不需要复用,旧节点标记为删除

多节点diff算法 (render方法创建的element元素子节点有多个)

多节点diff有俩次 for 循环, 第一次 for 循环判断元素是否需要更新,第二次 for 循环判断元素是否需要移动位置

1 第一次 for 循环比较key和tag, 如果相同则复用, 并用 lastIndex 标记当前可以复用的节点位置

2 遇到不相同时, 跳出第一层 for 循环, 创建一个 Map 对象, 存储旧节点的 key 和 index

  • key不同导致不可复用,立即跳出整个遍历,第一轮遍历结束
  • key 相同 type 不同导致不可复用,会将 oldFiber 标记为 DELETION,并继续遍历

3 在 Map 对象中查找新节点的 key, 如果存在, 则说明新节点可以复用旧节点, 并且判断是否需要移动位置

4 如果 index > lastIndex, 则不需要移动位置, 更新 lastIndex

5 如果 index < lastIndex, 则需要移动位置, 不需要更新 lastIndex

+ \ No newline at end of file diff --git "a/guide/React/react\345\274\202\345\270\270\346\234\272\345\210\266.html" "b/guide/React/react\345\274\202\345\270\270\346\234\272\345\210\266.html" index 68ba8a49..2224fcf9 100644 --- "a/guide/React/react\345\274\202\345\270\270\346\234\272\345\210\266.html" +++ "b/guide/React/react\345\274\202\345\270\270\346\234\272\345\210\266.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content
- +
Skip to content
+ \ No newline at end of file diff --git "a/guide/React/setState\346\230\257\345\220\214\346\255\245\350\277\230\346\230\257\345\274\202\346\255\245\347\232\204.html" "b/guide/React/setState\346\230\257\345\220\214\346\255\245\350\277\230\346\230\257\345\274\202\346\255\245\347\232\204.html" index dac90f9a..633ec5fe 100644 --- "a/guide/React/setState\346\230\257\345\220\214\346\255\245\350\277\230\346\230\257\345\274\202\346\255\245\347\232\204.html" +++ "b/guide/React/setState\346\230\257\345\220\214\346\255\245\350\277\230\346\230\257\345\274\202\346\255\245\347\232\204.html" @@ -11,7 +11,7 @@ - + @@ -331,8 +331,8 @@ } }

最终将输出

this.state.count0 0
 this.state.count1 1
this.state.count0 0
-this.state.count1 1

参考资料

- +this.state.count1 1

参考资料

+ \ No newline at end of file diff --git "a/guide/React/\344\273\200\344\271\210\346\230\257Fiber.html" "b/guide/React/\344\273\200\344\271\210\346\230\257Fiber.html" index 17b13ee4..acf2b7f9 100644 --- "a/guide/React/\344\273\200\344\271\210\346\230\257Fiber.html" +++ "b/guide/React/\344\273\200\344\271\210\346\230\257Fiber.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

什么是 Fiber

Fiber 是什么

  • 从计算机领域来看: Fiber 是比线程还要纤细的一个过程, 也就是所谓的 “纤程”

  • 从架构角度上看: Fiber是对 React 核心算法的重写,将 React16以前的 Stack Reconciler 替换成了异步可中断的 Fiber Reconciler

  • 从编码的角度上看: Fiber 是 React 内部定义的数据结构,每一个节点都是一个 FiberNode 对象,用来存储组件的各种状态

  • 从工作流的角度上看: Fiber 节点保存了组件需要更新的状态和副作用, 便于更新与复用

Fiber 架构应用的目的是为了实现任务可中断、可恢复、并赋予任务优先级,从而实现时间切片,让出主线程,让主线程有时间去处理其他任务,从而提升用户体验。

Fiber 之间的关系图

  • 通过 child 可以获取子节点
  • 通过 sibling 可以获取兄弟节点
  • 通过 return 可以获取父节点

Fiber 之间的关系图

- +
Skip to content

什么是 Fiber

Fiber 是什么

  • 从计算机领域来看: Fiber 是比线程还要纤细的一个过程, 也就是所谓的 “纤程”

  • 从架构角度上看: Fiber是对 React 核心算法的重写,将 React16以前的 Stack Reconciler 替换成了异步可中断的 Fiber Reconciler

  • 从编码的角度上看: Fiber 是 React 内部定义的数据结构,每一个节点都是一个 FiberNode 对象,用来存储组件的各种状态

  • 从工作流的角度上看: Fiber 节点保存了组件需要更新的状态和副作用, 便于更新与复用

Fiber 架构应用的目的是为了实现任务可中断、可恢复、并赋予任务优先级,从而实现时间切片,让出主线程,让主线程有时间去处理其他任务,从而提升用户体验。

Fiber 之间的关系图

  • 通过 child 可以获取子节点
  • 通过 sibling 可以获取兄弟节点
  • 通过 return 可以获取父节点

Fiber 之间的关系图

+ \ No newline at end of file diff --git "a/guide/React/\345\246\202\344\275\225\350\256\276\350\256\241React\347\273\204\344\273\266.html" "b/guide/React/\345\246\202\344\275\225\350\256\276\350\256\241React\347\273\204\344\273\266.html" index a957a52e..61a8a7a2 100644 --- "a/guide/React/\345\246\202\344\275\225\350\256\276\350\256\241React\347\273\204\344\273\266.html" +++ "b/guide/React/\345\246\202\344\275\225\350\256\276\350\256\241React\347\273\204\344\273\266.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

如何设计 React 组件

设计分类

  • 展示组件: 只负责 UI 展示,不涉及业务逻辑

  • 业务组件: 复用负责业务逻辑

展示组件

展示组件一般受制于 props, 具有通用性、复用性

业务组件

业务组件一般受制于 state, 具有复用性

组件分类

- +
Skip to content

如何设计 React 组件

设计分类

  • 展示组件: 只负责 UI 展示,不涉及业务逻辑

  • 业务组件: 复用负责业务逻辑

展示组件

展示组件一般受制于 props, 具有通用性、复用性

业务组件

业务组件一般受制于 state, 具有复用性

组件分类

+ \ No newline at end of file diff --git "a/guide/React/\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.html" "b/guide/React/\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.html" index bb7a57f1..98d008ba 100644 --- "a/guide/React/\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.html" +++ "b/guide/React/\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content
- +
Skip to content
+ \ No newline at end of file diff --git "a/guide/Redux/\346\272\220\347\240\201\350\247\243\350\257\273.html" "b/guide/Redux/\346\272\220\347\240\201\350\247\243\350\257\273.html" index 642dcf65..660a8180 100644 --- "a/guide/Redux/\346\272\220\347\240\201\350\247\243\350\257\273.html" +++ "b/guide/Redux/\346\272\220\347\240\201\350\247\243\350\257\273.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content
- +
Skip to content
+ \ No newline at end of file diff --git "a/guide/Redux/\350\256\276\350\256\241\347\220\206\345\277\265.html" "b/guide/Redux/\350\256\276\350\256\241\347\220\206\345\277\265.html" index f8cb8bd1..5f7ad105 100644 --- "a/guide/Redux/\350\256\276\350\256\241\347\220\206\345\277\265.html" +++ "b/guide/Redux/\350\256\276\350\256\241\347\220\206\345\277\265.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content
- +
Skip to content
+ \ No newline at end of file diff --git "a/guide/canvas/Canvas\345\260\272\345\257\270\345\217\212\345\210\206\350\276\250\347\216\207\347\237\253\346\255\243.html" "b/guide/canvas/Canvas\345\260\272\345\257\270\345\217\212\345\210\206\350\276\250\347\216\207\347\237\253\346\255\243.html" index c05035dd..ade2c9ab 100644 --- "a/guide/canvas/Canvas\345\260\272\345\257\270\345\217\212\345\210\206\350\276\250\347\216\207\347\237\253\346\255\243.html" +++ "b/guide/canvas/Canvas\345\260\272\345\257\270\345\217\212\345\210\206\350\276\250\347\216\207\347\237\253\346\255\243.html" @@ -11,7 +11,7 @@ - + @@ -163,8 +163,8 @@ // 这时候我们还需要重新缩放 ctx const ctx = canvas.getContext('2d'); ctx.setTransform(1, 0, 0, 1, 0, 0); // scale 前先恢复变换矩阵,不然会重复 scale -ctx.scale(dpr, dpr);

参考文档

- +ctx.scale(dpr, dpr);

参考文档

+ \ No newline at end of file diff --git "a/guide/canvas/\345\217\257\350\247\206\345\214\272\345\237\237\345\206\205\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.html" "b/guide/canvas/\345\217\257\350\247\206\345\214\272\345\237\237\345\206\205\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.html" index a64f9a2a..869aaebd 100644 --- "a/guide/canvas/\345\217\257\350\247\206\345\214\272\345\237\237\345\206\205\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.html" +++ "b/guide/canvas/\345\217\257\350\247\206\345\214\272\345\237\237\345\206\205\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.html" @@ -11,7 +11,7 @@ - + @@ -225,8 +225,8 @@ ctx.restore(); }, [] -);

实现效果

canvas

具体代码

参考文章

- +);

实现效果

canvas

具体代码

参考文章

+ \ No newline at end of file diff --git "a/guide/canvas/\345\246\202\344\275\225\345\234\250Canvas\347\224\273\346\235\277\344\270\212\350\207\252\347\224\261\344\271\246\345\206\231.html" "b/guide/canvas/\345\246\202\344\275\225\345\234\250Canvas\347\224\273\346\235\277\344\270\212\350\207\252\347\224\261\344\271\246\345\206\231.html" index 79990c7a..ae502738 100644 --- "a/guide/canvas/\345\246\202\344\275\225\345\234\250Canvas\347\224\273\346\235\277\344\270\212\350\207\252\347\224\261\344\271\246\345\206\231.html" +++ "b/guide/canvas/\345\246\202\344\275\225\345\234\250Canvas\347\224\273\346\235\277\344\270\212\350\207\252\347\224\261\344\271\246\345\206\231.html" @@ -11,7 +11,7 @@ - + @@ -357,8 +357,8 @@ addPoint(e); // 将鼠标移动的点添加到points数组中 render(ctx, points); // 绘制 updatePointCounter(points.length); - }));

之前绘制一条直线需要近 40 个点 canvas

通过点稀释,我们发现画一条直线只需要 8 个点就可以了,这样就大大提高了性能。 canvas

虽然点稀释可以减少绘制的点数,提高性能,但在绘制曲线的时候,我们会发现曲线的圆滑度不够,这是因为我们的点数太少了,我们可以通过贝塞尔曲线来优化我们的 Canvas 书写。

canvas

参考

- + }));

之前绘制一条直线需要近 40 个点 canvas

通过点稀释,我们发现画一条直线只需要 8 个点就可以了,这样就大大提高了性能。 canvas

虽然点稀释可以减少绘制的点数,提高性能,但在绘制曲线的时候,我们会发现曲线的圆滑度不够,这是因为我们的点数太少了,我们可以通过贝塞尔曲线来优化我们的 Canvas 书写。

canvas

参考

+ \ No newline at end of file diff --git "a/guide/canvas/\351\200\232\350\277\207 OffscreenCanvas + Worker \346\217\220\351\253\230\344\271\246\345\206\231\346\200\247\350\203\275.html" "b/guide/canvas/\351\200\232\350\277\207 OffscreenCanvas + Worker \346\217\220\351\253\230\344\271\246\345\206\231\346\200\247\350\203\275.html" index f71343e0..1c8c60a3 100644 --- "a/guide/canvas/\351\200\232\350\277\207 OffscreenCanvas + Worker \346\217\220\351\253\230\344\271\246\345\206\231\346\200\247\350\203\275.html" +++ "b/guide/canvas/\351\200\232\350\277\207 OffscreenCanvas + Worker \346\217\220\351\253\230\344\271\246\345\206\231\346\200\247\350\203\275.html" @@ -11,7 +11,7 @@ - + @@ -145,8 +145,8 @@ x, y, }); -}

实现效果

初始状态图

具体代码

参考文章

- +}

实现效果

初始状态图

具体代码

参考文章

+ \ No newline at end of file diff --git "a/guide/canvas/\351\200\232\350\277\207\344\270\212\344\270\213\345\210\206\345\261\202\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.html" "b/guide/canvas/\351\200\232\350\277\207\344\270\212\344\270\213\345\210\206\345\261\202\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.html" index 6835a86f..0a8475b7 100644 --- "a/guide/canvas/\351\200\232\350\277\207\344\270\212\344\270\213\345\210\206\345\261\202\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.html" +++ "b/guide/canvas/\351\200\232\350\277\207\344\270\212\344\270\213\345\210\206\345\261\202\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.html" @@ -11,7 +11,7 @@ - + @@ -109,8 +109,8 @@ points = []; // 绘制完毕后,清空points数组 renderLowerCanvas(ctx, ctxContent); }); -</script>

演示效果

这里我将动静 Canvas 分成了左右 2 个部分,左边是动态层 Canvas,右边是静态层 Canvas,可以看到,当书写的时候,只有左边的 Canvas 会有书写的效果,右边的 Canvas 不会有书写的效果,当书写完成后,左边的 Canvas 会将书写的内容绘制到右边的 Canvas 中,然后清空左边的 Canvas 的内容,这样就可以达到书写的效果。

canvas

当我们把 2 个 Canvas 整合在一起后,具体的效果如下

canvas

具体代码

https://github.com/enson0131/learn/blob/main/Canvas/白板相关/上下分层绘制.html

- +</script>

演示效果

这里我将动静 Canvas 分成了左右 2 个部分,左边是动态层 Canvas,右边是静态层 Canvas,可以看到,当书写的时候,只有左边的 Canvas 会有书写的效果,右边的 Canvas 不会有书写的效果,当书写完成后,左边的 Canvas 会将书写的内容绘制到右边的 Canvas 中,然后清空左边的 Canvas 的内容,这样就可以达到书写的效果。

canvas

当我们把 2 个 Canvas 整合在一起后,具体的效果如下

canvas

具体代码

https://github.com/enson0131/learn/blob/main/Canvas/白板相关/上下分层绘制.html

+ \ No newline at end of file diff --git "a/guide/canvas/\351\200\232\350\277\207\347\246\273\345\261\217\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.html" "b/guide/canvas/\351\200\232\350\277\207\347\246\273\345\261\217\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.html" index 17a0fa54..a8eec6b5 100644 --- "a/guide/canvas/\351\200\232\350\277\207\347\246\273\345\261\217\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.html" +++ "b/guide/canvas/\351\200\232\350\277\207\347\246\273\345\261\217\346\270\262\346\237\223\346\217\220\351\253\230Canvas\344\271\246\345\206\231\346\200\247\350\203\275.html" @@ -11,7 +11,7 @@ - + @@ -317,8 +317,8 @@ y: minY * dpr - padding }); } -</script>

实现的效果

canvas

具体代码

https://github.com/enson0131/learn/blob/main/Canvas/白板相关/性能优化之离屏渲染及缓存.html

- +</script>

实现的效果

canvas

具体代码

https://github.com/enson0131/learn/blob/main/Canvas/白板相关/性能优化之离屏渲染及缓存.html

+ \ No newline at end of file diff --git "a/guide/canvas/\351\200\232\350\277\207\350\264\235\345\241\236\345\260\224\346\233\262\347\272\277\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.html" "b/guide/canvas/\351\200\232\350\277\207\350\264\235\345\241\236\345\260\224\346\233\262\347\272\277\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.html" index 1fc1f50e..479635ae 100644 --- "a/guide/canvas/\351\200\232\350\277\207\350\264\235\345\241\236\345\260\224\346\233\262\347\272\277\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.html" +++ "b/guide/canvas/\351\200\232\350\277\207\350\264\235\345\241\236\345\260\224\346\233\262\347\272\277\344\274\230\345\214\226Canvas\344\271\246\345\206\231\346\200\247\350\203\275.html" @@ -11,7 +11,7 @@ - + @@ -367,8 +367,8 @@ } </script> </body> -</html>

将两个点的中点作为控制点的选择通常用于创建平滑的曲线,该方法可以确保曲线通过两个点并且在两个点之间有一个平滑的拐角。 方法的依据是曲线的切线在控制点处与曲线的切线在两个点的中点处平行,从而使曲线过渡更加平滑。

canvas

参考文章

- +</html>

将两个点的中点作为控制点的选择通常用于创建平滑的曲线,该方法可以确保曲线通过两个点并且在两个点之间有一个平滑的拐角。 方法的依据是曲线的切线在控制点处与曲线的切线在两个点的中点处平行,从而使曲线过渡更加平滑。

canvas

参考文章

+ \ No newline at end of file diff --git "a/guide/css\347\233\270\345\205\263/BFC.html" "b/guide/css\347\233\270\345\205\263/BFC.html" index 2ecdc15b..1950d586 100644 --- "a/guide/css\347\233\270\345\205\263/BFC.html" +++ "b/guide/css\347\233\270\345\205\263/BFC.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

BFC

块级格式化上下文

条件

  1. 根元素 (html)
  2. 浮动元素
  3. position 为绝对定位元素 (absolute/fixed)
  4. display: inline-block、inline-flex等
  5. overflow: auto/scroll/hidden (overflow 值不为 visible 或 clip 的块级元素)

特点

  1. BFC 内部元素不影响外部元素
  2. 计算高度需要计算浮动元素
  3. BFC 区域不会与浮动容器发生重叠
  4. 在 BFC 中上下相邻的俩个容器的 margin 会重叠
  5. 每个元素的左 margin 值和容器的左 border 相接触

作用

  1. 清除浮动带来的高度塌陷问题
  2. 解决俩个元素的 margin 重叠问题
  3. 创建自适应的俩栏布局
- +
Skip to content

BFC

块级格式化上下文

条件

  1. 根元素 (html)
  2. 浮动元素
  3. position 为绝对定位元素 (absolute/fixed)
  4. display: inline-block、inline-flex等
  5. overflow: auto/scroll/hidden (overflow 值不为 visible 或 clip 的块级元素)

特点

  1. BFC 内部元素不影响外部元素
  2. 计算高度需要计算浮动元素
  3. BFC 区域不会与浮动容器发生重叠
  4. 在 BFC 中上下相邻的俩个容器的 margin 会重叠
  5. 每个元素的左 margin 值和容器的左 border 相接触

作用

  1. 清除浮动带来的高度塌陷问题
  2. 解决俩个元素的 margin 重叠问题
  3. 创建自适应的俩栏布局
+ \ No newline at end of file diff --git "a/guide/css\347\233\270\345\205\263/display.html" "b/guide/css\347\233\270\345\205\263/display.html" index 700e7542..19f454cb 100644 --- "a/guide/css\347\233\270\345\205\263/display.html" +++ "b/guide/css\347\233\270\345\205\263/display.html" @@ -11,7 +11,7 @@ - + @@ -115,8 +115,8 @@ <li>元素的头尾的空白符会直接忽略</li> <li>内容中间有多个空格,会被合并成一个空格</li> </ul> -</body> - +</body> + \ No newline at end of file diff --git "a/guide/css\347\233\270\345\205\263/display\343\200\201float\343\200\201position\347\232\204\345\205\263\347\263\273.html" "b/guide/css\347\233\270\345\205\263/display\343\200\201float\343\200\201position\347\232\204\345\205\263\347\263\273.html" index 8f88d6bb..9c8fc7e0 100644 --- "a/guide/css\347\233\270\345\205\263/display\343\200\201float\343\200\201position\347\232\204\345\205\263\347\263\273.html" +++ "b/guide/css\347\233\270\345\205\263/display\343\200\201float\343\200\201position\347\232\204\345\205\263\347\263\273.html" @@ -11,7 +11,7 @@ - + @@ -87,8 +87,8 @@ </div> </body> -</html> - +</html> + \ No newline at end of file diff --git "a/guide/css\347\233\270\345\205\263/display\343\200\201visibility\343\200\201opacity\345\214\272\345\210\253.html" "b/guide/css\347\233\270\345\205\263/display\343\200\201visibility\343\200\201opacity\345\214\272\345\210\253.html" index 0fbb7ba6..a65d5b3d 100644 --- "a/guide/css\347\233\270\345\205\263/display\343\200\201visibility\343\200\201opacity\345\214\272\345\210\253.html" +++ "b/guide/css\347\233\270\345\205\263/display\343\200\201visibility\343\200\201opacity\345\214\272\345\210\253.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

display、visibility、opacity区别

  • 占据空间

    • opacity、visibility 占据空间,不会引起回流,但是会重绘
    • display 不占据空间,但会引起页面的回流和重绘
  • 绑定事件

    • display、visibility 不会触发绑定事件
    • opacity 会触发绑定事件

display: none 和 visibility: hidden 的区别

  • 从渲染树上看
    • display: none 不存在渲染树中
    • visibility: hidden 的元素存在渲染树中,还会占据空间
  • 从继承上看
    • display 不会被继承
    • visibility 会被继承
  • 从渲染上看
    • display 会影响回流重绘
    • visibility 只会引起重绘
- +
Skip to content

display、visibility、opacity区别

  • 占据空间

    • opacity、visibility 占据空间,不会引起回流,但是会重绘
    • display 不占据空间,但会引起页面的回流和重绘
  • 绑定事件

    • display、visibility 不会触发绑定事件
    • opacity 会触发绑定事件

display: none 和 visibility: hidden 的区别

  • 从渲染树上看
    • display: none 不存在渲染树中
    • visibility: hidden 的元素存在渲染树中,还会占据空间
  • 从继承上看
    • display 不会被继承
    • visibility 会被继承
  • 从渲染上看
    • display 会影响回流重绘
    • visibility 只会引起重绘
+ \ No newline at end of file diff --git "a/guide/css\347\233\270\345\205\263/position.html" "b/guide/css\347\233\270\345\205\263/position.html" index d2bcb6fa..61037033 100644 --- "a/guide/css\347\233\270\345\205\263/position.html" +++ "b/guide/css\347\233\270\345\205\263/position.html" @@ -11,7 +11,7 @@ - + @@ -135,8 +135,8 @@ <div class="subbottom"></div> </div> </body> -</html> - +</html> + \ No newline at end of file diff --git "a/guide/css\347\233\270\345\205\263/\345\257\271 line-height \347\232\204\347\220\206\350\247\243\345\217\212\345\205\266\350\265\213\345\200\274\346\226\271\345\274\217.html" "b/guide/css\347\233\270\345\205\263/\345\257\271 line-height \347\232\204\347\220\206\350\247\243\345\217\212\345\205\266\350\265\213\345\200\274\346\226\271\345\274\217.html" index 6c6c82b2..83139fef 100644 --- "a/guide/css\347\233\270\345\205\263/\345\257\271 line-height \347\232\204\347\220\206\350\247\243\345\217\212\345\205\266\350\265\213\345\200\274\346\226\271\345\274\217.html" +++ "b/guide/css\347\233\270\345\205\263/\345\257\271 line-height \347\232\204\347\220\206\350\247\243\345\217\212\345\205\266\350\265\213\345\200\274\346\226\271\345\274\217.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

对 line-height 的理解及其赋值方式

概念

line-height 指一行文本的高度,包含了字间距,实际上是下一行基线到上一行基线的距离

line-height 和 height 都能撑开元素高度 (如果 line-height 和 height 一致时可以实现单行文字的垂直居中)

计算方式

带单位的px

line-height 为 固定值

纯数字

直接 line-height 会把比例传递给后代

例如,父级行高为 1.5,子元素字体为 18px,则子元素行高为 1.5 * 18 = 27px

百分比

父元素将计算后的值传递给后代

例如,父元素行高为 200%,父元素字体为 18px,那么子元素行高为 18 * 200% = 36px

- +
Skip to content

对 line-height 的理解及其赋值方式

概念

line-height 指一行文本的高度,包含了字间距,实际上是下一行基线到上一行基线的距离

line-height 和 height 都能撑开元素高度 (如果 line-height 和 height 一致时可以实现单行文字的垂直居中)

计算方式

带单位的px

line-height 为 固定值

纯数字

直接 line-height 会把比例传递给后代

例如,父级行高为 1.5,子元素字体为 18px,则子元素行高为 1.5 * 18 = 27px

百分比

父元素将计算后的值传递给后代

例如,父元素行高为 200%,父元素字体为 18px,那么子元素行高为 18 * 200% = 36px

+ \ No newline at end of file diff --git "a/guide/css\347\233\270\345\205\263/\346\246\202\350\246\201.html" "b/guide/css\347\233\270\345\205\263/\346\246\202\350\246\201.html" index 17a65928..24b32bf2 100644 --- "a/guide/css\347\233\270\345\205\263/\346\246\202\350\246\201.html" +++ "b/guide/css\347\233\270\345\205\263/\346\246\202\350\246\201.html" @@ -12,7 +12,7 @@ - + @@ -24,8 +24,8 @@ -
Skip to content
- +
Skip to content
+ \ No newline at end of file diff --git "a/guide/css\347\233\270\345\205\263/\351\232\220\350\227\217\345\205\203\347\264\240\347\232\204\346\226\271\346\263\225.html" "b/guide/css\347\233\270\345\205\263/\351\232\220\350\227\217\345\205\203\347\264\240\347\232\204\346\226\271\346\263\225.html" index ec4662d6..1e678432 100644 --- "a/guide/css\347\233\270\345\205\263/\351\232\220\350\227\217\345\205\203\347\264\240\347\232\204\346\226\271\346\263\225.html" +++ "b/guide/css\347\233\270\345\205\263/\351\232\220\350\227\217\345\205\203\347\264\240\347\232\204\346\226\271\346\263\225.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

隐藏元素的方法

    1. display: none - 不会显示在渲染树上,不占据空间,无法监听事件
    1. visibility: hidden - 占据空间,无法监听事件
    1. opacity: 0 - 占据空间,可以监听事件
    1. transform: scale(0, 0)
    1. 绝对定位
    1. z-index 为负数
- +
Skip to content

隐藏元素的方法

    1. display: none - 不会显示在渲染树上,不占据空间,无法监听事件
    1. visibility: hidden - 占据空间,无法监听事件
    1. opacity: 0 - 占据空间,可以监听事件
    1. transform: scale(0, 0)
    1. 绝对定位
    1. z-index 为负数
+ \ No newline at end of file diff --git "a/guide/javaScript\347\233\270\345\205\263/DOM\347\233\270\345\205\263.html" "b/guide/javaScript\347\233\270\345\205\263/DOM\347\233\270\345\205\263.html" index b72fe113..b0802da5 100644 --- "a/guide/javaScript\347\233\270\345\205\263/DOM\347\233\270\345\205\263.html" +++ "b/guide/javaScript\347\233\270\345\205\263/DOM\347\233\270\345\205\263.html" @@ -11,7 +11,7 @@ - + @@ -39,8 +39,8 @@ var imoocList = document.getElementByClassName('imooc'); // 查询类名 imooc 类名集合 -var imoocList = docuemnt.querySelectorAll('.imooc'); // 查询类名 imooc 的集合

高度相关

判断是否有滚动条 scrollHeight >= clientHeight

顶部高度

鼠标事件

按下

移动

- +var imoocList = docuemnt.querySelectorAll('.imooc'); // 查询类名 imooc 的集合

高度相关

判断是否有滚动条 scrollHeight >= clientHeight

顶部高度

鼠标事件

按下

移动

+ \ No newline at end of file diff --git "a/guide/javaScript\347\233\270\345\205\263/ES6\347\233\270\345\205\263.html" "b/guide/javaScript\347\233\270\345\205\263/ES6\347\233\270\345\205\263.html" index 61471834..f18108ee 100644 --- "a/guide/javaScript\347\233\270\345\205\263/ES6\347\233\270\345\205\263.html" +++ "b/guide/javaScript\347\233\270\345\205\263/ES6\347\233\270\345\205\263.html" @@ -11,7 +11,7 @@ - + @@ -123,8 +123,8 @@ let test = onWatch(obj); test.a // getting a! -test.a = 2 // setting a! - +test.a = 2 // setting a! + \ No newline at end of file diff --git "a/guide/javaScript\347\233\270\345\205\263/JS\345\274\202\345\270\270\346\215\225\350\216\267\346\234\272\345\210\266.html" "b/guide/javaScript\347\233\270\345\205\263/JS\345\274\202\345\270\270\346\215\225\350\216\267\346\234\272\345\210\266.html" index 669e2c73..730bf05e 100644 --- "a/guide/javaScript\347\233\270\345\205\263/JS\345\274\202\345\270\270\346\215\225\350\216\267\346\234\272\345\210\266.html" +++ "b/guide/javaScript\347\233\270\345\205\263/JS\345\274\202\345\270\270\346\215\225\350\216\267\346\234\272\345\210\266.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content
- +
Skip to content
+ \ No newline at end of file diff --git "a/guide/javaScript\347\233\270\345\205\263/JavaScript\346\211\247\350\241\214\346\234\272\345\210\266.html" "b/guide/javaScript\347\233\270\345\205\263/JavaScript\346\211\247\350\241\214\346\234\272\345\210\266.html" index ab11a303..222bca94 100644 --- "a/guide/javaScript\347\233\270\345\205\263/JavaScript\346\211\247\350\241\214\346\234\272\345\210\266.html" +++ "b/guide/javaScript\347\233\270\345\205\263/JavaScript\346\211\247\350\241\214\346\234\272\345\210\266.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

JavaScript 执行机制

先编译后执行

编译 -> 创建上下文、创建变量环境、创建词法环境 -> 将上下文压入执行调用栈执行代码

- +
Skip to content

JavaScript 执行机制

先编译后执行

编译 -> 创建上下文、创建变量环境、创建词法环境 -> 将上下文压入执行调用栈执行代码

+ \ No newline at end of file diff --git "a/guide/javaScript\347\233\270\345\205\263/JavaScript\347\274\226\350\257\221\346\234\272\345\210\266.html" "b/guide/javaScript\347\233\270\345\205\263/JavaScript\347\274\226\350\257\221\346\234\272\345\210\266.html" index 2dea618e..7ee6776b 100644 --- "a/guide/javaScript\347\233\270\345\205\263/JavaScript\347\274\226\350\257\221\346\234\272\345\210\266.html" +++ "b/guide/javaScript\347\233\270\345\205\263/JavaScript\347\274\226\350\257\221\346\234\272\345\210\266.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

JavaScript 编译机制

code -> 词法分析、语法分析 -> AST -> 生成字节码 -> 解释执行

- +
Skip to content

JavaScript 编译机制

code -> 词法分析、语法分析 -> AST -> 生成字节码 -> 解释执行

+ \ No newline at end of file diff --git "a/guide/javaScript\347\233\270\345\205\263/Promise.html" "b/guide/javaScript\347\233\270\345\205\263/Promise.html" index 167cea93..01014a6b 100644 --- "a/guide/javaScript\347\233\270\345\205\263/Promise.html" +++ "b/guide/javaScript\347\233\270\345\205\263/Promise.html" @@ -11,7 +11,7 @@ - + @@ -81,8 +81,8 @@ }) } }) -}

Promise.any

参数是一个数组,返回第一个成功的值

Promise.finally

不管 Promise 返回什么状态都会执行

常见的问题

Promise 解决了什么问题

- +}

Promise.any

参数是一个数组,返回第一个成功的值

Promise.finally

不管 Promise 返回什么状态都会执行

常见的问题

Promise 解决了什么问题

+ \ No newline at end of file diff --git "a/guide/javaScript\347\233\270\345\205\263/index.html" "b/guide/javaScript\347\233\270\345\205\263/index.html" index 9100c9ad..1cb4519e 100644 --- "a/guide/javaScript\347\233\270\345\205\263/index.html" +++ "b/guide/javaScript\347\233\270\345\205\263/index.html" @@ -12,7 +12,7 @@ - + @@ -24,8 +24,8 @@ -
Skip to content
- +
Skip to content
+ \ No newline at end of file diff --git "a/guide/javaScript\347\233\270\345\205\263/\344\272\213\344\273\266\345\276\252\347\216\257\346\234\272\345\210\266.html" "b/guide/javaScript\347\233\270\345\205\263/\344\272\213\344\273\266\345\276\252\347\216\257\346\234\272\345\210\266.html" index f57587a0..145c5aca 100644 --- "a/guide/javaScript\347\233\270\345\205\263/\344\272\213\344\273\266\345\276\252\347\216\257\346\234\272\345\210\266.html" +++ "b/guide/javaScript\347\233\270\345\205\263/\344\272\213\344\273\266\345\276\252\347\216\257\346\234\272\345\210\266.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

事件循环机制

执行 js 代码时,会将代码分成同步代码和异步代码, 同步任务会进入主线程执行,异步任务又分成宏任务和微任务 宏任务会进入宏任务队列,微任务会进入微任务队列 当主线程的代码执行完后,会查看是否有微任务队列,有则执行,无则进入下一个宏任务

- +
Skip to content

事件循环机制

执行 js 代码时,会将代码分成同步代码和异步代码, 同步任务会进入主线程执行,异步任务又分成宏任务和微任务 宏任务会进入宏任务队列,微任务会进入微任务队列 当主线程的代码执行完后,会查看是否有微任务队列,有则执行,无则进入下一个宏任务

+ \ No newline at end of file diff --git "a/guide/javaScript\347\233\270\345\205\263/\345\236\203\345\234\276\345\233\236\346\224\266\346\234\272\345\210\266.html" "b/guide/javaScript\347\233\270\345\205\263/\345\236\203\345\234\276\345\233\236\346\224\266\346\234\272\345\210\266.html" index 86f529fa..d9f94795 100644 --- "a/guide/javaScript\347\233\270\345\205\263/\345\236\203\345\234\276\345\233\236\346\224\266\346\234\272\345\210\266.html" +++ "b/guide/javaScript\347\233\270\345\205\263/\345\236\203\345\234\276\345\233\236\346\224\266\346\234\272\345\210\266.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

垃圾回收机制

在 JS 的垃圾回收机制中,分成新生代和老生代 新生代采用的是 GC 算法,将新生代划分成活动对象区域和空闲区域,例如声明的对象会被放入活动对象区域,当活动对象区域填满时, 会进行一次垃圾回收,将存活的对象移入空闲区域并进行碎片空间整理,完成后再将空闲区域和活动对象区域进行翻转,依次循环回收。

当进行 2次 垃圾回收后,存活的对象会被放入老生代中,

老生代采用的是标记清除和标记整理算法,递归遍历堆内存的变量,将不需要使用的变量标记为垃圾数据,将需要使用的变量标记成活动变量,清除掉垃圾,然后进行标记整理碎片空间。

- +
Skip to content

垃圾回收机制

在 JS 的垃圾回收机制中,分成新生代和老生代 新生代采用的是 GC 算法,将新生代划分成活动对象区域和空闲区域,例如声明的对象会被放入活动对象区域,当活动对象区域填满时, 会进行一次垃圾回收,将存活的对象移入空闲区域并进行碎片空间整理,完成后再将空闲区域和活动对象区域进行翻转,依次循环回收。

当进行 2次 垃圾回收后,存活的对象会被放入老生代中,

老生代采用的是标记清除和标记整理算法,递归遍历堆内存的变量,将不需要使用的变量标记为垃圾数据,将需要使用的变量标记成活动变量,清除掉垃圾,然后进行标记整理碎片空间。

+ \ No newline at end of file diff --git "a/guide/javaScript\347\233\270\345\205\263/\345\237\272\347\241\200\346\246\202\345\277\265.html" "b/guide/javaScript\347\233\270\345\205\263/\345\237\272\347\241\200\346\246\202\345\277\265.html" index 4f94f882..753248a3 100644 --- "a/guide/javaScript\347\233\270\345\205\263/\345\237\272\347\241\200\346\246\202\345\277\265.html" +++ "b/guide/javaScript\347\233\270\345\205\263/\345\237\272\347\241\200\346\246\202\345\277\265.html" @@ -11,7 +11,7 @@ - + @@ -60,8 +60,8 @@ } } -fn(); // undefined - +fn(); // undefined + \ No newline at end of file diff --git "a/guide/javaScript\347\233\270\345\205\263/\345\255\227\347\254\246\344\270\262\345\270\270\350\247\201\347\232\204API.html" "b/guide/javaScript\347\233\270\345\205\263/\345\255\227\347\254\246\344\270\262\345\270\270\350\247\201\347\232\204API.html" index ae4da882..03e68216 100644 --- "a/guide/javaScript\347\233\270\345\205\263/\345\255\227\347\254\246\344\270\262\345\270\270\350\247\201\347\232\204API.html" +++ "b/guide/javaScript\347\233\270\345\205\263/\345\255\227\347\254\246\344\270\262\345\270\270\350\247\201\347\232\204API.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content
- +
Skip to content
+ \ No newline at end of file diff --git "a/guide/javaScript\347\233\270\345\205\263/\345\256\232\344\271\211.html" "b/guide/javaScript\347\233\270\345\205\263/\345\256\232\344\271\211.html" index 5ecfdf3b..81c4a3d0 100644 --- "a/guide/javaScript\347\233\270\345\205\263/\345\256\232\344\271\211.html" +++ "b/guide/javaScript\347\233\270\345\205\263/\345\256\232\344\271\211.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

1 定义

JavaScript 是一门动态语言,可以不需要定义变量类型

JavaScript 是一门弱类型语言,存在隐式类型转化

JavaScript 是一门解释型语言,在运行程序时动态编译

解释型语言特点: 1 每次运行都需要将源代码转化成机器码并执行,效率低 2 只要平台提供相应的解析器,就可以运行源代码,跨平台

V8 执行一段代码的流程图 流程

- +
Skip to content

1 定义

JavaScript 是一门动态语言,可以不需要定义变量类型

JavaScript 是一门弱类型语言,存在隐式类型转化

JavaScript 是一门解释型语言,在运行程序时动态编译

解释型语言特点: 1 每次运行都需要将源代码转化成机器码并执行,效率低 2 只要平台提供相应的解析器,就可以运行源代码,跨平台

V8 执行一段代码的流程图 流程

+ \ No newline at end of file diff --git "a/guide/javaScript\347\233\270\345\205\263/\345\257\271\350\261\241\345\270\270\350\247\201\347\232\204API.html" "b/guide/javaScript\347\233\270\345\205\263/\345\257\271\350\261\241\345\270\270\350\247\201\347\232\204API.html" index a8d4ca3c..0fad2d3e 100644 --- "a/guide/javaScript\347\233\270\345\205\263/\345\257\271\350\261\241\345\270\270\350\247\201\347\232\204API.html" +++ "b/guide/javaScript\347\233\270\345\205\263/\345\257\271\350\261\241\345\270\270\350\247\201\347\232\204API.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content
- +
Skip to content
+ \ No newline at end of file diff --git "a/guide/javaScript\347\233\270\345\205\263/\346\225\260\346\215\256\347\261\273\345\236\213.html" "b/guide/javaScript\347\233\270\345\205\263/\346\225\260\346\215\256\347\261\273\345\236\213.html" index 99d0a0a2..ad4007c2 100644 --- "a/guide/javaScript\347\233\270\345\205\263/\346\225\260\346\215\256\347\261\273\345\236\213.html" +++ "b/guide/javaScript\347\233\270\345\205\263/\346\225\260\346\215\256\347\261\273\345\236\213.html" @@ -11,7 +11,7 @@ - + @@ -117,8 +117,8 @@ a.length; // 3 a.toUpperCase(); // "ABC"

3 undefined 和 null 的区别

undefined 表示未定义,一般变量声明了但还没有定义的时候返回 undefined null 表示空值,常用在对象初始化的场景

区别如下:

4 isNaN 和 Number.isNaN 的区别

js
isNaN('a'); // true
 Number.isNaN('a'); // false
isNaN('a'); // true
-Number.isNaN('a'); // false
- +Number.isNaN('a'); // false + \ No newline at end of file diff --git "a/guide/javaScript\347\233\270\345\205\263/\346\225\260\347\273\204\345\270\270\350\247\201\347\232\204API.html" "b/guide/javaScript\347\233\270\345\205\263/\346\225\260\347\273\204\345\270\270\350\247\201\347\232\204API.html" index 921e1761..ec3a4805 100644 --- "a/guide/javaScript\347\233\270\345\205\263/\346\225\260\347\273\204\345\270\270\350\247\201\347\232\204API.html" +++ "b/guide/javaScript\347\233\270\345\205\263/\346\225\260\347\273\204\345\270\270\350\247\201\347\232\204API.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content
- +
Skip to content
+ \ No newline at end of file diff --git "a/guide/javaScript\347\233\270\345\205\263/\346\226\260\347\232\204\350\277\220\347\256\227\347\254\246.html" "b/guide/javaScript\347\233\270\345\205\263/\346\226\260\347\232\204\350\277\220\347\256\227\347\254\246.html" index 844c805d..a570911b 100644 --- "a/guide/javaScript\347\233\270\345\205\263/\346\226\260\347\232\204\350\277\220\347\256\227\347\254\246.html" +++ "b/guide/javaScript\347\233\270\345\205\263/\346\226\260\347\232\204\350\277\220\347\256\227\347\254\246.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content
- +
Skip to content
+ \ No newline at end of file diff --git "a/guide/javaScript\347\233\270\345\205\263/\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217.html" "b/guide/javaScript\347\233\270\345\205\263/\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217.html" index f4b06b2f..47de88cf 100644 --- "a/guide/javaScript\347\233\270\345\205\263/\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217.html" +++ "b/guide/javaScript\347\233\270\345\205\263/\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content
- +
Skip to content
+ \ No newline at end of file diff --git "a/guide/javaScript\347\233\270\345\205\263/\347\273\247\346\211\277\347\233\270\345\205\263.html" "b/guide/javaScript\347\233\270\345\205\263/\347\273\247\346\211\277\347\233\270\345\205\263.html" index 1de72916..76bee52e 100644 --- "a/guide/javaScript\347\233\270\345\205\263/\347\273\247\346\211\277\347\233\270\345\205\263.html" +++ "b/guide/javaScript\347\233\270\345\205\263/\347\273\247\346\211\277\347\233\270\345\205\263.html" @@ -11,7 +11,7 @@ - + @@ -163,8 +163,8 @@ } const children = new Children(); -children.getName(); // parent - +children.getName(); // parent + \ No newline at end of file diff --git a/guide/webpack/index.html b/guide/webpack/index.html index 3721847e..421c88b6 100644 --- a/guide/webpack/index.html +++ b/guide/webpack/index.html @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content
- +
Skip to content
+ \ No newline at end of file diff --git "a/guide/webpack/\346\236\204\345\273\272\346\265\201\347\250\213.html" "b/guide/webpack/\346\236\204\345\273\272\346\265\201\347\250\213.html" index 3df3b514..1f969c7f 100644 --- "a/guide/webpack/\346\236\204\345\273\272\346\265\201\347\250\213.html" +++ "b/guide/webpack/\346\236\204\345\273\272\346\265\201\347\250\213.html" @@ -11,7 +11,7 @@ - + @@ -47,8 +47,8 @@ config: [__filename], // 当配置修改时,缓存失效 }, }, -};

4 sideEffects

5 支持 import 加载异步模块

6 支持模块联邦

参考文章

- +};

4 sideEffects

5 支持 import 加载异步模块

6 支持模块联邦

参考文章

+ \ No newline at end of file diff --git "a/guide/\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263/\346\246\202\350\246\201.html" "b/guide/\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263/\346\246\202\350\246\201.html" index 3198028b..7079113d 100644 --- "a/guide/\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263/\346\246\202\350\246\201.html" +++ "b/guide/\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263/\346\246\202\350\246\201.html" @@ -12,7 +12,7 @@ - + @@ -24,8 +24,8 @@ -
Skip to content
- +
Skip to content
+ \ No newline at end of file diff --git "a/guide/\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263/\346\265\217\350\247\210\345\231\250\345\206\205\346\240\270.html" "b/guide/\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263/\346\265\217\350\247\210\345\231\250\345\206\205\346\240\270.html" index f628c097..c22b6fa8 100644 --- "a/guide/\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263/\346\265\217\350\247\210\345\231\250\345\206\205\346\240\270.html" +++ "b/guide/\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263/\346\265\217\350\247\210\345\231\250\345\206\205\346\240\270.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

浏览器内核

  • Trident (IE)
  • Gecko (Firefox)
  • Webkit (Safari)
  • Blink (Chrome、Opera) Blink 是 Webkit 的一个分支
- +
Skip to content

浏览器内核

  • Trident (IE)
  • Gecko (Firefox)
  • Webkit (Safari)
  • Blink (Chrome、Opera) Blink 是 Webkit 的一个分支
+ \ No newline at end of file diff --git "a/guide/\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263/\346\265\217\350\247\210\345\231\250\345\256\211\345\205\250.html" "b/guide/\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263/\346\265\217\350\247\210\345\231\250\345\256\211\345\205\250.html" index 7a220b4d..1b63d2d4 100644 --- "a/guide/\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263/\346\265\217\350\247\210\345\231\250\345\256\211\345\205\250.html" +++ "b/guide/\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263/\346\265\217\350\247\210\345\231\250\345\256\211\345\205\250.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

浏览器安全

页面安全

同源策略

协议、域名、端口号都相同,才是同源。

限制

  1. 无法进行 DOM 操作
  2. 无法获取 Cookie、LocalStorage 等数据
  3. 无法向不同源发请求

开放

  1. 默认页面中可以引用任意第三方资源

    引入 CSP (内容安全策略)

    渲染流程图

  2. 只能请求同源的接口

    引入 CORS (跨域资源共享)

    • 简单请求 (HEAD/POST/GET请求)

      1. 浏览器在请求头上添加 Oirgin 字段,该字段用来说明请求来自那个源,服务器可以根据这个值决定是否同意这次请求
      2. 当服务器收到请求后,根据 Origin 判断是否在许可范围内
      3. 如果不在范围内,服务器会返回一个正常的 HTTP 响应,浏览器发现该响应头没有包含 Access-Control-Allow-Origin 字段,就会抛出一个错误,被 XMLHttpRequest 的 onerror 回调函数捕获 (由于正常响应,其状态码是 200,所以该错误不能通过状态码识别)
      4. 如果 Origin 在指定范围内,服务器返回的响应会多几个头信息字段
        • Access-Control-Allow-Origin(必须) 判断源是否可以跨域,该值要么是请求的 Origin,要么是 *

        • Access-Control-Allow-Credentials 是否允许发送 Cookie,默认为 false 如果 Access-Control-Allow-Origin 的值为 *,则无法发送 Cookie

        • Access-Control-Expose-Headers 制定其他的头信息字段可以暴露给客户端 因为默认情况下,只有 6 个字段可以被暴露,其他的都会被过滤掉

          简单请求

    • 非简单请求 (PUT/DELETE 或者 Content-type字段类型是 application/json)

      1. 浏览器发起 Option 预检请求
      2. 服务器收到预检请求后,检查
        • Origin 发起请求的源信息
        • Access-Control-Request-Method 浏览器会发起请求的方法
        • Access-Control-Request-Headers 请求额外发送的头信息字段
      3. 如果服务器否定预检请求,会返回一个正常的 HTTP 响应,但是没有任何的 CORS 相关的头信息字段,这是浏览器会认定服务器不同意预检,触发错误
      4. 如果服务器同意预检请求,会返回一个正常的 HTTP 响应,但是会多几个 CORS 相关的头信息字段
        • Access-Control-Allow-Origin (必须)
        • Access-Control-Allow-Credentials
        • Access-Control-Expose-Headers
        • Access-Control-Max-Age - 预检请求的有效期, 单位秒
        • Access-Control-Allow-Methods (必须)
        • Access-Control-Allow-Headers

      非简单请求

  3. 只能操作同源的DOM 引入了跨文档消息机制 postMessage

XSS 攻击

跨域脚本攻击。

类型

  1. 存储型

    脚本存储在服务器,用户访问时,脚本从服务器返回,浏览器执行脚本

  2. 反射型

    在文章链接参数上存放了一段恶意脚本,用户访问时,脚本从参数中取出,浏览器执行脚本

  3. DOM 型

    比如在搜索的时候,添加了一段脚本, 如果网站的搜索功能没有对用户输入进行适当的过滤和转义,搜索结果页面可能会将恶意的脚本代码直接插入到 HTML 中,并在用户浏览器中执行

    web 资源在传输或者用户在使用的过程中修改了 Web 页面的数据

预防

  1. 对输入的内容进行截取或者转义(encode)
  2. 限制输入的长度和类型
  3. 引入内容安全策略 (CSP)
  4. 对 Cookie 设置 HttpOnly 属性

CSRF 攻击

跨站请求伪造。

比如诱导用户点击链接,访问网址后,网址通过用户的登录信息伪造请求

必要条件

  1. 站点有 CSRF 漏洞
  2. 用户登录了
  3. 用户点击了诱导链接

预防

  1. 给 Cookie 新增 SameSite 属性
    • Strict: 第三方站点无法发送 Cookie
    • Lax (默认): 第三方站点如果是 GET 请求可以发送 Cookie
    • None 不做限制 Cookie的书写
  2. 通过请求的 Origin or Referer 字段判断请求合法性
  3. 在请求地址中添加 token 并验证

浏览器安全

将渲染进程放在沙箱中

  • 无法持久存储
  • 无法访问网络
  • 无法监听用户交互
  • 需要通过 IPC 与浏览器主进程通信,由浏览器进程处理后,再将结果传递给渲染进程

网络安全

HTTPS、重放攻击、验签

- +
Skip to content

浏览器安全

页面安全

同源策略

协议、域名、端口号都相同,才是同源。

限制

  1. 无法进行 DOM 操作
  2. 无法获取 Cookie、LocalStorage 等数据
  3. 无法向不同源发请求

开放

  1. 默认页面中可以引用任意第三方资源

    引入 CSP (内容安全策略)

    渲染流程图

  2. 只能请求同源的接口

    引入 CORS (跨域资源共享)

    • 简单请求 (HEAD/POST/GET请求)

      1. 浏览器在请求头上添加 Oirgin 字段,该字段用来说明请求来自那个源,服务器可以根据这个值决定是否同意这次请求
      2. 当服务器收到请求后,根据 Origin 判断是否在许可范围内
      3. 如果不在范围内,服务器会返回一个正常的 HTTP 响应,浏览器发现该响应头没有包含 Access-Control-Allow-Origin 字段,就会抛出一个错误,被 XMLHttpRequest 的 onerror 回调函数捕获 (由于正常响应,其状态码是 200,所以该错误不能通过状态码识别)
      4. 如果 Origin 在指定范围内,服务器返回的响应会多几个头信息字段
        • Access-Control-Allow-Origin(必须) 判断源是否可以跨域,该值要么是请求的 Origin,要么是 *

        • Access-Control-Allow-Credentials 是否允许发送 Cookie,默认为 false 如果 Access-Control-Allow-Origin 的值为 *,则无法发送 Cookie

        • Access-Control-Expose-Headers 制定其他的头信息字段可以暴露给客户端 因为默认情况下,只有 6 个字段可以被暴露,其他的都会被过滤掉

          简单请求

    • 非简单请求 (PUT/DELETE 或者 Content-type字段类型是 application/json)

      1. 浏览器发起 Option 预检请求
      2. 服务器收到预检请求后,检查
        • Origin 发起请求的源信息
        • Access-Control-Request-Method 浏览器会发起请求的方法
        • Access-Control-Request-Headers 请求额外发送的头信息字段
      3. 如果服务器否定预检请求,会返回一个正常的 HTTP 响应,但是没有任何的 CORS 相关的头信息字段,这是浏览器会认定服务器不同意预检,触发错误
      4. 如果服务器同意预检请求,会返回一个正常的 HTTP 响应,但是会多几个 CORS 相关的头信息字段
        • Access-Control-Allow-Origin (必须)
        • Access-Control-Allow-Credentials
        • Access-Control-Expose-Headers
        • Access-Control-Max-Age - 预检请求的有效期, 单位秒
        • Access-Control-Allow-Methods (必须)
        • Access-Control-Allow-Headers

      非简单请求

  3. 只能操作同源的DOM 引入了跨文档消息机制 postMessage

XSS 攻击

跨域脚本攻击。

类型

  1. 存储型

    脚本存储在服务器,用户访问时,脚本从服务器返回,浏览器执行脚本

  2. 反射型

    在文章链接参数上存放了一段恶意脚本,用户访问时,脚本从参数中取出,浏览器执行脚本

  3. DOM 型

    比如在搜索的时候,添加了一段脚本, 如果网站的搜索功能没有对用户输入进行适当的过滤和转义,搜索结果页面可能会将恶意的脚本代码直接插入到 HTML 中,并在用户浏览器中执行

    web 资源在传输或者用户在使用的过程中修改了 Web 页面的数据

预防

  1. 对输入的内容进行截取或者转义(encode)
  2. 限制输入的长度和类型
  3. 引入内容安全策略 (CSP)
  4. 对 Cookie 设置 HttpOnly 属性

CSRF 攻击

跨站请求伪造。

比如诱导用户点击链接,访问网址后,网址通过用户的登录信息伪造请求

必要条件

  1. 站点有 CSRF 漏洞
  2. 用户登录了
  3. 用户点击了诱导链接

预防

  1. 给 Cookie 新增 SameSite 属性
    • Strict: 第三方站点无法发送 Cookie
    • Lax (默认): 第三方站点如果是 GET 请求可以发送 Cookie
    • None 不做限制 Cookie的书写
  2. 通过请求的 Origin or Referer 字段判断请求合法性
  3. 在请求地址中添加 token 并验证

浏览器安全

将渲染进程放在沙箱中

  • 无法持久存储
  • 无法访问网络
  • 无法监听用户交互
  • 需要通过 IPC 与浏览器主进程通信,由浏览器进程处理后,再将结果传递给渲染进程

网络安全

HTTPS、重放攻击、验签

+ \ No newline at end of file diff --git "a/guide/\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263/\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\346\265\201\347\250\213.html" "b/guide/\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263/\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\346\265\201\347\250\213.html" index 9f94bed6..3bdfd66e 100644 --- "a/guide/\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263/\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\346\265\201\347\250\213.html" +++ "b/guide/\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263/\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\346\265\201\347\250\213.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

浏览器渲染流程

浏览器渲染流程

  1. 发出请求到页面首次绘制
    • 第一阶段: 页面提交请求到服务器响应,这时候页面还是之前的页面
    • 第二阶段: 获取到响应数据提交到渲染进程,进行 HTML 解析、CSS 加载、JS 加载、JS 执行、CSSOM 解析、布局树生成、页面绘制
    • 第三阶段: 等首次加载完成后,页面一点点被渲染
  2. HTML 解析
  3. 生成 CSSOM 树 CSS 不会阻塞 HTML 解析,但是会阻塞页面渲染,因为要生成渲染树
  4. 生成布局树 去除不显示的节点,计算样式
  5. 分层和合成机制
    • 分层: 分层树在布局树之后,分层树的每一个节点都是图层,如没有,则和父节点同一个图层
    • 绘制阶段: 根据图层在绘制阶段生成绘制指令
    • 光栅化: 根据绘制指令,将每个图层都绘制成一张图片
    • 合成: 合成线程将多张图片合成一张图片,然后显示在屏幕上 (由合成线程完成,不影响主线程) - 优化操作1: 合成线程内会维护一个光栅化线程池,将绘制指令列表提交到 GPU 进行光栅化,生成位图,放在内存中 - 优化操作2: 分块,合成线程将图层分块,优先渲染离屏幕最近的图块 - 合成线程
  6. 页面显示

常见的问题

1 从输入 URL 到页面渲染完成,发生了什么?

  1. 浏览器会根据用户输入的内容判断是关键字还是URL
  2. 如果是关键字,会将其组成成带有搜索关键字的URL,通过IPC进程通信发送给网络进程
  3. 网络进程发起请求前,会判断是否命中强缓存,如命中直接返回存储资源
  4. 否则发起请求,根据 DNS 解析获取域名对应的 IP 地址,进行 TCP、HTTP 连接
  5. 服务端收到请求后,会判断是否命中协商缓存,如命中则返回304状态码
  6. 如返回的是301、302状态码,浏览器会根据响应头返回的location字段,进行重定向
  7. 如是正常返回资源类型,浏览器会根据 content-type 对资源做相对应的操作,如果是下载类型则进行下载,如果是html类型则会提交到渲染进程进行解析
  8. 解析HTML,转换成浏览器能识别的DOM树
  9. 解析CSS,转化成浏览器能识别的CSS样式树
  10. 根据DOM和CSS样式树,通过布局计算生成布局树
  11. 根据布局树上的分层属性(z-index),生成分层树
  12. 根据分层树,生成绘制指令列表
  13. 渲染主线程会将绘制指令列表提交给合成线程
  14. 合成线程会发送指令给光栅化线程池,将绘制指令列表提交到 GPU 进行光栅化,生成位图,放在内存中
  15. 合成线程通信浏览器进程,浏览器进程将内存中的数据输出到显卡的后缓存区,在下一帧绘制之前,显卡的后缓冲区与前缓冲区对换,显示屏读取前缓冲区数据,显示到屏幕上

整体流程

2 回流和重绘有什么区别

回流:元素尺寸、定位改变,可能会影响到其他元素的位置

重绘:元素外观改变,如背景色、颜色,元素尺寸位置不改变且不影响其他元素

减少回流的方法:

  1. 集中修改
    • 修改样式,使用 class
    • 修改前将 DOM 改成 display: none,修改后再显示
    • 使用 DocumentFragment
    • resize、scroll 事件,使用防抖
  2. 使用 BFC
    • 隔离内部元素对外部元素的影响
  3. 脱离文档流
    • position: absolute、fixed
    • float
  4. 提升合成图层
    • CSS3 属性: will-change、transform: translate3d(0);
  5. 不是用 offsetHeight、getBoundingClientRect
    • 使用 intersectionObserver API - 判断元素是否在可视区域内

BFC: 块级格式化上下文 特点: BFC 内部元素不会影响到外部元素 形成条件:

  1. HTML 元素
  2. overflow: hidden、auto、scroll
  3. position: absolute、fixed
  4. float 元素
  5. display: inline-block、flex、inline-flex等

3 渲染流程图

渲染流程图

JS 会阻塞 HTML 的解析和渲染

CSS 不会阻塞 HTML 解析,但会阻塞 DOM 渲染,还会阻塞 JS 的执行

为什么 CSS 会阻塞 JS 的执行?

因为 JS 可能会操作 DOM 节点和 CSS 样式,因此浏览器为了获取到最新的 CSS 样式,样式表会在后面的 JS 执行前先加载执行完毕,所以 CSS 会阻塞 JS 的执行

- +
Skip to content

浏览器渲染流程

浏览器渲染流程

  1. 发出请求到页面首次绘制
    • 第一阶段: 页面提交请求到服务器响应,这时候页面还是之前的页面
    • 第二阶段: 获取到响应数据提交到渲染进程,进行 HTML 解析、CSS 加载、JS 加载、JS 执行、CSSOM 解析、布局树生成、页面绘制
    • 第三阶段: 等首次加载完成后,页面一点点被渲染
  2. HTML 解析
  3. 生成 CSSOM 树 CSS 不会阻塞 HTML 解析,但是会阻塞页面渲染,因为要生成渲染树
  4. 生成布局树 去除不显示的节点,计算样式
  5. 分层和合成机制
    • 分层: 分层树在布局树之后,分层树的每一个节点都是图层,如没有,则和父节点同一个图层
    • 绘制阶段: 根据图层在绘制阶段生成绘制指令
    • 光栅化: 根据绘制指令,将每个图层都绘制成一张图片
    • 合成: 合成线程将多张图片合成一张图片,然后显示在屏幕上 (由合成线程完成,不影响主线程) - 优化操作1: 合成线程内会维护一个光栅化线程池,将绘制指令列表提交到 GPU 进行光栅化,生成位图,放在内存中 - 优化操作2: 分块,合成线程将图层分块,优先渲染离屏幕最近的图块 - 合成线程
  6. 页面显示

常见的问题

1 从输入 URL 到页面渲染完成,发生了什么?

  1. 浏览器会根据用户输入的内容判断是关键字还是URL
  2. 如果是关键字,会将其组成成带有搜索关键字的URL,通过IPC进程通信发送给网络进程
  3. 网络进程发起请求前,会判断是否命中强缓存,如命中直接返回存储资源
  4. 否则发起请求,根据 DNS 解析获取域名对应的 IP 地址,进行 TCP、HTTP 连接
  5. 服务端收到请求后,会判断是否命中协商缓存,如命中则返回304状态码
  6. 如返回的是301、302状态码,浏览器会根据响应头返回的location字段,进行重定向
  7. 如是正常返回资源类型,浏览器会根据 content-type 对资源做相对应的操作,如果是下载类型则进行下载,如果是html类型则会提交到渲染进程进行解析
  8. 解析HTML,转换成浏览器能识别的DOM树
  9. 解析CSS,转化成浏览器能识别的CSS样式树
  10. 根据DOM和CSS样式树,通过布局计算生成布局树
  11. 根据布局树上的分层属性(z-index),生成分层树
  12. 根据分层树,生成绘制指令列表
  13. 渲染主线程会将绘制指令列表提交给合成线程
  14. 合成线程会发送指令给光栅化线程池,将绘制指令列表提交到 GPU 进行光栅化,生成位图,放在内存中
  15. 合成线程通信浏览器进程,浏览器进程将内存中的数据输出到显卡的后缓存区,在下一帧绘制之前,显卡的后缓冲区与前缓冲区对换,显示屏读取前缓冲区数据,显示到屏幕上

整体流程

2 回流和重绘有什么区别

回流:元素尺寸、定位改变,可能会影响到其他元素的位置

重绘:元素外观改变,如背景色、颜色,元素尺寸位置不改变且不影响其他元素

减少回流的方法:

  1. 集中修改
    • 修改样式,使用 class
    • 修改前将 DOM 改成 display: none,修改后再显示
    • 使用 DocumentFragment
    • resize、scroll 事件,使用防抖
  2. 使用 BFC
    • 隔离内部元素对外部元素的影响
  3. 脱离文档流
    • position: absolute、fixed
    • float
  4. 提升合成图层
    • CSS3 属性: will-change、transform: translate3d(0);
  5. 不是用 offsetHeight、getBoundingClientRect
    • 使用 intersectionObserver API - 判断元素是否在可视区域内

BFC: 块级格式化上下文 特点: BFC 内部元素不会影响到外部元素 形成条件:

  1. HTML 元素
  2. overflow: hidden、auto、scroll
  3. position: absolute、fixed
  4. float 元素
  5. display: inline-block、flex、inline-flex等

3 渲染流程图

渲染流程图

JS 会阻塞 HTML 的解析和渲染

CSS 不会阻塞 HTML 解析,但会阻塞 DOM 渲染,还会阻塞 JS 的执行

为什么 CSS 会阻塞 JS 的执行?

因为 JS 可能会操作 DOM 节点和 CSS 样式,因此浏览器为了获取到最新的 CSS 样式,样式表会在后面的 JS 执行前先加载执行完毕,所以 CSS 会阻塞 JS 的执行

+ \ No newline at end of file diff --git "a/guide/\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263/\346\265\217\350\247\210\345\231\250\347\274\223\345\255\230.html" "b/guide/\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263/\346\265\217\350\247\210\345\231\250\347\274\223\345\255\230.html" index 8492119c..b5f72619 100644 --- "a/guide/\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263/\346\265\217\350\247\210\345\231\250\347\274\223\345\255\230.html" +++ "b/guide/\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263/\346\265\217\350\247\210\345\231\250\347\274\223\345\255\230.html" @@ -11,7 +11,7 @@ - + @@ -115,8 +115,8 @@ return response; })() ); -}); - +}); + \ No newline at end of file diff --git "a/guide/\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263/\346\265\217\350\247\210\345\231\250\350\277\233\347\250\213\346\236\266\346\236\204.html" "b/guide/\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263/\346\265\217\350\247\210\345\231\250\350\277\233\347\250\213\346\236\266\346\236\204.html" index 3cd06346..20007b21 100644 --- "a/guide/\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263/\346\265\217\350\247\210\345\231\250\350\277\233\347\250\213\346\236\266\346\236\204.html" +++ "b/guide/\346\265\217\350\247\210\345\231\250\347\233\270\345\205\263/\346\265\217\350\247\210\345\231\250\350\277\233\347\250\213\346\236\266\346\236\204.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

浏览器进程架构

进程与线程

进程

进程是一个程序的实例 进程是系统进行资源调度和分配的最小单位 进程之间相互独立,通过 IPC 进行通信

线程

线程是 CPU 调度的最小单位 线程之间共享进程的数据 线程里面会有协程,但只能运行一个

浏览器架构

1 浏览器主进程

用户交互、文件存储、页面显示、子进程管理

2 渲染进程

解析资源、执行 js 渲染进程被浏览器放在安全沙箱里面,因此渲染进程的资源是通过网络获取 - 渲染线程: 渲染页面 - JS 线程:解析执行 js - 事件触发线程: 事件循环 - 定时器线程:定时器相关 - 异步 http 请求线程: 请求相关

3 GPU 进程

UI界面的绘制

4 网络进程

网络资源加载

5 插件进程

管理插件

- +
Skip to content

浏览器进程架构

进程与线程

进程

进程是一个程序的实例 进程是系统进行资源调度和分配的最小单位 进程之间相互独立,通过 IPC 进行通信

线程

线程是 CPU 调度的最小单位 线程之间共享进程的数据 线程里面会有协程,但只能运行一个

浏览器架构

1 浏览器主进程

用户交互、文件存储、页面显示、子进程管理

2 渲染进程

解析资源、执行 js 渲染进程被浏览器放在安全沙箱里面,因此渲染进程的资源是通过网络获取 - 渲染线程: 渲染页面 - JS 线程:解析执行 js - 事件触发线程: 事件循环 - 定时器线程:定时器相关 - 异步 http 请求线程: 请求相关

3 GPU 进程

UI界面的绘制

4 网络进程

网络资源加载

5 插件进程

管理插件

+ \ No newline at end of file diff --git "a/guide/\347\275\221\347\273\234\347\233\270\345\205\263/CDN.html" "b/guide/\347\275\221\347\273\234\347\233\270\345\205\263/CDN.html" index 819f8de3..bde5ebc7 100644 --- "a/guide/\347\275\221\347\273\234\347\233\270\345\205\263/CDN.html" +++ "b/guide/\347\275\221\347\273\234\347\233\270\345\205\263/CDN.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

CDN

定义

内容分发网络,利用最靠近用户的服务器,将资源更快更可靠的给到用户

组成

  1. 分发服务系统

    最小单位是 Cache 设备

    • 响应用户请求
    • 与源站点进行资源同步
  2. 负载均衡系统

    负责对用户的请求进行调度

  3. 运营管理系统

    负责业务层面与外界系统的交互所需要的收集、整理、交付等工作 (为了做闭环)

    运营管理子系统 网络管理子系统

作用

托管 web 资源,加速 web 资源的获取速度

性能方面

  1. 用户从最近的 CDN 站点获取资源,访问速度更快
  2. 突破 TCP 只有同域名下只有 6 个的限制
  3. 减少源服务器的负担

安全方面

  1. 针对 DDos: 通过监控分析异常流量,限制请求频率
  2. 针对 MITM: 从源服务器到 CDN 节点到 ISP (Internet Service Provider, 网络运营提供商),全链路 HTTPS 通信

工作原理

没有使用 CDN 过程

  1. 浏览器通过 DNS 对域名进行解析,得到此域名对应的 IP 地址
  2. 浏览器根据得到的 IP 地址,向域名的服务主机发送数据请求
  3. 服务器向浏览器返回响应数据

使用了 CDN 过程

  1. 获取负载均衡服务器 IP 地址 (自底向上)

      1. 数据的 URL 先进行 DNS 系统解析,发现该 URL 对应的是一个 CDN 专用的 DNS 服务器,DNS 系统就会将域名解析权交给 CNAME 指向的 CDN 专用的 DNS 服务器
      1. CDN 专用的 DNS 服务器将 CDN 全局负载均衡设备 IP 地址返回给用户
      1. 用户向 CDN 的全局负载均衡设备发起数据请求
  2. 获取目标缓存服务器 IP 地址 (自顶向下)

      1. CDN 全局负载均衡设备根据用户 IP 地址以及用户请求的 URL,选择一台用户所属区域的负载均衡设备
      1. 区域负责均衡设备选择一台适合的缓存服务器来提供服务,将该缓存服务器的 IP 地址返回给全局负载均衡设备
      1. 全局负载均衡设备把服务器 IP 地址返回给用户
  3. 用户发起请求获取

    • 用户向该缓存服务器发起请求,缓存服务器响应用户的请求,将用户所需内容发送支用户终端 (如果缓存服务器没有用户想要的内容,那么缓存服务器会穿透 CDN 集群往源服务器获取设备)

流程

使用场景

  1. 使用第三方 CDN 服务 (例如开源框架可以使用第三方 CDN 服务,如 React、Vue、JQuery)
  2. 使用 CDN 进行静态资源的缓存 (将网站的资源放在 CDN 上)
  3. 直播传送 (直播本质也是使用流媒体进行传送,CDN 也支持流媒体传送,所以直播完全可以使用 CDN 来提高访问速度)
- +
Skip to content

CDN

定义

内容分发网络,利用最靠近用户的服务器,将资源更快更可靠的给到用户

组成

  1. 分发服务系统

    最小单位是 Cache 设备

    • 响应用户请求
    • 与源站点进行资源同步
  2. 负载均衡系统

    负责对用户的请求进行调度

  3. 运营管理系统

    负责业务层面与外界系统的交互所需要的收集、整理、交付等工作 (为了做闭环)

    运营管理子系统 网络管理子系统

作用

托管 web 资源,加速 web 资源的获取速度

性能方面

  1. 用户从最近的 CDN 站点获取资源,访问速度更快
  2. 突破 TCP 只有同域名下只有 6 个的限制
  3. 减少源服务器的负担

安全方面

  1. 针对 DDos: 通过监控分析异常流量,限制请求频率
  2. 针对 MITM: 从源服务器到 CDN 节点到 ISP (Internet Service Provider, 网络运营提供商),全链路 HTTPS 通信

工作原理

没有使用 CDN 过程

  1. 浏览器通过 DNS 对域名进行解析,得到此域名对应的 IP 地址
  2. 浏览器根据得到的 IP 地址,向域名的服务主机发送数据请求
  3. 服务器向浏览器返回响应数据

使用了 CDN 过程

  1. 获取负载均衡服务器 IP 地址 (自底向上)

      1. 数据的 URL 先进行 DNS 系统解析,发现该 URL 对应的是一个 CDN 专用的 DNS 服务器,DNS 系统就会将域名解析权交给 CNAME 指向的 CDN 专用的 DNS 服务器
      1. CDN 专用的 DNS 服务器将 CDN 全局负载均衡设备 IP 地址返回给用户
      1. 用户向 CDN 的全局负载均衡设备发起数据请求
  2. 获取目标缓存服务器 IP 地址 (自顶向下)

      1. CDN 全局负载均衡设备根据用户 IP 地址以及用户请求的 URL,选择一台用户所属区域的负载均衡设备
      1. 区域负责均衡设备选择一台适合的缓存服务器来提供服务,将该缓存服务器的 IP 地址返回给全局负载均衡设备
      1. 全局负载均衡设备把服务器 IP 地址返回给用户
  3. 用户发起请求获取

    • 用户向该缓存服务器发起请求,缓存服务器响应用户的请求,将用户所需内容发送支用户终端 (如果缓存服务器没有用户想要的内容,那么缓存服务器会穿透 CDN 集群往源服务器获取设备)

流程

使用场景

  1. 使用第三方 CDN 服务 (例如开源框架可以使用第三方 CDN 服务,如 React、Vue、JQuery)
  2. 使用 CDN 进行静态资源的缓存 (将网站的资源放在 CDN 上)
  3. 直播传送 (直播本质也是使用流媒体进行传送,CDN 也支持流媒体传送,所以直播完全可以使用 CDN 来提高访问速度)
+ \ No newline at end of file diff --git "a/guide/\347\275\221\347\273\234\347\233\270\345\205\263/DNS.html" "b/guide/\347\275\221\347\273\234\347\233\270\345\205\263/DNS.html" index 9059aca3..e566491a 100644 --- "a/guide/\347\275\221\347\273\234\347\233\270\345\205\263/DNS.html" +++ "b/guide/\347\275\221\347\273\234\347\233\270\345\205\263/DNS.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

DNS

定义

域名解析系统

工作原理 (自下而上)

例如查找 www.baidu.com 的 ip 地址

  1. 查找缓存
      1. 检查浏览器缓存
      1. 检查操作系统缓存 (常见的有 host 文件)
      1. 检查路由器缓存
  2. 如何缓存查找到,会向 ISP (网络服务提供商) 的本地 DNS 服务器查询
  3. 如果本地 DNS 服务器没有找到,会向根域名服务器请求解析,分为以下几步:(自顶向下)
      1. 根服务器返回顶级域名服务器(如.com、.cn、.org等)地址,例如该例子中的 .com 的地址
      1. 接着向顶级瑜域名服务器发送请求,然后会返回次级域名服务器的地址,例如该例子会返回 .baidu 的地址
      1. 接着向次级域名服务器发送请求,会返回通过三级域名地址的 IP,例如本例子返回的 www.baidu.com 的地址
    • 4.Local DNS Server会缓存结果,并返回给用户,缓存在系统中
- +
Skip to content

DNS

定义

域名解析系统

工作原理 (自下而上)

例如查找 www.baidu.com 的 ip 地址

  1. 查找缓存
      1. 检查浏览器缓存
      1. 检查操作系统缓存 (常见的有 host 文件)
      1. 检查路由器缓存
  2. 如何缓存查找到,会向 ISP (网络服务提供商) 的本地 DNS 服务器查询
  3. 如果本地 DNS 服务器没有找到,会向根域名服务器请求解析,分为以下几步:(自顶向下)
      1. 根服务器返回顶级域名服务器(如.com、.cn、.org等)地址,例如该例子中的 .com 的地址
      1. 接着向顶级瑜域名服务器发送请求,然后会返回次级域名服务器的地址,例如该例子会返回 .baidu 的地址
      1. 接着向次级域名服务器发送请求,会返回通过三级域名地址的 IP,例如本例子返回的 www.baidu.com 的地址
    • 4.Local DNS Server会缓存结果,并返回给用户,缓存在系统中
+ \ No newline at end of file diff --git "a/guide/\347\275\221\347\273\234\347\233\270\345\205\263/GET\350\257\267\346\261\202\345\222\214POST\350\257\267\346\261\202\347\232\204\345\214\272\345\210\253.html" "b/guide/\347\275\221\347\273\234\347\233\270\345\205\263/GET\350\257\267\346\261\202\345\222\214POST\350\257\267\346\261\202\347\232\204\345\214\272\345\210\253.html" index 51814ea0..217a9c9b 100644 --- "a/guide/\347\275\221\347\273\234\347\233\270\345\205\263/GET\350\257\267\346\261\202\345\222\214POST\350\257\267\346\261\202\347\232\204\345\214\272\345\210\253.html" +++ "b/guide/\347\275\221\347\273\234\347\233\270\345\205\263/GET\350\257\267\346\261\202\345\222\214POST\350\257\267\346\261\202\347\232\204\345\214\272\345\210\253.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

GET 请求和 POST 请求的区别

  1. 功能上: GET 请求常用于获取数据,POST 请求常用于提交数据
  2. 参数上: GET 请求参数放在 URL 上,POST 请求参数放在请求体上
  3. 参数类型上: POST 请求支持更多的参数类型
  4. 安全性上: POST 请求更加安全
  5. 是否有缓存上: GET 请求会被缓存
  6. 请求长度上: 由于浏览器存在 URL 长度限制,因此会影响 GET 请求的长度
- +
Skip to content

GET 请求和 POST 请求的区别

  1. 功能上: GET 请求常用于获取数据,POST 请求常用于提交数据
  2. 参数上: GET 请求参数放在 URL 上,POST 请求参数放在请求体上
  3. 参数类型上: POST 请求支持更多的参数类型
  4. 安全性上: POST 请求更加安全
  5. 是否有缓存上: GET 请求会被缓存
  6. 请求长度上: 由于浏览器存在 URL 长度限制,因此会影响 GET 请求的长度
+ \ No newline at end of file diff --git "a/guide/\347\275\221\347\273\234\347\233\270\345\205\263/HTTP.html" "b/guide/\347\275\221\347\273\234\347\233\270\345\205\263/HTTP.html" index 7be2837c..ca86989b 100644 --- "a/guide/\347\275\221\347\273\234\347\233\270\345\205\263/HTTP.html" +++ "b/guide/\347\275\221\347\273\234\347\233\270\345\205\263/HTTP.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

HTTP

HTTP 0.9

早期做学术研究使用,只是单纯的文本传输(只有请求行、没有请求头和请求体)

HTTP1.0

支持图片、视频传输,但传输效率太低

核心需求:支持多种类型的文件下载(引入了请求头和响应头)

HTTP1.1

持久连接 keep-alive

在此之前一个 HTTP 请求需要建立一个 TCP 连接

目前浏览器中对于 同一个域名,默认允许同时建立 6 个 TCP 连接

管道化连接

将串行请求改成并行请求

支持虚拟主机

HTTP 根据 Host 去区分同一 IP 物理机子上的不同虚拟主机

对动态生成的内容提供完美支持

Chunk transfer 机制

Cookie、完全机制

主要问题

    1. HTTP/1.1 对头阻塞问题 在 HTTP 中,因为前一条请求因某些原因没有及时返回,会导致后面的请求无法发起,容易导致对头阻塞(串行)。虽然 HTTP1.1 引入了管道化技术尝试解决队头阻塞问题,但服务端还是需要按顺序处理请求并返回,因此阻塞问题依然存在
    1. 带宽利用率不理想
    • 原因:
      • TCP 的慢启动: 传输数据的速度从慢到快
      • 同时开启多个 TCP 连接,那么这些连接会竞争固定的带宽(带宽不足时,TCP 传输速度会变慢)

HTTP/1.0 与 HTTP/1.1 的 区别?

1 连接方面

持久化连接: HTTP1.1 支持持久化连接,减少每次 HTTP 请求都需要建立 TCP 连接的耗时

管道化连接:提高请求效率

2 缓存方面

HTTP1.1 新增了协商缓存的字段 ETag 比 if-None-Match 更加紧准

3 新增 Host 字段

根据 Host 区分同一 IP 服务器上的不同网站

之前只能通过 IP 区分网站

4 请求资源方面

添加范围请求 (206 状态码)

5 新增了请求方法

PUT、HEAD、OPTIONS 等

HTTP/2.0

一个域名只有一个 TCP 长连接传输数据 (避规 HTTP 1.1 的 TCP 慢启动和多个 TCP 连接时竞争带宽资源)

多路复用机制

通过引入二进制分帧层,实现多路复用机制

整体流程整体流程

  1. 浏览器发起请求,经过二进制分帧层将请求拆分成一个个带请求id的帧,发送给服务端
  2. 服务端收到这些帧后,根据请求id组装成完整请求信息,服务端处理完请求后,将响应请求发送到二进制分帧层,经过二进制分帧层转化为一个个带有响应id的帧发送给浏览器
  3. 浏览器收到这些帧后,会组合成一个完整的响应请求

实现基础: HTTP2 是一个二进制协议,在 HTTP/1.1 版中,报文的头信息必须是文本(ASCII 编码),数据体可以是文本,也可以是二进制。HTTP/2 则是一个彻底的二进制协议,头信息和数据体都是二进制,并且统称为"帧",可以分为头信息帧和数据帧。 帧的概念是它实现多路复用的基础

头部压缩

HTTP/2 实现了头信息压缩,由于 HTTP 1.1 协议不带状态,每次请求都必须附上所有信息。所以,请求的很多字段都是重复的,比如 Cookie 和 User Agent ,一模一样的内容,每次请求都必须附带,这会浪费很多带宽,也影响速度。HTTP/2 对这一点做了优化,引入了头信息压缩机制。一方面,头信息使用 gzip 或 compress 压缩后再发送;另一方面,客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就能提高速度了。

设置请求优先级

服务器推送

存在的问题

TCP 协议本身存在的问题:

    1. TCP 的队头阻塞 TCP 传输过程中把一份数据分成多个数据包进行传输,当某个数据包没有按顺序返回,接收端会一直保持连接等待数据包返回,这就阻塞了后续数据包的传输 整体流程
    1. TCP 建立连接需要耗时

优点

多路复用技术能有效利用带宽(只有一个TCP连接),缓解 TCP 慢启动带来的问题,解决了 HTTP 队头阻塞问题,同时还支持设置优先级、服务器推送、头部压缩极大的提高了 HTTP 的传输效率

http2 与 http1 的区别?

  1. 为了解决 HTTP1.1 的队头阻塞问题引入了二进制分帧层
  2. 只建立一个 TCP 连接,解决 HTTP1.1中 TCP 慢启动以及多个 TCP 之间相互竞争带宽问题
  3. 头部压缩,HTTP2 请求头部采用头部压缩,减少数据内容的大小,提高效率
  4. 服务端推送: 服务端可以向客户端推送资源

HTTP3.0

采用UDP + QUIC协议

  1. UDP 可以减少连接耗费的 RTT,加快数据传输
  2. 使用 QUIC 协议,可以使用多路复用、TLS、可靠性传输等 TCP 协议的特点

存在的问题:

  1. 规范的制定和落地有着较大的差异(比如官方的QUIC和谷歌的QUIC协议有较大差异)
  2. 是对底层协议的改造,落地成本高。

HTTP1.0/1.1/2.0有什么区别?

这道题应该从HTTP的发展历史的角度出发

  1. http1.0 在 http0.9 时代新增了图片、视频的传输,同时新增了请求、响应头,支持文件下载,但请求的效率低,因为每个http请求需要一次TCP连接
  2. HTTP1.1 引入了缓存策略、支持长连接keep-alive等,支持PUT/DELETE/OPTION方法,提高了HTTP的传输效率,但并发请求时会有一个HTTP的头部阻塞问题
  3. HTTP2 通过引入二进制分帧层、采用多路复用避规了HTTP的头部阻塞问题,还支持头部压缩,提高HTTP的传输效率,服务端推送

RTT

浏览器发送数据包到服务器 + 浏览器接收到服务器确认接收的数据包的往返时间,成为RTT

- +
Skip to content

HTTP

HTTP 0.9

早期做学术研究使用,只是单纯的文本传输(只有请求行、没有请求头和请求体)

HTTP1.0

支持图片、视频传输,但传输效率太低

核心需求:支持多种类型的文件下载(引入了请求头和响应头)

HTTP1.1

持久连接 keep-alive

在此之前一个 HTTP 请求需要建立一个 TCP 连接

目前浏览器中对于 同一个域名,默认允许同时建立 6 个 TCP 连接

管道化连接

将串行请求改成并行请求

支持虚拟主机

HTTP 根据 Host 去区分同一 IP 物理机子上的不同虚拟主机

对动态生成的内容提供完美支持

Chunk transfer 机制

Cookie、完全机制

主要问题

    1. HTTP/1.1 对头阻塞问题 在 HTTP 中,因为前一条请求因某些原因没有及时返回,会导致后面的请求无法发起,容易导致对头阻塞(串行)。虽然 HTTP1.1 引入了管道化技术尝试解决队头阻塞问题,但服务端还是需要按顺序处理请求并返回,因此阻塞问题依然存在
    1. 带宽利用率不理想
    • 原因:
      • TCP 的慢启动: 传输数据的速度从慢到快
      • 同时开启多个 TCP 连接,那么这些连接会竞争固定的带宽(带宽不足时,TCP 传输速度会变慢)

HTTP/1.0 与 HTTP/1.1 的 区别?

1 连接方面

持久化连接: HTTP1.1 支持持久化连接,减少每次 HTTP 请求都需要建立 TCP 连接的耗时

管道化连接:提高请求效率

2 缓存方面

HTTP1.1 新增了协商缓存的字段 ETag 比 if-None-Match 更加紧准

3 新增 Host 字段

根据 Host 区分同一 IP 服务器上的不同网站

之前只能通过 IP 区分网站

4 请求资源方面

添加范围请求 (206 状态码)

5 新增了请求方法

PUT、HEAD、OPTIONS 等

HTTP/2.0

一个域名只有一个 TCP 长连接传输数据 (避规 HTTP 1.1 的 TCP 慢启动和多个 TCP 连接时竞争带宽资源)

多路复用机制

通过引入二进制分帧层,实现多路复用机制

整体流程整体流程

  1. 浏览器发起请求,经过二进制分帧层将请求拆分成一个个带请求id的帧,发送给服务端
  2. 服务端收到这些帧后,根据请求id组装成完整请求信息,服务端处理完请求后,将响应请求发送到二进制分帧层,经过二进制分帧层转化为一个个带有响应id的帧发送给浏览器
  3. 浏览器收到这些帧后,会组合成一个完整的响应请求

实现基础: HTTP2 是一个二进制协议,在 HTTP/1.1 版中,报文的头信息必须是文本(ASCII 编码),数据体可以是文本,也可以是二进制。HTTP/2 则是一个彻底的二进制协议,头信息和数据体都是二进制,并且统称为"帧",可以分为头信息帧和数据帧。 帧的概念是它实现多路复用的基础

头部压缩

HTTP/2 实现了头信息压缩,由于 HTTP 1.1 协议不带状态,每次请求都必须附上所有信息。所以,请求的很多字段都是重复的,比如 Cookie 和 User Agent ,一模一样的内容,每次请求都必须附带,这会浪费很多带宽,也影响速度。HTTP/2 对这一点做了优化,引入了头信息压缩机制。一方面,头信息使用 gzip 或 compress 压缩后再发送;另一方面,客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就能提高速度了。

设置请求优先级

服务器推送

存在的问题

TCP 协议本身存在的问题:

    1. TCP 的队头阻塞 TCP 传输过程中把一份数据分成多个数据包进行传输,当某个数据包没有按顺序返回,接收端会一直保持连接等待数据包返回,这就阻塞了后续数据包的传输 整体流程
    1. TCP 建立连接需要耗时

优点

多路复用技术能有效利用带宽(只有一个TCP连接),缓解 TCP 慢启动带来的问题,解决了 HTTP 队头阻塞问题,同时还支持设置优先级、服务器推送、头部压缩极大的提高了 HTTP 的传输效率

http2 与 http1 的区别?

  1. 为了解决 HTTP1.1 的队头阻塞问题引入了二进制分帧层
  2. 只建立一个 TCP 连接,解决 HTTP1.1中 TCP 慢启动以及多个 TCP 之间相互竞争带宽问题
  3. 头部压缩,HTTP2 请求头部采用头部压缩,减少数据内容的大小,提高效率
  4. 服务端推送: 服务端可以向客户端推送资源

HTTP3.0

采用UDP + QUIC协议

  1. UDP 可以减少连接耗费的 RTT,加快数据传输
  2. 使用 QUIC 协议,可以使用多路复用、TLS、可靠性传输等 TCP 协议的特点

存在的问题:

  1. 规范的制定和落地有着较大的差异(比如官方的QUIC和谷歌的QUIC协议有较大差异)
  2. 是对底层协议的改造,落地成本高。

HTTP1.0/1.1/2.0有什么区别?

这道题应该从HTTP的发展历史的角度出发

  1. http1.0 在 http0.9 时代新增了图片、视频的传输,同时新增了请求、响应头,支持文件下载,但请求的效率低,因为每个http请求需要一次TCP连接
  2. HTTP1.1 引入了缓存策略、支持长连接keep-alive等,支持PUT/DELETE/OPTION方法,提高了HTTP的传输效率,但并发请求时会有一个HTTP的头部阻塞问题
  3. HTTP2 通过引入二进制分帧层、采用多路复用避规了HTTP的头部阻塞问题,还支持头部压缩,提高HTTP的传输效率,服务端推送

RTT

浏览器发送数据包到服务器 + 浏览器接收到服务器确认接收的数据包的往返时间,成为RTT

+ \ No newline at end of file diff --git "a/guide/\347\275\221\347\273\234\347\233\270\345\205\263/HTTPS.html" "b/guide/\347\275\221\347\273\234\347\233\270\345\205\263/HTTPS.html" index f2314ad4..1418205d 100644 --- "a/guide/\347\275\221\347\273\234\347\233\270\345\205\263/HTTPS.html" +++ "b/guide/\347\275\221\347\273\234\347\233\270\345\205\263/HTTPS.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

HTTPS

HTTP 和 HTTPS 的区别

  1. HTTP 是超文本传输协议,明文传输、简单、无状态,而 HTTPS 是在 HTTP 基础上增加了 SSL 协议,更加安全
  2. HTTP 协议默认端口是 80,HTTPS 协议默认端口是 443
  3. HTTPS 需要 CA 证书、相对于 HTTP 费用更高

HTTPS 演进过程

第一版对称加密 - 不安全

流程

非对称加密 - 传输效率低

流程

对称加密与非对称加密结合 - 存在中间人攻击

流程

通过数字证书校验网站的真实性和获取网站的公钥

之前传输的是密钥,这种方式传输的是装有密钥的保险箱,就算获取到了保险箱,也没有保险箱的钥匙🔑

流程

  1. 浏览器将对称加密方法列表、非对称加密方法列表、随机数 A 传输给服务端
  2. 服务器接受后,将对称加密、非对称加密方法、服务器生成的随机数 B 、数字证书发送给浏览器
  3. 浏览器接受后,验证证书的可靠性,并获取证书内的非对称加密的公钥
  4. 浏览器通过 2 个随机数生成新的随机数 C,并通过非对成加密的公钥对随机数 C 进行加密发送给服务器
  5. 服务器确认后,服务器与浏览器通过 3 个随机数生成对称加密密钥,进行数据传输

如何验证证书的可靠性

  1. 浏览器获取到证书后,通过 CA 相同的 Hash 算法对证书信息进行加密得到摘要 A
  2. 通过 CA 的公钥对证书内的数字签名进行解密,获取到摘要 B
  3. 如果 AB 相同,则证书可靠

什么是 HTTPS 中间人攻击?如何预防?

  1. 先说下 HTTPS 传输过程
  2. 客户端和服务端通信之间,新增一个中间人,伪造 CA 证书和加密数据,获取服务器和客户端的通信信息

流程

如何预防?

使用正规厂商的第三方证书

- +
Skip to content

HTTPS

HTTP 和 HTTPS 的区别

  1. HTTP 是超文本传输协议,明文传输、简单、无状态,而 HTTPS 是在 HTTP 基础上增加了 SSL 协议,更加安全
  2. HTTP 协议默认端口是 80,HTTPS 协议默认端口是 443
  3. HTTPS 需要 CA 证书、相对于 HTTP 费用更高

HTTPS 演进过程

第一版对称加密 - 不安全

流程

非对称加密 - 传输效率低

流程

对称加密与非对称加密结合 - 存在中间人攻击

流程

通过数字证书校验网站的真实性和获取网站的公钥

之前传输的是密钥,这种方式传输的是装有密钥的保险箱,就算获取到了保险箱,也没有保险箱的钥匙🔑

流程

  1. 浏览器将对称加密方法列表、非对称加密方法列表、随机数 A 传输给服务端
  2. 服务器接受后,将对称加密、非对称加密方法、服务器生成的随机数 B 、数字证书发送给浏览器
  3. 浏览器接受后,验证证书的可靠性,并获取证书内的非对称加密的公钥
  4. 浏览器通过 2 个随机数生成新的随机数 C,并通过非对成加密的公钥对随机数 C 进行加密发送给服务器
  5. 服务器确认后,服务器与浏览器通过 3 个随机数生成对称加密密钥,进行数据传输

如何验证证书的可靠性

  1. 浏览器获取到证书后,通过 CA 相同的 Hash 算法对证书信息进行加密得到摘要 A
  2. 通过 CA 的公钥对证书内的数字签名进行解密,获取到摘要 B
  3. 如果 AB 相同,则证书可靠

什么是 HTTPS 中间人攻击?如何预防?

  1. 先说下 HTTPS 传输过程
  2. 客户端和服务端通信之间,新增一个中间人,伪造 CA 证书和加密数据,获取服务器和客户端的通信信息

流程

如何预防?

使用正规厂商的第三方证书

+ \ No newline at end of file diff --git "a/guide/\347\275\221\347\273\234\347\233\270\345\205\263/\345\223\215\345\272\224\346\212\245\346\226\207.html" "b/guide/\347\275\221\347\273\234\347\233\270\345\205\263/\345\223\215\345\272\224\346\212\245\346\226\207.html" index 3f1c8a85..0ccbf296 100644 --- "a/guide/\347\275\221\347\273\234\347\233\270\345\205\263/\345\223\215\345\272\224\346\212\245\346\226\207.html" +++ "b/guide/\347\275\221\347\273\234\347\233\270\345\205\263/\345\223\215\345\272\224\346\212\245\346\226\207.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

响应报文

由响应行、响应头、响应体组成

响应行

由版本、状态码、原因语句组成

状态码

  • 1xx: 请求已被接受,需要继续处理

  • 2xx: 请求已成功处理

    • 200 请求正常处理、命中强缓存
    • 204 请求处理成功,但没有资源返回
    • 206 客户端进行了范围请求,服务端成功执行了这部分 GET 请求
  • 3xx:客户端需要采取进一步操作才能完成

    • 301 永久重定向
    • 302 临时重定向
    • 304 命中协商缓存
  • 4xx: 客户端错误

    • 400 请求存在语法错误
    • 401 用户登录权限不通过
    • 403 用户登录了,但操作权限不通过
    • 404 资源不存在
    • 405 请求行中制定的方法不能被用于请求相应的资源
  • 5xx: 服务端错误

    • 500 服务端报错
    • 504 服务/网关超时

流程

响应头

响应内容相关

  • content-type 内容类型 Content-Type: text/plain;charset=UTF-8
    • 常见的有:
      • application/x-www-form-urlencoded: 浏览器的原生 form 表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。该种方式提交的数据放在 body 里面,数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL转码
      • application/json: 服务器消息主体是序列化后的 JSON 字符串
      • multipart/form-data: 该种方式也是一个常见的 POST 提交方式,通常表单上传文件时使用该种方式。
  • content-length 内容长度

缓存相关

  • Cache-Control
  • Last-Modified
  • ETag

客户端相关

  • Set-Cookie: isGray=true;

跨域相关

  • 简单请求

    • Access-Control-Allow-Origin
  • 非简单请求

    • Access-Control-Allow-Methods
    • Access-Control-Allow-Headers
    • Access-Control-Max-Age
  • Cookie 相关

    • Access-Control-Allow-Credentials: true;

时间相关

Date: Mon, 21 Mar 2022 03:36:53 GMT

响应体

- +
Skip to content

响应报文

由响应行、响应头、响应体组成

响应行

由版本、状态码、原因语句组成

状态码

  • 1xx: 请求已被接受,需要继续处理

  • 2xx: 请求已成功处理

    • 200 请求正常处理、命中强缓存
    • 204 请求处理成功,但没有资源返回
    • 206 客户端进行了范围请求,服务端成功执行了这部分 GET 请求
  • 3xx:客户端需要采取进一步操作才能完成

    • 301 永久重定向
    • 302 临时重定向
    • 304 命中协商缓存
  • 4xx: 客户端错误

    • 400 请求存在语法错误
    • 401 用户登录权限不通过
    • 403 用户登录了,但操作权限不通过
    • 404 资源不存在
    • 405 请求行中制定的方法不能被用于请求相应的资源
  • 5xx: 服务端错误

    • 500 服务端报错
    • 504 服务/网关超时

流程

响应头

响应内容相关

  • content-type 内容类型 Content-Type: text/plain;charset=UTF-8
    • 常见的有:
      • application/x-www-form-urlencoded: 浏览器的原生 form 表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。该种方式提交的数据放在 body 里面,数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL转码
      • application/json: 服务器消息主体是序列化后的 JSON 字符串
      • multipart/form-data: 该种方式也是一个常见的 POST 提交方式,通常表单上传文件时使用该种方式。
  • content-length 内容长度

缓存相关

  • Cache-Control
  • Last-Modified
  • ETag

客户端相关

  • Set-Cookie: isGray=true;

跨域相关

  • 简单请求

    • Access-Control-Allow-Origin
  • 非简单请求

    • Access-Control-Allow-Methods
    • Access-Control-Allow-Headers
    • Access-Control-Max-Age
  • Cookie 相关

    • Access-Control-Allow-Credentials: true;

时间相关

Date: Mon, 21 Mar 2022 03:36:53 GMT

响应体

+ \ No newline at end of file diff --git "a/guide/\347\275\221\347\273\234\347\233\270\345\205\263/\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.html" "b/guide/\347\275\221\347\273\234\347\233\270\345\205\263/\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.html" index 6374bd11..7bc22fa6 100644 --- "a/guide/\347\275\221\347\273\234\347\233\270\345\205\263/\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.html" +++ "b/guide/\347\275\221\347\273\234\347\233\270\345\205\263/\345\270\270\350\247\201\347\232\204\351\227\256\351\242\230.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content
- +
Skip to content
+ \ No newline at end of file diff --git "a/guide/\347\275\221\347\273\234\347\233\270\345\205\263/\346\246\202\350\246\201.html" "b/guide/\347\275\221\347\273\234\347\233\270\345\205\263/\346\246\202\350\246\201.html" index 42bddc34..73520d93 100644 --- "a/guide/\347\275\221\347\273\234\347\233\270\345\205\263/\346\246\202\350\246\201.html" +++ "b/guide/\347\275\221\347\273\234\347\233\270\345\205\263/\346\246\202\350\246\201.html" @@ -12,7 +12,7 @@ - + @@ -24,8 +24,8 @@ -
Skip to content
- +
Skip to content
+ \ No newline at end of file diff --git "a/guide/\347\275\221\347\273\234\347\233\270\345\205\263/\350\257\267\346\261\202\346\212\245\346\226\207.html" "b/guide/\347\275\221\347\273\234\347\233\270\345\205\263/\350\257\267\346\261\202\346\212\245\346\226\207.html" index 4a5d8b79..a8f4fe9d 100644 --- "a/guide/\347\275\221\347\273\234\347\233\270\345\205\263/\350\257\267\346\261\202\346\212\245\346\226\207.html" +++ "b/guide/\347\275\221\347\273\234\347\233\270\345\205\263/\350\257\267\346\261\202\346\212\245\346\226\207.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

请求报文

由请求行、请求头、请求体组成

请求行

由请求方法、URI、协议版本组成

流程

请求方法

  1. GET 请求获取资源
  2. POST 提交数据
  3. PUT 更新资源
  4. DELETE 删除资源
  5. OPTIONS 查询针对请求 URL 指定的资源支持的方法(常用在非简单请求的预检上)
  6. HEAD 获取响应头
  7. CONNECT 要求用隧道协议链接代理
  8. TRACE 追踪请求经过的路径

URI 字段

协议版本

HTTP0.9、 HTTP1.0、HTTP1.1、HTTP2.0、HTTP3.0

请求头

接受内容相关

  1. Accept 浏览器接受的格式 Accept: application/json, text/plain, /
  2. Accept-Encoding 浏览器接受的压缩格式 Accept-Encoding: gzip, deflate, br
  3. Accept-Language 浏览器接受的语言 Accept-Language: zh-CN
  4. Accept-Charset 浏览器接受的字符集

强缓存相关

  1. Cache-Control

协商缓存相关

  1. If-Modified-Since 上一次访问时文件的更改时间 (存在校验问题,比如文件内容只是添加了空格,但是 Last-Modified 改变了)
  2. If-None-Match 上次访问的 ETag 信息 (如果 If-None-Match 和 ETag 一致,则命中 304 协商缓存)

请求域名相关

  1. HOST HTTP 请求的域名
  2. Origin 页面域名 (常用于防止 CSRF 攻击和跨域请求)
  3. Referer 发出请求的页面 URL

客户端相关

  • UA
  • COOKIE

连接相关

  • Connection Connection: keep-alive

流程

请求体

- +
Skip to content

请求报文

由请求行、请求头、请求体组成

请求行

由请求方法、URI、协议版本组成

流程

请求方法

  1. GET 请求获取资源
  2. POST 提交数据
  3. PUT 更新资源
  4. DELETE 删除资源
  5. OPTIONS 查询针对请求 URL 指定的资源支持的方法(常用在非简单请求的预检上)
  6. HEAD 获取响应头
  7. CONNECT 要求用隧道协议链接代理
  8. TRACE 追踪请求经过的路径

URI 字段

协议版本

HTTP0.9、 HTTP1.0、HTTP1.1、HTTP2.0、HTTP3.0

请求头

接受内容相关

  1. Accept 浏览器接受的格式 Accept: application/json, text/plain, /
  2. Accept-Encoding 浏览器接受的压缩格式 Accept-Encoding: gzip, deflate, br
  3. Accept-Language 浏览器接受的语言 Accept-Language: zh-CN
  4. Accept-Charset 浏览器接受的字符集

强缓存相关

  1. Cache-Control

协商缓存相关

  1. If-Modified-Since 上一次访问时文件的更改时间 (存在校验问题,比如文件内容只是添加了空格,但是 Last-Modified 改变了)
  2. If-None-Match 上次访问的 ETag 信息 (如果 If-None-Match 和 ETag 一致,则命中 304 协商缓存)

请求域名相关

  1. HOST HTTP 请求的域名
  2. Origin 页面域名 (常用于防止 CSRF 攻击和跨域请求)
  3. Referer 发出请求的页面 URL

客户端相关

  • UA
  • COOKIE

连接相关

  • Connection Connection: keep-alive

流程

请求体

+ \ No newline at end of file diff --git "a/guide/\347\275\221\347\273\234\347\233\270\345\205\263/\350\267\250\345\237\237\350\257\267\346\261\202.html" "b/guide/\347\275\221\347\273\234\347\233\270\345\205\263/\350\267\250\345\237\237\350\257\267\346\261\202.html" index 1581c697..4edf3b95 100644 --- "a/guide/\347\275\221\347\273\234\347\233\270\345\205\263/\350\267\250\345\237\237\350\257\267\346\261\202.html" +++ "b/guide/\347\275\221\347\273\234\347\233\270\345\205\263/\350\267\250\345\237\237\350\257\267\346\261\202.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

跨域请求

简单请求

若请求满足所有下述条件,则该请求可视为简单请求:

  1. HEAD/GET/POST 请求
  2. Content-Type: text/plain、multipart/form-data、application/x-www-form-urlencoded
  3. 除了被用户代理自动设置的标头字段,剩下的请求头是: Accept、Accept-Language、Content-Language、Content-Type、Range

请求过程

  1. 发起请求,请求头会带上 Origin 字段,该字段用来说明请求来自哪个源(协议 + 域名 + 端口),服务器根据这个值决定是否同意这次请求
  2. 当服务器接收到请求后,根据 Origin 判断是否在允许的范围内
  3. 如果不在范围内,服务器会返回一个正常的 HTTP 响应,浏览器发现响应头信息没有 Access-Control-Allow-Origin 字段,就知道出错了,从而抛出错误,被 XML 的 onerror 回调函数捕获。(注意:由于正常响应,其状态码为200,因此该错误不能通过状态码识别)
  4. 如果 Origin 指定的域名在范围内,服务器返回的响应会多出几个头信息字段(Access-Control-Allow-Origin、Access-Control-Allow-Credentials、Access-Control-Expose-Header 等)

流程

非简单请求

请求方法是 PUT、DELETE 或者 Content-Type 是 application/json 类型

请求过程 (源、请求头、方法、缓存、Cookie)

  1. 浏览器发起 Option 预检请求
  2. 服务器收到预检请求以后,检查了 Origin、Access-Control-Request-Method 和 Access-Control-Request-Headers 字段后,确认允许跨域请求,就可以做出回应
    • Origin (必须): 发起请求的源信息
    • Access-Control-Request-Method(必须): 用来列出浏览器的 CORS 请求会用到哪些 HTTP 方法
    • Access-Control-Request-Headers 跨域请求而外的请求头字段
  3. 如果服务器预检请求,会返回一个正常的 HTTP 回应,但没有任何的 CORS 相关的头信息字段,这时浏览器就会认定服务器不同意预检请求,触发错误。
  4. 如果服务器通过了预检请求,以后每次浏览器正常的 CORS 请求就跟简单请求一样
    • Access-Control-Allow-Origin(必须): 运行哪些源跨域,如果是 * 无法携带 Cookie
    • Access-Control-Allow-Method(必须): 服务器支持哪些请求
    • Access-Control-Allow-Header: 服务器支持的头信息字段
    • Access-Control-Max-Age: 预检请求的有效期,单位秒

流程

  1. 响应头设置 Access-Control-Allow-Credentials 等于 true
  2. Access-Control-Allow-Origin 不能设置成 * (Cookie 的 SameSite 属性如果是 Lax 可能也会导致带不上去)
  3. 前端设置 withCredentials: true

常见的问题

cookie 一般用于登录验证,存储用户信息,大小为 4KB,会随着网络请求携带给服务端

session 一般存储在服务端,常用于与 Cookie 配合做登录检验

  • cookie 是 HTTP 的内容,token 是自定义的数据
  • cookie 可以默认存储在浏览器中,token 需要自行存储
  • token 没有跨域限制,cookie 存在跨域限制
  • token 常用于 CSRF 或者 JWT(JSON WEB TOKEN)
  • Cookie 常于 Session 配合,做用户登录鉴权
  • 基本属性:

    • name
    • value
  • 访问性:

    • expire
    • path
    • domain
  • 安全性:

    • secure
    • httpOnly
    • sameSite

Session 和 JWT 哪个更合适?

  • Session

    • 优点:
      1. 易于学习
      2. 用户信息存储在服务器,可以快速封禁某个用户
    • 缺点:
      1. 占用服务器资源,硬件成本高
      2. 多进程、多服务器时,不好同步 (需要第三方缓存, Redis)
      3. Session 需要配合 Cookie 使用,cookie 有域名限制
  • Json Web Token

    • 优点:
      1. 存储在客户端,不占用服务端资源
      2. 易于同步
      3. 没有跨域限制
    • 缺点:
      1. 无法快速封禁用户
      2. Token 不安全,一但秘钥被泄漏,容易窃取用户信息
      3. Token很大,影响请求体积
  • 使用场景:

    • 用户信息安全 -> 使用 Session
    • 没有特殊要求 -> 使用 JWT

如何实现 SSO 单点登录

Cookie 默认跨域不共享

可以通过设置 Cookie 的 domain 为相同的主域名,即可共享 Cookie

比如 www.baidu.com、image.baidu.com 主域名是相同的,设置 cookie domain 为主域名,即可共享 cookie

流程

如果主域名不一致

  1. 使用 SSO 第三方登录, 获取 ticket 返回给 A、B 系统

流程

  1. OAuth2.0

第三方登录(例如微信扫码登录)

流程

- +
Skip to content

跨域请求

简单请求

若请求满足所有下述条件,则该请求可视为简单请求:

  1. HEAD/GET/POST 请求
  2. Content-Type: text/plain、multipart/form-data、application/x-www-form-urlencoded
  3. 除了被用户代理自动设置的标头字段,剩下的请求头是: Accept、Accept-Language、Content-Language、Content-Type、Range

请求过程

  1. 发起请求,请求头会带上 Origin 字段,该字段用来说明请求来自哪个源(协议 + 域名 + 端口),服务器根据这个值决定是否同意这次请求
  2. 当服务器接收到请求后,根据 Origin 判断是否在允许的范围内
  3. 如果不在范围内,服务器会返回一个正常的 HTTP 响应,浏览器发现响应头信息没有 Access-Control-Allow-Origin 字段,就知道出错了,从而抛出错误,被 XML 的 onerror 回调函数捕获。(注意:由于正常响应,其状态码为200,因此该错误不能通过状态码识别)
  4. 如果 Origin 指定的域名在范围内,服务器返回的响应会多出几个头信息字段(Access-Control-Allow-Origin、Access-Control-Allow-Credentials、Access-Control-Expose-Header 等)

流程

非简单请求

请求方法是 PUT、DELETE 或者 Content-Type 是 application/json 类型

请求过程 (源、请求头、方法、缓存、Cookie)

  1. 浏览器发起 Option 预检请求
  2. 服务器收到预检请求以后,检查了 Origin、Access-Control-Request-Method 和 Access-Control-Request-Headers 字段后,确认允许跨域请求,就可以做出回应
    • Origin (必须): 发起请求的源信息
    • Access-Control-Request-Method(必须): 用来列出浏览器的 CORS 请求会用到哪些 HTTP 方法
    • Access-Control-Request-Headers 跨域请求而外的请求头字段
  3. 如果服务器预检请求,会返回一个正常的 HTTP 回应,但没有任何的 CORS 相关的头信息字段,这时浏览器就会认定服务器不同意预检请求,触发错误。
  4. 如果服务器通过了预检请求,以后每次浏览器正常的 CORS 请求就跟简单请求一样
    • Access-Control-Allow-Origin(必须): 运行哪些源跨域,如果是 * 无法携带 Cookie
    • Access-Control-Allow-Method(必须): 服务器支持哪些请求
    • Access-Control-Allow-Header: 服务器支持的头信息字段
    • Access-Control-Max-Age: 预检请求的有效期,单位秒

流程

  1. 响应头设置 Access-Control-Allow-Credentials 等于 true
  2. Access-Control-Allow-Origin 不能设置成 * (Cookie 的 SameSite 属性如果是 Lax 可能也会导致带不上去)
  3. 前端设置 withCredentials: true

常见的问题

cookie 一般用于登录验证,存储用户信息,大小为 4KB,会随着网络请求携带给服务端

session 一般存储在服务端,常用于与 Cookie 配合做登录检验

  • cookie 是 HTTP 的内容,token 是自定义的数据
  • cookie 可以默认存储在浏览器中,token 需要自行存储
  • token 没有跨域限制,cookie 存在跨域限制
  • token 常用于 CSRF 或者 JWT(JSON WEB TOKEN)
  • Cookie 常于 Session 配合,做用户登录鉴权
  • 基本属性:

    • name
    • value
  • 访问性:

    • expire
    • path
    • domain
  • 安全性:

    • secure
    • httpOnly
    • sameSite

Session 和 JWT 哪个更合适?

  • Session

    • 优点:
      1. 易于学习
      2. 用户信息存储在服务器,可以快速封禁某个用户
    • 缺点:
      1. 占用服务器资源,硬件成本高
      2. 多进程、多服务器时,不好同步 (需要第三方缓存, Redis)
      3. Session 需要配合 Cookie 使用,cookie 有域名限制
  • Json Web Token

    • 优点:
      1. 存储在客户端,不占用服务端资源
      2. 易于同步
      3. 没有跨域限制
    • 缺点:
      1. 无法快速封禁用户
      2. Token 不安全,一但秘钥被泄漏,容易窃取用户信息
      3. Token很大,影响请求体积
  • 使用场景:

    • 用户信息安全 -> 使用 Session
    • 没有特殊要求 -> 使用 JWT

如何实现 SSO 单点登录

Cookie 默认跨域不共享

可以通过设置 Cookie 的 domain 为相同的主域名,即可共享 Cookie

比如 www.baidu.com、image.baidu.com 主域名是相同的,设置 cookie domain 为主域名,即可共享 cookie

流程

如果主域名不一致

  1. 使用 SSO 第三方登录, 获取 ticket 返回给 A、B 系统

流程

  1. OAuth2.0

第三方登录(例如微信扫码登录)

流程

+ \ No newline at end of file diff --git a/hashmap.json b/hashmap.json index 824fcd93..ee973665 100644 --- a/hashmap.json +++ b/hashmap.json @@ -1 +1 @@ -{"guide_网络相关_跨域请求.md":"2626dc46","shoot_实战技巧_如何拍雨丝.md":"c8378969","guide_react_react与vue的区别.md":"a4cc8156","guide_react_react中的事件机制.md":"125ce9e6","guide_css相关_对 line-height 的理解及其赋值方式.md":"91a29d6d","guide_node相关_概要.md":"914ab426","shoot_基础概念_光圈.md":"6fcc955a","guide_javascript相关_垃圾回收机制.md":"e3ad0c7a","guide_canvas_通过上下分层优化canvas书写性能.md":"ef016078","guide_canvas_如何在canvas画板上自由书写.md":"984beaeb","guide_css相关_隐藏元素的方法.md":"b8d72453","guide_react_如何设计react组件.md":"d49001fb","guide_canvas_通过离屏渲染提高canvas书写性能.md":"c3dc05ff","shoot_实战技巧_拍摄梦幻光斑.md":"ab138890","guide_react_react为什么要使用jsx.md":"917208ca","guide_javascript相关_es6相关.md":"bd6110d8","guide_网络相关_https.md":"24fcb37f","guide_javascript相关_定义.md":"ede1ac70","guide_javascript相关_数据类型.md":"78b17d35","guide_css相关_display.md":"1eb7437c","guide_css相关_display、visibility、opacity区别.md":"79a76e72","guide_javascript相关_字符串常见的api.md":"f8114998","guide_css相关_概要.md":"28c775f1","guide_react_什么是fiber.md":"3ee10b32","guide_webpack_index.md":"e15e3d26","guide_css相关_position.md":"cc780e52","guide_react_react组件是如何通信的.md":"20eef01c","guide_网络相关_请求报文.md":"ccdffe1b","guide_javascript相关_事件循环机制.md":"050f60d8","guide_网络相关_响应报文.md":"2f7e04b4","guide_css相关_bfc.md":"0b433659","guide_网络相关_概要.md":"3cfbfdfd","guide_css相关_display、float、position的关系.md":"1fe9ac57","shoot_实战技巧_如何拍花的黑背景.md":"647a17e0","index.md":"57af2e65","shoot_基础概念_快门速度.md":"0fea1225","shoot_基础概念_iso感光度.md":"f82c77cc","guide_react_react是什么.md":"bd2dae02","guide_javascript相关_dom相关.md":"016710fe","guide_javascript相关_javascript执行机制.md":"912ab316","guide_react_setstate是同步还是异步的.md":"181019e4","guide_javascript相关_javascript编译机制.md":"1bf41186","guide_javascript相关_promise.md":"fa3d3914","guide_网络相关_常见的问题.md":"e25938b4","guide_javascript相关_基础概念.md":"6cb63943","guide_javascript相关_对象常见的api.md":"fa4ed7c9","guide_react_diff算法.md":"e7fed7ec","guide_浏览器相关_浏览器进程架构.md":"13fb4bd1","guide_canvas_可视区域内渲染提高canvas书写性能.md":"3686d5ec","guide_浏览器相关_浏览器内核.md":"ac5651f8","guide_javascript相关_新的运算符.md":"4ef7cdb7","guide_网络相关_get请求和post请求的区别.md":"5e98e509","guide_网络相关_dns.md":"e56a26c8","guide_浏览器相关_浏览器安全.md":"0e2ad803","guide_javascript相关_正则表达式.md":"9ee8e248","guide_react_常见的问题.md":"fc7d945a","guide_redux_源码解读.md":"b8a89f65","guide_react_react异常机制.md":"b97e740a","guide_canvas_通过贝塞尔曲线优化canvas书写性能.md":"acad2b6c","guide_网络相关_cdn.md":"c26e601b","guide_webpack_构建流程.md":"379b02b0","guide_javascript相关_index.md":"b2d97d4d","guide_网络相关_http.md":"22d66eca","guide_canvas_通过 offscreencanvas _ worker 提高书写性能.md":"18a4aa5f","guide_react_react中的异常机制.md":"44ac2de8","guide_浏览器相关_浏览器渲染流程.md":"a1f24938","guide_javascript相关_数组常见的api.md":"4cdc62b7","guide_javascript相关_js异常捕获机制.md":"93a23d57","guide_浏览器相关_浏览器缓存.md":"8cddcc95","guide_javascript相关_继承相关.md":"237c7c62","guide_canvas_canvas尺寸及分辨率矫正.md":"5236c485","guide_redux_设计理念.md":"ec673eba","guide_react_react是如何渲染的.md":"3113f4a0","guide_浏览器相关_概要.md":"1965a3c6","guide_react_react中的性能优化.md":"581ed9f6"} +{"guide_node相关_概要.md":"632ffa2f","guide_react_react为什么要使用jsx.md":"d1fcafa8","guide_javascript相关_新的运算符.md":"d9d1e0c1","guide_javascript相关_正则表达式.md":"37761b31","guide_webpack_index.md":"f2414c6a","guide_网络相关_概要.md":"3b48bb07","guide_canvas_如何在canvas画板上自由书写.md":"b9949f49","guide_css相关_position.md":"f6e57cb3","guide_网络相关_cdn.md":"e85fe02e","guide_css相关_对 line-height 的理解及其赋值方式.md":"7b9b530a","guide_css相关_概要.md":"20b96226","guide_redux_设计理念.md":"b1a2b96a","guide_react_react是什么.md":"6fb31cb5","guide_浏览器相关_概要.md":"f313a7ec","guide_网络相关_dns.md":"3f43cbe6","guide_网络相关_http.md":"3d19dae2","guide_javascript相关_index.md":"ff95dc7a","guide_css相关_display、float、position的关系.md":"1a5ef489","guide_浏览器相关_浏览器渲染流程.md":"1331606e","guide_javascript相关_es6相关.md":"98a38a5e","guide_javascript相关_数组常见的api.md":"2dc845e4","guide_css相关_隐藏元素的方法.md":"49a19e25","guide_canvas_可视区域内渲染提高canvas书写性能.md":"419e5315","guide_javascript相关_dom相关.md":"bd7d10f3","guide_浏览器相关_浏览器内核.md":"9cd84d74","guide_css相关_bfc.md":"0cc3082f","guide_网络相关_请求报文.md":"715db4fc","guide_react_react与vue的区别.md":"5fd109fc","guide_css相关_display、visibility、opacity区别.md":"5aec2cb5","guide_浏览器相关_浏览器进程架构.md":"1b1db83e","guide_react_react是如何渲染的.md":"b469a419","guide_javascript相关_垃圾回收机制.md":"6755966f","guide_javascript相关_定义.md":"c58c5632","index.md":"a6c2532f","guide_react_react组件是如何通信的.md":"72c5ac4e","guide_浏览器相关_浏览器缓存.md":"88373219","guide_网络相关_get请求和post请求的区别.md":"5b02925b","guide_css相关_display.md":"24ba2b32","guide_javascript相关_promise.md":"adc6aed9","guide_webpack_构建流程.md":"07f4ea79","guide_javascript相关_javascript编译机制.md":"6b3e2f0d","guide_javascript相关_js异常捕获机制.md":"1e9b4755","guide_canvas_通过 offscreencanvas _ worker 提高书写性能.md":"10b7092a","guide_网络相关_常见的问题.md":"3b584d49","guide_网络相关_响应报文.md":"e9c73579","guide_网络相关_https.md":"4c7346fd","guide_javascript相关_对象常见的api.md":"4eca8a1e","guide_javascript相关_javascript执行机制.md":"8aebbf95","guide_react_diff算法.md":"926d46b2","guide_react_setstate是同步还是异步的.md":"89186477","guide_react_react异常机制.md":"6a032df0","guide_react_常见的问题.md":"4f1f1ac9","guide_react_如何设计react组件.md":"195ded5e","guide_react_什么是fiber.md":"ec244869","shoot_基础概念_快门速度.md":"9e05d8bb","shoot_基础概念_iso感光度.md":"1470d204","shoot_实战技巧_如何拍雨丝.md":"5a2c1fb7","guide_浏览器相关_浏览器安全.md":"cda4119d","guide_react_react中的性能优化.md":"8eb2e33c","shoot_实战技巧_拍摄梦幻光斑.md":"345608b9","guide_javascript相关_事件循环机制.md":"4ff87ac5","guide_javascript相关_数据类型.md":"d9e46f31","guide_javascript相关_继承相关.md":"0b549acd","shoot_基础概念_光圈.md":"ae3bc87c","shoot_实战技巧_如何拍花的黑背景.md":"013683af","guide_react_react中的事件机制.md":"9d3f4079","guide_网络相关_跨域请求.md":"f2530ac2","guide_react_react中的异常机制.md":"67ec8db4","guide_canvas_通过上下分层优化canvas书写性能.md":"2eca7891","guide_javascript相关_字符串常见的api.md":"19aad48b","guide_javascript相关_基础概念.md":"dcfd312c","guide_redux_源码解读.md":"dc2eca87","guide_canvas_通过贝塞尔曲线优化canvas书写性能.md":"c136fb49","guide_canvas_canvas尺寸及分辨率矫正.md":"a8665ee4","guide_canvas_通过离屏渲染提高canvas书写性能.md":"af60bf99"} diff --git a/index.html b/index.html index 5cbb3175..bb2c476f 100644 --- a/index.html +++ b/index.html @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

个人知识库

👋 欢迎来到我的博客,这里是我记录学习和生活的地方,希望能帮助到你

采用 VitePress 进行构建,为了有更好的阅读体验,请使用新版本浏览器

- +
Skip to content

个人知识库

👋 欢迎来到我的博客,这里是我记录学习和生活的地方,希望能帮助到你

采用 VitePress 进行构建,为了有更好的阅读体验,请使用新版本浏览器

+ \ No newline at end of file diff --git "a/shoot/\345\237\272\347\241\200\346\246\202\345\277\265/ISO\346\204\237\345\205\211\345\272\246.html" "b/shoot/\345\237\272\347\241\200\346\246\202\345\277\265/ISO\346\204\237\345\205\211\345\272\246.html" index 23fe06ec..0f514776 100644 --- "a/shoot/\345\237\272\347\241\200\346\246\202\345\277\265/ISO\346\204\237\345\205\211\345\272\246.html" +++ "b/shoot/\345\237\272\347\241\200\346\246\202\345\277\265/ISO\346\204\237\345\205\211\345\272\246.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

ISO 感光度

传感器对光线的敏感程度

  • 感光度越大、图片越亮,但也容易出现噪点
- +
Skip to content

ISO 感光度

传感器对光线的敏感程度

  • 感光度越大、图片越亮,但也容易出现噪点
+ \ No newline at end of file diff --git "a/shoot/\345\237\272\347\241\200\346\246\202\345\277\265/\345\205\211\345\234\210.html" "b/shoot/\345\237\272\347\241\200\346\246\202\345\277\265/\345\205\211\345\234\210.html" index 2a0118b2..b1f58f04 100644 --- "a/shoot/\345\237\272\347\241\200\346\246\202\345\277\265/\345\205\211\345\234\210.html" +++ "b/shoot/\345\237\272\347\241\200\346\246\202\345\277\265/\345\205\211\345\234\210.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

光圈

控制光圈大小

  1. 数字越大、光圈越小就越暗 - 图像越清晰
  2. 数字越小、光圈越大就越亮 - 光圈过大虚化效果明显
- +
Skip to content

光圈

控制光圈大小

  1. 数字越大、光圈越小就越暗 - 图像越清晰
  2. 数字越小、光圈越大就越亮 - 光圈过大虚化效果明显
+ \ No newline at end of file diff --git "a/shoot/\345\237\272\347\241\200\346\246\202\345\277\265/\345\277\253\351\227\250\351\200\237\345\272\246.html" "b/shoot/\345\237\272\347\241\200\346\246\202\345\277\265/\345\277\253\351\227\250\351\200\237\345\272\246.html" index f9c0eb49..561cbd01 100644 --- "a/shoot/\345\237\272\347\241\200\346\246\202\345\277\265/\345\277\253\351\227\250\351\200\237\345\272\246.html" +++ "b/shoot/\345\237\272\347\241\200\346\246\202\345\277\265/\345\277\253\351\227\250\351\200\237\345\272\246.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

快门速度

控制开启传感器的时间

  • 快门速度越短,越能凝固物体,常用在抓拍
  • 快门速度越长,容易得到拖影的图
    • 快门速度
    • 拍静止的水面 (一般需要借助三脚架)
- +
Skip to content

快门速度

控制开启传感器的时间

  • 快门速度越短,越能凝固物体,常用在抓拍
  • 快门速度越长,容易得到拖影的图
    • 快门速度
    • 拍静止的水面 (一般需要借助三脚架)
+ \ No newline at end of file diff --git "a/shoot/\345\256\236\346\210\230\346\212\200\345\267\247/\345\246\202\344\275\225\346\213\215\350\212\261\347\232\204\351\273\221\350\203\214\346\231\257.html" "b/shoot/\345\256\236\346\210\230\346\212\200\345\267\247/\345\246\202\344\275\225\346\213\215\350\212\261\347\232\204\351\273\221\350\203\214\346\231\257.html" index 84d6a89e..7d8ff6cc 100644 --- "a/shoot/\345\256\236\346\210\230\346\212\200\345\267\247/\345\246\202\344\275\225\346\213\215\350\212\261\347\232\204\351\273\221\350\203\214\346\231\257.html" +++ "b/shoot/\345\256\236\346\210\230\346\212\200\345\267\247/\345\246\202\344\275\225\346\213\215\350\212\261\347\232\204\351\273\221\350\203\214\346\231\257.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

如何拍花

  1. 采用 点测光 突出花的亮度
  2. 背景采用 深色系 突出主体
- +
Skip to content

如何拍花

  1. 采用 点测光 突出花的亮度
  2. 背景采用 深色系 突出主体
+ \ No newline at end of file diff --git "a/shoot/\345\256\236\346\210\230\346\212\200\345\267\247/\345\246\202\344\275\225\346\213\215\351\233\250\344\270\235.html" "b/shoot/\345\256\236\346\210\230\346\212\200\345\267\247/\345\246\202\344\275\225\346\213\215\351\233\250\344\270\235.html" index 68bc1ffa..a4a5a04c 100644 --- "a/shoot/\345\256\236\346\210\230\346\212\200\345\267\247/\345\246\202\344\275\225\346\213\215\351\233\250\344\270\235.html" +++ "b/shoot/\345\256\236\346\210\230\346\212\200\345\267\247/\345\246\202\344\275\225\346\213\215\351\233\250\344\270\235.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

如何拍雨丝

灯位要求

需要俩盏灯

  • 逆光灯: 在拍摄物体后方 (容易拍摄到雨丝,而且物体会有光边效果)
  • 正光灯:在拍摄物体前方(避免物体逆光,变黑)

逆光灯亮度 > 主光灯

  • 灯位要求

白平衡

如果拍摄物体偏黄,可以调低白平衡,使物体变白

快门速度

  • 快门速度越慢,雨水成丝
  • 快门速度越快,雨水成点
- +
Skip to content

如何拍雨丝

灯位要求

需要俩盏灯

  • 逆光灯: 在拍摄物体后方 (容易拍摄到雨丝,而且物体会有光边效果)
  • 正光灯:在拍摄物体前方(避免物体逆光,变黑)

逆光灯亮度 > 主光灯

灯位要求

白平衡

如果拍摄物体偏黄,可以调低白平衡,使物体变白

快门速度

  • 快门速度越慢,雨水成丝
  • 快门速度越快,雨水成点
+ \ No newline at end of file diff --git "a/shoot/\345\256\236\346\210\230\346\212\200\345\267\247/\346\213\215\346\221\204\346\242\246\345\271\273\345\205\211\346\226\221.html" "b/shoot/\345\256\236\346\210\230\346\212\200\345\267\247/\346\213\215\346\221\204\346\242\246\345\271\273\345\205\211\346\226\221.html" index 700cc303..46e11e12 100644 --- "a/shoot/\345\256\236\346\210\230\346\212\200\345\267\247/\346\213\215\346\221\204\346\242\246\345\271\273\345\205\211\346\226\221.html" +++ "b/shoot/\345\256\236\346\210\230\346\212\200\345\267\247/\346\213\215\346\221\204\346\242\246\345\271\273\345\205\211\346\226\221.html" @@ -11,7 +11,7 @@ - + @@ -23,8 +23,8 @@ -
Skip to content

拍摄梦幻光斑

采用大光圈镜头,有很好的背景虚化效果

需要一个补光灯,减少避免物体逆光导致过黑

  • 拍摄物体在光斑前面
  • 对焦到物体上(也可以通过精细对焦,即放大后手动对焦)
- +
Skip to content

拍摄梦幻光斑

采用大光圈镜头,有很好的背景虚化效果

需要一个补光灯,减少避免物体逆光导致过黑

  • 拍摄物体在光斑前面
  • 对焦到物体上(也可以通过精细对焦,即放大后手动对焦)
+ \ No newline at end of file