淺談前端頁面性能以及優(yōu)化實(shí)踐

什么是性能
? ? ? 我理解的就是滿足用戶體驗(yàn),在最優(yōu)的時(shí)間能讓用戶看到頁面內(nèi)容,留住用戶。

前序---js在網(wǎng)頁端的執(zhí)行環(huán)境-瀏覽器
? ? ? 參考:http://www.itdecent.cn/p/33f1c67bf381

一、頁面性能的衡量的輔助工具--?Performance Timing Api

瀏覽器提供了一些能力讓我們做性能優(yōu)化,判斷頁面的性能好壞,它的關(guān)鍵是每個(gè)關(guān)鍵節(jié)點(diǎn)的事件回調(diào),在回調(diào)中可以打印時(shí)間戳。根據(jù)相關(guān)標(biāo)準(zhǔn)或者公司規(guī)定找到優(yōu)化點(diǎn)。

先了解瀏覽器運(yùn)行過程中與性能關(guān)乎的幾個(gè)大部分

Navigation Timing Api

1. navigationStart 從上一個(gè)頁面開始要進(jìn)行跳轉(zhuǎn)的最初鉤子

2. unloadEventStart / End 表示前一個(gè)頁面unload的時(shí)間點(diǎn)

3. redirectStart / End? 頁面重定向發(fā)生的事件開始 & 結(jié)束

4.fetchStart / End? 瀏覽器準(zhǔn)備好用http請(qǐng)求抓取文檔的時(shí)間(準(zhǔn)備時(shí)間)

5. domainLookupStart / End http開始/重新建立連接的時(shí)間
? ? ?問題:如果是長連接,需要從哪個(gè)時(shí)間段獲取當(dāng)前建立時(shí)間,長連接是持久不會(huì)中斷的鏈接,長連接的結(jié)束是抓取文檔結(jié)束
? ? 不同版本的http協(xié)議,對(duì)于tcp 的兼容性或者實(shí)現(xiàn)方式不同 1.0 是一次請(qǐng)求建立一次TCP鏈接,1.1建立一次TCP鏈接可以復(fù)用, 2.0 可以多幀傳遞,將一次請(qǐng)求分為多幀,按照幀結(jié)構(gòu)發(fā)送數(shù)據(jù)

6. connectStart / End 開始鏈接的時(shí)間
? ? 所有跟前后端相關(guān)的都在這個(gè)階段,自己包含前后端,純數(shù)據(jù)鏈接的事情

7. secureConnectionStart / End http加密通路開始的時(shí)間和結(jié)束的時(shí)間

8. requestStart? / End 請(qǐng)求花費(fèi)的時(shí)間

9. responseStart / End 返回花費(fèi)的時(shí)間

10. domLoading (loading interactive ready三合一 )
?開始渲染dom樹的時(shí)間
? ? ?和它對(duì)應(yīng)的還有domInteractive,代表完成dom解析的時(shí)間
domContentEventStart / End 代表dom解析完成后,網(wǎng)頁內(nèi)部資源開始加載和結(jié)束時(shí)間
domComplete代表dom解析完成

11. loadEventStart / End 代表load事件回調(diào)函數(shù)執(zhí)行完畢的點(diǎn)

使用:
// index.html

<script>
? ? ?javascript:(() => {
? ? ? ? var perfData = window.performance.timing
? ? ? ? var pageLoadTime = perfData.loadEventEnd -?perfData.navigationStart
console.log('頁面加載耗時(shí)', pageLoadTime,‘ms’)
? ? ?})()
</script>

問題匯總

如何建立一個(gè)長連接
1、建立一個(gè)websoket
? ? ? 一定要記得銷毀
2、開啟一個(gè)keep-alive,與后臺(tái)溝通好,某一次請(qǐng)求是keep-alive的長連接,這個(gè)請(qǐng)求一定會(huì)等到后臺(tái)或者網(wǎng)關(guān)、中間層等返回超時(shí)才會(huì)斷掉,不然會(huì)一直等到鏈接有返回

udp:發(fā)布消息,不確定一定會(huì)受到
tcp:發(fā)布消息有回應(yīng),三次握手

http與https的區(qū)別

單頁面有重定向嗎?沒有
? ? 單頁面路由應(yīng)用內(nèi)部是前端內(nèi)部自己控制的單個(gè)組件之間的路轉(zhuǎn),不會(huì)經(jīng)過performance navigation timing api的階段。
單頁應(yīng)用的app實(shí)例是不會(huì)被銷毀的,可以在路由導(dǎo)航守衛(wèi)里去時(shí)間戳的差

加載頁面時(shí),載入條從0到100發(fā)生了社么?
? ?載入條從加載到加載滿不包含dom渲染。從重排之后,開始渲染的時(shí)候就加載完了。(這才引深了要不要加載骨架屏、loading框等,loading框本身也是dom)。載入條完成代表頁面組織好,重排好,開始渲染了。

為什么有的頁面載入條加載完了,頁面依然沒內(nèi)容?
? ? ?因?yàn)殇秩究赡芤蕾嚻渌蛩?,比如說v-if,有邏輯被padding住了, js線程堵塞了dom渲染

只要用瀏覽器就可以使用這些api,單頁面用不到這些api,單頁面只有一個(gè)頁面,是通過路由切換頁面,可以在代碼里打印出來的,沒必要用這些api

ajax的接口性能怎么拿?
? ?ajax工具的攔截器上拿

http cache
? ?302,重定向,origin來源有個(gè)cache,來自緩存

http cache + dns是一個(gè)完整的尋址過程
dns地址解析過程?
? ?本機(jī)->路由器->供應(yīng)商本地機(jī)房->區(qū)域核心機(jī)房->......->根服務(wù)器

單頁面加載性能、接口性能、資源性能、運(yùn)行時(shí)幀數(shù)
? ? 加載性能:導(dǎo)航守衛(wèi)
? ? 接口性能:接口工具攔截器
? ? 資源性能:
? ? ? ? ? 單頁分兩種:一種cdn遠(yuǎn)端加載一種是本地加載。
? ? ? 本地加載性能是把當(dāng)前資源加載的時(shí)間計(jì)算出來,
? ? ? cdn資源是fetch抓取文檔的時(shí)間
? ? 運(yùn)行幀數(shù):

loadEventEnd-loadEventStart就是window.load回調(diào)函數(shù)執(zhí)行時(shí)間

瀏覽器是從dominteractive這個(gè)時(shí)間點(diǎn)開始第一次“事件循環(huán)”的嗎?

二、 頁面性能的核心指標(biāo)

標(biāo)準(zhǔn):谷歌提出的網(wǎng)頁性能的核心指標(biāo)-core web vitals,可衡量的,并且反應(yīng)真實(shí)體驗(yàn):加載、交互、視覺穩(wěn)定性

1、LCP(largest contentful paint)最大內(nèi)容渲染
? ? ?衡量頁面的裝載性能,前2.5s內(nèi)進(jìn)行最大內(nèi)容的渲染。

a. 最大內(nèi)容包含什么?
? ?-<img>元素
? -<svg>元素
? -<video>元素
-通過url加載的背景圖片
-包含了文本節(jié)點(diǎn)或其他內(nèi)聯(lián)文元素的塊級(jí)元素

b.LCP值低下的原因
?-服務(wù)響應(yīng)慢
?-阻斷渲染的js和css
?-資源的加載
?-項(xiàng)目的渲染

c. 針對(duì)改造(優(yōu)化)
?-緩存? 離線頁面、請(qǐng)求內(nèi)容的緩存、資源緩存=>減少服務(wù)的請(qǐng)求 | 減少服務(wù)的查詢=>強(qiáng)緩存、協(xié)商緩存 | 緩存機(jī)制

渲染的阻斷:css | js進(jìn)行壓縮、合并、內(nèi)聯(lián);后置js邏輯

對(duì)于文件的優(yōu)化=>對(duì)于格式的優(yōu)化 轉(zhuǎn)化圖片的格式為JPG或者webp=>圖片格式 =>加載和顯示 | 云資源管理

工程化:打包優(yōu)化-壓縮、分片、異步、懶加載
框架層面-首屏加載問題,拆分、異步模塊、統(tǒng)一封裝
寫法-減少網(wǎng)絡(luò)請(qǐng)求、及時(shí)清理垃圾

cdn怎么找到最近的節(jié)點(diǎn)的?
? ? 主要的路徑訪問的是主路徑的服務(wù),靜態(tài)資源經(jīng)過統(tǒng)一的cdn服務(wù)商,服務(wù)商分發(fā)具體的ip,在找ip的時(shí)候就找過去了
? ?cdn緩存,有時(shí)需要手動(dòng)更新

2、FID(first iput delay)第一次輸入延遲
? ?頁面首頁輸入延遲應(yīng)該小于100ms
? ? 衡量交互

造成FID的原因:
a. js執(zhí)行時(shí)間過長
? ? ?-縮小壓縮js文件
? ? ?-延遲加載不要的js邏輯
? ? -盡量減少未使用的ployfill(新的api讓任何版本瀏覽器都兼容)
? ?b. 分解耗時(shí)任務(wù)
? ? ? ? -50ms長任務(wù) (比如提交表單,不要提交時(shí)才提示,不能提交就不給表單權(quán)限)
? ? ? ?- 長任務(wù)拆分成前置、后置或者多個(gè)短任務(wù)
c. workers
? 通過woker提高執(zhí)行效率,并實(shí)時(shí)同步

3、CLS (cumulative layout shift)頁面布局變化的頻率
? 衡量視覺穩(wěn)定性
? ? ?元素布局移動(dòng)可能發(fā)生的位置偏移量

? ? ?a. 不使用無尺寸元素
? ? ? ? ? 比如:圖片,外邊框有寬高
? ? ? b. 減少內(nèi)部內(nèi)容的插入
? ? ? ? ? 插入內(nèi)容把高度預(yù)留好,減少抖動(dòng)
? ? ? c. 字體的控制,默認(rèn)字體為先=>本地替換字體=>加載字體
? ? ? ? ?全局字體的統(tǒng)一

4,其他指標(biāo)
? ? ?FMP:首次有意義的渲染
? ? ?白屏率:白屏率指標(biāo)(4s or 6s), 從用戶點(diǎn)擊之后6s后截屏,如果是白屏或者有顏色的屏幕則計(jì)入白屏率,白屏次數(shù)/總進(jìn)入次數(shù)
舉例:

三、性能評(píng)估神器--CWV工具-core?
? ? ?下載參考:https://www.chajianxw.com/developer/26697.html
? ? ? 指標(biāo)參考:http://www.itdecent.cn/p/5b6a7c947f42

四、大廠的監(jiān)控體系
? ? ? a)埋點(diǎn)上報(bào) =>點(diǎn)到點(diǎn)上報(bào)(關(guān)心的上報(bào))+ 信息采集匯總
? ? ?b) 數(shù)據(jù)處理 =>閾值設(shè)置 / 數(shù)據(jù)分類(前端、后端、node)/ 數(shù)據(jù)重組
? ? ?c) 可視化展現(xiàn) =>grafana /自研報(bào)表
? ? ? d) 告警處理 => 告警觸發(fā) / 觸發(fā)分派 =>通過一定途徑分發(fā)

未來的可能-bigpipe
? ?本質(zhì):頁面分解為若干pagelet
? ? 1、服務(wù)端接收來自客戶端的http請(qǐng)求
? ? 2、從存儲(chǔ)層獲取數(shù)據(jù)
? ? 3、生成HTML,作為部分模塊的基礎(chǔ)
? ? 4. 瀏覽器回去解析內(nèi)容,遺留區(qū)域作為展示面板進(jìn)行客戶端渲染
? ? 5、加載渲染生成

五、問題匯總

項(xiàng)目發(fā)布后,配置了文件名hash,不希望用戶有手動(dòng)刷新這個(gè)操作如何實(shí)現(xiàn)?
1、不刷新做到實(shí)時(shí)更新不太可能,靜態(tài)資源不會(huì)主動(dòng)更新
? ? ?獲取新資源的方式
? ? ? 1、通知您的當(dāng)前頁面頁面有更新,請(qǐng)手動(dòng)刷新。
? ? ? ? 2、頁面停留或者使用超過一定時(shí)間,自動(dòng)登出,要求用戶重新登陸。

online表單與普通表單的區(qū)別
? ?online表單是json-sgram生成表單

頁面交互過程中,檢測到頁面js執(zhí)行報(bào)錯(cuò),怎么阻止頁面白屏?
? ?js報(bào)錯(cuò)之后已經(jīng)晚了,需要做的是在渲染之后再加載js,舉個(gè)例子,渲染表格在請(qǐng)求到數(shù)據(jù)后有3s的時(shí)間前端需要處理數(shù)據(jù)才能組裝成表格數(shù)據(jù),則我們需要把數(shù)據(jù)拉過來,mounted之后再對(duì)數(shù)據(jù)進(jìn)行處理,這樣頁面會(huì)先渲染表格,之后再把數(shù)據(jù)填到表格。
? ?這時(shí)會(huì)涉及到表格閃一下,則可以加loading框等

iframe
? 父子應(yīng)用的window是否是一個(gè)
? ?父子應(yīng)用是同域是window是一個(gè),外部可以拿到內(nèi)部的東西;
非同域情況,外部拿不到內(nèi)部東西
只要window不一樣,他們的瀏覽器相關(guān)的api都不一樣。

六、性能優(yōu)化

1、js性能優(yōu)化

參考:https://csspod.com/frontend-performance-best-practices/

2、 前端框架-單頁應(yīng)用相關(guān)性能

(1)性能優(yōu)化的目標(biāo)
? ? ? 性能優(yōu)化需要針對(duì)不同的項(xiàng)目,具體問題具體分析,根據(jù)性能數(shù)據(jù)分析, 定位影響加載時(shí)長的階段,分析監(jiān)控?cái)?shù)據(jù)得出預(yù)期能優(yōu)化到的目標(biāo),比如:接口如果返回?cái)?shù)據(jù)需要1000ms,那么這個(gè)數(shù)據(jù)必然存在優(yōu)化空間的,再比預(yù)取數(shù)據(jù)數(shù)據(jù)可以在init的時(shí)候調(diào)用接口,偏偏在mounted里調(diào)用,顯然也存在優(yōu)化空間等等,這也說明性能優(yōu)化不只是前端或者后端的問題,是前后端配合或者都需要參與的工作。

(2)可優(yōu)化的方面
1、整體方面
? ? ? prelink:提前建立鏈接,提前發(fā)送預(yù)連接請(qǐng)求,將連接放入連接池,使用時(shí)直接拿出,節(jié)省DNS查詢和建立TCP連接的時(shí)間
? ? ?預(yù)請(qǐng)求:提前請(qǐng)求接口數(shù)據(jù)
? ? ?預(yù)加載:提前加載js代碼包
? ? 骨架屏:提升用戶體驗(yàn)
? ? redis緩存、數(shù)據(jù)庫遷移釋放空間
? ?按需加載:https://www.cnblogs.com/ToBeBest/p/13404617.html

2、頁面方面
? ? ? ? (1)預(yù)取數(shù)據(jù)/預(yù)加載? ?(prefetch\preload: https://juejin.cn/post/6893681741240909832)
? ? ? ? (2)非核心請(qǐng)求后置:將啟動(dòng)階段的非核心請(qǐng)求(例如日志后置)在FMP之后被發(fā)送,減少核心請(qǐng)求的響應(yīng)時(shí)間,設(shè)置defer: true,減少首屏數(shù)據(jù)的邏輯處理,減少setdata次數(shù),減少http/https請(qǐng)求次數(shù),雪碧圖、文件壓縮打包
? ? ? ? (3)cdn緩存:靜態(tài)資源緩存如(react、react-dom、axios等),異步加載 script加載??( defer:在HTML解析完之后才會(huì)執(zhí)行。如果是多個(gè),則按照加載的順序依次執(zhí)行。async:在加載完之后立即執(zhí)行。如果是多個(gè),執(zhí)行順序和加載順序無關(guān)。)
? ? ? ?(4)避免組建重復(fù)打包:在webpack的config文件中,修改commonChunkPlugin的配置minChunks為2,這樣就會(huì)把使用2次以上的包打包到公共文件中,避免重復(fù)加載組件。
? ? ? ?(5)tree-shaking 刪除冗余代碼
? ? ? ?(6)圖片懶加載 / 圖片壓縮 / 小圖片圖文字體或者base64
? ? ? ?(7)分屏渲染:首次進(jìn)入頁面只渲染可視范圍的內(nèi)容,首次渲染結(jié)束,再異步渲染剩下的,列表只渲染幾條,列表數(shù)據(jù)可以前端拆也可以獲取到的就是幾條,第二屏的內(nèi)容可以通過事件觸發(fā)渲染(滑動(dòng)頁面),除了縱向,橫向也可能超過一屏,例如swiper

3、第三方插件方面
? ? ? ? 框架版本升級(jí),接入優(yōu)化包(appjs 拆分,apack,css-module)
? ? ? ? 預(yù)加載/懶加載
? ? ? ? cdn緩存
? ? ? ?UI框架按需加載,例如:import { button } from 'elementUI'

4、打包工具,以webpack為例
? ? ? ? 減收主包體積的手段:分包減少包加載耗時(shí)
? ? ? ? (1)動(dòng)態(tài)加載路由,減少入口文件體積:es6的import()方法與webpack的require.essure()都可以根據(jù)動(dòng)態(tài)加載的組件來生成單獨(dú)的chunk進(jìn)行分包;
? ? ? ? 框架版本升級(jí)
? ? ? ?(2)webpack提升打包速度
? ? ? ? ? 1、配置 resolve.modules? ?減少檢索路徑
? ? ? ? ? 2、配置裝載機(jī)的 include & exclude??減少目錄檢索范圍 在使用 loader 的時(shí)候,通過指定 exclude 和 incude 選項(xiàng),減少 loader 遍歷的目錄范圍,從而加快 Webpack 編譯速度。? ? ? ?
? ? ? ? ? 3、使用 webpack-parallel-uglify-plugin 插件來壓縮代碼
? ? ? ? ? 4、使用 HappyPack 來加速代碼構(gòu)建
? ? ? ? ? 5、利用 DllPlugin 和 DllReferencePlugin 預(yù)編譯資源模塊-拆分bundles

? ? ?(3)webpack優(yōu)化打包的大小,減小打包體積
? ? ? ? ? 1、?Tree Shaking??Tree Shaking 可以實(shí)現(xiàn)刪除項(xiàng)目中未被引用的代碼??webpack4的話,開啟生產(chǎn)環(huán)境就會(huì)自動(dòng)啟動(dòng)這個(gè)優(yōu)化功能。
? ????????2、 splitchunkspluginwebapck4抽取公共模塊“SplitChunksPlugin”?commenChunkPlugin?提取公共代碼組件
? ? ? ? ??3、合理使用 sourceMap (去除devtool選項(xiàng)?)
?????????????很多教程都會(huì)教你在webpack.config.js設(shè)置devtool選項(xiàng),比如:devtool:'eval-source-map'。但是這只適用于開發(fā)環(huán)境,這會(huì)導(dǎo)致打包的文件往往有幾M,所以在生產(chǎn)環(huán)境必須要去除掉此配置。
? ??????????把部分依賴轉(zhuǎn)移到 CDN 上,避免在每次編譯過程中都由 Webpack 處理,通過script加載(externals將第三方庫以cdn的方式去引入? ? ? ? ? ? ? ? ? ? ? ? ????????????????https://www.cnblogs.com/ssh-007/p/7944491.html)
? ? ? ? ? ? 4、 使用 webpack-parallel-uglify-plugin 插件來壓縮代碼
? ? ? ? ? ? 5、? ?分離css。安裝插件 npm install extract-text-webpack-plugin --save

5、秒開實(shí)踐
? ? ?https://smartprogram.baidu.com/docs/develop/performance/experience/

6、自測數(shù)據(jù)獲取方法
? ? ? ??(1)獲取方法運(yùn)行時(shí)長
? ? ? ? ? ? ? ? ?console.time 和 console.timeEnd
? ? ? ? (2) 準(zhǔn)確獲取首屏加載時(shí)間
? ? ? ? ? ? ? ??https://blog.csdn.net/qq_34595425/article/details/132725747
? ? ? ? (3)獲取首頁圖片的加載時(shí)長
? ? ? ? ? ? ? ? ?針對(duì)某張圖片:imagesloaded插件(done / fail / progress)

優(yōu)化并不是一氣呵成的事兒,而且隨著迭代開發(fā)也會(huì)出現(xiàn)新的性能問題,總體來說我們可以分步驟,從整體到頁面再到投放渠道逐步進(jìn)行,且多方協(xié)商合作效果可能更顯著
?整體:前端,預(yù)加載、預(yù)鏈接、預(yù)請(qǐng)求、骨架屏
? ? ? ? ? ? 后端,緩存、數(shù)據(jù)庫遷移空間釋放
頁面:前端,本地圖片壓縮、分屏數(shù)據(jù)、首頁數(shù)據(jù)緩存、圖片懶加載、data對(duì)象優(yōu)化
? ? ? ? ? ?后端,接口數(shù)據(jù)優(yōu)化,cdn
投放渠道:集中投放時(shí)間點(diǎn)錯(cuò)開、全量加載

性能優(yōu)化文檔匯總:https://www.cnblogs.com/feiyu6/p/7262778.html
? ? ?https://blog.csdn.net/qq_42072086/article/details/110849890

7,項(xiàng)目實(shí)踐-bd小程序

FMP理論標(biāo)準(zhǔn)

(1)指標(biāo)含義

80分位FMP
? ? ?NA有意義的渲染時(shí)長(整體),正排后取80分位

計(jì)算方式:
Android:小程序啟動(dòng)過程中,dom tree構(gòu)建時(shí)觸發(fā)NA webview的layout布局,當(dāng)layout布局完成后,開始渲染內(nèi)容。內(nèi)容渲染高度超過當(dāng)前屏幕的時(shí)間。 (結(jié)束點(diǎn)通過T7內(nèi)核domFirstScreenPaint NA回調(diào)收集)
IOS:小程序啟動(dòng)過程中,dom tree構(gòu)建時(shí)觸發(fā)NA webview的layout布局高度超過當(dāng)前屏幕的時(shí)間

4s白屏率
指標(biāo)含義:WebView 有意義的渲染時(shí)長超過4s的白屏比例

計(jì)算方式:WebView 的Fmp超過4s計(jì)為1次白屏pv,4s白屏率 = 白屏pv / 啟動(dòng)pv

6s白屏率(B端白屏)
指標(biāo)含義:用戶觸發(fā)頁面打開后,6s后仍然沒有任何頁面繪制,則認(rèn)定為白屏

計(jì)算方式:從用戶點(diǎn)擊小程序入口開始計(jì)算時(shí)間,6s后進(jìn)行截圖分析。當(dāng)截圖為空白頁面或只有背景色,則記為一次白屏

到達(dá)率
指標(biāo)含義:WebView有意義渲染成功的比例

計(jì)算方式:FMP到達(dá)次數(shù)/調(diào)起次數(shù)

(2)優(yōu)化目標(biāo)
? ? ? ? ?Android:2.2s,IOS:1.0s

(3)性能現(xiàn)狀

我們的小程序,整體差很多,安卓?3.378s(目標(biāo)2.2s),IOS?1.078s(目標(biāo)1.0s

(4)優(yōu)化方案

? ? ??階段一: 整體優(yōu)化;

? ? ? ?階段二:頁面優(yōu)化和渠道優(yōu)化并行推進(jìn)優(yōu)化。高流量重點(diǎn)頁面優(yōu)先優(yōu)化(流量占比1%以上);低流量和渠道推進(jìn)優(yōu)化

(5)優(yōu)化結(jié)果

我們雙端收益均相對(duì)理想:

Android :fmp80 從?3378ms → 1789ms?(下降 47.04%)、4s白屏從?13.98%→ 2.81%?(下降 79.90%)、6s白屏從?0.91%?→ 0.26%?(下降71.43%)、到達(dá)率從?73.00%?→ 92.43%?(升高26.62%)

IOS:fmp80?從1078ms → 710ms(下降 34.14%)、4s白屏從?2.72%→ 1.30%?(下降?52.20%)、6s白屏從?0.94%?→ 0.52%?(下降44.68%)、到達(dá)率從?86.02%?→ 97.71%?(升高13.59%)

2. 優(yōu)化時(shí)間關(guān)鍵點(diǎn)說明:

以Android為例進(jìn)行說明。

Android 性能趨勢圖:

(5) 優(yōu)化盤點(diǎn)及收益說明

在小程序上做的優(yōu)化及收益,盤點(diǎn)如下:

(6)統(tǒng)計(jì)平臺(tái)匯總

1. 小程序-性能統(tǒng)計(jì)平臺(tái):
2. showx小程序性能平臺(tái)(可用于和其他小程序?qū)Ρ龋?br>3. 小程序B端:
4. 前端接口時(shí)長/性能統(tǒng)計(jì)平臺(tái):

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容