진행하면서 코드 최적화

저는 작업 중인 제품의 크든 작든 상관없이 코드를 작성할 때 항상 확장과 최적화에 대해 생각하는 것을 강력히 지지합니다. 많은 사람들이 최적화할 필요가 없을 때 최적화할 이유가 없으며 이는 시간 낭비라고 주장합니다. 예, 때로는 약간의 추가 시간이 걸리지만 나중에는 약간의 시간이 큰 골칫거리를 덜어줄 수 있습니다.

나는 전체 기능을 재설계하는 것에 대해 말하는 것이 아니라 미래에 차이를 만들 것이라고 보장하는 코딩하는 동안 할 수 있는 작은 일에 대해 말하는 것입니다. 이 게시물에서는 DEV에서 최근에 수행한 작은 최적화의 예와 풀 요청 생성을 완전히 피할 수 있는 방법을 살펴보겠습니다.

가장 인기 있는 DEV 엔드포인트



DEV 페이지가 로드될 때마다 뷰에서 변수를 채우는 데 도움이 되는 일부 사용자 데이터를 가져오기 위해 비동기 호출을 수행합니다. 이 사용자 데이터는 엔드포인트async_info/base_data에서 가져옵니다. 이 호출은 모든 페이지 로드에 대해 이루어지기 때문에 가장 많이 적중된 끝점보다 위에 있습니다. 맨 위의 자주색 선은 async_info/base_data 엔드포인트에 대한 호출 수를 나타냅니다.



우리가 이 끝점을 많이 부르는 것을 감안할 때 나는 그것이 가능한 한 간결하고 의미가 있는지 확인하기 위해 자세히 살펴보기로 결정했습니다. 내가 한 첫 번째 일은 우리가 반환할 해시를 어떻게 구축하고 있는지 확인하는 것이었습니다. 변경 전의 해시는 다음과 같습니다.

{
  id: @user.id,
  name: @user.name,
  username: @user.username,
  profile_image_90: ProfileImage.new(@user).get(width: 90),

  followed_tag_names: @user.cached_followed_tag_names,
  followed_tags: @user.cached_followed_tags.to_json(only: %i[id name bg_color_hex text_color_hex hotness_score], methods: [:points]),

  followed_user_ids: @user.cached_following_users_ids,
  followed_organization_ids: @user.cached_following_organizations_ids,
  ...
}


동일한 데이터를 반환하는 두 개의 서로 다른 태그 필드가 있습니다. 어떤 필드가 먼저 추가되었는지는 모르지만 이 예를 위해 followed_tag_names가 첫 번째 필드라고 가정해 보겠습니다.

척하자...



해시에 followed_tags 값을 추가한 과거 개발자라고 가정해 보겠습니다. 이름뿐 아니라 뷰에 모든 태그 정보가 필요하므로 새 필드followed_tags를 해시에 추가합니다. 여기에서 많은 개발자가 중지합니다. 그들은 필요한 정보를 가지고 있으므로 작업이 완료됩니다.



이것은 내가 말할 때 멈추지 마십시오! 잠시 시간을 내어 해시를 살펴보세요. 이제 동일한 태그 정보를 얻기 위해 두 번의 호출을 하고 있습니다. 해시가 자주 생성되지 않는 경우에는 괜찮을 수 있지만 사이트가 시작되고 이 해시가 하루에 수백만 번 생성되는 경우에는 이상적이지 않습니다. 그 추가 호출이 합산됩니다. 중지하는 대신 이 최적화되지 않은 코드를 해결하기 위해 몇 분 더 시간을 할애하면 이 문제를 쉽게 해결할 수 있고 미래의 자신이 많은 골칫거리를 덜 수 있습니다.

최적화 옵션



다음은 이 코드를 최적화할 때 고려한 두 가지 옵션입니다.

1) 변수에 태그를 메모한 다음 아래와 같이 해시에서 해당 변수를 참조할 수 있습니다. 이렇게 하면 추가 데이터베이스 히트를 저장하고 중복 호출에 리소스를 낭비하지 않도록 할 수 있습니다.

tags = @user.cached_followed_tags
{
  id: @user.id,
  name: @user.name,
  username: @user.username,
  profile_image_90: ProfileImage.new(@user).get(width: 90),
  followed_tag_names: tags.map(&:name),
  followed_tags: tags.to_json(only: %i[id name bg_color_hex text_color_hex hotness_score], methods: [:points]),
  followed_user_ids: @user.cached_following_users_ids,
  followed_organization_ids: @user.cached_following_organizations_ids,
  ...
}


2) 추가 데이터베이스 호출을 원하지 않고 중복 정보 전송을 제거하려는 경우 . 풀 요청에서 followed_tag_names 필드를 제거하고 뷰 코드를 업데이트하여 followed_tags 필드에서 JSON을 구문 분석했습니다. 데이터베이스 히트를 저장하고 서버에서 주고받는 정보의 양을 줄이기 때문에 이것을 선택합니다.

const followedTagNames = JSON.parse(currentUser.followed_tags).map(t => t.name);
...
<ReadingList
  availableTags={followedTagNames}
  statusView={root.dataset.view}
/>,


TL; DR



몇 분 더 시간을 들여 코드를 살펴보고 규모에 대해 생각함으로써 최소한 미래의 자신에게 추가 작업을 절약할 수 있습니다. 기껏해야 앱이 대량 성장에 부딪히면 큰 둔화로부터 앱을 구할 수 있습니다.

행복한 스케일링!

좋은 웹페이지 즐겨찾기