프런트 엔드 성능 최적화의 목적은 페이지 로드 속도를 높이고 사용자에게 더 나은 사용자 경험을 제공하는 것입니다. 그렇다면 프런트 엔드 성능을 최적화하는 방법은 무엇입니까? 구체적으로 어떻게 해야 할까요? 다음 문서에서는 프런트 엔드 성능 최적화에 대한 몇 가지 지식 포인트를 소개합니다.
다음 세 가지 질문을 계속해서 읽어보세요.
그렇다면 대답은 어디에 있습니까?
create-react-app
프로젝트를 초기화합니다. 두부 블록, Header, Bar
, 긴 스크롤 ScrollView
등 홈페이지에 일부 구성 요소를 작성합니다. 그런 다음 프로젝트가 컴파일되고 패키징되어 온라인에 게시됩니다. create-react-app
初始化一个项目吧。 首页写好一些组件,例如豆腐块、Header、Bar
、长滚动ScrollView
。然后项目编译、打包上线。
webpack
手搭一个项目。
路由按需加载弄上,可无痕浏览的带loadmore
的高性能ScrollList
。
因为是首页,明显会牵扯到首屏幕加载的问题。那骨架屏给安排上吧。
再搞一套webpack的最佳实践,目的是能最终得到体积尽量小的打包文件。
SSR来一套吧。因为首页DOM结构太复杂了,如果走Virtual DOM
那一套,等到GPU渲染UI就太慢了。
以上,有命中你的某个点吗? 不管有木有道理,这是你想到的点吗?是不是总感觉好像少了点什么?
本篇文章不细讲其它内容。 但到这了就得提一嘴,留个印象。
- 系统层设计
- 一个新系统留20%来满足当前已有业务。 剩下80% 用来系统演进。可以思考下,天猫首页一直变,却依然能保证性能达标。
- 业务层设计
- 已有业务是否与其它业务产生了耦合,是否存在前置业务,如果有那前置业务的权限又在哪里。已有业务是否能根据系统演进程度不断兼容新业务?
- 应用层设计
- 例如微前端,例如组件库,例如
npm install
- webpack优化
- 骨架屏
- 路有动态按需加载
- 代码层设计
- 写好高性能React 代码?如何利用好Vue3 时间切片?
- 不说了。太初级的浪费慢慢积累就好。
所以,你应该发现了“总感觉好像少了点什么” 是少在哪里了。对,前端性能优化不仅仅是应用层面、代码层的优化,更重要的是系统层、业务层的优化。
看了以上的心理预设,那接下来就进入正式进入主题吧。
尝试着走完下面这个流程:
性能指标设定(FPS、页面秒开率、报错率、请求数等)
性能标准确定
收益评估
诊断清单
优化手段
Hybrid APP 性能优化
首评秒开的X种方法?
骨架屏
NSR
SSR
webView
webpack
프로젝트를 직접 빌드합니다. 🎜🎜🎜🎜Routing🎜주문형 로딩🎜눈에 보이지 않는 탐색을 위해 loadmore
를 사용하여 고성능 ScrollList
를 받으세요. 🎜🎜🎜🎜홈페이지이기 때문에 당연히 첫 화면 로딩 문제가 있을 겁니다. 그런 다음 🎜골격 화면🎜을 정리하세요. 🎜🎜🎜🎜 가능한 한 크기가 작은 패키지 파일을 얻는 것을 목표로 웹팩 모범 사례 세트를 개발해 보겠습니다. 🎜🎜🎜🎜SSR세트 구매하세요. 홈페이지의 DOM 구조가 너무 복잡하기 때문에 Virtual DOM
을 사용하면 GPU가 UI를 렌더링할 때까지 너무 느려집니다. 🎜🎜🎜🎜🎜🎜🎜위의 문제 중 하나라도 해당되셨나요? 말이 되든 안 되든, 당신은 이렇게 생각하나요? 항상 뭔가 빠진 듯한 느낌이 드시나요? 🎜🎜🎜이 글에서는 다른 콘텐츠에 대해 자세히 다루지 않습니다. 하지만 여기서는 언급하고 인상을 남겨야합니다. 🎜🎜🎜시스템 레이어 디자인🎜🎜현재 비즈니스를 만족시키기 위해 새로운 시스템은 20%를 남겨둡니다. 나머지 80%는 시스템 진화에 사용됩니다. 생각해보면 Tmall 홈페이지는 계속 바뀌지만 성능은 여전히 표준에 도달한다는 것을 보장할 수 있습니다. 🎜🎜🎜🎜비즈니스 레이어 디자인🎜🎜기존 사업이 다른 사업과 결합되어 있는지, 프런트엔드 사업이 있는지, 그렇다면 프런트엔드 사업의 권한은 무엇인가요? 시스템 진화 정도에 따라 기존 서비스가 새로운 서비스와 지속적으로 호환될 수 있나요? 🎜🎜🎜🎜애플리케이션 레이어 디자인🎜🎜예: npm install
과 같은 구성 요소 라이브러리와 같은 마이크로 프런트 엔드🎜🎜webpack 최적화🎜🎜Skeleton screen🎜🎜Road에는 동적 온디맨드 로딩이 있습니다. 🎜🎜🎜🎜코드 레이어 디자인 🎜🎜고성능 React 코드를 작성하시겠습니까? Vue3 타임 슬라이싱을 잘 활용하는 방법은 무엇입니까? 🎜🎜더 이상은 없습니다. 너무 초보적인 쓰레기는 천천히 쌓일 수 있습니다. 🎜🎜🎜🎜
🎜그러면 "🎜항상 뭔가 빠진 듯한 느낌🎜"이라는 사실을 발견했어야 했는데 무엇이 빠졌나요? 그렇습니다. 프런트엔드 성능 최적화는 애플리케이션 계층과 코드 계층의 최적화뿐만 아니라 더 중요한 것은 시스템 계층과 비즈니스 계층의 최적화입니다. 🎜🎜위의 심리 사전 설정을 읽은 후 공식 주제로 들어가 보겠습니다. 🎜NSR
🎜🎜🎜🎜SSR
🎜🎜🎜🎜webView
레이어 및 코드 아키텍처 수준 최적화🎜성능 개선 아이템
성능연습
이제 프런트 엔드 성능 최적화에 대해 완전히 이해하셨나요? 성능 최적화에 대해 이야기할 때 먼저 성능을 "진단"하는 방법에 대해 이야기해야 하는 경우가 많습니다. 대부분의 경우 성능을 모니터링하는 방법을 묻지 않습니다. (목소리가 점점 낮아지네요...)
다음으로 최적화 방법에 대해 자세히 이야기해보겠습니다
그 중 하나 가장 일반적인 최적화 방법.
지연 로딩은 긴 페이지 로딩 프로세스 중에 주요 콘텐츠가 먼저 로드되고 중요하지 않은 콘텐츠는 지연된다는 의미입니다. 예를 들어, 페이지를 열었고 그 콘텐츠가 브라우저의 표시 영역을 초과하는 경우 프런트 엔드 표시 영역 콘텐츠를 먼저 로드한 다음 요청에 따라 표시 영역에 들어간 후 나머지 콘텐츠를 로드할 수 있습니다.
밤 하나 주세요. 티몰 홈페이지에 선정되었습니다. 위 그림.
공교롭게도 티몰 618 이벤트에요. Tmall 홈페이지의 IOS 버전 선택입니다. Tmall 홈페이지 셀렉션을 자주 방문하시면 거의 투명 브라우징이 활성화되어 있는 것을 보실 수 있습니다. 여기서는 지연 로딩이 매우 잘 사용됩니다. 물론 이러한 효과를 얻는 것은 지연 로딩만이 아닙니다.
그냥 게으른 로딩인데, Tmall 홈페이지 선택은 무엇을 하나요? 추측해보세요.
지연 로딩
네이티브
에 의해 캐시됩니다. native
做过缓存的。List
滚动高度发生很大变化,那请求数据最终还是会敌不过你的高速滑动。也就是说,在没有新的数据之前你看不到下一张卡片了,这是你必须等待了。这时候就会有一个loading
的动画显示,接着等拿到了新数据,新卡片就会出现并且自动完全滑入可视区域。IOS
的阻尼本来就会使得动画、滚动效果更加顺畅。在这里为想说的是,Android
애니메이션의 지연 로딩
List
의 스크롤 높이가 크게 변경되면 요청한 데이터가 결국 고속 슬라이딩과 경쟁할 수 없게 됩니다. 즉, 새로운 데이터가 나올 때까지 다음 카드를 볼 수 없기 때문에 기다려야 한다는 것이다. 이때 로드
애니메이션이 표시되고, 새로운 데이터를 획득하면 새 카드가 나타나고 자동으로 보이는 영역으로 완전히 미끄러집니다. 어떤 사람들은 IOS
의 댐핑으로 인해 애니메이션과 스크롤 효과가 더 부드러워졌을 것이라고 말할 수도 있습니다. 여기서 말씀드리고 싶은 점은 안드로이드
도 사용 가능하다는 점입니다.
2. 캐싱
지연 로딩의 핵심이 첫 번째 화면 이후에 중요하지 않은 콘텐츠를 요청할 수 있는 기능을 제공하는 것이라면, 캐싱은 반복적인 요청 없이 2차 방문을 할 수 있는 기능을 제공하는 것입니다. 첫 번째 화면 최적화 솔루션에서는 인터페이스 캐싱과 정적 리소스 캐싱이 주요 역할을 합니다. 방금 지연 로딩에 대한 질문으로 돌아가서, 왜 새로운 데이터가 없는 상황이 발생하기 전에 잠시 동안 화면을 빠르게 스와이프해야 합니까? 그 이유는 캐시된 데이터가 모두 소진되어 서버에서 최신 데이터만 제공할 수 있기 때문입니다.인터페이스 캐시
인터페이스 캐시 구현이 최종인 경우 모든 요청은 기본 요청을 거쳐 인터페이스 캐시를 구현합니다. 왜 이런 일을 하는가?그렇다면 네이티브를 통해 인터페이스를 캐시하는 방법은 무엇일까요?
이를 달성하기 위해 SDK 캡슐화를 사용할 수 있습니다. 즉, 원래 데이터 인터페이스 요청 방법을 수정하여 Axios와 유사한 요청 방법을 구현할 수 있습니다. 특히 게시, 가져오기 및 요청 기능을 포함한 인터페이스가 SDK에 캡슐화됩니다. 🎜🎜🎜이런 방식으로 클라이언트가 요청을 시작하면 프로그램은 SDK.axios 메서드를 호출합니다. WebView는 요청을 가로채서 앱에 로컬로 데이터 캐시가 있는지 확인합니다. 그렇지 않은 경우 먼저 서버가 데이터 인터페이스를 요청하고 인터페이스 데이터를 획득하여 앱 캐시에 저장합니다. 🎜🎜🎜🎜🎜정적 리소스 캐싱🎜 먼저 사진을 보세요. 🎜🎜🎜🎜🎜🎜요청 91개, 전송량 113kB, 리소스 2.2MB, 완료: 2.93초, DOMContentLoaded: 177ms.
리소스 2.2M, 초 단위로 열림. 크기 열을 살펴보면 뭔가 이해가 될 것입니다. 91 requests,113 kB transferred, 2.2 MB resources,Finish: 2.93 s,DOMContentLoaded: 177 ms.
2.2M的资源,达到秒开。看看Size那一列,你就应该好像领悟到什么了。
没错。HTTP缓存。 数据接口的请求一般来说较少,只有几个,而静态资源(如 JS、CSS、图片和字体等)的请求就太多了。以天猫首页为例,91 个请求中除了少数script外,其余都是静态资源请求。
那么,如何做静态缓存方案呢?这里有两种情况,一种是静态资源长期不需要修改,还有一种是静态资源修改频繁的。你可以尝试多刷新几次页面看看。
资源长期不变的话,比如 1 年都不怎么变化,我们可以使用强缓存,如 Cache-Control 来实现。具体来说可以通过设置 Cache-Control:max-age=31536000,来让浏览器在一年内直接使用本地缓存文件,而不是向服务端发出请求。
至于第二种,如果资源本身随时会发生改动的,可以通过设置 Etag 实现协商缓存。具体来说,在初次请求资源时,设置 Etag(比如使用资源的 md5 作为 Etag),并且返回 200 的状态码,之后请求时带上 If-none-match 字段,来询问服务器当前版本是否可用。如果服务端数据没有变化,会返回一个 304 的状态码给客户端,告诉客户端不需要请求数据,直接使用之前缓存的数据即可。当然,这里还涉及 WebView相关的东西,先不细讲。。。
离线化是指线上实时变动的资源数据静态化到本地,访问时走的是本地文件的方案。
离线包
就是一是离线化的一种方案,是将静态资源存储到 App 本地的方案,这里先不细讲。
但更复杂的另一种离线化方案:把页面内容静态化到本地。离线化一般适合首页或者列表页等不需要登录页面的场景,同时能够支持 SEO 功能。
那么,如何实现离线化呢?在打包构建时预渲染页面,前端请求落到 index.html 上时,已经是渲染过的内容。此时,可以通过 Webpack 的 prerender-spa-plugin 来实现预渲染,进而实现离线化。
Webpack 实现预渲染的代码示例如下:
// webpack.conf.js var path = require('path') var PrerenderSpaPlugin = require('prerender-spa-plugin') module.exports = { // ... plugins: [ new PrerenderSpaPlugin( // 编译后的html需要存放的路径 path.join(__dirname, '../dist'), // 列出哪些路由需要预渲染 [ '/', '/about', '/contact' ] ) ] } // 面试的时候离线化能讲到这,往往就是做死现场,但风险和收益成正比,值得冒险。那就是,你有木有自己的预渲染方案。
如果说懒加载、缓存和离线化都是在请求本身搞事情,想尽办法减少请求或者推迟请求,那并行化则是在请求通道上优化问题,解决请求阻塞问题,进而减少首屏时间。
例如广州打疫苗排队,新闻上报道是如何如何阻塞。 那除了让群众错开打疫苗的时间,还可以增加打疫苗的医生数量。我们在处理请求阻塞时,也可以加大请求通道数量——借助于HTTP 2.0
的多路复用方案来解决。
HTTP 1.1
时代,有两个性能瓶颈点,串行的文件传输和同域名的连接数限制(6个
)。到了HTTP 2.0
时代,因为提供了多路复用的功能,传输数据不再使用文本传输(文本传输必须按顺序传输,否则接收端不知道字符的顺序),而是采用二进制数据帧和流的方式进行传输。
其中,帧是数据接收的最小单位,流是连接中的一个虚拟通道,它可以承载双向信息。每个流都会有一个唯一的整数 ID 对数据顺序进行标识,这样接收端收到数据后,可以按照顺序对数据进行合并,不会出现顺序出错的情况。所以,在使用流的情况下,不论多少个资源请求,只要建立一个连接即可。
文件传输环节问题解决后,同域名连接数限制问题怎么解决呢?以 Nginx 服务器为例,原先因为每个域名有6
个连接数限制,最大并发就是 100
个请求,采用 HTTP 2.0
之后,现在则可以做到 600
,提升了 6
倍。
你一定会问,这不是运维侧要做的事情吗,我们前端开发需要做什么?我们要改变静态文件合并(JS、CSS、图片文件)和静态资源服务器做域名散列这两种开发方式。
具体来说,使用 HTTP 2.0
多路复用之后,单个文件可以单独上线,不需要再做 JS 文件合并了。这里提一个保留问题,用过阿里系的Antd组件库吧?库每次更新都不是全部更新,可能这次只更新一个Button
组件,再次只更新一个Card
맞습니다. HTTP 캐시. 일반적으로 데이터 인터페이스에 대한 요청은 적고 소수에 불과한 반면 정적 리소스(예: JS, CSS, 이미지, 글꼴 등)에 대한 요청은 너무 많습니다. Tmall 홈페이지를 예로 들면, 91개의 요청 중 일부 스크립트를 제외하고 나머지는 정적 리소스 요청입니다.
오프라인 패키지
는 오프라인 솔루션입니다🎜. 이는 정적 리소스를 앱에 로컬로 저장하는 솔루션입니다. 여기서는 자세히 설명하지 않겠습니다. 🎜🎜그러나 또 다른 더 복잡한 오프라인 솔루션은 페이지 콘텐츠를 로컬에서 정적화하는 것입니다. 🎜오프라인은 일반적으로 로그인 페이지가 필요하지 않은 홈페이지나 목록 페이지와 같은 시나리오에 적합하며 SEO 기능도 지원할 수 있습니다. 🎜🎜그렇다면 오프라인에서는 어떻게 달성할 수 있을까요? 페이지는 패키징 및 구성 중에 사전 렌더링됩니다. 프런트 엔드 요청이 index.html에 해당하면 이미 렌더링된 콘텐츠입니다. 이때 Webpack의 prerender-spa-plugin을 사용하여 사전 렌더링을 구현하고 오프라인 렌더링을 달성할 수 있습니다. 🎜🎜Webpack은 다음과 같이 사전 렌더링 코드 예제를 구현합니다. 🎜rrreeeHTTP 2.0
의 멀티플렉싱 솔루션을 사용하면 이 문제를 해결할 수 있습니다. 🎜🎜HTTP 1.1
시대에는 직렬 파일 전송과 동일한 도메인 이름(6
)에 대한 연결 수 제한이라는 두 가지 성능 병목 현상이 있었습니다. HTTP 2.0
시대에는 다중화 기능으로 인해 더 이상 텍스트 전송을 사용하여 데이터를 전송하지 않습니다. (텍스트 전송은 순서대로 전송해야하며 그렇지 않으면 수신 측에서 문자 순서를 알 수 없습니다) , 그러나 바이너리 데이터 프레임과 스트림은 전송됩니다. 🎜🎜🎜그 중 프레임은 데이터 수신의 가장 작은 단위이고 스트림은 양방향 정보를 전달할 수 있는 연결의 가상 채널입니다. 각 스트림에는 데이터 순서를 식별하는 고유한 정수 ID가 있으므로 수신 측에서 데이터를 수신한 후 순서 오류 없이 데이터를 순서대로 병합할 수 있습니다. 따라서 스트림을 사용하면 아무리 많은 리소스 요청이 있어도 하나의 연결만 설정됩니다. 🎜🎜파일 전송 문제가 해결된 후 동일한 도메인 이름으로 연결 수를 제한하는 문제를 해결하는 방법은 무엇입니까? Nginx 서버를 예로 들어보겠습니다. 원래 각 도메인 이름에는 6
연결 제한이 있었기 때문에 HTTP 2.0100
요청이었습니다. /code> 이제 6
배 증가한 600
을 달성할 수 있습니다. 🎜🎜이런게 운영 및 유지보수 측면에서 해야 할 일이 아닌가? 프론트엔드 개발에서 우리가 해야 할 일은 무엇일까? 정적 파일 병합(JS, CSS, 이미지 파일)과 정적 리소스 서버에 의한 도메인 이름 해싱이라는 두 가지 개발 방법을 변경해야 합니다. 🎜🎜구체적으로, HTTP 2.0
멀티플렉싱을 사용한 후에는 단일 파일을 독립적으로 온라인에 올릴 수 있으며 JS 파일을 병합할 필요가 없습니다. 다음은 예약된 질문입니다. Alibaba의 🎜Antd 구성 요소 라이브러리를 사용해 본 적이 있습니까? 라이브러리가 업데이트될 때마다 모든 항목이 업데이트되는 것은 아닙니다. 이번에는 하나의 Button
구성 요소만 업데이트되고 다시 하나의 Card
구성 요소만 업데이트됩니다. 그렇다면 개별 구성 요소를 별도로 릴리스하려면 어떻게 해야 할까요? 🎜🎜정적 도메인 이름 차단(성능 병목 현상)을 해결하려면 정적 도메인 이름을 pic0-pic5로 나누어 요청 병렬 처리 능력을 향상시켜야 합니다.
정적 리소스 도메인 이름을 해싱하면 문제가 해결되지만 DNS 확인 시간은 훨씬 길어지고 문제를 해결하려면 추가 서버가 필요합니다. HTTP 2.0
Multiplexing은 이 문제를 해결합니다.
더 많은 프로그래밍 관련 지식을 보려면 프로그래밍 소개를 방문하세요! !
위 내용은 당신이 알아야 할 프런트 엔드 성능 최적화에 대한 몇 가지 지식 포인트(1부)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!