[{"data":1,"prerenderedAt":2438},["ShallowReactive",2],{"page-\u002Fvue\u002Fvue首屏性能优化组件":3},{"id":4,"title":5,"body":6,"description":2431,"extension":2432,"meta":2433,"navigation":151,"path":2434,"seo":2435,"stem":2436,"__hash__":2437},"content\u002FVue\u002FVue首屏性能优化组件.md","Vue首屏性能优化组件",{"type":7,"value":8,"toc":2422},"minimark",[9,13,37,41,70,74,110,219,431,440,501,509,512,524,546,589,592,707,1507,2401,2404,2410,2413,2419],[10,11,5],"h1",{"id":12},"vue首屏性能优化组件",[14,15,16,17,21,22,25,26,28,29,32,33,36],"p",{},"简单实现一个",[18,19,20],"code",{},"Vue","首屏性能优化组件，现代化浏览器提供了很多新接口，在不考虑",[18,23,24],{},"IE","兼容性的情况下，这些接口可以很大程度上减少编写代码的工作量以及做一些性能优化方面的事情，当然为了考虑",[18,27,24],{},"我们也可以在封装组件的时候为其兜底，本文的首屏性能优化组件主要是使用",[18,30,31],{},"IntersectionObserver","以及",[18,34,35],{},"requestIdleCallback","两个接口。",[38,39,40],"h2",{"id":40},"描述",[14,42,43,44,46,47,50,51,54,55,58,59,61,62,65,66,69],{},"先考虑首屏场景，当做一个主要为展示用的首屏时，通常会加载较多的资源例如图片等，如果我们不想在用户打开时就加载所有资源，而是希望用户滚动到相关位置时再加载组件，此时就可以选择",[18,45,31],{},"这个接口，当然也可以使用",[18,48,49],{},"onscroll","事件去做一个监听，只不过这样性能可能比较差一些。还有一些组件，我们希望他必须要加载，但是又不希望他在初始化页面时同步加载，这样我们可以使用异步的方式比如",[18,52,53],{},"Promise","和",[18,56,57],{},"setTimeout","等，但是如果想再降低这个组件加载的优先级，我们就可以考虑",[18,60,35],{},"这个接口，相关代码在",[18,63,64],{},"https:\u002F\u002Fgithub.com\u002FWindrunnerMax\u002Fwebpack-simple-environment","的",[18,67,68],{},"vue--first-screen-optimization","分支。",[71,72,31],"h3",{"id":73},"intersectionobserver",[14,75,76,78,79,82,83,86,87,89,90,93,94,97,98,101,102,105,106,109],{},[18,77,31],{},"接口，从属于",[18,80,81],{},"Intersection Observer API","，提供了一种异步观察目标元素与其祖先元素或顶级文档视窗",[18,84,85],{},"viewport","交叉状态的方法，祖先元素与视窗",[18,88,85],{},"被称为根",[18,91,92],{},"root","，也就是说",[18,95,96],{},"IntersectionObserver API","，可以自动观察元素是否可见，由于可见",[18,99,100],{},"visible","的本质是，目标元素与视口产生一个交叉区，所以这个",[18,103,104],{},"API","叫做交叉观察器，兼容性",[18,107,108],{},"https:\u002F\u002Fcaniuse.com\u002F?search=IntersectionObserver","。",[111,112,117],"pre",{"className":113,"code":114,"language":115,"meta":116,"style":116},"language-javascript shiki shiki-themes github-light github-dark","const io = new IntersectionObserver(callback, option);\n\n\u002F\u002F 开始观察\nio.observe(document.getElementById(\"example\"));\n\u002F\u002F 停止观察\nio.unobserve(element);\n\u002F\u002F 关闭观察器\nio.disconnect();\n","javascript","",[18,118,119,146,153,160,185,191,202,208],{"__ignoreMap":116},[120,121,124,128,132,135,138,142],"span",{"class":122,"line":123},"line",1,[120,125,127],{"class":126},"szBVR","const",[120,129,131],{"class":130},"sj4cs"," io",[120,133,134],{"class":126}," =",[120,136,137],{"class":126}," new",[120,139,141],{"class":140},"sScJk"," IntersectionObserver",[120,143,145],{"class":144},"sVt8B","(callback, option);\n",[120,147,149],{"class":122,"line":148},2,[120,150,152],{"emptyLinePlaceholder":151},true,"\n",[120,154,156],{"class":122,"line":155},3,[120,157,159],{"class":158},"sJ8bj","\u002F\u002F 开始观察\n",[120,161,163,166,169,172,175,178,182],{"class":122,"line":162},4,[120,164,165],{"class":144},"io.",[120,167,168],{"class":140},"observe",[120,170,171],{"class":144},"(document.",[120,173,174],{"class":140},"getElementById",[120,176,177],{"class":144},"(",[120,179,181],{"class":180},"sZZnC","\"example\"",[120,183,184],{"class":144},"));\n",[120,186,188],{"class":122,"line":187},5,[120,189,190],{"class":158},"\u002F\u002F 停止观察\n",[120,192,194,196,199],{"class":122,"line":193},6,[120,195,165],{"class":144},[120,197,198],{"class":140},"unobserve",[120,200,201],{"class":144},"(element);\n",[120,203,205],{"class":122,"line":204},7,[120,206,207],{"class":158},"\u002F\u002F 关闭观察器\n",[120,209,211,213,216],{"class":122,"line":210},8,[120,212,165],{"class":144},[120,214,215],{"class":140},"disconnect",[120,217,218],{"class":144},"();\n",[220,221,222,237,338,353,383,395,405,413,423],"ul",{},[223,224,225,226,229,230,232,233,236],"li",{},"参数",[18,227,228],{},"callback","，创建一个新的",[18,231,31],{},"对象后，当其监听到目标元素的可见部分穿过了一个或多个阈",[18,234,235],{},"thresholds","时，会执行指定的回调函数。",[223,238,225,239,242,243,245,246],{},[18,240,241],{},"option","，",[18,244,31],{},"构造函数的第二个参数是一个配置对象，其可以设置以下属性:\n",[220,247,248,287,299],{},[223,249,250,253,254,257,258,261,262,265,266,269,270,273,274,273,277,273,280,273,283,286],{},[18,251,252],{},"threshold","属性决定了什么时候触发回调函数，它是一个数组，每个成员都是一个门槛值，默认为",[18,255,256],{},"[0]","，即交叉比例",[18,259,260],{},"intersectionRatio","达到",[18,263,264],{},"0","时触发回调函数，用户可以自定义这个数组，比如",[18,267,268],{},"[0, 0.25, 0.5, 0.75, 1]","就表示当目标元素",[18,271,272],{},"0%","、",[18,275,276],{},"25%",[18,278,279],{},"50%",[18,281,282],{},"75%",[18,284,285],{},"100%","可见时，会触发回调函数。",[223,288,289,291,292,295,296,298],{},[18,290,92],{},"属性指定了目标元素所在的容器节点即根元素，目标元素不仅会随着窗口滚动，还会在容器里面滚动，比如在",[18,293,294],{},"iframe","窗口里滚动，这样就需要设置",[18,297,92],{},"属性，注意，容器元素必须是目标元素的祖先节点。",[223,300,301,304,305,308,309,312,313,316,317,320,321,324,325,273,328,273,331,54,334,337],{},[18,302,303],{},"rootMargin","属性定义根元素的",[18,306,307],{},"margin","，用来扩展或缩小",[18,310,311],{},"rootBounds","这个矩形的大小，从而影响",[18,314,315],{},"intersectionRect","交叉区域的大小，它使用",[18,318,319],{},"CSS","的定义方法，比如",[18,322,323],{},"10px 20px 30px 40px","，表示",[18,326,327],{},"top",[18,329,330],{},"right",[18,332,333],{},"bottom",[18,335,336],{},"left","四个方向的值。",[223,339,340,341,344,345,348,349,352],{},"属性",[18,342,343],{},"IntersectionObserver.root","只读，所监听对象的具体祖先元素",[18,346,347],{},"element","，如果未传入值或值为",[18,350,351],{},"null","，则默认使用顶级文档的视窗。",[223,354,340,355,358,359,361,362,365,366,273,369,372,373,273,376,379,380,109],{},[18,356,357],{},"IntersectionObserver.rootMargin","只读，计算交叉时添加到根",[18,360,92],{},"边界盒",[18,363,364],{},"bounding box","的矩形偏移量，可以有效的缩小或扩大根的判定范围从而满足计算需要，此属性返回的值可能与调用构造函数时指定的值不同，因此可能需要更改该值，以匹配内部要求，所有的偏移量均可用像素",[18,367,368],{},"pixel",[18,370,371],{},"px","或百分比",[18,374,375],{},"percentage",[18,377,378],{},"%","来表达，默认值为",[18,381,382],{},"0px 0px 0px 0px",[223,384,340,385,388,389,392,393,109],{},[18,386,387],{},"IntersectionObserver.thresholds","只读，一个包含阈值的列表，按升序排列，列表中的每个阈值都是监听对象的交叉区域与边界区域的比率，当监听对象的任何阈值被越过时，都会生成一个通知",[18,390,391],{},"Notification","，如果构造器未传入值，则默认值为",[18,394,264],{},[223,396,397,398,401,402,404],{},"方法",[18,399,400],{},"IntersectionObserver.disconnect()","，使",[18,403,31],{},"对象停止监听工作。",[223,406,397,407,401,410,412],{},[18,408,409],{},"IntersectionObserver.observe()",[18,411,31],{},"开始监听一个目标元素。",[223,414,397,415,418,419,422],{},[18,416,417],{},"IntersectionObserver.takeRecords()","，返回所有观察目标的",[18,420,421],{},"IntersectionObserverEntry","对象数组。",[223,424,397,425,401,428,430],{},[18,426,427],{},"IntersectionObserver.unobserve()",[18,429,31],{},"停止监听特定目标元素。",[14,432,433,434,436,437,439],{},"此外当执行",[18,435,228],{},"函数时，会传递一个",[18,438,421],{},"对象参数，其提供的信息如下。",[220,441,442,448,458,470,476,482],{},[223,443,444,447],{},[18,445,446],{},"time:","可见性发生变化的时间，是一个高精度时间戳，单位为毫秒。",[223,449,450,453,454,457],{},[18,451,452],{},"target:","被观察的目标元素，是一个",[18,455,456],{},"DOM","节点对象。",[223,459,460,463,464,467,468,109],{},[18,461,462],{},"rootBounds:","根元素的矩形区域的信息，是",[18,465,466],{},"getBoundingClientRect","方法的返回值，如果没有根元素即直接相对于视口滚动，则返回",[18,469,351],{},[223,471,472,475],{},[18,473,474],{},"boundingClientRect:","目标元素的矩形区域的信息。",[223,477,478,481],{},[18,479,480],{},"intersectionRect:","目标元素与视口或根元素的交叉区域的信息。",[223,483,484,487,488,490,491,494,495,498,499,109],{},[18,485,486],{},"intersectionRatio:","目标元素的可见比例，即",[18,489,315],{},"占",[18,492,493],{},"boundingClientRect","的比例，完全可见时为",[18,496,497],{},"1","，完全不可见时小于等于",[18,500,264],{},[111,502,507],{"className":503,"code":505,"language":506},[504],"language-text","{\n  time: 3893.92,\n  rootBounds: ClientRect {\n    bottom: 920,\n    height: 1024,\n    left: 0,\n    right: 1024,\n    top: 0,\n    width: 920\n  },\n  boundingClientRect: ClientRect {\n     \u002F\u002F ...\n  },\n  intersectionRect: ClientRect {\n    \u002F\u002F ...\n  },\n  intersectionRatio: 0.54,\n  target: element\n}\n","text",[18,508,505],{"__ignoreMap":116},[71,510,35],{"id":511},"requestidlecallback",[14,513,514,516,517,520,521,109],{},[18,515,35],{},"方法能够接受一个函数，这个函数将在浏览器空闲时期被调用，这使开发者能够在主事件循环上执行后台和低优先级工作，而不会影响延迟关键事件，如动画和输入响应，函数一般会按先进先调用的顺序执行，如果回调函数指定了执行超时时间",[18,518,519],{},"timeout","，则有可能为了在超时前执行函数而打乱执行顺序，兼容性",[18,522,523],{},"https:\u002F\u002Fcaniuse.com\u002F?search=requestIdleCallback",[111,525,527],{"className":113,"code":526,"language":115,"meta":116,"style":116},"const handle = window.requestIdleCallback(callback[, options]);\n",[18,528,529],{"__ignoreMap":116},[120,530,531,533,536,538,541,543],{"class":122,"line":123},[120,532,127],{"class":126},[120,534,535],{"class":130}," handle",[120,537,134],{"class":126},[120,539,540],{"class":144}," window.",[120,542,35],{"class":140},[120,544,545],{"class":144},"(callback[, options]);\n",[220,547,548,561,570],{},[223,549,550,552,553,556,557,560],{},[18,551,35],{},"方法返回一个",[18,554,555],{},"ID","，可以把它传入",[18,558,559],{},"window.cancelIdleCallback()","方法来结束回调。",[223,562,225,563,565,566,569],{},[18,564,228],{},"，一个在事件循环空闲时即将被调用的函数的引用，函数会接收到一个名为",[18,567,568],{},"IdleDeadline","的参数，这个参数可以获取当前空闲时间以及回调是否在超时时间前已经执行的状态。",[223,571,225,572,575,576],{},[18,573,574],{},"options","可选，包括可选的配置参数，具有如下属性:\n",[220,577,578],{},[223,579,580,582,583,585,586,588],{},[18,581,519],{},": 如果指定了",[18,584,519],{},"，并且有一个正值，而回调在",[18,587,519],{},"毫秒过后还没有被调用，那么回调任务将放入事件循环中排队，即使这样做有可能对性能产生负面影响。",[38,590,591],{"id":591},"实现",[14,593,594,595,597,598,600,601,604,605,608,609,612,613,615,616,618,619,622,623,625,626,629,630,633,634,637,638,641,642,644,645,65,647,649,650,653,654,657,658,661,662,665,666,669,670,65,673,675,676,679,680,682,683,685,686,54,689,692,693,54,696,699,700,54,703,706],{},"实际上编写组件主要是搞清楚如何使用这两个主要的",[18,596,104],{},"就好，首先关注",[18,599,31],{},"，因为考虑需要使用动态组件",[18,602,603],{},"\u003Ccomponent \u002F>","，那么我们向其传值的时候就需要使用异步加载组件",[18,606,607],{},"() => import(\"component\")","的形式。监听的时候，可以考虑加载完成之后即销毁监听器，或者离开视觉区域后就将其销毁等，这方面主要是策略问题。在页面销毁的时候就必须将",[18,610,611],{},"Intersection Observer","进行",[18,614,215],{},"，防止内存泄漏。另外我们为了使用",[18,617,31],{},"则必须需要一个可以观察的目标，如果什么不都渲染，我们就无从观察，所以我们需要引入一个骨架屏，我们可以为真实的组件做一个在尺寸上非常接近真实组件的组件，在这里为了演示只是简单的渲染了",[18,620,621],{},"\u003Csection \u002F>","作为骨架屏。使用",[18,624,35],{},"就比较简单了，只需要将回调函数执行即可，同样也类似于",[18,627,628],{},"Promise.resolve().then","这种异步处理的情况。",[631,632],"br",{},"\n这里是简单的实现逻辑，通常",[18,635,636],{},"observer","的使用方案是先使用一个",[18,639,640],{},"div","等先进行占位，然后在",[18,643,636],{},"监控其占位的容器，当容器在视区时加载相关的组件，相关的代码在",[18,646,64],{},[18,648,68],{},"分支，请尽量使用",[18,651,652],{},"yarn","进行安装，可以使用",[18,655,656],{},"yarn.lock","文件锁住版本，避免依赖问题。使用",[18,659,660],{},"npm run dev","运行之后可以在",[18,663,664],{},"Console","中看到这四个懒加载组件",[18,667,668],{},"created","创建的顺序，其中",[18,671,672],{},"A",[18,674,636],{},"懒加载是需要等其加载页面渲染完成之后，判断在可视区，才进行加载，首屏使能够直接看到的，而",[18,677,678],{},"D","的懒加载则是需要将滚动条滑动到",[18,681,678],{},"的外部容器出现在视图之后才会出现，也就是说只要不滚动到底部是不会加载",[18,684,678],{},"组件的，另外还可以通过",[18,687,688],{},"component-params",[18,690,691],{},"component-events","将",[18,694,695],{},"attrs",[18,697,698],{},"listeners","传递到懒加载的组件，类似于",[18,701,702],{},"$attrs",[18,704,705],{},"$listeners","，至此懒加载组件已简单实现。",[111,708,712],{"className":709,"code":710,"language":711,"meta":116,"style":116},"language-html shiki shiki-themes github-light github-dark","\u003C!-- App.vue -->\n\u003Ctemplate>\n    \u003Cdiv>\n        \u003Csection>1\u003C\u002Fsection>\n        \u003Csection>\n            \u003Cdiv>2\u003C\u002Fdiv>\n            \u003Clazy-load\n                :lazy-component=\"Example\"\n                type=\"observer\"\n                :component-params=\"{ content: 'Example A' }\"\n                :component-events=\"{\n                    'test-event': testEvent,\n                }\"\n            >\u003C\u002Flazy-load>\n        \u003C\u002Fsection>\n        \u003Csection>\n            \u003Cdiv>3\u003C\u002Fdiv>\n            \u003Clazy-load\n                :lazy-component=\"Example\"\n                type=\"idle\"\n                :component-params=\"{ content: 'Example B' }\"\n                :component-events=\"{\n                    'test-event': testEvent,\n                }\"\n            >\u003C\u002Flazy-load>\n        \u003C\u002Fsection>\n        \u003Csection>\n            \u003Cdiv>4\u003C\u002Fdiv>\n            \u003Clazy-load\n                :lazy-component=\"Example\"\n                type=\"lazy\"\n                :component-params=\"{ content: 'Example C' }\"\n                :component-events=\"{\n                    'test-event': testEvent,\n                }\"\n            >\u003C\u002Flazy-load>\n        \u003C\u002Fsection>\n        \u003Csection>\n            \u003Cdiv>5\u003C\u002Fdiv>\n            \u003Clazy-load\n                :lazy-component=\"Example\"\n                type=\"observer\"\n                :component-params=\"{ content: 'Example D' }\"\n                :component-events=\"{\n                    'test-event': testEvent,\n                }\"\n            >\u003C\u002Flazy-load>\n        \u003C\u002Fsection>\n    \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript lang=\"ts\">\nimport { Component, Vue } from \"vue-property-decorator\";\nimport LazyLoad from \".\u002Fcomponents\u002Flazy-load\u002Flazy-load.vue\";\n@Component({\n    components: { LazyLoad },\n})\nexport default class App extends Vue {\n    protected Example = () => import(\".\u002Fcomponents\u002Fexample\u002Fexample.vue\");\n\n    protected testEvent(content: string) {\n        console.log(content);\n    }\n}\n\u003C\u002Fscript>\n\n\u003Cstyle lang=\"scss\">\n@import \".\u002Fcommon\u002Fstyles.scss\";\nbody {\n    padding: 0;\n    margin: 0;\n}\nsection {\n    margin: 20px 0;\n    color: #fff;\n    height: 500px;\n    background: $color-blue;\n}\n\u003C\u002Fstyle>\n","html",[18,713,714,719,731,740,755,763,777,784,795,806,817,828,834,840,851,861,870,884,891,900,910,920,929,934,939,948,957,966,980,987,996,1006,1016,1025,1030,1035,1044,1053,1062,1076,1083,1092,1101,1111,1120,1125,1130,1139,1148,1158,1168,1173,1191,1209,1224,1236,1242,1248,1272,1300,1305,1328,1340,1346,1352,1361,1366,1383,1394,1402,1415,1427,1432,1439,1456,1469,1484,1493,1498],{"__ignoreMap":116},[120,715,716],{"class":122,"line":123},[120,717,718],{"class":158},"\u003C!-- App.vue -->\n",[120,720,721,724,728],{"class":122,"line":148},[120,722,723],{"class":144},"\u003C",[120,725,727],{"class":726},"s9eBZ","template",[120,729,730],{"class":144},">\n",[120,732,733,736,738],{"class":122,"line":155},[120,734,735],{"class":144},"    \u003C",[120,737,640],{"class":726},[120,739,730],{"class":144},[120,741,742,745,748,751,753],{"class":122,"line":162},[120,743,744],{"class":144},"        \u003C",[120,746,747],{"class":726},"section",[120,749,750],{"class":144},">1\u003C\u002F",[120,752,747],{"class":726},[120,754,730],{"class":144},[120,756,757,759,761],{"class":122,"line":187},[120,758,744],{"class":144},[120,760,747],{"class":726},[120,762,730],{"class":144},[120,764,765,768,770,773,775],{"class":122,"line":193},[120,766,767],{"class":144},"            \u003C",[120,769,640],{"class":726},[120,771,772],{"class":144},">2\u003C\u002F",[120,774,640],{"class":726},[120,776,730],{"class":144},[120,778,779,781],{"class":122,"line":204},[120,780,767],{"class":144},[120,782,783],{"class":726},"lazy-load\n",[120,785,786,789,792],{"class":122,"line":210},[120,787,788],{"class":140},"                :lazy-component",[120,790,791],{"class":144},"=",[120,793,794],{"class":180},"\"Example\"\n",[120,796,798,801,803],{"class":122,"line":797},9,[120,799,800],{"class":140},"                type",[120,802,791],{"class":144},[120,804,805],{"class":180},"\"observer\"\n",[120,807,809,812,814],{"class":122,"line":808},10,[120,810,811],{"class":140},"                :component-params",[120,813,791],{"class":144},[120,815,816],{"class":180},"\"{ content: 'Example A' }\"\n",[120,818,820,823,825],{"class":122,"line":819},11,[120,821,822],{"class":140},"                :component-events",[120,824,791],{"class":144},[120,826,827],{"class":180},"\"{\n",[120,829,831],{"class":122,"line":830},12,[120,832,833],{"class":180},"                    'test-event': testEvent,\n",[120,835,837],{"class":122,"line":836},13,[120,838,839],{"class":180},"                }\"\n",[120,841,843,846,849],{"class":122,"line":842},14,[120,844,845],{"class":144},"            >\u003C\u002F",[120,847,848],{"class":726},"lazy-load",[120,850,730],{"class":144},[120,852,854,857,859],{"class":122,"line":853},15,[120,855,856],{"class":144},"        \u003C\u002F",[120,858,747],{"class":726},[120,860,730],{"class":144},[120,862,864,866,868],{"class":122,"line":863},16,[120,865,744],{"class":144},[120,867,747],{"class":726},[120,869,730],{"class":144},[120,871,873,875,877,880,882],{"class":122,"line":872},17,[120,874,767],{"class":144},[120,876,640],{"class":726},[120,878,879],{"class":144},">3\u003C\u002F",[120,881,640],{"class":726},[120,883,730],{"class":144},[120,885,887,889],{"class":122,"line":886},18,[120,888,767],{"class":144},[120,890,783],{"class":726},[120,892,894,896,898],{"class":122,"line":893},19,[120,895,788],{"class":140},[120,897,791],{"class":144},[120,899,794],{"class":180},[120,901,903,905,907],{"class":122,"line":902},20,[120,904,800],{"class":140},[120,906,791],{"class":144},[120,908,909],{"class":180},"\"idle\"\n",[120,911,913,915,917],{"class":122,"line":912},21,[120,914,811],{"class":140},[120,916,791],{"class":144},[120,918,919],{"class":180},"\"{ content: 'Example B' }\"\n",[120,921,923,925,927],{"class":122,"line":922},22,[120,924,822],{"class":140},[120,926,791],{"class":144},[120,928,827],{"class":180},[120,930,932],{"class":122,"line":931},23,[120,933,833],{"class":180},[120,935,937],{"class":122,"line":936},24,[120,938,839],{"class":180},[120,940,942,944,946],{"class":122,"line":941},25,[120,943,845],{"class":144},[120,945,848],{"class":726},[120,947,730],{"class":144},[120,949,951,953,955],{"class":122,"line":950},26,[120,952,856],{"class":144},[120,954,747],{"class":726},[120,956,730],{"class":144},[120,958,960,962,964],{"class":122,"line":959},27,[120,961,744],{"class":144},[120,963,747],{"class":726},[120,965,730],{"class":144},[120,967,969,971,973,976,978],{"class":122,"line":968},28,[120,970,767],{"class":144},[120,972,640],{"class":726},[120,974,975],{"class":144},">4\u003C\u002F",[120,977,640],{"class":726},[120,979,730],{"class":144},[120,981,983,985],{"class":122,"line":982},29,[120,984,767],{"class":144},[120,986,783],{"class":726},[120,988,990,992,994],{"class":122,"line":989},30,[120,991,788],{"class":140},[120,993,791],{"class":144},[120,995,794],{"class":180},[120,997,999,1001,1003],{"class":122,"line":998},31,[120,1000,800],{"class":140},[120,1002,791],{"class":144},[120,1004,1005],{"class":180},"\"lazy\"\n",[120,1007,1009,1011,1013],{"class":122,"line":1008},32,[120,1010,811],{"class":140},[120,1012,791],{"class":144},[120,1014,1015],{"class":180},"\"{ content: 'Example C' }\"\n",[120,1017,1019,1021,1023],{"class":122,"line":1018},33,[120,1020,822],{"class":140},[120,1022,791],{"class":144},[120,1024,827],{"class":180},[120,1026,1028],{"class":122,"line":1027},34,[120,1029,833],{"class":180},[120,1031,1033],{"class":122,"line":1032},35,[120,1034,839],{"class":180},[120,1036,1038,1040,1042],{"class":122,"line":1037},36,[120,1039,845],{"class":144},[120,1041,848],{"class":726},[120,1043,730],{"class":144},[120,1045,1047,1049,1051],{"class":122,"line":1046},37,[120,1048,856],{"class":144},[120,1050,747],{"class":726},[120,1052,730],{"class":144},[120,1054,1056,1058,1060],{"class":122,"line":1055},38,[120,1057,744],{"class":144},[120,1059,747],{"class":726},[120,1061,730],{"class":144},[120,1063,1065,1067,1069,1072,1074],{"class":122,"line":1064},39,[120,1066,767],{"class":144},[120,1068,640],{"class":726},[120,1070,1071],{"class":144},">5\u003C\u002F",[120,1073,640],{"class":726},[120,1075,730],{"class":144},[120,1077,1079,1081],{"class":122,"line":1078},40,[120,1080,767],{"class":144},[120,1082,783],{"class":726},[120,1084,1086,1088,1090],{"class":122,"line":1085},41,[120,1087,788],{"class":140},[120,1089,791],{"class":144},[120,1091,794],{"class":180},[120,1093,1095,1097,1099],{"class":122,"line":1094},42,[120,1096,800],{"class":140},[120,1098,791],{"class":144},[120,1100,805],{"class":180},[120,1102,1104,1106,1108],{"class":122,"line":1103},43,[120,1105,811],{"class":140},[120,1107,791],{"class":144},[120,1109,1110],{"class":180},"\"{ content: 'Example D' }\"\n",[120,1112,1114,1116,1118],{"class":122,"line":1113},44,[120,1115,822],{"class":140},[120,1117,791],{"class":144},[120,1119,827],{"class":180},[120,1121,1123],{"class":122,"line":1122},45,[120,1124,833],{"class":180},[120,1126,1128],{"class":122,"line":1127},46,[120,1129,839],{"class":180},[120,1131,1133,1135,1137],{"class":122,"line":1132},47,[120,1134,845],{"class":144},[120,1136,848],{"class":726},[120,1138,730],{"class":144},[120,1140,1142,1144,1146],{"class":122,"line":1141},48,[120,1143,856],{"class":144},[120,1145,747],{"class":726},[120,1147,730],{"class":144},[120,1149,1151,1154,1156],{"class":122,"line":1150},49,[120,1152,1153],{"class":144},"    \u003C\u002F",[120,1155,640],{"class":726},[120,1157,730],{"class":144},[120,1159,1161,1164,1166],{"class":122,"line":1160},50,[120,1162,1163],{"class":144},"\u003C\u002F",[120,1165,727],{"class":726},[120,1167,730],{"class":144},[120,1169,1171],{"class":122,"line":1170},51,[120,1172,152],{"emptyLinePlaceholder":151},[120,1174,1176,1178,1181,1184,1186,1189],{"class":122,"line":1175},52,[120,1177,723],{"class":144},[120,1179,1180],{"class":726},"script",[120,1182,1183],{"class":140}," lang",[120,1185,791],{"class":144},[120,1187,1188],{"class":180},"\"ts\"",[120,1190,730],{"class":144},[120,1192,1194,1197,1200,1203,1206],{"class":122,"line":1193},53,[120,1195,1196],{"class":126},"import",[120,1198,1199],{"class":144}," { Component, Vue } ",[120,1201,1202],{"class":126},"from",[120,1204,1205],{"class":180}," \"vue-property-decorator\"",[120,1207,1208],{"class":144},";\n",[120,1210,1212,1214,1217,1219,1222],{"class":122,"line":1211},54,[120,1213,1196],{"class":126},[120,1215,1216],{"class":144}," LazyLoad ",[120,1218,1202],{"class":126},[120,1220,1221],{"class":180}," \".\u002Fcomponents\u002Flazy-load\u002Flazy-load.vue\"",[120,1223,1208],{"class":144},[120,1225,1227,1230,1233],{"class":122,"line":1226},55,[120,1228,1229],{"class":144},"@",[120,1231,1232],{"class":140},"Component",[120,1234,1235],{"class":144},"({\n",[120,1237,1239],{"class":122,"line":1238},56,[120,1240,1241],{"class":144},"    components: { LazyLoad },\n",[120,1243,1245],{"class":122,"line":1244},57,[120,1246,1247],{"class":144},"})\n",[120,1249,1251,1254,1257,1260,1263,1266,1269],{"class":122,"line":1250},58,[120,1252,1253],{"class":126},"export",[120,1255,1256],{"class":126}," default",[120,1258,1259],{"class":126}," class",[120,1261,1262],{"class":140}," App",[120,1264,1265],{"class":126}," extends",[120,1267,1268],{"class":140}," Vue",[120,1270,1271],{"class":144}," {\n",[120,1273,1275,1278,1281,1283,1286,1289,1292,1294,1297],{"class":122,"line":1274},59,[120,1276,1277],{"class":126},"    protected",[120,1279,1280],{"class":140}," Example",[120,1282,134],{"class":126},[120,1284,1285],{"class":144}," () ",[120,1287,1288],{"class":126},"=>",[120,1290,1291],{"class":126}," import",[120,1293,177],{"class":144},[120,1295,1296],{"class":180},"\".\u002Fcomponents\u002Fexample\u002Fexample.vue\"",[120,1298,1299],{"class":144},");\n",[120,1301,1303],{"class":122,"line":1302},60,[120,1304,152],{"emptyLinePlaceholder":151},[120,1306,1308,1310,1313,1315,1319,1322,1325],{"class":122,"line":1307},61,[120,1309,1277],{"class":126},[120,1311,1312],{"class":140}," testEvent",[120,1314,177],{"class":144},[120,1316,1318],{"class":1317},"s4XuR","content",[120,1320,1321],{"class":126},":",[120,1323,1324],{"class":130}," string",[120,1326,1327],{"class":144},") {\n",[120,1329,1331,1334,1337],{"class":122,"line":1330},62,[120,1332,1333],{"class":144},"        console.",[120,1335,1336],{"class":140},"log",[120,1338,1339],{"class":144},"(content);\n",[120,1341,1343],{"class":122,"line":1342},63,[120,1344,1345],{"class":144},"    }\n",[120,1347,1349],{"class":122,"line":1348},64,[120,1350,1351],{"class":144},"}\n",[120,1353,1355,1357,1359],{"class":122,"line":1354},65,[120,1356,1163],{"class":144},[120,1358,1180],{"class":726},[120,1360,730],{"class":144},[120,1362,1364],{"class":122,"line":1363},66,[120,1365,152],{"emptyLinePlaceholder":151},[120,1367,1369,1371,1374,1376,1378,1381],{"class":122,"line":1368},67,[120,1370,723],{"class":144},[120,1372,1373],{"class":726},"style",[120,1375,1183],{"class":140},[120,1377,791],{"class":144},[120,1379,1380],{"class":180},"\"scss\"",[120,1382,730],{"class":144},[120,1384,1386,1389,1392],{"class":122,"line":1385},68,[120,1387,1388],{"class":126},"@import",[120,1390,1391],{"class":180}," \".\u002Fcommon\u002Fstyles.scss\"",[120,1393,1208],{"class":144},[120,1395,1397,1400],{"class":122,"line":1396},69,[120,1398,1399],{"class":726},"body",[120,1401,1271],{"class":144},[120,1403,1405,1408,1411,1413],{"class":122,"line":1404},70,[120,1406,1407],{"class":130},"    padding",[120,1409,1410],{"class":144},": ",[120,1412,264],{"class":130},[120,1414,1208],{"class":144},[120,1416,1418,1421,1423,1425],{"class":122,"line":1417},71,[120,1419,1420],{"class":130},"    margin",[120,1422,1410],{"class":144},[120,1424,264],{"class":130},[120,1426,1208],{"class":144},[120,1428,1430],{"class":122,"line":1429},72,[120,1431,1351],{"class":144},[120,1433,1435,1437],{"class":122,"line":1434},73,[120,1436,747],{"class":726},[120,1438,1271],{"class":144},[120,1440,1442,1444,1446,1449,1451,1454],{"class":122,"line":1441},74,[120,1443,1420],{"class":130},[120,1445,1410],{"class":144},[120,1447,1448],{"class":130},"20",[120,1450,371],{"class":126},[120,1452,1453],{"class":130}," 0",[120,1455,1208],{"class":144},[120,1457,1459,1462,1464,1467],{"class":122,"line":1458},75,[120,1460,1461],{"class":130},"    color",[120,1463,1410],{"class":144},[120,1465,1466],{"class":130},"#fff",[120,1468,1208],{"class":144},[120,1470,1472,1475,1477,1480,1482],{"class":122,"line":1471},76,[120,1473,1474],{"class":130},"    height",[120,1476,1410],{"class":144},[120,1478,1479],{"class":130},"500",[120,1481,371],{"class":126},[120,1483,1208],{"class":144},[120,1485,1487,1490],{"class":122,"line":1486},77,[120,1488,1489],{"class":130},"    background",[120,1491,1492],{"class":144},": $color-blue;\n",[120,1494,1496],{"class":122,"line":1495},78,[120,1497,1351],{"class":144},[120,1499,1501,1503,1505],{"class":122,"line":1500},79,[120,1502,1163],{"class":144},[120,1504,1373],{"class":726},[120,1506,730],{"class":144},[111,1508,1510],{"className":709,"code":1509,"language":711,"meta":116,"style":116},"\u003C!-- lazy-load.vue -->\n\u003Ctemplate>\n    \u003Cdiv>\n        \u003Ccomponent\n            :is=\"renderComponent\"\n            v-bind=\"componentParams\"\n            v-on=\"componentEvents\"\n        >\u003C\u002Fcomponent>\n    \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript lang=\"ts\">\nimport { Component, Prop, Vue } from \"vue-property-decorator\";\n@Component\nexport default class LazyLoad extends Vue {\n    @Prop({ type: Function, required: true })\n    lazyComponent!: () => Vue;\n    @Prop({ type: String, required: true })\n    type!: \"observer\" | \"idle\" | \"lazy\";\n    @Prop({ type: Object, default: () => ({}) })\n    componentParams!: Record\u003Cstring, unknown>;\n    @Prop({ type: Object, default: () => ({}) })\n    componentEvents!: Record\u003Cstring, unknown>;\n\n    protected observer: IntersectionObserver | null = null;\n    protected renderComponent: (() => Vue) | null = null;\n\n    protected mounted() {\n        this.init();\n    }\n\n    private init() {\n        if (this.type === \"observer\") {\n            \u002F\u002F 存在`window.IntersectionObserver`\n            if (window.IntersectionObserver) {\n                this.observer = new IntersectionObserver(entries => {\n                    entries.forEach(item => {\n                        \u002F\u002F `intersectionRatio`为目标元素的可见比例，大于`0`代表可见\n                        \u002F\u002F 在这里也有实现策略问题 例如加载后不解除`observe`而在不可见时销毁等\n                        if (item.intersectionRatio > 0) {\n                            this.loadComponent();\n                            \u002F\u002F 加载完成后将其解除`observe`\n                            this.observer?.unobserve(item.target);\n                        }\n                    });\n                });\n                this.observer.observe(this.$el.parentElement || this.$el);\n            } else {\n                \u002F\u002F 直接加载\n                this.loadComponent();\n            }\n        } else if (this.type === \"idle\") {\n            \u002F\u002F 存在`requestIdleCallback`\n            \u002F\u002F eslint-disable-next-line @typescript-eslint\u002Fban-ts-comment\n            \u002F\u002F @ts-ignore\n            if (window.requestIdleCallback) {\n                requestIdleCallback(this.loadComponent, { timeout: 3 });\n            } else {\n                \u002F\u002F 直接加载\n                this.loadComponent();\n            }\n        } else if (this.type === \"lazy\") {\n            \u002F\u002F 存在`Promise`\n            if (window.Promise) {\n                Promise.resolve().then(this.loadComponent);\n            } else {\n                \u002F\u002F 降级使用`setTimeout`\n                setTimeout(this.loadComponent);\n            }\n        } else {\n            throw new Error(`type: \"observer\" | \"idle\" | \"lazy\"`);\n        }\n    }\n\n    private loadComponent() {\n        this.renderComponent = this.lazyComponent;\n        this.$emit(\"loaded\");\n    }\n\n    protected destroyed() {\n        this.observer && this.observer.disconnect();\n    }\n}\n\u003C\u002Fscript>\n",[18,1511,1512,1517,1525,1533,1541,1551,1561,1571,1581,1589,1597,1601,1615,1628,1633,1650,1667,1683,1696,1719,1739,1763,1779,1798,1802,1824,1854,1858,1868,1881,1885,1889,1899,1920,1925,1933,1957,1974,1979,1984,1999,2011,2016,2028,2033,2038,2043,2068,2078,2083,2093,2098,2120,2125,2130,2135,2142,2160,2168,2172,2182,2186,2206,2211,2218,2241,2249,2254,2265,2269,2277,2294,2299,2303,2307,2316,2330,2346,2350,2354,2364,2382,2387,2392],{"__ignoreMap":116},[120,1513,1514],{"class":122,"line":123},[120,1515,1516],{"class":158},"\u003C!-- lazy-load.vue -->\n",[120,1518,1519,1521,1523],{"class":122,"line":148},[120,1520,723],{"class":144},[120,1522,727],{"class":726},[120,1524,730],{"class":144},[120,1526,1527,1529,1531],{"class":122,"line":155},[120,1528,735],{"class":144},[120,1530,640],{"class":726},[120,1532,730],{"class":144},[120,1534,1535,1537],{"class":122,"line":162},[120,1536,744],{"class":144},[120,1538,1540],{"class":1539},"s7hpK","component\n",[120,1542,1543,1546,1548],{"class":122,"line":187},[120,1544,1545],{"class":140},"            :is",[120,1547,791],{"class":144},[120,1549,1550],{"class":180},"\"renderComponent\"\n",[120,1552,1553,1556,1558],{"class":122,"line":193},[120,1554,1555],{"class":140},"            v-bind",[120,1557,791],{"class":144},[120,1559,1560],{"class":180},"\"componentParams\"\n",[120,1562,1563,1566,1568],{"class":122,"line":204},[120,1564,1565],{"class":140},"            v-on",[120,1567,791],{"class":144},[120,1569,1570],{"class":180},"\"componentEvents\"\n",[120,1572,1573,1576,1579],{"class":122,"line":210},[120,1574,1575],{"class":144},"        >\u003C\u002F",[120,1577,1578],{"class":1539},"component",[120,1580,730],{"class":144},[120,1582,1583,1585,1587],{"class":122,"line":797},[120,1584,1153],{"class":144},[120,1586,640],{"class":726},[120,1588,730],{"class":144},[120,1590,1591,1593,1595],{"class":122,"line":808},[120,1592,1163],{"class":144},[120,1594,727],{"class":726},[120,1596,730],{"class":144},[120,1598,1599],{"class":122,"line":819},[120,1600,152],{"emptyLinePlaceholder":151},[120,1602,1603,1605,1607,1609,1611,1613],{"class":122,"line":830},[120,1604,723],{"class":144},[120,1606,1180],{"class":726},[120,1608,1183],{"class":140},[120,1610,791],{"class":144},[120,1612,1188],{"class":180},[120,1614,730],{"class":144},[120,1616,1617,1619,1622,1624,1626],{"class":122,"line":836},[120,1618,1196],{"class":126},[120,1620,1621],{"class":144}," { Component, Prop, Vue } ",[120,1623,1202],{"class":126},[120,1625,1205],{"class":180},[120,1627,1208],{"class":144},[120,1629,1630],{"class":122,"line":842},[120,1631,1632],{"class":144},"@Component\n",[120,1634,1635,1637,1639,1641,1644,1646,1648],{"class":122,"line":853},[120,1636,1253],{"class":126},[120,1638,1256],{"class":126},[120,1640,1259],{"class":126},[120,1642,1643],{"class":140}," LazyLoad",[120,1645,1265],{"class":126},[120,1647,1268],{"class":140},[120,1649,1271],{"class":144},[120,1651,1652,1655,1658,1661,1664],{"class":122,"line":863},[120,1653,1654],{"class":144},"    @",[120,1656,1657],{"class":140},"Prop",[120,1659,1660],{"class":144},"({ type: Function, required: ",[120,1662,1663],{"class":130},"true",[120,1665,1666],{"class":144}," })\n",[120,1668,1669,1672,1675,1677,1679,1681],{"class":122,"line":872},[120,1670,1671],{"class":140},"    lazyComponent",[120,1673,1674],{"class":126},"!:",[120,1676,1285],{"class":144},[120,1678,1288],{"class":126},[120,1680,1268],{"class":140},[120,1682,1208],{"class":144},[120,1684,1685,1687,1689,1692,1694],{"class":122,"line":886},[120,1686,1654],{"class":144},[120,1688,1657],{"class":140},[120,1690,1691],{"class":144},"({ type: String, required: ",[120,1693,1663],{"class":130},[120,1695,1666],{"class":144},[120,1697,1698,1701,1703,1706,1709,1712,1714,1717],{"class":122,"line":893},[120,1699,1700],{"class":1317},"    type",[120,1702,1674],{"class":126},[120,1704,1705],{"class":180}," \"observer\"",[120,1707,1708],{"class":126}," |",[120,1710,1711],{"class":180}," \"idle\"",[120,1713,1708],{"class":126},[120,1715,1716],{"class":180}," \"lazy\"",[120,1718,1208],{"class":144},[120,1720,1721,1723,1725,1728,1731,1734,1736],{"class":122,"line":902},[120,1722,1654],{"class":144},[120,1724,1657],{"class":140},[120,1726,1727],{"class":144},"({ type: Object, ",[120,1729,1730],{"class":140},"default",[120,1732,1733],{"class":144},": () ",[120,1735,1288],{"class":126},[120,1737,1738],{"class":144}," ({}) })\n",[120,1740,1741,1744,1746,1749,1751,1754,1757,1760],{"class":122,"line":912},[120,1742,1743],{"class":1317},"    componentParams",[120,1745,1674],{"class":126},[120,1747,1748],{"class":140}," Record",[120,1750,723],{"class":144},[120,1752,1753],{"class":130},"string",[120,1755,1756],{"class":144},", ",[120,1758,1759],{"class":130},"unknown",[120,1761,1762],{"class":144},">;\n",[120,1764,1765,1767,1769,1771,1773,1775,1777],{"class":122,"line":922},[120,1766,1654],{"class":144},[120,1768,1657],{"class":140},[120,1770,1727],{"class":144},[120,1772,1730],{"class":140},[120,1774,1733],{"class":144},[120,1776,1288],{"class":126},[120,1778,1738],{"class":144},[120,1780,1781,1784,1786,1788,1790,1792,1794,1796],{"class":122,"line":931},[120,1782,1783],{"class":1317},"    componentEvents",[120,1785,1674],{"class":126},[120,1787,1748],{"class":140},[120,1789,723],{"class":144},[120,1791,1753],{"class":130},[120,1793,1756],{"class":144},[120,1795,1759],{"class":130},[120,1797,1762],{"class":144},[120,1799,1800],{"class":122,"line":936},[120,1801,152],{"emptyLinePlaceholder":151},[120,1803,1804,1806,1809,1811,1813,1815,1818,1820,1822],{"class":122,"line":941},[120,1805,1277],{"class":126},[120,1807,1808],{"class":1317}," observer",[120,1810,1321],{"class":126},[120,1812,141],{"class":140},[120,1814,1708],{"class":126},[120,1816,1817],{"class":130}," null",[120,1819,134],{"class":126},[120,1821,1817],{"class":130},[120,1823,1208],{"class":144},[120,1825,1826,1828,1831,1833,1836,1838,1840,1843,1846,1848,1850,1852],{"class":122,"line":950},[120,1827,1277],{"class":126},[120,1829,1830],{"class":1317}," renderComponent",[120,1832,1321],{"class":126},[120,1834,1835],{"class":144}," (() ",[120,1837,1288],{"class":126},[120,1839,1268],{"class":140},[120,1841,1842],{"class":144},") ",[120,1844,1845],{"class":126},"|",[120,1847,1817],{"class":130},[120,1849,134],{"class":126},[120,1851,1817],{"class":130},[120,1853,1208],{"class":144},[120,1855,1856],{"class":122,"line":959},[120,1857,152],{"emptyLinePlaceholder":151},[120,1859,1860,1862,1865],{"class":122,"line":968},[120,1861,1277],{"class":126},[120,1863,1864],{"class":140}," mounted",[120,1866,1867],{"class":144},"() {\n",[120,1869,1870,1873,1876,1879],{"class":122,"line":982},[120,1871,1872],{"class":130},"        this",[120,1874,1875],{"class":144},".",[120,1877,1878],{"class":140},"init",[120,1880,218],{"class":144},[120,1882,1883],{"class":122,"line":989},[120,1884,1345],{"class":144},[120,1886,1887],{"class":122,"line":998},[120,1888,152],{"emptyLinePlaceholder":151},[120,1890,1891,1894,1897],{"class":122,"line":1008},[120,1892,1893],{"class":126},"    private",[120,1895,1896],{"class":140}," init",[120,1898,1867],{"class":144},[120,1900,1901,1904,1907,1910,1913,1916,1918],{"class":122,"line":1018},[120,1902,1903],{"class":126},"        if",[120,1905,1906],{"class":144}," (",[120,1908,1909],{"class":130},"this",[120,1911,1912],{"class":144},".type ",[120,1914,1915],{"class":126},"===",[120,1917,1705],{"class":180},[120,1919,1327],{"class":144},[120,1921,1922],{"class":122,"line":1027},[120,1923,1924],{"class":158},"            \u002F\u002F 存在`window.IntersectionObserver`\n",[120,1926,1927,1930],{"class":122,"line":1032},[120,1928,1929],{"class":126},"            if",[120,1931,1932],{"class":144}," (window.IntersectionObserver) {\n",[120,1934,1935,1938,1941,1943,1945,1947,1949,1952,1955],{"class":122,"line":1037},[120,1936,1937],{"class":130},"                this",[120,1939,1940],{"class":144},".observer ",[120,1942,791],{"class":126},[120,1944,137],{"class":126},[120,1946,141],{"class":140},[120,1948,177],{"class":144},[120,1950,1951],{"class":1317},"entries",[120,1953,1954],{"class":126}," =>",[120,1956,1271],{"class":144},[120,1958,1959,1962,1965,1967,1970,1972],{"class":122,"line":1046},[120,1960,1961],{"class":144},"                    entries.",[120,1963,1964],{"class":140},"forEach",[120,1966,177],{"class":144},[120,1968,1969],{"class":1317},"item",[120,1971,1954],{"class":126},[120,1973,1271],{"class":144},[120,1975,1976],{"class":122,"line":1055},[120,1977,1978],{"class":158},"                        \u002F\u002F `intersectionRatio`为目标元素的可见比例，大于`0`代表可见\n",[120,1980,1981],{"class":122,"line":1064},[120,1982,1983],{"class":158},"                        \u002F\u002F 在这里也有实现策略问题 例如加载后不解除`observe`而在不可见时销毁等\n",[120,1985,1986,1989,1992,1995,1997],{"class":122,"line":1078},[120,1987,1988],{"class":126},"                        if",[120,1990,1991],{"class":144}," (item.intersectionRatio ",[120,1993,1994],{"class":126},">",[120,1996,1453],{"class":130},[120,1998,1327],{"class":144},[120,2000,2001,2004,2006,2009],{"class":122,"line":1085},[120,2002,2003],{"class":130},"                            this",[120,2005,1875],{"class":144},[120,2007,2008],{"class":140},"loadComponent",[120,2010,218],{"class":144},[120,2012,2013],{"class":122,"line":1094},[120,2014,2015],{"class":158},"                            \u002F\u002F 加载完成后将其解除`observe`\n",[120,2017,2018,2020,2023,2025],{"class":122,"line":1103},[120,2019,2003],{"class":130},[120,2021,2022],{"class":144},".observer?.",[120,2024,198],{"class":140},[120,2026,2027],{"class":144},"(item.target);\n",[120,2029,2030],{"class":122,"line":1113},[120,2031,2032],{"class":144},"                        }\n",[120,2034,2035],{"class":122,"line":1122},[120,2036,2037],{"class":144},"                    });\n",[120,2039,2040],{"class":122,"line":1127},[120,2041,2042],{"class":144},"                });\n",[120,2044,2045,2047,2050,2052,2054,2056,2059,2062,2065],{"class":122,"line":1132},[120,2046,1937],{"class":130},[120,2048,2049],{"class":144},".observer.",[120,2051,168],{"class":140},[120,2053,177],{"class":144},[120,2055,1909],{"class":130},[120,2057,2058],{"class":144},".$el.parentElement ",[120,2060,2061],{"class":126},"||",[120,2063,2064],{"class":130}," this",[120,2066,2067],{"class":144},".$el);\n",[120,2069,2070,2073,2076],{"class":122,"line":1141},[120,2071,2072],{"class":144},"            } ",[120,2074,2075],{"class":126},"else",[120,2077,1271],{"class":144},[120,2079,2080],{"class":122,"line":1150},[120,2081,2082],{"class":158},"                \u002F\u002F 直接加载\n",[120,2084,2085,2087,2089,2091],{"class":122,"line":1160},[120,2086,1937],{"class":130},[120,2088,1875],{"class":144},[120,2090,2008],{"class":140},[120,2092,218],{"class":144},[120,2094,2095],{"class":122,"line":1170},[120,2096,2097],{"class":144},"            }\n",[120,2099,2100,2103,2105,2108,2110,2112,2114,2116,2118],{"class":122,"line":1175},[120,2101,2102],{"class":144},"        } ",[120,2104,2075],{"class":126},[120,2106,2107],{"class":126}," if",[120,2109,1906],{"class":144},[120,2111,1909],{"class":130},[120,2113,1912],{"class":144},[120,2115,1915],{"class":126},[120,2117,1711],{"class":180},[120,2119,1327],{"class":144},[120,2121,2122],{"class":122,"line":1193},[120,2123,2124],{"class":158},"            \u002F\u002F 存在`requestIdleCallback`\n",[120,2126,2127],{"class":122,"line":1211},[120,2128,2129],{"class":158},"            \u002F\u002F eslint-disable-next-line @typescript-eslint\u002Fban-ts-comment\n",[120,2131,2132],{"class":122,"line":1226},[120,2133,2134],{"class":158},"            \u002F\u002F @ts-ignore\n",[120,2136,2137,2139],{"class":122,"line":1238},[120,2138,1929],{"class":126},[120,2140,2141],{"class":144}," (window.requestIdleCallback) {\n",[120,2143,2144,2147,2149,2151,2154,2157],{"class":122,"line":1244},[120,2145,2146],{"class":140},"                requestIdleCallback",[120,2148,177],{"class":144},[120,2150,1909],{"class":130},[120,2152,2153],{"class":144},".loadComponent, { timeout: ",[120,2155,2156],{"class":130},"3",[120,2158,2159],{"class":144}," });\n",[120,2161,2162,2164,2166],{"class":122,"line":1250},[120,2163,2072],{"class":144},[120,2165,2075],{"class":126},[120,2167,1271],{"class":144},[120,2169,2170],{"class":122,"line":1274},[120,2171,2082],{"class":158},[120,2173,2174,2176,2178,2180],{"class":122,"line":1302},[120,2175,1937],{"class":130},[120,2177,1875],{"class":144},[120,2179,2008],{"class":140},[120,2181,218],{"class":144},[120,2183,2184],{"class":122,"line":1307},[120,2185,2097],{"class":144},[120,2187,2188,2190,2192,2194,2196,2198,2200,2202,2204],{"class":122,"line":1330},[120,2189,2102],{"class":144},[120,2191,2075],{"class":126},[120,2193,2107],{"class":126},[120,2195,1906],{"class":144},[120,2197,1909],{"class":130},[120,2199,1912],{"class":144},[120,2201,1915],{"class":126},[120,2203,1716],{"class":180},[120,2205,1327],{"class":144},[120,2207,2208],{"class":122,"line":1342},[120,2209,2210],{"class":158},"            \u002F\u002F 存在`Promise`\n",[120,2212,2213,2215],{"class":122,"line":1348},[120,2214,1929],{"class":126},[120,2216,2217],{"class":144}," (window.Promise) {\n",[120,2219,2220,2223,2225,2228,2231,2234,2236,2238],{"class":122,"line":1354},[120,2221,2222],{"class":130},"                Promise",[120,2224,1875],{"class":144},[120,2226,2227],{"class":140},"resolve",[120,2229,2230],{"class":144},"().",[120,2232,2233],{"class":140},"then",[120,2235,177],{"class":144},[120,2237,1909],{"class":130},[120,2239,2240],{"class":144},".loadComponent);\n",[120,2242,2243,2245,2247],{"class":122,"line":1363},[120,2244,2072],{"class":144},[120,2246,2075],{"class":126},[120,2248,1271],{"class":144},[120,2250,2251],{"class":122,"line":1368},[120,2252,2253],{"class":158},"                \u002F\u002F 降级使用`setTimeout`\n",[120,2255,2256,2259,2261,2263],{"class":122,"line":1385},[120,2257,2258],{"class":140},"                setTimeout",[120,2260,177],{"class":144},[120,2262,1909],{"class":130},[120,2264,2240],{"class":144},[120,2266,2267],{"class":122,"line":1396},[120,2268,2097],{"class":144},[120,2270,2271,2273,2275],{"class":122,"line":1404},[120,2272,2102],{"class":144},[120,2274,2075],{"class":126},[120,2276,1271],{"class":144},[120,2278,2279,2282,2284,2287,2289,2292],{"class":122,"line":1417},[120,2280,2281],{"class":126},"            throw",[120,2283,137],{"class":126},[120,2285,2286],{"class":140}," Error",[120,2288,177],{"class":144},[120,2290,2291],{"class":180},"`type: \"observer\" | \"idle\" | \"lazy\"`",[120,2293,1299],{"class":144},[120,2295,2296],{"class":122,"line":1429},[120,2297,2298],{"class":144},"        }\n",[120,2300,2301],{"class":122,"line":1434},[120,2302,1345],{"class":144},[120,2304,2305],{"class":122,"line":1441},[120,2306,152],{"emptyLinePlaceholder":151},[120,2308,2309,2311,2314],{"class":122,"line":1458},[120,2310,1893],{"class":126},[120,2312,2313],{"class":140}," loadComponent",[120,2315,1867],{"class":144},[120,2317,2318,2320,2323,2325,2327],{"class":122,"line":1471},[120,2319,1872],{"class":130},[120,2321,2322],{"class":144},".renderComponent ",[120,2324,791],{"class":126},[120,2326,2064],{"class":130},[120,2328,2329],{"class":144},".lazyComponent;\n",[120,2331,2332,2334,2336,2339,2341,2344],{"class":122,"line":1486},[120,2333,1872],{"class":130},[120,2335,1875],{"class":144},[120,2337,2338],{"class":140},"$emit",[120,2340,177],{"class":144},[120,2342,2343],{"class":180},"\"loaded\"",[120,2345,1299],{"class":144},[120,2347,2348],{"class":122,"line":1495},[120,2349,1345],{"class":144},[120,2351,2352],{"class":122,"line":1500},[120,2353,152],{"emptyLinePlaceholder":151},[120,2355,2357,2359,2362],{"class":122,"line":2356},80,[120,2358,1277],{"class":126},[120,2360,2361],{"class":140}," destroyed",[120,2363,1867],{"class":144},[120,2365,2367,2369,2371,2374,2376,2378,2380],{"class":122,"line":2366},81,[120,2368,1872],{"class":130},[120,2370,1940],{"class":144},[120,2372,2373],{"class":126},"&&",[120,2375,2064],{"class":130},[120,2377,2049],{"class":144},[120,2379,215],{"class":140},[120,2381,218],{"class":144},[120,2383,2385],{"class":122,"line":2384},82,[120,2386,1345],{"class":144},[120,2388,2390],{"class":122,"line":2389},83,[120,2391,1351],{"class":144},[120,2393,2395,2397,2399],{"class":122,"line":2394},84,[120,2396,1163],{"class":144},[120,2398,1180],{"class":726},[120,2400,730],{"class":144},[38,2402,2403],{"id":2403},"每日一题",[111,2405,2408],{"className":2406,"code":2407,"language":506},[504],"https:\u002F\u002Fgithub.com\u002FWindrunnerMax\u002FEveryDay\n",[18,2409,2407],{"__ignoreMap":116},[38,2411,2412],{"id":2412},"参考",[111,2414,2417],{"className":2415,"code":2416,"language":506},[504],"https:\u002F\u002Fwww.ruanyifeng.com\u002Fblog\u002F2016\u002F11\u002Fintersectionobserver_api.html\nhttps:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FAPI\u002FIntersectionObserver\nhttps:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FAPI\u002FWindow\u002FrequestIdleCallback\n",[18,2418,2416],{"__ignoreMap":116},[1373,2420,2421],{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .s7hpK, html code.shiki .s7hpK{--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-dark:#FDAEB7;--shiki-dark-font-style:italic}",{"title":116,"searchDepth":148,"depth":148,"links":2423},[2424,2428,2429,2430],{"id":40,"depth":148,"text":40,"children":2425},[2426,2427],{"id":73,"depth":155,"text":31},{"id":511,"depth":155,"text":35},{"id":591,"depth":148,"text":591},{"id":2403,"depth":148,"text":2403},{"id":2412,"depth":148,"text":2412},"简单实现一个Vue首屏性能优化组件，现代化浏览器提供了很多新接口，在不考虑IE兼容性的情况下，这些接口可以很大程度上减少编写代码的工作量以及做一些性能优化方面的事情，当然为了考虑IE我们也可以在封装组件的时候为其兜底，本文的首屏性能优化组件主要是使用IntersectionObserver以及requestIdleCallback两个接口。","md",{},"\u002Fvue\u002Fvue首屏性能优化组件",{"title":5,"description":2431},"Vue\u002FVue首屏性能优化组件","xVROXmEKAFmCnJ22X5h9uNnrLhiBRWLKiiqMvvQHlaQ",1791042472299]