React プロジェクトのサーバー側レンダリングの最適化
今回は React プロジェクトのサーバーサイドレンダリングの最適化についてお届けします。 React プロジェクトのサーバーサイドレンダリングの最適化に関する注意事項 について、実際のケースを見てみましょう。
Web ページの SEO の必要性のため、調査と研究を行った後、以前の React プロジェクトをサーバーサイド レンダリングに変換したいと考えました。罠を踏むことに成功した。
選択の考え方: サーバーサイドレンダリングを実装するには、Reactの最新バージョンを使用し、既存の記述方法に大きな変更を加えないでください。 最初からサーバーサイドでレンダリングするつもりであれば、それはです。 NEXT フレームワークを使用して直接記述することをお勧めします
プロジェクトアドレス: https://github.com/wlx200510/react_koa_ssr
スキャフォールディングの選択: webpack3.11.0 + React Router4 + Redux + koa2 + React16 + Node8.x
Main経験: React関連の知識を深め、拡張に成功しました 私自身の技術分野では、実際のプロジェクトでサーバーサイド技術の経験を積みました
注意: フレームワークを使用する前に、現在のWebpackバージョンが3.x およびノードは 8.x 以降であることが推奨されます。読者は React を 3 か月以上使用し、実際の React プロジェクトの経験があることが最適です
プロジェクト ディレクトリの紹介
├── assets │ └── index.css //放置一些全局的资源文件 可以是js 图片等 ├── config │ ├── webpack.config.dev.js 开发环境webpack打包设置 │ └── webpack.config.prod.js 生产环境webpack打包设置 ├── package.json ├── README.md ├── server server端渲染文件,如果对不是很了解,建议参考[koa教程](http://wlxadyl.cn/2018/02/11/koa-learn/) │ ├── app.js │ ├── clientRouter.js // 在此文件中包含了把服务端路由匹配到react路由的逻辑 │ ├── ignore.js │ └── index.js └── src ├── app 此文件夹下主要用于放置浏览器和服务端通用逻辑 │ ├── configureStore.js //redux-thunk设置 │ ├── createApp.js //根据渲染环境不同来设置不同的router模式 │ ├── index.js │ └── router │ ├── index.js │ └── routes.js //路由配置文件! 重要 ├── assets │ ├── css 放置一些公共的样式文件 │ │ ├── _base.scss //很多项目都会用到的初始化css │ │ ├── index.scss │ │ └── my.scss │ └── img ├── components 放置一些公共的组件 │ ├── FloatDownloadBtn 公共组件样例写法 │ │ ├── FloatDownloadBtn.js │ │ ├── FloatDownloadBtn.scss │ │ └── index.js │ ├── Loading.js │ └── Model.js 函数式组件的写法 │ ├── favicon.ico ├── index.ejs //渲染的模板 如果项目需要,可以放一些公共文件进去 ├── index.js //包括热更新的逻辑 ├── pages 页面组件文件夹 │ ├── home │ │ ├── components // 用于放置页面组件,主要逻辑 │ │ │ └── homePage.js │ │ ├── containers // 使用connect来封装出高阶组件 注入全局state数据 │ │ │ └── homeContainer.js │ │ ├── index.js // 页面路由配置文件 注意thunk属性 │ │ └── reducer │ │ └── index.js // 页面的reducer 这里暴露出来给store统一处理 注意写法 │ └── user │ ├── components │ │ └── userPage.js │ ├── containers │ │ └── userContainer.js │ └── index.js └── store ├── actions // 各action存放地 │ ├── home.js │ └── thunk.js ├── constants.js // 各action名称汇集处 防止重名 └── reducers └── index.js // 引用各页面的所有reducer 在此处统一combine处理
。
ローカル開発では、webpack-dev-server を使用してホット アップデートを実現します。基本的なプロセスは以前の反応開発と似ていますが、ブラウザ側でレンダリングするため、コードを記述するときは、一連のロジックと 2 つのレンダリングを考慮する必要があります。環境。
フロントエンドページのレンダリングが完了すると、ルータージャンプはサーバーにリクエストを行わなくなり、サーバーへの負荷が軽減されます。したがって、ページに入る方法も2つあります。 2 つのレンダリング環境におけるルーティングの同型性が問題です。
実稼働環境では、オンデマンド読み込みを実装し、サーバー側でデータを取得し、HTML 全体をレンダリングするためにバックエンドサーバーとして koa を使用する必要があります。React16 の最新機能を使用して状態ツリー全体をマージします。サーバー側のレンダリングを実現します。
ローカル開発の概要
ローカル開発の表示に関係する主なファイルは、現在の実行環境を決定するための src ディレクトリ内のindex.js ファイルです。 module.hot の API は開発環境でのみ使用されます。 Reducer が変更されたときに現在のページのレンダリング更新通知を実装するために使用されます。 これは、v16 バージョンで特別に追加された新しい API メソッドであり、render メソッドをベースにして最大限の可能性を実現します。サーバーサイドコンテンツのレンダリングを再利用することで、静的DOMから動的NODESへのプロセスを実現します。本質は、v15 バージョンでのチェックサム マークを判断するプロセスを置き換えて、再利用プロセスをより効率的かつ洗練されたものにすることです。
const renderApp=()=>{ let application=createApp({store,history}); hydrate(application,document.getElementById('root')); } window.main = () => { Loadable.preloadReady().then(() => { renderApp() }); }; if(process.env.NODE_ENV==='development'){ if(module.hot){ module.hot.accept('./store/reducers/index.js',()=>{ let newReducer=require('./store/reducers/index.js'); store.replaceReducer(newReducer) }) module.hot.accept('./app/index.js',()=>{ let {createApp}=require('./app/index.js'); let newReducer=require('./store/reducers/index.js'); store.replaceReducer(newReducer) let application=createApp({store,history}); hydrate(application,document.getElementById('root')); }) } }
window.main 関数の定義に注意してください。index.ejs と組み合わせると、この関数はすべてのスクリプトがロードされた後にトリガーされることがわかります。反応ロード可能な書き込みメソッドはページの遅延読み込みに使用されます。ページについては、ルーティング設定と合わせて個別にパッケージ化されているので、全体的な感想を述べておきます。アプリ ファイルの下で公開される 3 つのメソッドは、ブラウザ側とサーバー側で共通であることに注意してください。以下では主にこの部分のアイデアについて説明します。
ルート処理
次に、src/app ディレクトリ内の次のファイルを見てください。index.js は、サーバー側とブラウザー側の両方の開発で使用される 3 つのメソッドを公開します。 router ファイルのコードの考え方と createApp.js ファイルのルーティングの処理について これが、両端のルート間で相互通信を実現するための重要なポイントです。 router フォルダー内の
routes.js は、各ページのルーティング設定をインポートし、設定配列に合成することで、ページのオンラインとオフラインを柔軟に制御するために使用できます。同じディレクトリ内の Index.js は、RouterV4 を記述する標準的な方法です。 ConnectRouter は、ルーターをマージするために使用されるコンポーネントであり、パラメーターとして渡す必要があることに注意してください。 createApp.js ファイルに含める必要があります。別の処理を実行します。 Route コンポーネントのいくつかの構成項目を簡単に見てみましょう。注目に値するのは、バックエンドがデータを取得した後のレンダリングを実現するための重要なステップである、Next と同様のコンポーネントがデータを取得できるようにする属性です。 ライフサイクルフックおよびその他の属性は、関連する React-router ドキュメントに記載されているため、ここでは説明しません。
import routesConfig from './routes'; const Routers=({history})=>( <ConnectedRouter history={history}> <p> { routesConfig.map(route=>( <Route key={route.path} exact={route.exact} path={route.path} component={route.component} thunk={route.thunk} /> )) } </p> </ConnectedRouter> ) export default Routers;
查看app目录下的createApp.js里面的代码可以发现,本框架是针对不同的工作环境做了不同的处理,只有在生产环境下才利用Loadable.Capture方法实现了懒加载,动态引入不同页面对应的打包之后的js文件。到这里还要看一下组件里面的路由配置文件的写法,以home页面下的index.js为例。注意/* webpackChunkName: 'Home' */这串字符,实质是指定了打包后此页面对应的js文件名,所以针对不同的页面,这个注释也需要修改,避免打包到一起。loading这个配置项只会在开发环境生效,当页面加载未完成前显示,这个实际项目开发如果不需要可以删除此组件。
import {homeThunk} from '../../store/actions/thunk'; const LoadableHome = Loadable({ loader: () =>import(/* webpackChunkName: 'Home' */'./containers/homeContainer.js'), loading: Loading, }); const HomeRouter = { path: '/', exact: true, component: LoadableHome, thunk: homeThunk // 服务端渲染会开启并执行这个action,用于获取页面渲染所需数据 } export default HomeRouter
这里多说一句,有时我们要改造的项目的页面文件里有从window.location里面获取参数的代码,改造成服务端渲染时要全部去掉,或者是要在render之后的生命周期中使用。并且页面级别组件都已经注入了相关路由信息,可以通过this.props.location来获取URL里面的参数。本项目用的是BrowserRouter,如果用HashRouter则包含参数可能略有不同,根据实际情况取用。
根据React16的服务端渲染的API介绍:
浏览器端使用的注入ConnectedRouter中的history为:import createHistory from 'history/createBrowserHistory'
服务器端使用的history为import createHistory from 'history/createMemoryHistory'
服务端渲染
这里就不会涉及到koa2的一些基础知识,如果对koa2框架不熟悉可以参考我的另外一篇博文。这里是看server文件夹下都是服务端的代码。首先是简洁的app.js用于保证每次连接都返回的是一个新的服务器端实例,这对于单线程的js语言是很关键的思路。需要重点介绍的就是clientRouter.js这个文件,结合/src/app/configureStore.js这个文件共同理解服务端渲染的数据获取流程和React的渲染机制。
/*configureStore.js*/ import {createStore, applyMiddleware,compose} from "redux"; import thunkMiddleware from "redux-thunk"; import createHistory from 'history/createMemoryHistory'; import { routerReducer, routerMiddleware } from 'react-router-redux' import rootReducer from '../store/reducers/index.js'; const routerReducers=routerMiddleware(createHistory());//路由 const composeEnhancers = process.env.NODE_ENV=='development'?window.REDUX_DEVTOOLS_EXTENSION_COMPOSE : compose; const middleware=[thunkMiddleware,routerReducers]; //把路由注入到reducer,可以从reducer中直接获取路由信息 let configureStore=(initialState)=>createStore(rootReducer,initialState,composeEnhancers(applyMiddleware(...middleware))); export default configureStore;
window.REDUX_DEVTOOLS_EXTENSION_COMPOSE这个变量是浏览器里面的Redux的开发者工具,开发React-redux应用时建议安装,否则会有报错提示。这里面大部分都是redux-thunk的示例代码,关于这部分如果看不懂建议看一下redux-thunk的官方文档,这里要注意的是configureStore这个方法要传入的initialState参数,这个渲染的具体思路是:在服务端判断路由的thunk方法,如果存在则需要执行这个获取数据逻辑,这是个阻塞过程,可以当作同步,获取后放到全局State中,在前端输出的HTML中注入window.INITIAL_STATE这个全局变量,当html载入完毕后,这个变量赋值已有数据的全局State作为initState提供给react应用,然后浏览器端的js加载完毕后会通过复用页面上已有的dom和初始的initState作为开始,合并到render后的生命周期中,从而在componentDidMount中已经可以从this.props中获取渲染所需数据。
但还要考虑到页面切换也有可能在前端执行跳转,此时作为React的应用不会触发对后端的请求,因此在componentDidMount这个生命周期里并没有获取数据,为了解决这个问题,我建议在这个生命周期中都调用props中传来的action触发函数,但在action内部进行一层逻辑判断,避免重复的请求,实际项目中请求数据往往会有个标识性ID,就可以将这个ID存入store中,然后就可以进行一次对比校验来提前返回,避免重复发送ajax请求,具体可看store/actions/home.js`中的逻辑处理。
import {ADD,GET_HOME_INFO} from '../constants' export const add=(count)=>({type: ADD, count,}) export const getHomeInfo=(sendId=1)=>async(dispatch,getState)=>{ let {name,age,id}=getState().HomeReducer.homeInfo; if (id === sendId) { return //是通过对请求id和已有数据的标识性id进行对比校验,避免重复获取数据。 } console.log('footer'.includes('foo')) await new Promise(resolve=>{ let homeInfo={name:'wd2010',age:'25',id:sendId} console.log('-----------请求getHomeInfo') setTimeout(()=>resolve(homeInfo),1000) }).then(homeInfo=>{ dispatch({type:GET_HOME_INFO,data:{homeInfo}}) }) }
注意这里的async/await写法,这里涉及到服务端koa2使用这个来做数据请求,因此需要统一返回async函数,这块不熟的同学建议看下ES7的知识,主要是async如何配合Promise实现异步流程改造,并且如果涉及koa2的服务端工作,对async函数用的更多,这也是本项目要求Node版本为8.x以上的原因,从8开始就可以直接用这两个关键字。
不过到具体项目中,往往会涉及到一些服务端参数的注入问题,但这块根据不同项目需求差异很大,并且不属于这个React服务端改造的一部分,没法统一分享,如果真是公司项目要用到对这块有需求咨询可以打赏后加我微信讨论。
以Home页面为例的渲染流程
誰もが理解しやすいように、データ フローの全体的なプロセスを整理し、そのアイデアを見てみるページを例として取り上げました:
サーバーはリクエストを受信し、/ を通じて対応するルーティング設定を見つけます。 home
- を使用して、route thunk メソッドの存在を確認します。このとき、store/actions/thunk.js にある公開された関数が実行され、この時点でディスパッチ ディストリビューションに非同期で取得されます。 time は実際には反映されません。
- 出力される HTML コードでは、データを取得した後のグローバル状態が initState
- としてグローバル変数 window.INITIAL_STATE に配置されます。 React ライフサイクルが有効になる前のグローバル状態。この時点で、React は dom が生成されたことを検出し、レンダリングは再度トリガーされず、データのステータスは同期されます
- サーバーは HTML を直接出力します
一部のReducerの関数記述とアクションの位置については、インターネット上の分析を元にまとめたものです。これに沿っている限り、さまざまな意見があります。自分自身の理解を深め、チーム開発に役立ててください。この記事の冒頭で私が設定した読者の背景を満たしているのであれば、この記事の説明は独自のサーバーサイド レンダリング テクノロジを理解するのに十分であると思います。 React についてあまり知らなくても問題ありません。React の基礎知識を補うためにここを参照してください。この記事の事例を読んだ後は、方法を習得したと思います。さらに興味深い情報については、お支払いください。 PHP 中国語 Web サイトの他の関連記事にも注目してください。
react-nativeパッケージプラグインswiperを使用する手順の詳細な説明
Nodejs mysqlデータベースに接続する手順の詳細な説明以上がReact プロジェクトのサーバー側レンダリングの最適化の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









1. まず、Kijiale でレンダリングするデザインプランを開きます。 2. 次に、レンダリング メニューでトップ ビュー レンダリングを開きます。 3. 次に、トップ ビュー レンダリング インターフェイスのパラメーター設定で [直交] をクリックします。 4. 最後に、モデルの角度を調整した後、[今すぐレンダリング]をクリックして直交上面ビューをレンダリングします。

PHP、Vue、React: 最適なフロントエンド フレームワークを選択するには?インターネット技術の継続的な発展に伴い、フロントエンド フレームワークは Web 開発において重要な役割を果たしています。 PHP、Vue、React は 3 つの代表的なフロントエンド フレームワークであり、それぞれに独自の特徴と利点があります。使用するフロントエンド フレームワークを選択するとき、開発者はプロジェクトのニーズ、チームのスキル、個人の好みに基づいて情報に基づいた決定を下す必要があります。この記事では、PHP、Vue、React の 3 つのフロントエンド フレームワークの特徴と用途を比較します。

Java フレームワークと React フレームワークの統合: 手順: バックエンド Java フレームワークをセットアップします。プロジェクト構造を作成します。ビルドツールを設定します。 React アプリケーションを作成します。 REST API エンドポイントを作成します。通信メカニズムを構成します。実際のケース (SpringBoot+React): Java コード: RESTfulAPI コントローラーを定義します。 React コード: API によって返されたデータを取得して表示します。

時間計算量は、入力のサイズに対するアルゴリズムの実行時間を測定します。 C++ プログラムの時間の複雑さを軽減するためのヒントには、適切なコンテナー (ベクター、リストなど) を選択して、データのストレージと管理を最適化することが含まれます。クイックソートなどの効率的なアルゴリズムを利用して計算時間を短縮します。複数の操作を排除して二重カウントを削減します。条件分岐を使用して、不必要な計算を回避します。二分探索などのより高速なアルゴリズムを使用して線形探索を最適化します。

1. デスクトップでキーの組み合わせ (win キー + R) を押してファイル名を指定して実行ウィンドウを開き、[regedit] と入力して Enter キーを押して確定します。 2. レジストリ エディターを開いた後、[HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionExplorer] をクリックして展開し、ディレクトリに Serialize 項目があるかどうかを確認します。ない場合は、エクスプローラーを右クリックして新しい項目を作成し、Serialize という名前を付けます。 3. 次に、「シリアル化」をクリックし、右側のペインの空白スペースを右クリックして、新しい DWORD (32) ビット値を作成し、「Star」という名前を付けます。

Vivox100s のパラメーター構成が明らかに: プロセッサーのパフォーマンスを最適化するには?テクノロジーが急速に発展する今日、スマートフォンは私たちの日常生活に欠かせないものとなっています。スマートフォンの重要な部分であるプロセッサのパフォーマンスの最適化は、携帯電話のユーザー エクスペリエンスに直接関係します。注目度の高いスマートフォンとして、Vivox100s のパラメータ構成は多くの注目を集めており、特にプロセッサー性能の最適化はユーザーからの注目を集めています。プロセッサは携帯電話の「頭脳」として、携帯電話の動作速度に直接影響します。

PHP 関数の効率を最適化する 5 つの方法: 変数の不必要なコピーを避ける。参照を使用して変数のコピーを回避します。繰り返しの関数呼び出しを避けてください。単純な関数をインライン化します。配列を使用したループの最適化。

最近、「Black Myth: Wukong」は世界中で大きな注目を集めており、各プラットフォームでの同時オンライン人口は過去最高に達しており、このゲームは複数のプラットフォームで大きな商業的成功を収めています。 『Black Myth: Wukong』のXbox版は延期 『Black Myth: Wukong』はPCとPS5プラットフォームでリリースされているが、Xbox版については明確な情報はない。 『Black Myth: Wukong』がXboxプラットフォームで発売されることを関係者が認めたことが分かりました。ただし、具体的な発売日はまだ発表されていない。 Xbox 版の遅延は技術的な問題によるものであると最近報告されました。関連ブロガーによると、同氏はGamescom期間中の開発者や「Xbox関係者」とのやり取りから、Xbox版「Black Myth: Wukong」が存在することを知ったという。
